home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol05 / 01 / isam / fig20.c < prev   
Text File  |  1989-12-11  |  6KB  |  214 lines

  1.  
  2.  
  3. /* Table of currently connected clients. The clientTbl is
  4. typically accessed through the three routines getClient,
  5. putClient, delClient and reapClient. */
  6.  
  7. static HWND clientTbl[MAX_CLIENTS];
  8.  
  9. static int putClient(HWND);
  10. static int getClient(HWND);
  11. static int delClient(HWND);
  12. static int reapClient(HWND);
  13.  
  14. /* Server communications window WndProc. All client requests
  15. come through here. */
  16.  
  17. long FAR PASCAL WndProc (
  18.     HWND       hWnd,
  19.     unsigned   iMessage,
  20.     WORD       wParam,
  21.     LONG       lParam )
  22. {
  23.     static char    *szInit = "WM_INITIATE_ISAM";
  24.     static char    *szSend = "WM_SEND_ISAM";
  25.     static char    *szTerm = "WM_TERMINATE_ISAM";
  26.     static WORD    wmInitISAM;
  27.     static WORD    wmSendISAM;
  28.     static WORD    wmTermISAM;
  29.  
  30.     GLOBALHANDLE   hRequestBlock;
  31.     HWND           hWndClient;
  32.     int            iRetVal;
  33.  
  34.     switch (iMessage) {
  35.     case WM_CREATE:
  36.         /* Register WinTrieve protocol messages. */
  37.         wmInitISAM = RegisterWindowMessage(szInit);
  38.         wmSendISAM = RegisterWindowMessage(szSend);
  39.         wmTermISAM = RegisterWindowMessage(szTerm);
  40.  
  41.         break;
  42.     case WM_CLOSE:
  43.         /* Detect if any clients are still connected. */
  44.         if (reapClients()) {
  45.             /* There are still connected clients. What
  46.              * is done here is server dependent. WinTrieve
  47.              * displays a message box and returns (does
  48.              * not terminate).
  49.              */
  50.         }
  51.         else
  52.             /* No connected clients, ok to terminate. */
  53.             return DefWindowProc(hWnd, iMessage, wParam,
  54. lParam);
  55.  
  56.         break;
  57.     case WM_DESTROY:
  58.         /* Can do some final cleanup here before the server
  59. terminates. */
  60.  
  61.         break;
  62.     case WM_QUERYOPEN:
  63.         /* The server is always an icon. */
  64.  
  65.         break;
  66.     default:
  67.         if (iMessage == wmSendISAM) {
  68.             /* Get handle to query block. */
  69.             hRequestBlock = HIWORD(lParam);
  70.  
  71.             /* Check that client is connected. */
  72.             hWndClient = wParam;
  73.             if (getClient(hWndClient) < 0)
  74.                 return ISNOTCONN;
  75.  
  76.             /* Process the request, this is server
  77. dependent.
  78.              * If protocol error, for example, cannot lock
  79.              * query block returns an error code, otherwise
  80.              * returns ISOK.
  81.              */
  82.             iRetVal = ProcessRequest(hWndClient,
  83. hRequestBlock);
  84.             return iRetVal;
  85.         }
  86.         else if (iMessage == wmInitISAM) {
  87.             /* A server must be robust. Client handles
  88.              * that have become invalid are checked for
  89. here.
  90.              */
  91.             reapClients();
  92.  
  93.             /* Initiate a connection. */
  94.             hWndClient = wParam;
  95.  
  96.             /* Check that client isn't already connected. */
  97.             if (getClient(hWndClient) >= 0)
  98.                 return ISCONN;
  99.  
  100.             /* Check for maximum connections. */
  101.             if (putClient(hWndClient) < 0)
  102.                 return ISMAXCONN;
  103.  
  104.             /* Client connected. */
  105.             return ISOK;
  106.         }
  107.         else if (iMessage == wmTermISAM) {
  108.             /* Terminate a connection. */
  109.             hWndClient = wParam;
  110.  
  111.             /* Check that client is connected. */
  112.             if (delClient(hWndClient) < 0)
  113.                 return ISNOTCONN;
  114.  
  115.             return ISOK;
  116.         }
  117.         else
  118.             /* Default message processing. */
  119.             return DefWindowProc(hWnd, iMessage, wParam,
  120. lParam);
  121.  
  122.         break;
  123.     }
  124.  
  125.     return 0L;
  126. }
  127.  
  128. /* Put new client into client table. If successful returns
  129. index of table where the handle is stored. If the table is
  130. full returns -1. */
  131.  
  132. static int putClient(
  133.    HWND  hWnd )
  134. {
  135.         register int   i;
  136.  
  137.    for (i = 0; i < MAXHANDLES; i++) {
  138.       if (clientTbl[i] == NULL) {
  139.          clientTbl[i] = hWnd;
  140.          return i;
  141.       }
  142.    }
  143.    return -1;                 /* client table full */
  144. }
  145.  
  146. /* Delete client from client table. If successful returns
  147. index position of table where the handle was deleted from.
  148. If handle not found returns -1. */
  149. static int delClient(hWnd)
  150.    HWND  hWnd;
  151. {
  152.    register int   i;
  153.  
  154.    for (i = 0; i < MAXHANDLES; i++) {
  155.       if (clientTbl[i] == hWnd) {
  156.          clientTbl[i] = NULL;
  157.          return i;
  158.       }
  159.    }
  160.    return -1;                 /* handle not found */
  161. }
  162.  
  163. /* Returns index position in client window handles table for
  164. the specified client handle. If client handle not found
  165. returns -1. */
  166. static int getClient(hWnd)
  167.    HWND  hWnd;
  168. {
  169.    register int   i;
  170.  
  171.    for (i = 0; i < MAXHANDLES; i++) {
  172.       if (clientTbl[i] == hWnd)
  173.          return i;
  174.    }
  175.    return -1;
  176. }
  177.  
  178. /* Check the client table for any invalid client handles.
  179. For example clients that died suddenly or clients that just
  180. plan forgot to terminate the connection properly. Returns 0
  181. if no more clients connected. */
  182.  
  183. static int reapClients()
  184. {
  185.     int    i;
  186.     int    n;
  187.     HWND   hWndClient;
  188.  
  189.     /* Run through client table looking for connected
  190. clients. */
  191.     for (i = n = 0; i < MAX_CLIENTS; i++) {
  192.         if (clientTbl[i] != NULL) {
  193.             hWndClient = clientTbl[i];
  194.             /* Check if still valid handle by calling
  195.              * Windows function IsWindow.
  196.              */
  197.             if (IsWindow(hWndClient) == NULL) {
  198.                 /* Client died. The function cleanUp
  199.                  * is a server specific routine that
  200.                  * removes the state of a client
  201.                  * if it is no longer valid.
  202.                  */
  203.                 cleanUp(hWndClient);
  204.                 clientTbl[i] = NULL;
  205.                 continue;
  206.             }
  207.             n++;              /* increment connected clients
  208. count */
  209.         }
  210.     }
  211.  
  212.     return n;
  213. }
  214.