home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / DDELIB13.ZIP / SUB.C < prev    next >
C/C++ Source or Header  |  1990-09-12  |  9KB  |  359 lines

  1. /* **********************************************************
  2.    sub.c - Controls a sub in FISH to shoot fish using DDE
  3.  
  4.    Placed in public domain by Horizon Technologies Inc. 1990
  5.  
  6.   ***revision history***
  7. 1 SUB.C 24-Jan-90,15:11:52,`JMH' Initial version
  8. 2 SUB.C 29-Jan-90,9:13:06,`JMH' Semi-stable version
  9. 3 SUB.C 19-Feb-90,14:43:14,`JMH' Version as of 3/5/90
  10. 4 SUB.C 19-Jun-90,10:51:24,`JMH' Version as of 6/25/90
  11. 5 SUB.C 25-Jun-90,14:48:12,`JMH' Version as of 6/25/90
  12. 6 SUB.C 2-Jul-90,14:15:54,`PRS' Version as of 6/25/90
  13. 7 SUB.C 19-Jul-90,9:22:42,`PRS' Version with win.ini regerstered settings
  14. 8 SUB.C 12-Sep-90,15:59:04,`JMH' Version 1.3
  15.   ***revision history***
  16. ********************************************************** */
  17. #define MAIN
  18. #define NOCOMM
  19.  
  20. #include "windows.h"
  21. #include "stdio.h"
  22. #include "stdlib.h"
  23. #include "string.h"
  24. #include "dde.h"
  25. #include "ddelib.h"
  26. #include "sub.h"
  27.  
  28. /* Undocumented windows functions */
  29. int FAR PASCAL lstrlen (LPSTR);
  30. LPSTR FAR PASCAL lstrcpy (LPSTR, LPSTR);
  31. LPSTR FAR PASCAL lstrcat (LPSTR, LPSTR);
  32. int FAR PASCAL lstrcmp (LPSTR, LPSTR);
  33.  
  34. /* Globals */
  35.  
  36. static HANDLE ghInstance;
  37.  
  38. static char *gszAppName = "Sub";
  39.  
  40. static int gxFish, gyFish;
  41.  
  42. static int gxSub, gySub;
  43.  
  44. static int gxPrevFish;
  45.  
  46. static DWORD gdwSampleRate;
  47.  
  48. static DWORD gdwSampleCounter;
  49.  
  50. static HANDLE ghFish;
  51.  
  52. static HANDLE ghSub;
  53.  
  54. static DDECALLBACK glpfnFish;
  55.  
  56. static DDECALLBACK glpfnSub;
  57.  
  58. static FARPROC glpfnAbout;
  59.  
  60. /* Functions */
  61. int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
  62. long FAR PASCAL SubProc (HWND, unsigned, WORD, LONG);
  63. WORD FAR PASCAL Fish (HWND, unsigned, LPSTR, HANDLE);
  64. WORD FAR PASCAL Sub (HWND, unsigned, LPSTR, HANDLE);
  65. void MoveSub (void);
  66. BOOL FAR PASCAL About (HWND, unsigned, WORD, LONG);
  67.  
  68.  
  69. int PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  70. HANDLE hInstance;
  71. HANDLE hPrevInstance;
  72. LPSTR lpCmdLine;
  73. int nCmdShow;
  74. {
  75.    WNDCLASS wndclass;
  76.    MSG msg;
  77.    HWND hWnd;
  78.  
  79.    ghInstance = hInstance;
  80.  
  81.    if ( !hPrevInstance )
  82.       {
  83.       wndclass.style = CS_HREDRAW | CS_VREDRAW;
  84.       wndclass.lpfnWndProc = SubProc;
  85.       wndclass.cbClsExtra = 0;
  86.       wndclass.cbWndExtra = 0;
  87.       wndclass.hInstance = hInstance;
  88.       wndclass.hIcon = LoadIcon ( hInstance, gszAppName );
  89.       wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW );
  90.       wndclass.hbrBackground = (HBRUSH) GetStockObject ( WHITE_BRUSH );
  91.       wndclass.lpszMenuName = gszAppName;
  92.       wndclass.lpszClassName = gszAppName;
  93.  
  94.       if ( !RegisterClass ( &wndclass ) )
  95.      return FALSE;
  96.       }  /* if ! hPrevInstance */
  97.  
  98.    hWnd = CreateWindow ( gszAppName, gszAppName, WS_OVERLAPPEDWINDOW,
  99.              CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
  100.              hInstance, NULL );
  101.  
  102.    if ( !hWnd )
  103.       return ( NULL );
  104.  
  105.    ShowWindow ( hWnd, SW_SHOWMINIMIZED );
  106.    UpdateWindow ( hWnd );
  107.  
  108.    while ( GetMessage ( &msg, NULL, NULL, NULL ) )
  109.       {
  110.       TranslateMessage ( &msg );
  111.       DispatchMessage ( &msg );
  112.       }  /* while GetMessage */
  113.  
  114.    return ( msg.wParam );
  115. }  /* function WinMain */
  116.  
  117.  
  118. long FAR PASCAL SubProc (hWnd, iMessage, wParam, lParam)
  119. HWND hWnd;
  120. unsigned iMessage;
  121. WORD wParam;
  122. LONG lParam;
  123. {
  124.    DDEADVISE ddeAdvise;
  125.    PAINTSTRUCT ps;
  126.    char szText[40];
  127.  
  128.    switch ( iMessage )
  129.       {
  130.       case WM_CREATE:
  131.      /* Provide callback addresses for DDE callback functions */
  132.      glpfnFish = (DDECALLBACK) MakeProcInstance ( (FARPROC) Fish,
  133.                               ghInstance );
  134.      glpfnSub = (DDECALLBACK) MakeProcInstance ( (FARPROC) Sub,
  135.                              ghInstance );
  136.  
  137.      /* Inititate DDE Sessions with FISH */
  138.      if ( !( ghFish = DDEInitiate ( hWnd, "Fish", "Position" ) ) )
  139.         break;
  140.      if ( !( ghSub = DDEInitiate ( hWnd, "Fish", "Sub" ) ) )
  141.         break;
  142.  
  143.      /* Ask to be advised everytime fish number zero makes a move */
  144.      ddeAdvise.fDeferUpd = FALSE;
  145.      ddeAdvise.fAckReq = TRUE;
  146.      ddeAdvise.cfFormat = CF_TEXT;
  147.      DDEAdvise ( ghFish, "0", &ddeAdvise, glpfnFish );
  148.  
  149.      /* Set up a timer to determine the sampling rate */
  150.      SetTimer ( hWnd, NULL, 5000, NULL );
  151.      break;
  152.  
  153.       case WM_COMMAND:
  154.      switch ( wParam )
  155.         {
  156.         case IDM_EXIT:
  157.            SendMessage ( hWnd, WM_CLOSE, 0, 0L );
  158.            break;
  159.  
  160.         case IDM_ABOUT:
  161.            glpfnAbout = MakeProcInstance ( About, ghInstance );
  162.            DialogBox ( ghInstance, "About", hWnd, glpfnAbout );
  163.            FreeProcInstance ( glpfnAbout );
  164.            break;
  165.         }  /* switch wParam */
  166.      break;
  167.  
  168.       case WM_PAINT:
  169.      BeginPaint ( hWnd, &ps );
  170.  
  171.      /* Print the sampling rate */
  172.      sprintf ( szText, "Sample rate:  %ld/minute, %ld/second",
  173.            gdwSampleRate, gdwSampleRate / 60 );
  174.      TextOut ( ps.hdc, 0, 0, szText, strlen ( szText ) );
  175.  
  176.      sprintf ( szText, "Message rate: %ld/minute, %ld/second",
  177.            gdwSampleRate * 7, gdwSampleRate * 7 / 60 );
  178.      TextOut ( ps.hdc, 0, 20, szText, strlen ( szText ) );
  179.  
  180.      EndPaint ( hWnd, &ps );
  181.      break;
  182.  
  183.       case WM_TIMER:
  184.      /* Reset the sample rate counter */
  185.      gdwSampleRate = gdwSampleCounter * 12;
  186.      gdwSampleCounter = 0;
  187.  
  188.      /* Cause a repainting of the client area */
  189.      InvalidateRect ( hWnd, NULL, TRUE );
  190.      UpdateWindow ( hWnd );
  191.      break;
  192.  
  193.       case WM_DESTROY:
  194.      /* Cancel the advise circuit for fish zero */
  195.      // DDEUnadvise (ghFish, "0"); - BUG: FISH does not ack the unadvise
  196.  
  197.      /* End the sessions with FISH */
  198.      DDETerminate ( ghFish );
  199.      DDETerminate ( ghSub );
  200.      PostQuitMessage ( 0 );
  201.      break;
  202.  
  203.       default:
  204.      return DefWindowProc ( hWnd, iMessage, wParam, lParam );
  205.       }  /* switch iMessage */
  206.  
  207.    return 0L;
  208. }  /* function SubProc */
  209.  
  210.  
  211. /* Callback routine to notify us when the fish moves */
  212. WORD FAR PASCAL Fish (hFish, iMessage, lpszItem, hData)
  213. HWND hFish;
  214. unsigned iMessage;
  215. LPSTR lpszItem;
  216. HANDLE hData;
  217. {
  218.    LPDDEDATA lpData;
  219.    char szData[20];
  220.  
  221.    /* If this is good data */
  222.  
  223.    if ( iMessage == DDE_DATA )
  224.       {
  225.       /* Move data to a local string */
  226.       lpData = (LPDDEDATA) GlobalLock ( hData );
  227.       lstrcpy ( szData, lpData->Value );
  228.       GlobalUnlock ( hData );
  229.  
  230.       /* Save the previous x-position of Fish zero */
  231.       gxPrevFish = gxFish;
  232.  
  233.       /* Fish out new fish position */
  234.       sscanf ( szData, "%d %d", &gxFish, &gyFish );
  235.  
  236.       /* Request the current position of the sub */
  237.       DDERequest ( ghSub, "Position", CF_TEXT, glpfnSub );
  238.  
  239.       /* Go get the fish that moved */
  240.       MoveSub ();
  241.  
  242.       /* Show a sample hit */
  243.       gdwSampleCounter++;
  244.       }  /* if iMessage */
  245.  
  246.    return NULL;
  247. }  /* function Fish */
  248.  
  249.  
  250. /* Callback routine to notify us of the current sub position */
  251. WORD FAR PASCAL Sub (hSub, iMessage, lpszItem, hData)
  252. HWND hSub;
  253. unsigned iMessage;
  254. LPSTR lpszItem;
  255. HANDLE hData;
  256. {
  257.    LPDDEDATA lpData;
  258.    char szData[20];
  259.  
  260.    /* If this is good data */
  261.  
  262.    if ( iMessage == DDE_DATA )
  263.       {
  264.       /* Move data to a local string */
  265.       lpData = (LPDDEDATA) GlobalLock ( hData );
  266.       lstrcpy ( szData, lpData->Value );
  267.       GlobalUnlock ( hData );
  268.  
  269.       /* Fish out sub position */
  270.       sscanf ( szData, "%d %d", &gxSub, &gySub );
  271.       }  /* if iMessage */
  272.  
  273.    return NULL;
  274. }  /* function Sub */
  275.  
  276.  
  277. /* Function to compute execute command and do it */
  278. void MoveSub ()
  279. {
  280.    HANDLE hCommand;
  281.    LPSTR lpszCommand;
  282.    BOOL bFire = TRUE;
  283.  
  284.    /* Allocate room for the command */
  285.  
  286.    hCommand = GlobalAlloc ( GHND | GMEM_DDESHARE, (DWORD) 10 );
  287.    lpszCommand = GlobalLock ( hCommand );
  288.  
  289.    /* Fish is moving right... */
  290.    if ( gxFish > gxPrevFish )
  291.       {
  292.       /* We are behind the fish, go get it! */
  293.       if ( gxFish > gxSub + 100 )
  294.      lstrcpy ( lpszCommand, "[r]" );
  295.  
  296.       /* Can't fire... too close... back away */
  297.       else
  298.      {
  299.      lstrcpy ( lpszCommand, "[l]" );
  300.      bFire = FALSE;
  301.      }  /* else */
  302.       }  /* if gxFish */
  303.  
  304.    /* Fish is moving left... */
  305.    else
  306.       {
  307.       /* We are behind the fish, go get it! */
  308.       if ( gxFish < gxSub - 100 )
  309.      lstrcpy ( lpszCommand, "[l]" );
  310.  
  311.       /* Can't fire... too close... back away */
  312.       else
  313.      {
  314.      lstrcpy ( lpszCommand, "[r]" );
  315.      bFire = FALSE;
  316.      }  /* else */
  317.       }  /* else */
  318.  
  319.    /* Compute simple up/down command */
  320.    lstrcat ( lpszCommand, ( gyFish < gySub ) ? "[u]" : "[d]" );
  321.  
  322.    /* Check for vertical accuracy, cancel fire if too high or low */
  323.    if ( abs ( gyFish - gySub ) > 10 )
  324.       bFire = FALSE;
  325.  
  326.    /* Add the command to Fire! */
  327.    if ( bFire )
  328.       lstrcat ( lpszCommand, "[f]" );
  329.  
  330.    /* Clean up */
  331.    GlobalUnlock ( hCommand );
  332.  
  333.    /* Execute the command */
  334.    DDEExecute ( ghSub, hCommand );
  335. }  /* function MoveSub */
  336.  
  337.  
  338. /* About box */
  339. BOOL FAR PASCAL About (hDlg, iMessage, wParam, lParam)
  340. HWND hDlg;
  341. unsigned iMessage;
  342. WORD wParam;
  343. LONG lParam;
  344. {
  345.    switch ( iMessage )
  346.       {
  347.       case WM_INITDIALOG:
  348.      break;
  349.  
  350.       case WM_COMMAND:
  351.      EndDialog ( hDlg, FALSE );
  352.      break;
  353.  
  354.       default:
  355.      return FALSE;
  356.       }  /* switch iMessage */
  357.    return TRUE;
  358. }  /* function About */
  359.