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 / misc.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  11KB  |  378 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:   misc.c
  9. //
  10. //  PURPOSE:  Contains all helper functions "global" to the application.
  11. //
  12. //  FUNCTIONS:
  13. //    CenterWindow - Center one window over another.
  14. //    ReceiveInBox - Reads incoming socket data.
  15. //    SendOutBox   - Writes outgoing socket data.
  16. //    AtoH         - Converts ascii string to network order hex
  17. //    BtoH         - Converts ascii byte to hex
  18. //    CleanUp      - closes sockets and detaches winsock dll
  19. //    GetAddrString - Puts IPX address into <network>.<node>.<socket> string format
  20. //    HtoA          - Converts network order hex to ascii string
  21. //    HtoB          - Converts hex byte to asci string
  22. //
  23. //  COMMENTS:
  24. //
  25. //
  26.  
  27. #include <windows.h>            // required for all Windows applications
  28. #include <windowsx.h>
  29. #include <wsipx.h>
  30. #include "globals.h"            // prototypes specific to this application
  31.  
  32.  
  33.  
  34. //
  35. //  FUNCTION: CenterWindow(HWND, HWND)
  36. //
  37. //  PURPOSE:  Center one window over another.
  38. //
  39. //  PARAMETERS:
  40. //    hwndChild - The handle of the window to be centered.
  41. //    hwndParent- The handle of the window to center on.
  42. //
  43. //  RETURN VALUE:
  44. //
  45. //    TRUE  - Success
  46. //    FALSE - Failure
  47. //
  48. //  COMMENTS:
  49. //
  50. //    Dialog boxes take on the screen position that they were designed
  51. //    at, which is not always appropriate. Centering the dialog over a
  52. //    particular window usually results in a better position.
  53. //
  54.  
  55. BOOL CenterWindow(HWND hwndChild, HWND hwndParent)
  56. {
  57.     RECT    rcChild, rcParent;
  58.     int     cxChild, cyChild, cxParent, cyParent;
  59.     int     cxScreen, cyScreen, xNew, yNew;
  60.     HDC     hdc;
  61.  
  62.     // Get the Height and Width of the child window
  63.     GetWindowRect(hwndChild, &rcChild);
  64.     cxChild = rcChild.right - rcChild.left;
  65.     cyChild = rcChild.bottom - rcChild.top;
  66.  
  67.     // Get the Height and Width of the parent window
  68.     GetWindowRect(hwndParent, &rcParent);
  69.     cxParent = rcParent.right - rcParent.left;
  70.     cyParent = rcParent.bottom - rcParent.top;
  71.  
  72.     // Get the display limits
  73.     hdc = GetDC(hwndChild);
  74.     cxScreen = GetDeviceCaps(hdc, HORZRES);
  75.     cyScreen = GetDeviceCaps(hdc, VERTRES);
  76.     ReleaseDC(hwndChild, hdc);
  77.  
  78.     // Calculate new X position, then adjust for screen
  79.     xNew = rcParent.left + ((cxParent - cxChild) / 2);
  80.     if (xNew < 0)
  81.     {
  82.         xNew = 0;
  83.     }
  84.     else if ((xNew + cxChild) > cxScreen)
  85.     {
  86.         xNew = cxScreen - cxChild;
  87.     }
  88.  
  89.     // Calculate new Y position, then adjust for screen
  90.     yNew = rcParent.top  + ((cyParent - cyChild) / 2);
  91.     if (yNew < 0)
  92.     {
  93.         yNew = 0;
  94.     }
  95.     else if ((yNew + cyChild) > cyScreen)
  96.     {
  97.         yNew = cyScreen - cyChild;
  98.     }
  99.  
  100.     // Set it, and return
  101.     return SetWindowPos(hwndChild,
  102.                         NULL,
  103.                         xNew, yNew,
  104.                         0, 0,
  105.                         SWP_NOSIZE | SWP_NOZORDER);
  106. }
  107.  
  108. //
  109. //  FUNCTION: ReceiveInBox(HWND, WPARAM, LPARAM, char *, int)
  110. //
  111. //  PURPOSE:  Reads incoming data from socket
  112. //
  113. //  PARAMETERS:
  114. //    hWnd      - Handle to current window
  115. //    uParam    - WPARAM (unused)
  116. //    lParam    - LPARAM contains event (FD_READ or FD_CLOSE).
  117. //    szRBuf    - Receive Buffer
  118. //    cRBufLen  - size of Receive Buffer
  119. //
  120. //  RETURN VALUE:
  121. //
  122. //    TRUE  - Data Read
  123. //    FALSE - If FD_CLOSE message
  124. //
  125. //  COMMENTS:
  126. //
  127. //    Called if socket has data OR if it is closed.  If closed post
  128. //    WM_DISCONNECTED message.  Else read data and make sure it is
  129. //    NULL terminated.
  130. //
  131.  
  132. BOOL ReceiveInBox(HWND hWnd, WPARAM uParam, LPARAM lParam, char * szRBuf, int cRBufLen)
  133. {
  134.     char * pRBuf;     // temp buf pointer
  135.     int cBytesRead;   // count of bytes actually read
  136.  
  137.     
  138.     if (LOWORD(lParam) == FD_CLOSE)                   // Is this a FD_CLOSE event?
  139.     {
  140.         SendMessage(hWnd, MW_DISCONNECTED, 0, 0);     // Yes, post message
  141.         return(FALSE);
  142.     }
  143.  
  144.     pRBuf = szRBuf;   // Set temp pointer
  145.     cRBufLen--;       // Save room for null terminator
  146.           
  147.     // read socket
  148.     if((cBytesRead = recv(sock, pRBuf, cRBufLen, 0)) != SOCKET_ERROR)
  149.         pRBuf += cBytesRead;    // Move temp pointer to end of buffer
  150.               
  151.     *pRBuf = 0;   // Null terminate - if recv() failed, then prBuf will 
  152.                   // point to first byte of the buffer
  153.     
  154.     return (TRUE);   // We've got a buffer to display
  155. }
  156.  
  157. //
  158. //  FUNCTION: SendOutBox(char *, int)
  159. //
  160. //  PURPOSE:  Reads incoming data from socket
  161. //
  162. //  PARAMETERS:
  163. //    szSBuf    - Send Buffer
  164. //    cSBufLen  - size of Send Buffer
  165. //
  166. //  COMMENTS:
  167. //
  168. //    Writes send buffer to socket -- repeats until all data is sent.
  169. //
  170.  
  171. void SendOutBox(char * szSBuf, int cSBufLen)
  172. {
  173.     char * pSBuf;
  174.     int cBytesSent;
  175.  
  176.     pSBuf = szSBuf; // Set temp pointer
  177.     
  178.     while((cBytesSent = send(sock,
  179.                              pSBuf,
  180.                              cSBufLen,
  181.                              0)) != SOCKET_ERROR)
  182.     {
  183.         pSBuf += cBytesSent;
  184.         cSBufLen -= cBytesSent;
  185.         if(!cSBufLen) return;
  186.     }
  187. }
  188.  
  189. //
  190. //  FUNCTION: AtoH(char *, char *, int)
  191. //
  192. //  PURPOSE:  Converts ascii string to network order hex
  193. //
  194. //  PARAMETERS:
  195. //    src    - pointer to input ascii string
  196. //    dest   - pointer to output hex
  197. //    destlen - size of dest
  198. //
  199. //  COMMENTS:
  200. //
  201. //    2 ascii bytes make a hex byte so must put 1st ascii byte of pair
  202. //    into upper nibble and 2nd ascii byte of pair into lower nibble.
  203. //
  204.  
  205. void AtoH(char * src, char * dest, int destlen)
  206. {
  207.     char * srcptr;
  208.  
  209.     srcptr = src;
  210.  
  211.     while(destlen--)
  212.     {
  213.     *dest = BtoH(*srcptr++) << 4;    // Put 1st ascii byte in upper nibble.
  214.     *dest++ += BtoH(*srcptr++);      // Add 2nd ascii byte to above.
  215.     }
  216. }
  217.  
  218. //
  219. //  FUNCTION: BtoH(char *, char *, int)
  220. //
  221. //  PURPOSE:  Converts ascii byte to numeric
  222. //
  223. //  PARAMETERS:
  224. //    ch - ascii byte to convert
  225. //
  226. //  RETURNS:
  227. //    associated numeric value
  228. //
  229. //  COMMENTS:
  230. //
  231. //    Will convert any hex ascii digit to its numeric counterpart.
  232. //    Puts in 0xff if not a valid hex digit.
  233. //
  234.  
  235. unsigned char BtoH(char ch)
  236. {
  237.     if (ch >= '0' && ch <= '9') return (ch - '0');        // Handle numerals
  238.     if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA);  // Handle capitol hex digits
  239.     if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA);  // Handle small hex digits
  240.     return(255);
  241. }
  242.  
  243. //
  244. //  FUNCTION: CleanUp(void)
  245. //
  246. //  PURPOSE:  Protocol specific cleanup function
  247. //
  248. //  COMMENTS:
  249. //
  250. //    Deletes our two possible sockets (they might not exist which
  251. //    just means closesocket might return an error -- we don't care).
  252. //
  253.  
  254. void CleanUp(void)
  255. {
  256.     closesocket(SrvSock);  // Close our server side socket
  257.     closesocket(sock);     // Close our connection specific socket
  258.     WSACleanup();          // Nix the DLL
  259. }
  260.  
  261. //
  262. //  FUNCTION: GetAddrString(PSOCKADDR_IPX, char *)
  263. //
  264. //  PURPOSE:  Converts IPX address to ascii string for displaying
  265. //
  266. //  PARAMETERS:
  267. //    pSAddr - pointer to socket address struc
  268. //    dest   - pointer to destination string
  269. //
  270. //  COMMENTS:
  271. //
  272. //    Address is in network order to use HtoA to convert to ascii.
  273. //    
  274. //    Final format is 
  275. //      <8 char network address>.<12 char node address>.<4 char sock address>
  276. //
  277.  
  278. void GetAddrString(PSOCKADDR_IPX pSAddr, char * dest)
  279. {
  280.     char abuf[15];                                // temp buffer
  281.     char * currptr;                               // temp destination pointer
  282.     int saddrlen = sizeof(struct sockaddr_ipx);   // sizeof address struc
  283.  
  284.     currptr = dest; // initialize destination pointer
  285.  
  286.     HtoA((char *)&pSAddr->sa_netnum, abuf, 4);    // convert network number
  287.     lstrcpy(currptr, abuf);
  288.     currptr += 8;
  289.     lstrcat(currptr, ".");                        // don't forget seperator
  290.     currptr++;
  291.     
  292.     HtoA((char *)&pSAddr->sa_nodenum, abuf, 6);   // convert node number
  293.     lstrcat(currptr, abuf);
  294.     currptr += 12;
  295.     lstrcat(currptr, ".");                        // seperator
  296.     currptr++;
  297.  
  298.     HtoA((char *)&pSAddr->sa_socket, abuf, 2);    // convert socket number
  299.     lstrcat(currptr, abuf);
  300.    
  301. }
  302.  
  303. //
  304. //  FUNCTION: HtoA(char *, char *, int)
  305. //
  306. //  PURPOSE:  Converts network ordered hex to ascii string
  307. //
  308. //  PARAMETERS:
  309. //    src     - pointer to network ordered hex
  310. //    dest    - pointer to ascii string
  311. //    srclen  - size of hex number in bytes
  312. //
  313. //  COMMENTS:
  314. //
  315. //    1 byte hex = 2 bytes ascii so convert high order nibble with HtoB()
  316. //    then convert low order nibble. dest buffer better be 2*srclen + 1.
  317. //
  318.  
  319. void HtoA(char * src, char * dest, int srclen)
  320. {
  321.     char * destptr; // temp pointers
  322.     UCHAR * srcptr;
  323.         
  324.     srcptr = (UCHAR *)src;
  325.     destptr = dest;
  326.  
  327.     while(srclen--)
  328.     {
  329.     *destptr++ = HtoB((UCHAR)(*srcptr >> 4));      // Convert high order nibble
  330.     *destptr++ = HtoB((UCHAR)(*srcptr++ & 0x0F));  // Convert low order nibble
  331.     }
  332.     *destptr = 0;  // Null terminator
  333. }
  334.  
  335. //
  336. //  FUNCTION: HtoB(UCHAR)
  337. //
  338. //  PURPOSE:  Converts hex byte to ascii byte
  339. //
  340. //  PARAMETERS:
  341. //    ch - Hex byte
  342. //                 
  343. //  RETURNS:
  344. //    ascii byte
  345. //
  346. //  COMMENTS:
  347. //
  348. //    We actually only convert a nibble since 1 byte hex = 2 bytes ascii.
  349. //    So if ch > 0xf we just return 'X'.
  350. //
  351.  
  352. char HtoB(UCHAR ch)
  353. {
  354.     if (ch <= 9) return ('0' + ch);             // handle decimal values
  355.     if (ch <= 0xf) return ('A' + ch - 10);      // handle hexidecimal specific values
  356.     return('X');                                // Someone screwed up
  357. }
  358.  
  359.  
  360. //---------------------------------------------------------------------------
  361. //
  362. // FUNCTION:    GetStringRes (int id INPUT ONLY)
  363. //
  364. // COMMENTS:    Load the resource string with the ID given, and return a
  365. //              pointer to it.  Notice that the buffer is common memory so
  366. //              the string must be used before this call is made a second time.
  367. //
  368. //---------------------------------------------------------------------------
  369.  
  370. LPTSTR GetStringRes (int id)
  371. {
  372.   static TCHAR buffer[MAX_PATH];
  373.  
  374.   buffer[0]=0;
  375.   LoadString (GetModuleHandle (NULL), id, buffer, MAX_PATH);
  376.   return buffer;
  377. }
  378.