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

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: 
                    150: int APIENTRY WinMain(
                    151:     HANDLE hInstance,
                    152:     HANDLE hPrevInstance,
                    153:     LPSTR lpCmdLine,
                    154:     int nCmdShow
                    155:     )
                    156: {
                    157:     MSG msg;                                 /* message                      */
                    158: 
                    159:     if (!hPrevInstance)                  /* Other instances of app running? */
                    160:         if (!InitApplication(hInstance)) /* Initialize shared things */
                    161:             return (FALSE);              /* Exits if unable to initialize     */
                    162: 
                    163:     /* Perform initializations that apply to a specific instance */
                    164: 
                    165:     if (!InitInstance(hInstance, nCmdShow))
                    166:         return (FALSE);
                    167: 
                    168:     /* Acquire and dispatch messages until a WM_QUIT message is received. */
                    169: 
                    170:     while (GetMessage(&msg,     /* message structure                      */
                    171:             0,                  /* handle of window receiving the message */
                    172:             0,                  /* lowest message to examine              */
                    173:             0))                 /* highest message to examine             */
                    174:         {
                    175:         TranslateMessage(&msg);    /* Translates virtual key codes           */
                    176:         DispatchMessage(&msg);     /* Dispatches message to window           */
                    177:     }
                    178: 
                    179:     UnregisterClass(szClass, hInstance);
                    180:     return (msg.wParam);           /* Returns the value from PostQuitMessage */
                    181: }
                    182: 
                    183: 
                    184: /****************************************************************************
                    185: 
                    186:     FUNCTION: InitApplication(HANDLE)
                    187: 
                    188:     PURPOSE: Initializes window data and registers window class
                    189: 
                    190:     COMMENTS:
                    191: 
                    192:         This function is called at initialization time only if no other
                    193:         instances of the application are running.  This function performs
                    194:         initialization tasks that can be done once for any number of running
                    195:         instances.
                    196: 
                    197:         In this case, we initialize a window class by filling out a data
                    198:         structure of type WNDCLASS and calling the Windows RegisterClass()
                    199:         function.  Since all instances of this application use the same window
                    200:         class, we only need to do this when the first instance is initialized.
                    201: 
                    202: 
                    203: ****************************************************************************/
                    204: 
                    205: BOOL InitApplication(hInstance)
                    206: HANDLE hInstance;                              /* current instance           */
                    207: {
                    208:     WNDCLASS  wc;
                    209: 
                    210:     /* Fill in window class structure with parameters that describe the       */
                    211:     /* main window.                                                           */
                    212: 
                    213:     wc.style = 0;                       /* Class style(s).                    */
                    214:     wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for  */
                    215:                                         /* windows of this class.             */
                    216:     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
                    217:     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
                    218:     wc.hInstance = hInstance;           /* Application that owns the class.   */
                    219:     wc.hIcon = LoadIcon(hInstance, "server");
                    220:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
                    221:     wc.hbrBackground = (HANDLE)(COLOR_APPWORKSPACE+1);
                    222:     wc.lpszMenuName =  "ServerMenu";   /* Name of menu resource in .RC file. */
                    223:     wc.lpszClassName = "ServerWClass"; /* Name used in call to CreateWindow. */
                    224: 
                    225:     /* Register the window class and return success/failure code. */
                    226: 
                    227:     return (RegisterClass(&wc));
                    228: 
                    229: }
                    230: 
                    231: 
                    232: /****************************************************************************
                    233: 
                    234:     FUNCTION:  InitInstance(HANDLE, int)
                    235: 
                    236:     PURPOSE:  Saves instance handle and creates main window
                    237: 
                    238:     COMMENTS:
                    239: 
                    240:         This function is called at initialization time for every instance of
                    241:         this application.  This function performs initialization tasks that
                    242:         cannot be shared by multiple instances.
                    243: 
                    244:         In this case, we save the instance handle in a static variable and
                    245:         create and display the main program window.
                    246: 
                    247: ****************************************************************************/
                    248: 
                    249: BOOL InitInstance(hInstance, nCmdShow)
                    250:     HANDLE          hInstance;          /* Current instance identifier.       */
                    251:     INT             nCmdShow;           /* Param for first ShowWindow() call. */
                    252: {
                    253:     INT i;
                    254:     RECT Rect;
                    255:     TEXTMETRIC metrics;
                    256:     HDC hdc;
                    257: 
                    258:     /* Save the instance handle in static variable, which will be used in  */
                    259:     /* many subsequence calls from this application to Windows.            */
                    260: 
                    261:     hInst = hInstance;
                    262: 
                    263: 
                    264:     /* Create a main window for this application instance.  */
                    265: 
                    266:     hwndServer = CreateWindow(
                    267:         "ServerWClass",                /* See RegisterClass() call.          */
                    268:         "Server|Test",
                    269:         WS_OVERLAPPEDWINDOW,            /* Window style.                      */
                    270:         CW_USEDEFAULT,                  /* Default horizontal position.       */
                    271:         CW_USEDEFAULT,                  /* Default vertical position.         */
                    272:         400,
                    273:         200,
                    274:         NULL,                           /* Overlapped windows have no parent. */
                    275:         NULL,                           /* Use the window class menu.         */
                    276:         hInstance,                      /* This instance owns this window.    */
                    277:         NULL                            /* Pointer not needed.                */
                    278:     );
                    279: 
                    280:     GetClientRect(hwndServer, (LPRECT) &Rect);
                    281: 
                    282:     /* If window could not be created, return "failure" */
                    283: 
                    284:     if (!hwndServer)
                    285:         return (FALSE);
                    286: 
                    287:     hdc = GetDC(hwndServer);
                    288:     GetTextMetrics(hdc, &metrics);
                    289:     cyText = (WORD)(metrics.tmHeight + metrics.tmExternalLeading);
                    290:     ReleaseDC(hwndServer, hdc);
                    291: 
                    292:     aFormats[0].atom = CF_TEXT; // exception - predefined.
                    293:     for (i = 1; i < CFORMATS; i++) {
                    294:         aFormats[i].atom = RegisterClipboardFormat(aFormats[i].sz);
                    295:     }
                    296: 
                    297:     /* Make the window visible; update its client area; and return "success" */
                    298: 
                    299:     ShowWindow(hwndServer, nCmdShow);  /* Show the window                        */
                    300:     UpdateWindow(hwndServer);          /* Sends WM_PAINT message                 */
                    301:     seed = 1;
                    302:     srand(1);
                    303:     CCFilter.iCodePage = CP_WINANSI;   // initial default codepage
                    304:     if (!DdeInitialize(&idInst, (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback,
                    305:                 hInstance), APPCMD_FILTERINITS, 0)) {
                    306:         Hszize();
                    307:         DdeNameService(idInst, hszAppName, 0, DNS_REGISTER);
                    308:         return(TRUE);
                    309:     }
                    310:     return (FALSE);
                    311: 
                    312: }
                    313: 
                    314: /****************************************************************************
                    315: 
                    316:     FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
                    317: 
                    318:     PURPOSE:  Processes messages
                    319: 
                    320:     MESSAGES:
                    321: 
                    322:         WM_COMMAND    - application menu (About dialog box)
                    323:         WM_DESTROY    - destroy window
                    324: 
                    325:     COMMENTS:
                    326: 
                    327:         To process the IDM_ABOUT message, call MakeProcInstance() to get the
                    328:         current instance address of the About() function.  Then call Dialog
                    329:         box which will create the box according to the information in your
                    330:         server.rc file and turn control over to the About() function.   When
                    331:         it returns, free the intance address.
                    332: 
                    333: ****************************************************************************/
                    334: 
                    335: LONG  APIENTRY MainWndProc(hWnd, message, wParam, lParam)
                    336: HWND hWnd;                                /* window handle                   */
                    337: UINT message;                         /* type of message                 */
                    338: WPARAM wParam;                              /* additional information          */
                    339: LONG lParam;                              /* additional information          */
                    340: {
                    341:     switch (message) {
                    342:     case WM_INITMENU:
                    343:         if (GetMenu(hWnd) != (HMENU)wParam)
                    344:             break;
                    345: 
                    346:         CheckMenuItem((HMENU)wParam, IDM_BLOCKALLCBS,
                    347:                 fAllBlocked ? MF_CHECKED : MF_UNCHECKED);
                    348:         CheckMenuItem((HMENU)wParam, IDM_UNBLOCKALLCBS,
                    349:                 fAllEnabled ? MF_CHECKED : MF_UNCHECKED);
                    350:         CheckMenuItem((HMENU)wParam, IDM_BLOCKNEXTCB,
                    351:                 fBlockNextCB ? MF_CHECKED : MF_UNCHECKED);
                    352:         CheckMenuItem((HMENU)wParam, IDM_TERMNEXTCB,
                    353:                 fTermNextCB ? MF_CHECKED : MF_UNCHECKED);
                    354:         CheckMenuItem((HMENU)wParam, IDM_RUNAWAY,
                    355:                 cRunaway ? MF_CHECKED : MF_UNCHECKED);
                    356:         CheckMenuItem((HMENU)wParam, IDM_APPOWNED,
                    357:                 fAppowned ? MF_CHECKED : MF_UNCHECKED);
                    358:         break;
                    359: 
                    360:     case WM_COMMAND:           /* message: command from application menu */
                    361:         switch (GET_WM_COMMAND_ID(wParam, lParam)) {
                    362:         case IDM_ENABLEONECB:
                    363:             DdeEnableCallback(idInst, 0, EC_ENABLEONE);
                    364:             fAllBlocked = FALSE;
                    365:             fAllEnabled = FALSE;
                    366:             InvalidateRect(hwndServer, &rcAllBlock, TRUE);
                    367:             break;
                    368: 
                    369:         case IDM_TERMNEXTCB:
                    370:             fTermNextCB = !fTermNextCB;
                    371:             InvalidateRect(hwndServer, &rcNextAction, TRUE);
                    372:             break;
                    373: 
                    374:         case IDM_BLOCKNEXTCB:
                    375:             fBlockNextCB = !fBlockNextCB;
                    376:             InvalidateRect(hwndServer, &rcNextAction, TRUE);
                    377:             break;
                    378: 
                    379:         case IDM_BLOCKALLCBS:
                    380:             DdeEnableCallback(idInst, 0, EC_DISABLE);
                    381:             fAllBlocked = TRUE;
                    382:             fAllEnabled = FALSE;
                    383:             InvalidateRect(hwndServer, &rcAllBlock, TRUE);
                    384:             break;
                    385: 
                    386:         case IDM_UNBLOCKALLCBS:
                    387:             DdeEnableCallback(idInst, 0, EC_ENABLEALL);
                    388:             fAllEnabled = TRUE;
                    389:             fAllBlocked = FALSE;
                    390:             InvalidateRect(hwndServer, &rcAllBlock, TRUE);
                    391:             break;
                    392: 
                    393:         case IDM_APPOWNED:
                    394:             fAppowned = !fAppowned;
                    395:             if (!fAppowned) {
                    396:                 WORD iFmt;
                    397:                 for (iFmt = 0; iFmt < CFORMATS; iFmt++) {
                    398:                     if (hDataHuge[iFmt]) {
                    399:                         DdeFreeDataHandle(hDataHuge[iFmt]);
                    400:                         hDataHuge[iFmt] = 0;
                    401:                         InvalidateRect(hwndServer, &rcHugeSize, TRUE);
                    402:                     }
                    403:                     if (hDataCount[iFmt]) {
                    404:                         DdeFreeDataHandle(hDataCount[iFmt]);
                    405:                         hDataCount[iFmt] = 0;
                    406:                     }
                    407:                     if (hDataRand[iFmt]) {
                    408:                         DdeFreeDataHandle(hDataRand[iFmt]);
                    409:                         hDataRand[iFmt] = 0;
                    410:                     }
                    411:                     if (hDataHelp[iFmt]) {
                    412:                         DdeFreeDataHandle(hDataHelp[iFmt]);
                    413:                         hDataHelp[iFmt] = 0;
                    414:                     }
                    415:                 }
                    416:             }
                    417:             InvalidateRect(hwndServer, &rcAppowned, TRUE);
                    418:             break;
                    419: 
                    420:         case IDM_RUNAWAY:
                    421:             cRunaway = !cRunaway;
                    422:             InvalidateRect(hwndServer, &rcRunaway, TRUE);
                    423:             if (!cRunaway) {
                    424:                 break;
                    425:             }
                    426:             // fall through
                    427: 
                    428:         case IDM_CHANGEDATA:
                    429:             PostMessage(hwndServer, UM_CHGDATA, 1, 0);  // rand
                    430:             PostMessage(hwndServer, UM_CHGDATA, 1, 1);  // count
                    431:             break;
                    432: 
                    433:         case IDM_RENDERDELAY:
                    434:             DoDialog("VALUEENTRY", (FARPROC)RenderDelayDlgProc, 0, TRUE);
                    435:             InvalidateRect(hwndServer, &rcRndrDelay, TRUE);
                    436:             break;
                    437: 
                    438:         case IDM_SETSERVER:
                    439:             DoDialog("VALUEENTRY", (FARPROC)SetServerDlgProc, 0, TRUE);
                    440:             break;
                    441: 
                    442:         case IDM_SETTOPIC:
                    443:             DoDialog("VALUEENTRY", (FARPROC)SetTopicDlgProc, 0, TRUE);
                    444:             break;
                    445: 
                    446:         case IDM_CONTEXT:
                    447:             DoDialog("CONTEXT", (FARPROC)ContextDlgProc, 0, TRUE);
                    448:             break;
                    449: 
                    450:         case IDM_ABOUT:
                    451:             DoDialog("ABOUT", (FARPROC)About, 0, TRUE);
                    452:             break;
                    453: 
                    454:         case IDM_HELP:
                    455:            break;
                    456: 
                    457:         default:
                    458:             return (DefWindowProc(hWnd, message, wParam, lParam));
                    459:         }
                    460:         break;
                    461: 
                    462:     case WM_PAINT:
                    463:         PaintServer(hWnd);
                    464:         break;
                    465: 
                    466:     case UM_CHGDATA:
                    467:         {
                    468:             WORD iFmt;
                    469: 
                    470:             // wParam = TopicIndex,
                    471:             // LOWORD(lParam) = ItemIndex
                    472:             // We asynchronously do DdePostAdvise() calls to prevent infinite
                    473:             // loops when in runaway mode.
                    474:             if (wParam == 1) {  // test topic
                    475:                 if (lParam == 0) {  // rand item
                    476:                     seed = rand();
                    477:                     for (iFmt = 0; iFmt < CFORMATS ; iFmt++) {
                    478:                         if (hDataRand[iFmt]) {
                    479:                             DdeFreeDataHandle(hDataRand[iFmt]);
                    480:                             hDataRand[iFmt] = 0;
                    481:                         }
                    482:                     }
                    483:                     InvalidateRect(hwndServer, &rcRand, TRUE);
                    484:                     DdePostAdvise(idInst, topicList[wParam].hszTopic,
                    485:                             (HSZ)topicList[wParam].pItemList[lParam].hszItem);
                    486:                 }
                    487:                 if (lParam == 1) {  // count item
                    488:                     count++;
                    489:                     for (iFmt = 0; iFmt < CFORMATS ; iFmt++) {
                    490:                         if (hDataCount[iFmt]) {
                    491:                             DdeFreeDataHandle(hDataCount[iFmt]);
                    492:                             hDataCount[iFmt] = 0;
                    493:                         }
                    494:                     }
                    495:                     InvalidateRect(hwndServer, &rcCount, TRUE);
                    496:                     DdePostAdvise(idInst, topicList[wParam].hszTopic,
                    497:                             (HSZ)topicList[wParam].pItemList[lParam].hszItem);
                    498:                 }
                    499:                 // Huge item does not runaway - too slow.
                    500:             }
                    501:             if (cRunaway) {
                    502:                 Delay(50, TRUE);
                    503:                         // This gives enough time for the system to remain
                    504:                         // useable in runaway mode.
                    505:                 PostMessage(hwndServer, UM_CHGDATA, wParam, lParam);
                    506:             }
                    507:         }
                    508:         break;
                    509: 
                    510:     case WM_DESTROY:                  /* message: window being destroyed */
                    511:         if (fAppowned)
                    512:             SendMessage(hwndServer, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_APPOWNED, 0, 0));
                    513:         DdeNameService(idInst, 0, 0, DNS_UNREGISTER); // unregister all services
                    514:         UnHszize();
                    515:         DdeUninitialize(idInst);
                    516:         PostQuitMessage(0);
                    517:         break;
                    518: 
                    519:     default:
                    520:         return (DefWindowProc(hWnd, message, wParam, lParam));
                    521:     }
                    522:     return(0);
                    523: }
                    524: 
                    525: 
                    526: 
                    527: 
                    528: 
                    529: VOID Delay(
                    530: DWORD delay,
                    531: BOOL fModal)
                    532: {
                    533:     MSG msg;
                    534:     delay = GetCurrentTime() + delay;
                    535:     while (GetCurrentTime() < delay) {
                    536:         if (fModal && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
                    537:             TranslateMessage(&msg);
                    538:             DispatchMessage(&msg);
                    539:         }
                    540:     }
                    541: }
                    542: 
                    543: 
                    544: 
                    545: /*
                    546:  * This function not only paints the server client area with current info,
                    547:  * it also has the side effect of setting the global RECTs that bound each
                    548:  * info area.  This way flashing is reduced.
                    549:  */
                    550: VOID PaintServer(
                    551: HWND hwnd)
                    552: {
                    553:     PAINTSTRUCT ps;
                    554:     RECT rc;
                    555:     CHAR szT[MAX_COMMENT];
                    556: 
                    557:     BeginPaint(hwnd, &ps);
                    558:     SetBkMode(ps.hdc, TRANSPARENT);
                    559:     GetClientRect(hwnd, &rc);
                    560:     rc.bottom = rc.top + cyText;    // all rects are cyText in height.
                    561: 
                    562:     rcComment = rc;
                    563:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, pszComment);
                    564: 
                    565:     wsprintf(szT, "# of connections:%d", cServers);
                    566:     rcConnCount = rc;
                    567:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    568: 
                    569:     szT[0] = '\0';
                    570:     rcAllBlock = rc;
                    571:     if (fAllEnabled)
                    572:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "All Conversations are Enabled.");
                    573:     else if (fAllBlocked)
                    574:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "All Conversations are Blocked.");
                    575:     else
                    576:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    577: 
                    578:     rcNextAction = rc;
                    579:     if (fBlockNextCB)
                    580:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "Next callback will block.");
                    581:     else if (fTermNextCB)
                    582:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, "Next callback will terminate.");
                    583:     else
                    584:         DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    585: 
                    586:     wsprintf(szT, "Count item = %ld", count);
                    587:     rcCount = rc;
                    588:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    589: 
                    590:     wsprintf(szT, "Rand item = %d", seed);
                    591:     rcRand = rc;
                    592:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    593: 
                    594:     wsprintf(szT, "Huge item size = %ld", cbHuge);
                    595:     rcHugeSize = rc;
                    596:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    597: 
                    598:     wsprintf(szT, "Render delay is %d milliseconds.", RenderDelay);
                    599:     rcRndrDelay = rc;
                    600:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szT);
                    601: 
                    602:     rcExec = rc;
                    603:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, szExec);
                    604: 
                    605:     rcRunaway = rc;
                    606:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, cRunaway ? "Runaway active." : "");
                    607: 
                    608:     rcAppowned = rc;
                    609:     DrawTextLine(ps.hdc, &ps.rcPaint, &rc, fAppowned ? "Using AppOwned Data Handles." : "");
                    610: 
                    611:     EndPaint(hwnd, &ps);
                    612: }
                    613: 
                    614: 
                    615: VOID DrawTextLine(
                    616: HDC hdc,
                    617: RECT *prcClip,
                    618: RECT *prcText,
                    619: PSTR psz)
                    620: {
                    621:     RECT rc;
                    622: 
                    623:     if (IntersectRect(&rc, prcText, prcClip)) {
                    624:         DrawText(hdc, psz, -1, prcText,
                    625:                 DT_LEFT | DT_EXTERNALLEADING | DT_SINGLELINE | DT_EXPANDTABS |
                    626:                 DT_NOCLIP | DT_NOPREFIX);
                    627:     }
                    628:     OffsetRect(prcText, 0, cyText);
                    629: }
                    630: 

unix.superglobalmegacorp.com

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