Annotation of mstools/samples/ddeml/server/ddemlsv.c, revision 1.1.1.2

1.1       root        1: /****************************************************************************
                      2: 
                      3:     PROGRAM: Server.c
                      4: 
                      5:     PURPOSE: Server template for Windows applications
                      6: 
                      7:     FUNCTIONS:
                      8: 
                      9:         WinMain() - calls initialization function, processes message loop
                     10:         InitApplication() - initializes window data and registers window
                     11:         InitInstance() - saves instance handle and creates main window
                     12:         MainWndProc() - processes messages
                     13:         About() - processes messages for "About" dialog box
                     14: 
                     15:     COMMENTS:
                     16: 
                     17:         Windows can have several copies of your application running at the
                     18:         same time.  The variable hInst keeps track of which instance this
                     19:         application is so that processing will be to the correct window.
                     20: 
                     21: ****************************************************************************/
                     22: 
                     23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26: #include "server.h"                 /* specific to this program              */
                     27: #include "huge.h"
                     28: 
                     29: DWORD idInst = 0;
                     30: CONVCONTEXT CCFilter = { sizeof(CONVCONTEXT), 0, 0, 0, 0L, 0L };
                     31: HANDLE hInst;                       /* current instance                      */
                     32: HWND hwndServer;
                     33: RECT rcRand;
                     34: RECT rcCount;
                     35: RECT rcComment;
                     36: RECT rcExec;
                     37: RECT rcConnCount;
                     38: RECT rcRndrDelay;
                     39: RECT rcRunaway;
                     40: RECT rcAllBlock;
                     41: RECT rcNextAction;
                     42: RECT rcHugeSize;
                     43: RECT rcAppowned;
                     44: BOOL fAllBlocked = FALSE;
                     45: BOOL fAllEnabled = TRUE;
                     46: BOOL fEnableOneCB = FALSE;
                     47: BOOL fBlockNextCB = FALSE;
                     48: BOOL fTermNextCB = FALSE;
                     49: BOOL fAppowned = FALSE;
                     50: WORD cRunaway = 0;
                     51: WORD RenderDelay = 0;
                     52: DWORD count = 0;
                     53: WORD seed = 0;
                     54: HSZ hszAppName = 0;
                     55: CHAR szClass[] = "ServerWClass";
                     56: CHAR szTopic[MAX_TOPIC] = "Test";
                     57: CHAR szServer[MAX_TOPIC] = "Server";
                     58: CHAR szComment[MAX_COMMENT] = "";
                     59: CHAR szExec[MAX_EXEC] = "";
                     60: CHAR *pszComment = szComment;
                     61: WORD cyText;
                     62: WORD cServers = 0;
                     63: HDDEDATA hDataHelp[CFORMATS] = {0};
                     64: HDDEDATA hDataCount[CFORMATS] = {0};
                     65: HDDEDATA hDataRand[CFORMATS] = {0};
                     66: HDDEDATA hDataHuge[CFORMATS] = {0};
                     67: DWORD cbHuge = 0;
                     68: 
                     69: char szDdeHelp[] = "DDEML test server help:\r\n\n"\
                     70:     "The 'Server'(service) and 'Test'(topic) names may change.\r\n\n"\
                     71:     "Items supported under the 'Test' topic are:\r\n"\
                     72:     "\tCount:\tThis value increments on each data change.\r\n"\
                     73:     "\tRand:\tThis value is randomly generated each data change.\r\n"\
                     74:     "\tHuge:\tThis is randomlly generated text data >64k that the\r\n"\
                     75:     "\t\tDDEML test client can verify.\r\n"\
                     76:     "The above items change after any request if in Runaway mode and \r\n"\
                     77:     "can bo POKEed in order to change their values.  POKEed Huge data \r\n"\
                     78:     "must be in a special format to verify the correctness of the data \r\n"\
                     79:     "or it will not be accepted.\r\n"\
                     80:     "If the server is set to use app owned data handles, all data sent \r\n"\
                     81:     "uses HDATA_APPOWNED data handles."\
                     82:     ;
                     83: 
                     84: FORMATINFO aFormats[CFORMATS] = {
                     85:     { 0, "CF_TEXT" },       // exception!  predefined format
                     86:     { 0, "Dummy1"  },
                     87:     { 0, "Dummy2"  },
                     88: };
                     89: 
                     90: 
                     91: /*
                     92:  *          Topic and Item tables supported by this application.
                     93:  */
                     94: 
                     95: /*   HSZ    PROCEDURE       PSZ        */
                     96: 
                     97: ITEMLIST SystemTopicItemList[CSYSTEMITEMS] = {
                     98: 
                     99:     { 0, TopicListXfer,  SZDDESYS_ITEM_TOPICS   },
                    100:     { 0, ItemListXfer,   SZDDESYS_ITEM_SYSITEMS },
                    101:     { 0, sysFormatsXfer, SZDDESYS_ITEM_FORMATS  },
                    102:     { 0, HelpXfer,       SZDDESYS_ITEM_HELP},
                    103:   };
                    104: 
                    105: 
                    106: ITEMLIST TestTopicItemList[CTESTITEMS] = {
                    107: 
                    108:     { 0, TestRandomXfer, "Rand" },   // 0 index
                    109:     { 0, TestCountXfer,  "Count"},   // 1 index
                    110:     { 0, TestHugeXfer,   "Huge" },   // 2 index
                    111:     { 0, ItemListXfer,   SZDDESYS_ITEM_SYSITEMS },  // 3 index
                    112:   };
                    113: 
                    114: 
                    115: /* The system topic is always assumed to be first. */
                    116: /*   HSZ   PROCEDURE            #ofITEMS        PSZ     */
                    117: TOPICLIST topicList[CTOPICS] = {
                    118: 
                    119:     { 0, SystemTopicItemList,   CSYSTEMITEMS,   SZDDESYS_TOPIC},    // 0 index
                    120:     { 0, TestTopicItemList,     CTESTITEMS,     szTopic},           // 1 index
                    121:   };
                    122: 
                    123: 
                    124: 
                    125: 
                    126: 
                    127: 
                    128: /****************************************************************************
                    129: 
                    130:     FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
                    131: 
                    132:     PURPOSE: calls initialization function, processes message loop
                    133: 
                    134:     COMMENTS:
                    135: 
                    136:         Windows recognizes this function by name as the initial entry point
                    137:         for the program.  This function calls the application initialization
                    138:         routine, if no other instance of the program is running, and always
                    139:         calls the instance initialization routine.  It then executes a message
                    140:         retrieval and dispatch loop that is the top-level control structure
                    141:         for the remainder of execution.  The loop is terminated when a WM_QUIT
                    142:         message is received, at which time this function exits the application
                    143:         instance by returning the value passed by PostQuitMessage().
                    144: 
                    145:         If this function must abort before entering the message loop, it
                    146:         returns the conventional value NULL.
                    147: 
                    148: ****************************************************************************/
                    149: 
1.1.1.2 ! root      150: INT WINAPI WinMain(
        !           151: HANDLE hInstance,
        !           152: HANDLE hPrevInstance,
        !           153: LPSTR lpCmdLine,
        !           154: INT nCmdShow)
1.1       root      155: {
                    156:     MSG msg;                                 /* message                      */
                    157: 
                    158:     if (!hPrevInstance)                  /* Other instances of app running? */
                    159:         if (!InitApplication(hInstance)) /* Initialize shared things */
                    160:             return (FALSE);              /* Exits if unable to initialize     */
                    161: 
                    162:     /* Perform initializations that apply to a specific instance */
                    163: 
                    164:     if (!InitInstance(hInstance, nCmdShow))
                    165:         return (FALSE);
                    166: 
                    167:     /* Acquire and dispatch messages until a WM_QUIT message is received. */
                    168: 
                    169:     while (GetMessage(&msg,     /* message structure                      */
                    170:             0,                  /* handle of window receiving the message */
                    171:             0,                  /* lowest message to examine              */
                    172:             0))                 /* highest message to examine             */
                    173:         {
                    174:         TranslateMessage(&msg);    /* Translates virtual key codes           */
                    175:         DispatchMessage(&msg);     /* Dispatches message to window           */
                    176:     }
                    177: 
                    178:     UnregisterClass(szClass, hInstance);
                    179:     return (msg.wParam);           /* Returns the value from PostQuitMessage */
                    180: }
                    181: 
                    182: 
                    183: /****************************************************************************
                    184: 
                    185:     FUNCTION: InitApplication(HANDLE)
                    186: 
                    187:     PURPOSE: Initializes window data and registers window class
                    188: 
                    189:     COMMENTS:
                    190: 
                    191:         This function is called at initialization time only if no other
                    192:         instances of the application are running.  This function performs
                    193:         initialization tasks that can be done once for any number of running
                    194:         instances.
                    195: 
                    196:         In this case, we initialize a window class by filling out a data
                    197:         structure of type WNDCLASS and calling the Windows RegisterClass()
                    198:         function.  Since all instances of this application use the same window
                    199:         class, we only need to do this when the first instance is initialized.
                    200: 
                    201: 
                    202: ****************************************************************************/
                    203: 
                    204: BOOL InitApplication(hInstance)
                    205: HANDLE hInstance;                              /* current instance           */
                    206: {
                    207:     WNDCLASS  wc;
                    208: 
                    209:     /* Fill in window class structure with parameters that describe the       */
                    210:     /* main window.                                                           */
                    211: 
                    212:     wc.style = 0;                       /* Class style(s).                    */
                    213:     wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for  */
                    214:                                         /* windows of this class.             */
                    215:     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
                    216:     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
                    217:     wc.hInstance = hInstance;           /* Application that owns the class.   */
                    218:     wc.hIcon = LoadIcon(hInstance, "server");
                    219:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
                    220:     wc.hbrBackground = (HANDLE)(COLOR_APPWORKSPACE+1);
                    221:     wc.lpszMenuName =  "ServerMenu";   /* Name of menu resource in .RC file. */
                    222:     wc.lpszClassName = "ServerWClass"; /* Name used in call to CreateWindow. */
                    223: 
                    224:     /* Register the window class and return success/failure code. */
                    225: 
                    226:     return (RegisterClass(&wc));
                    227: 
                    228: }
                    229: 
                    230: 
                    231: /****************************************************************************
                    232: 
                    233:     FUNCTION:  InitInstance(HANDLE, int)
                    234: 
                    235:     PURPOSE:  Saves instance handle and creates main window
                    236: 
                    237:     COMMENTS:
                    238: 
                    239:         This function is called at initialization time for every instance of
                    240:         this application.  This function performs initialization tasks that
                    241:         cannot be shared by multiple instances.
                    242: 
                    243:         In this case, we save the instance handle in a static variable and
                    244:         create and display the main program window.
                    245: 
                    246: ****************************************************************************/
                    247: 
                    248: BOOL InitInstance(hInstance, nCmdShow)
                    249:     HANDLE          hInstance;          /* Current instance identifier.       */
                    250:     INT             nCmdShow;           /* Param for first ShowWindow() call. */
                    251: {
                    252:     INT i;
                    253:     RECT Rect;
                    254:     TEXTMETRIC metrics;
                    255:     HDC hdc;
                    256: 
                    257:     /* Save the instance handle in static variable, which will be used in  */
                    258:     /* many subsequence calls from this application to Windows.            */
                    259: 
                    260:     hInst = hInstance;
                    261: 
                    262: 
                    263:     /* Create a main window for this application instance.  */
                    264: 
                    265:     hwndServer = CreateWindow(
                    266:         "ServerWClass",                /* See RegisterClass() call.          */
                    267:         "Server|Test",
                    268:         WS_OVERLAPPEDWINDOW,            /* Window style.                      */
                    269:         CW_USEDEFAULT,                  /* Default horizontal position.       */
                    270:         CW_USEDEFAULT,                  /* Default vertical position.         */
                    271:         400,
                    272:         200,
                    273:         NULL,                           /* Overlapped windows have no parent. */
                    274:         NULL,                           /* Use the window class menu.         */
                    275:         hInstance,                      /* This instance owns this window.    */
                    276:         NULL                            /* Pointer not needed.                */
                    277:     );
                    278: 
                    279:     GetClientRect(hwndServer, (LPRECT) &Rect);
                    280: 
                    281:     /* If window could not be created, return "failure" */
                    282: 
                    283:     if (!hwndServer)
                    284:         return (FALSE);
                    285: 
                    286:     hdc = GetDC(hwndServer);
                    287:     GetTextMetrics(hdc, &metrics);
                    288:     cyText = (WORD)(metrics.tmHeight + metrics.tmExternalLeading);
                    289:     ReleaseDC(hwndServer, hdc);
                    290: 
                    291:     aFormats[0].atom = CF_TEXT; // exception - predefined.
                    292:     for (i = 1; i < CFORMATS; i++) {
                    293:         aFormats[i].atom = RegisterClipboardFormat(aFormats[i].sz);
                    294:     }
                    295: 
                    296:     /* Make the window visible; update its client area; and return "success" */
                    297: 
                    298:     ShowWindow(hwndServer, nCmdShow);  /* Show the window                        */
                    299:     UpdateWindow(hwndServer);          /* Sends WM_PAINT message                 */
                    300:     seed = 1;
                    301:     srand(1);
                    302:     CCFilter.iCodePage = CP_WINANSI;   // initial default codepage
                    303:     if (!DdeInitialize(&idInst, (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback,
                    304:                 hInstance), APPCMD_FILTERINITS, 0)) {
                    305:         Hszize();
                    306:         DdeNameService(idInst, hszAppName, 0, DNS_REGISTER);
                    307:         return(TRUE);
                    308:     }
                    309:     return (FALSE);
                    310: 
                    311: }
                    312: 
                    313: /****************************************************************************
                    314: 
                    315:     FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
                    316: 
                    317:     PURPOSE:  Processes messages
                    318: 
                    319:     MESSAGES:
                    320: 
                    321:         WM_COMMAND    - application menu (About dialog box)
                    322:         WM_DESTROY    - destroy window
                    323: 
                    324:     COMMENTS:
                    325: 
                    326:         To process the IDM_ABOUT message, call MakeProcInstance() to get the
                    327:         current instance address of the About() function.  Then call Dialog
                    328:         box which will create the box according to the information in your
                    329:         server.rc file and turn control over to the About() function.   When
                    330:         it returns, free the intance address.
                    331: 
                    332: ****************************************************************************/
                    333: 
                    334: LONG  APIENTRY MainWndProc(hWnd, message, wParam, lParam)
                    335: HWND hWnd;                                /* window handle                   */
                    336: UINT message;                         /* type of message                 */
                    337: WPARAM wParam;                              /* additional information          */
1.1.1.2 ! root      338: LPARAM lParam;                              /* additional information          */
1.1       root      339: {
                    340:     switch (message) {
                    341:     case WM_INITMENU:
                    342:         if (GetMenu(hWnd) != (HMENU)wParam)
                    343:             break;
                    344: 
                    345:         CheckMenuItem((HMENU)wParam, IDM_BLOCKALLCBS,
                    346:                 fAllBlocked ? MF_CHECKED : MF_UNCHECKED);
                    347:         CheckMenuItem((HMENU)wParam, IDM_UNBLOCKALLCBS,
                    348:                 fAllEnabled ? MF_CHECKED : MF_UNCHECKED);
                    349:         CheckMenuItem((HMENU)wParam, IDM_BLOCKNEXTCB,
                    350:                 fBlockNextCB ? MF_CHECKED : MF_UNCHECKED);
                    351:         CheckMenuItem((HMENU)wParam, IDM_TERMNEXTCB,
                    352:                 fTermNextCB ? MF_CHECKED : MF_UNCHECKED);
                    353:         CheckMenuItem((HMENU)wParam, IDM_RUNAWAY,
                    354:                 cRunaway ? MF_CHECKED : MF_UNCHECKED);
                    355:         CheckMenuItem((HMENU)wParam, IDM_APPOWNED,
                    356:                 fAppowned ? MF_CHECKED : MF_UNCHECKED);
                    357:         break;
                    358: 
                    359:     case WM_COMMAND:           /* message: command from application menu */
1.1.1.2 ! root      360:         switch (LOWORD(wParam)) {
1.1       root      361:         case IDM_ENABLEONECB:
                    362:             DdeEnableCallback(idInst, 0, EC_ENABLEONE);
                    363:             fAllBlocked = FALSE;
                    364:             fAllEnabled = FALSE;
                    365:             InvalidateRect(hwndServer, &rcAllBlock, TRUE);
                    366:             break;
                    367: 
                    368:         case IDM_TERMNEXTCB:
                    369:             fTermNextCB = !fTermNextCB;
                    370:             InvalidateRect(hwndServer, &rcNextAction, TRUE);
                    371:             break;
                    372: 
                    373:         case IDM_BLOCKNEXTCB:
                    374:             fBlockNextCB = !fBlockNextCB;
                    375:             InvalidateRect(hwndServer, &rcNextAction, TRUE);
                    376:             break;
                    377: 
                    378:         case IDM_BLOCKALLCBS:
                    379:             DdeEnableCallback(idInst, 0, EC_DISABLE);
                    380:             fAllBlocked = TRUE;
                    381:             fAllEnabled = FALSE;
                    382:             InvalidateRect(hwndServer, &rcAllBlock, TRUE);
                    383:             break;
                    384: 
                    385:         case IDM_UNBLOCKALLCBS:
                    386:             DdeEnableCallback(idInst, 0, EC_ENABLEALL);
                    387:             fAllEnabled = TRUE;
                    388:             fAllBlocked = FALSE;
                    389:             InvalidateRect(hwndServer, &rcAllBlock, TRUE);
                    390:             break;
                    391: 
                    392:         case IDM_APPOWNED:
                    393:             fAppowned = !fAppowned;
                    394:             if (!fAppowned) {
                    395:                 WORD iFmt;
                    396:                 for (iFmt = 0; iFmt < CFORMATS; iFmt++) {
                    397:                     if (hDataHuge[iFmt]) {
                    398:                         DdeFreeDataHandle(hDataHuge[iFmt]);
                    399:                         hDataHuge[iFmt] = 0;
                    400:                         InvalidateRect(hwndServer, &rcHugeSize, TRUE);
                    401:                     }
                    402:                     if (hDataCount[iFmt]) {
                    403:                         DdeFreeDataHandle(hDataCount[iFmt]);
                    404:                         hDataCount[iFmt] = 0;
                    405:                     }
                    406:                     if (hDataRand[iFmt]) {
                    407:                         DdeFreeDataHandle(hDataRand[iFmt]);
                    408:                         hDataRand[iFmt] = 0;
                    409:                     }
                    410:                     if (hDataHelp[iFmt]) {
                    411:                         DdeFreeDataHandle(hDataHelp[iFmt]);
                    412:                         hDataHelp[iFmt] = 0;
                    413:                     }
                    414:                 }
                    415:             }
                    416:             InvalidateRect(hwndServer, &rcAppowned, TRUE);
                    417:             break;
                    418: 
                    419:         case IDM_RUNAWAY:
                    420:             cRunaway = !cRunaway;
                    421:             InvalidateRect(hwndServer, &rcRunaway, TRUE);
                    422:             if (!cRunaway) {
                    423:                 break;
                    424:             }
                    425:             // fall through
                    426: 
                    427:         case IDM_CHANGEDATA:
                    428:             PostMessage(hwndServer, UM_CHGDATA, 1, 0);  // rand
                    429:             PostMessage(hwndServer, UM_CHGDATA, 1, 1);  // count
                    430:             break;
                    431: 
                    432:         case IDM_RENDERDELAY:
1.1.1.2 ! root      433:             DoDialog("VALUEENTRY", (DLGPROC)RenderDelayDlgProc, 0, TRUE);
1.1       root      434:             InvalidateRect(hwndServer, &rcRndrDelay, TRUE);
                    435:             break;
                    436: 
                    437:         case IDM_SETSERVER:
1.1.1.2 ! root      438:             DoDialog("VALUEENTRY", (DLGPROC)SetServerDlgProc, 0, TRUE);
1.1       root      439:             break;
                    440: 
                    441:         case IDM_SETTOPIC:
1.1.1.2 ! root      442:             DoDialog("VALUEENTRY", (DLGPROC)SetTopicDlgProc, 0, TRUE);
1.1       root      443:             break;
                    444: 
                    445:         case IDM_CONTEXT:
1.1.1.2 ! root      446:             DoDialog("CONTEXT", (DLGPROC)ContextDlgProc, 0, TRUE);
1.1       root      447:             break;
                    448: 
                    449:         case IDM_ABOUT:
1.1.1.2 ! root      450:             DoDialog("ABOUT", (DLGPROC)About, 0, TRUE);
1.1       root      451:             break;
                    452: 
                    453:         case IDM_HELP:
                    454:            break;
                    455: 
                    456:         default:
                    457:             return (DefWindowProc(hWnd, message, wParam, lParam));
                    458:         }
                    459:         break;
                    460: 
                    461:     case WM_PAINT:
                    462:         PaintServer(hWnd);
                    463:         break;
                    464: 
                    465:     case UM_CHGDATA:
                    466:         {
                    467:             WORD iFmt;
                    468: 
                    469:             // wParam = TopicIndex,
                    470:             // LOWORD(lParam) = ItemIndex
                    471:             // We asynchronously do DdePostAdvise() calls to prevent infinite
                    472:             // loops when in runaway mode.
                    473:             if (wParam == 1) {  // test topic
                    474:                 if (lParam == 0) {  // rand item
                    475:                     seed = rand();
                    476:                     for (iFmt = 0; iFmt < CFORMATS ; iFmt++) {
                    477:                         if (hDataRand[iFmt]) {
                    478:                             DdeFreeDataHandle(hDataRand[iFmt]);
                    479:                             hDataRand[iFmt] = 0;
                    480:                         }
                    481:                     }
                    482:                     InvalidateRect(hwndServer, &rcRand, TRUE);
                    483:                     DdePostAdvise(idInst, topicList[wParam].hszTopic,
                    484:                             (HSZ)topicList[wParam].pItemList[lParam].hszItem);
                    485:                 }
                    486:                 if (lParam == 1) {  // count item
                    487:                     count++;
                    488:                     for (iFmt = 0; iFmt < CFORMATS ; iFmt++) {
                    489:                         if (hDataCount[iFmt]) {
                    490:                             DdeFreeDataHandle(hDataCount[iFmt]);
                    491:                             hDataCount[iFmt] = 0;
                    492:                         }
                    493:                     }
                    494:                     InvalidateRect(hwndServer, &rcCount, TRUE);
                    495:                     DdePostAdvise(idInst, topicList[wParam].hszTopic,
                    496:                             (HSZ)topicList[wParam].pItemList[lParam].hszItem);
                    497:                 }
                    498:                 // Huge item does not runaway - too slow.
                    499:             }
                    500:             if (cRunaway) {
                    501:                 Delay(50, TRUE);
                    502:                         // This gives enough time for the system to remain
                    503:                         // useable in runaway mode.
                    504:                 PostMessage(hwndServer, UM_CHGDATA, wParam, lParam);
                    505:             }
                    506:         }
                    507:         break;
                    508: 
                    509:     case WM_DESTROY:                  /* message: window being destroyed */
                    510:         if (fAppowned)
1.1.1.2 ! root      511:             SendMessage(hwndServer, WM_COMMAND, (WPARAM)MAKELONG(IDM_APPOWNED, 0), (LONG)(0));
1.1       root      512:         DdeNameService(idInst, 0, 0, DNS_UNREGISTER); // unregister all services
                    513:         UnHszize();
                    514:         DdeUninitialize(idInst);
                    515:         PostQuitMessage(0);
                    516:         break;
                    517: 
                    518:     default:
                    519:         return (DefWindowProc(hWnd, message, wParam, lParam));
                    520:     }
                    521:     return(0);
                    522: }
                    523: 
                    524: 
                    525: 
                    526: 
                    527: 
                    528: VOID Delay(
                    529: DWORD delay,
                    530: BOOL fModal)
                    531: {
                    532:     MSG msg;
                    533:     delay = GetCurrentTime() + delay;
                    534:     while (GetCurrentTime() < delay) {
                    535:         if (fModal && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
                    536:             TranslateMessage(&msg);
                    537:             DispatchMessage(&msg);
                    538:         }
                    539:     }
                    540: }
                    541: 
                    542: 
                    543: 
                    544: /*
                    545:  * This function not only paints the server client area with current info,
                    546:  * it also has the side effect of setting the global RECTs that bound each
                    547:  * info area.  This way flashing is reduced.
                    548:  */
                    549: VOID PaintServer(
                    550: HWND hwnd)
                    551: {
                    552:     PAINTSTRUCT ps;
                    553:     RECT rc;
                    554:     CHAR szT[MAX_COMMENT];
                    555: 
                    556:     BeginPaint(hwnd, &ps);
                    557:     SetBkMode(ps.hdc, TRANSPARENT);
                    558:     GetClientRect(hwnd, &rc);
                    559:     rc.bottom = rc.top + cyText;    // all rects are cyText in height.
                    560: 
                    561:     rcComment = rc;
                    562:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, pszComment);
                    563: 
                    564:     wsprintf(szT, "# of connections:%d", cServers);
                    565:     rcConnCount = rc;
                    566:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    567: 
                    568:     szT[0] = '\0';
                    569:     rcAllBlock = rc;
                    570:     if (fAllEnabled)
                    571:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "All Conversations are Enabled.");
                    572:     else if (fAllBlocked)
                    573:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "All Conversations are Blocked.");
                    574:     else
                    575:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    576: 
                    577:     rcNextAction = rc;
                    578:     if (fBlockNextCB)
                    579:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "Next callback will block.");
                    580:     else if (fTermNextCB)
                    581:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "Next callback will terminate.");
                    582:     else
                    583:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    584: 
                    585:     wsprintf(szT, "Count item = %ld", count);
                    586:     rcCount = rc;
                    587:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    588: 
                    589:     wsprintf(szT, "Rand item = %d", seed);
                    590:     rcRand = rc;
                    591:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    592: 
                    593:     wsprintf(szT, "Huge item size = %ld", cbHuge);
                    594:     rcHugeSize = rc;
                    595:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    596: 
                    597:     wsprintf(szT, "Render delay is %d milliseconds.", RenderDelay);
                    598:     rcRndrDelay = rc;
                    599:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    600: 
                    601:     rcExec = rc;
                    602:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szExec);
                    603: 
                    604:     rcRunaway = rc;
                    605:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, cRunaway ? "Runaway active." : "");
                    606: 
                    607:     rcAppowned = rc;
                    608:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, fAppowned ? "Using AppOwned Data Handles." : "");
                    609: 
                    610:     EndPaint(hwnd, &ps);
                    611: }
                    612: 
                    613: 
                    614: VOID DrawTextLine(
                    615: HDC hdc,
                    616: RECT *prcClip,
                    617: RECT *prcText,
                    618: PSTR psz)
                    619: {
                    620:     RECT rc;
                    621: 
                    622:     if (IntersectRect(&rc, prcText, prcClip)) {
                    623:         DrawText(hdc, psz, -1, prcText,
                    624:                 DT_LEFT | DT_EXTERNALLEADING | DT_SINGLELINE | DT_EXPANDTABS |
                    625:                 DT_NOCLIP | DT_NOPREFIX);
                    626:     }
                    627:     OffsetRect(prcText, 0, cyText);
                    628: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.