home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winsock / ipxchat / ipxchat.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  13KB  |  477 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   ipxchat.c
  9. //
  10. //  PURPOSE:   Implement the windows procedure for the main application
  11. //    windows.  Also implement the generic message and command dispatchers.
  12. //
  13. //  FUNCTIONS:
  14. //    WndProc           - Processes messages for the main window.
  15. //    MsgCreate         - Initializes Edit Controls for text input/output.
  16. //    MsgSize           - Adjusts size of Edit Controls when window is resized.
  17. //    MsgSetfocus       - Keeps window focus on edit control instead of parent.
  18. //    MsgDataready      - Reads data from incoming IPC mechanism.
  19. //    MsgRefreshdisplay - Refills Inbox edit control text contents
  20. //    MsgDisconnected   - Cleans up connection killed by other side
  21. //    MsgCommand        - Handle the WM_COMMAND messages for the main window.
  22. //    MsgDestroy        - Handles the WM_DESTROY message by calling 
  23. //                        PostQuitMessage().
  24. //    CmdOutbox         - Handles messages from Outbox edit control.
  25. //    CmdDisconnected   - Disconnects current connection
  26. //    CmdExit           - Handles the file exit command by calling destory 
  27. //                        window on the main window.
  28. //
  29. //  COMMENTS:
  30. //
  31.  
  32. #include <windows.h>            // required for all Windows applications
  33. #include <windowsx.h>
  34. #include <wsipx.h>
  35. #include "globals.h"            // prototypes specific to this application
  36.  
  37.  
  38. // Main window message table definition.
  39. MSD rgmsd[] =
  40. {
  41.     {WM_CREATE,         MsgCreate},
  42.     {WM_SIZE,           MsgSize},
  43.     {WM_SETFOCUS,       MsgSetfocus},
  44.     {WM_COMMAND,        MsgCommand},
  45.     {WM_DESTROY,        MsgDestroy},
  46.     {MW_DATAREADY,      MsgDataready},
  47.     {MW_DISCONNECTED,   MsgDisconnected},
  48.     {MW_DISPLAYREFRESH, MsgRefreshdisplay}
  49. };
  50.  
  51. MSDI msdiMain =
  52. {
  53.     sizeof(rgmsd) / sizeof(MSD),
  54.     rgmsd,
  55.     edwpWindow
  56. };
  57.  
  58.  
  59. // Main window command table definition.
  60. CMD rgcmd[] =
  61. {
  62.     {IDM_CONNECT,    CmdConnect},
  63.     {IDM_LISTEN,     CmdListen},
  64.     {IDM_EXIT,       CmdExit},
  65.     {IDM_ABOUT,      CmdAbout},
  66.     {ID_OUTBOX,      CmdOutbox},
  67.     {IDM_DISCONNECT, CmdDisconnect}
  68. };
  69.  
  70. CMDI cmdiMain =
  71. {
  72.     sizeof(rgcmd) / sizeof(CMD),
  73.     rgcmd,
  74.     edwpWindow
  75. };
  76.  
  77.  
  78. //
  79. //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  80. //
  81. //  PURPOSE:  Processes messages for the main window.
  82. //
  83. //  PARAMETERS:
  84. //    hwnd     - window handle
  85. //    uMessage - message number
  86. //    wparam   - additional information (dependant on message number)
  87. //    lparam   - additional information (dependant on message number)
  88. //
  89. //  RETURN VALUE:
  90. //    The return value depends on the message number.  If the message
  91. //    is implemented in the message dispatch table, the return value is
  92. //    the value returned by the message handling function.  Otherwise,
  93. //    the return value is the value returned by the default window procedure.
  94. //
  95. //  COMMENTS:
  96. //    Call the DispMessage() function with the main window's message dispatch
  97. //    information (msdiMain) and the message specific information.
  98. //
  99.  
  100. LRESULT CALLBACK WndProc(HWND   hwnd, 
  101.                          UINT   uMessage, 
  102.                          WPARAM wparam, 
  103.                          LPARAM lparam)
  104. {
  105.     return DispMessage(&msdiMain, hwnd, uMessage, wparam, lparam);
  106. }
  107.  
  108. //
  109. //  FUNCTION: MsgCreate(HWND, UINT, WPARAM, LPARAM)
  110. //
  111. //  PURPOSE: Creates Inbox and Outbox Edit controls
  112. //
  113. //  PARAMETERS:
  114. //
  115. //    hwnd      - Window handle
  116. //    uMessage  - Message number (Unused)
  117. //    wparam    - Extra data     (Unused)
  118. //    lparam    - Extra data     (Unused)
  119. //
  120. //  RETURN VALUE:
  121. //
  122. //    Always returns 0 - Message handled
  123. //
  124. //  COMMENTS:
  125. //
  126. //
  127.  
  128. LRESULT MsgCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  129. {
  130.     // Create Edit control for typing to be sent to server
  131.     hOutWnd = CreateWindow("EDIT",
  132.                            NULL,
  133.                            WS_BORDER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | 
  134.                            ES_MULTILINE | ES_AUTOVSCROLL,
  135.                            0,0,0,0,
  136.                            hwnd,
  137.                            (HMENU) ID_OUTBOX,
  138.                            (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
  139.                            0);
  140.     // Create Edit control for typing to be received from server
  141.     hInWnd = CreateWindow("EDIT",
  142.                           NULL,
  143.                           WS_BORDER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | 
  144.                           ES_MULTILINE | ES_AUTOVSCROLL,
  145.                           0,0,0,0,
  146.                           hwnd,
  147.                           (HMENU) ID_INBOX,
  148.                           (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
  149.                           0);
  150.  
  151.     return (TRUE);
  152. }
  153.  
  154. //
  155. //  FUNCTION: MsgSize(HWND, UINT, WPARAM, LPARAM)
  156. //
  157. //  PURPOSE: Adjust Size of Inbox and Outbox Edit controls
  158. //
  159. //  PARAMETERS:
  160. //
  161. //    hwnd      - Window handle
  162. //    uMessage  - Message number (Unused)
  163. //    wparam    - Extra data     (Unused)
  164. //    lparam    - Parent Window Size
  165. //
  166. //  RETURN VALUE:
  167. //
  168. //    Always returns 0 - Message handled
  169. //
  170. //  COMMENTS:
  171. //
  172. //
  173.  
  174. LRESULT MsgSize(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  175. {
  176.     // Size OutBox Edit Control
  177.     MoveWindow(hOutWnd,
  178.                1,1,                    // Upper Left Corner
  179.                LOWORD(lparam) - 2,         // Width of Parent Window
  180.                (HIWORD(lparam) / 2) - 2 ,     // Half the height of Parent
  181.                TRUE);                  // repaint
  182.  
  183.     // Size Inbox Edit Control
  184.     MoveWindow(hInWnd,
  185.                1, (HIWORD(lparam) / 2) + 1,  // Half Way down right side
  186.                LOWORD(lparam) - 2,         // Width of Parent Window
  187.                (HIWORD(lparam) / 2) - 2,      // Half the height of Parent
  188.                TRUE);                  // repaint
  189.     return (TRUE);
  190. }
  191.  
  192. //
  193. //  FUNCTION: MsgSetfocus(HWND, UINT, WPARAM, LPARAM)
  194. //
  195. //  PURPOSE: Keeps Window focus on edit control
  196. //
  197. //  PARAMETERS:
  198. //
  199. //    hwnd      - Window handle
  200. //    uMessage  - Message number (Unused)
  201. //    wparam    - Extra data     (Unused)
  202. //    lparam    - Extra data     (Unused)
  203. //
  204. //  RETURN VALUE:
  205. //
  206. //    Always returns 0 - Message handled
  207. //
  208. //  COMMENTS:
  209. //
  210. //
  211.  
  212. LRESULT MsgSetfocus(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  213. {
  214.     SetFocus(hOutWnd);  // Don't let main window have focus
  215.     return (TRUE);
  216. }
  217.  
  218. //
  219. //  FUNCTION: MsgDataready(HWND, UINT, WPARAM, LPARAM)
  220. //
  221. //  PURPOSE: Read data and post message to display data
  222. //
  223. //  PARAMETERS:
  224. //
  225. //    hwnd      - Window handle
  226. //    uMessage  - Message number (Unused)
  227. //    wparam    - forwarded to ReceiveInBox
  228. //    lparam    - forwarded to ReceiveInBox
  229. //
  230. //  RETURN VALUE:
  231. //
  232. //    Always returns 0 - Message handled
  233. //
  234. //  COMMENTS:
  235. //
  236. //
  237.  
  238. LRESULT MsgDataready(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  239. {
  240.     // Call protocol specific program to Read data and put in szRcvBuf
  241.     if(ReceiveInBox(hwnd, wparam, lparam, szRcvBuf, sizeof(szRcvBuf)))
  242.     {
  243.         PostMessage(hwnd, MW_DISPLAYREFRESH, 0, 0);
  244.     }
  245.     return(TRUE);
  246. }
  247. //
  248. //  FUNCTION: MsgRefreshdisplay(HWND, UINT, WPARAM, LPARAM)
  249. //
  250. //  PURPOSE: Display socket data in inbox
  251. //
  252. //  PARAMETERS:
  253. //
  254. //    hwnd      - Window handle
  255. //    uMessage  - Message number (Unused)
  256. //    wparam    - Extra Data     (Unused)
  257. //    lparam    - Extra Data     (Unused)
  258. //
  259. //  RETURN VALUE:
  260. //
  261. //    Always returns 0 - Message handled
  262. //
  263. //  COMMENTS:
  264. //
  265. //
  266.  
  267. LRESULT MsgRefreshdisplay(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  268. {
  269.     MSG peekmsg;
  270.  
  271.     // Don't bother displaying if there is already another update queued
  272.     if(PeekMessage(&peekmsg, hwnd, MW_DATAREADY, MW_DISPLAYREFRESH, PM_NOREMOVE))
  273.     {
  274.        return(TRUE);                          
  275.     }
  276.     // Put data in szRcvBuf in InBox
  277.     SendDlgItemMessage(hwnd,
  278.                        ID_INBOX,
  279.                        EM_SETSEL,
  280.                        0,-1);
  281.     SendDlgItemMessage(hwnd,
  282.                        ID_INBOX,
  283.                        EM_REPLACESEL,
  284.                        0,
  285.                        (LPARAM)szRcvBuf);
  286.     return(TRUE);
  287. }
  288.  
  289. //
  290. //  FUNCTION: MsgDisconnected(HWND, UINT, WPARAM, LPARAM)
  291. //
  292. //  PURPOSE: Cleanup connection dropped from other side
  293. //
  294. //  PARAMETERS:
  295. //
  296. //    hwnd      - Window handle
  297. //    uMessage  - Message number (Unused)
  298. //    wparam    - Extra data     (Unused)
  299. //    lparam    - Extra data     (Unused)
  300. //
  301. //  RETURN VALUE:
  302. //
  303. //    Always returns 0 - Message handled
  304. //
  305. //  COMMENTS:
  306. //
  307. //
  308.  
  309. LRESULT MsgDisconnected(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  310. {
  311.     HMENU hmenu;
  312.  
  313.     // Let the user know
  314.     MessageBox(hwnd,
  315.                "Connection Disconnected",
  316.                "Chat Dialog Stopped",
  317.                MB_OK);
  318.     // Protocol Specific Cleanup
  319.     CleanUp();
  320.     // Fix menus
  321.     hmenu = GetMenu(hwnd);
  322.     EnableMenuItem(hmenu, IDM_CONNECT, MF_ENABLED);
  323.     EnableMenuItem(hmenu, IDM_LISTEN, MF_ENABLED);
  324.     EnableMenuItem(hmenu, IDM_DISCONNECT, MF_GRAYED);
  325.     SetWindowText(hwnd, szTitle);
  326.     return(TRUE);
  327. }
  328.  
  329. //
  330. //  FUNCTION: MsgCommand(HWND, UINT, WPARAM, LPARAM)
  331. //
  332. //  PURPOSE: Handle the WM_COMMAND messages for the main window.
  333. //
  334. //  PARAMETERS:
  335. //    hwnd     - window handle
  336. //    uMessage - WM_COMMAND (Unused)
  337. //    GET_WM_COMMAND_ID(wparam, lparam)   - Command identifier
  338. //    GET_WM_COMMAND_HWND(wparam, lparam) - Control handle
  339. //
  340. //  RETURN VALUE:
  341. //    The return value depends on the message number.  If the message
  342. //    is implemented in the message dispatch table, the return value is
  343. //    the value returned by the message handling function.  Otherwise,
  344. //    the return value is the value returned by the default window procedure.
  345. //
  346. //  COMMENTS:
  347. //    Call the DispCommand() function with the main window's command dispatch
  348. //    information (cmdiMain) and the command specific information.
  349. //
  350.  
  351. LRESULT MsgCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  352. {
  353.     return DispCommand(&cmdiMain, hwnd, wparam, lparam);
  354. }
  355.  
  356.  
  357. //
  358. //  FUNCTION: MsgDestroy(HWND, UINT, WPARAM, LPARAM)
  359. //
  360. //  PURPOSE: Calls PostQuitMessage().
  361. //
  362. //  PARAMETERS:
  363. //
  364. //    hwnd      - Window handle  (Unused)
  365. //    uMessage  - Message number (Unused)
  366. //    wparam    - Extra data     (Unused)
  367. //    lparam    - Extra data     (Unused)
  368. //
  369. //  RETURN VALUE:
  370. //
  371. //    Always returns 0 - Message handled
  372. //
  373. //  COMMENTS:
  374. //
  375. //
  376.  
  377. LRESULT MsgDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  378. {
  379.     PostQuitMessage(0);
  380.     return 0;
  381. }
  382.  
  383. //
  384. //  FUNCTION: CmdOutbox(HWND, WORD, WORD, HWND)
  385. //
  386. //  PURPOSE: Handle messages from Outbox--Send data if EN_CHANGE
  387. //
  388. //  PARAMETERS:
  389. //    hwnd     - The window.
  390. //    wCommand - ID_OUTBOX (unused)
  391. //    wNotify  - Notification number (unused)
  392. //    hwndCtrl - NULL (unused)
  393. //
  394. //  RETURN VALUE:
  395. //    Always returns 0 - command handled.
  396. //
  397. //  COMMENTS:
  398. //
  399. //
  400.  
  401. LRESULT CmdOutbox(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  402. {
  403.     int cSendLen;
  404.  
  405.     if (wNotify != EN_CHANGE)  // We only care if text has changed
  406.     {
  407.         return 0;
  408.     }
  409.     // Text has changed!  Put OutBox's text in szSndBuf
  410.     cSendLen = GetDlgItemText(hwnd,
  411.                               ID_OUTBOX,
  412.                               szSndBuf,
  413.                               sizeof(szSndBuf));
  414.  
  415.     // Do protocol specific send
  416.     SendOutBox(szSndBuf, cSendLen);
  417.     return 0;
  418. }
  419.  
  420. //
  421. //  FUNCTION: CmdDisconnect(HWND, WORD, WORD, HWND)
  422. //
  423. //  PURPOSE: Cut off session and fix menus appropriately
  424. //
  425. //  PARAMETERS:
  426. //    hwnd     - The window.
  427. //    wCommand - ID_OUTBOX (unused)
  428. //    wNotify  - Notification number (unused)
  429. //    hwndCtrl - NULL (unused)
  430. //
  431. //  RETURN VALUE:
  432. //    Always returns 0 - command handled.
  433. //
  434. //  COMMENTS:
  435. //
  436. //
  437.  
  438. LRESULT CmdDisconnect(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  439. {
  440.     HMENU hmenu;
  441.  
  442.     // Protocol Specific cleanup
  443.     CleanUp();
  444.  
  445.     // Fix menus
  446.     hmenu = GetMenu(hwnd);
  447.     EnableMenuItem(hmenu, IDM_CONNECT, MF_ENABLED);
  448.     EnableMenuItem(hmenu, IDM_LISTEN, MF_ENABLED);
  449.     EnableMenuItem(hmenu, IDM_DISCONNECT, MF_GRAYED);
  450.     SetWindowText(hwnd, szTitle);
  451.     return 0;
  452. }
  453.  
  454. //
  455. //  FUNCTION: CmdExit(HWND, WORD, WORD, HWND)
  456. //
  457. //  PURPOSE: Exit the application.
  458. //
  459. //  PARAMETERS:
  460. //    hwnd     - The window.
  461. //    wCommand - IDM_EXIT            (unused)
  462. //    wNotify  - Notification number (unused)
  463. //    hwndCtrl - NULL                (unused)
  464. //
  465. //  RETURN VALUE:
  466. //    Always returns 0 - command handled.
  467. //
  468. //  COMMENTS:
  469. //
  470. //
  471.  
  472. LRESULT CmdExit(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  473. {
  474.     DestroyWindow(hwnd);
  475.     return 0;
  476. }
  477.