|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.