|
|
1.1 ! root 1: /* ! 2: * CLIPVIEW.C -- Clipboard Viewing application ! 3: * Created by Microsoft, IBM Corporation, 1990 ! 4: * ! 5: * DISCLAIMER OF WARRANTIES. The following [enclosed] code is ! 6: * sample code created by Microsoft Corporation and/or IBM ! 7: * Corporation. This sample code is not part of any standard ! 8: * Microsoft or IBM product and is provided to you solely for ! 9: * the purpose of assisting you in the development of your ! 10: * applications. The code is provided "AS IS", without ! 11: * warranty of any kind. Neither Microsoft nor IBM shall be ! 12: * liable for any damages arising out of your use of the sample ! 13: * code, even if they have been advised of the possibility of ! 14: * such damages. ! 15: * ! 16: * This program registers itself as the clipboard viewer, if no clipboard ! 17: * viewer exists. Then, it intercepts WM_DRAWCLIPBOARD messages. ! 18: * ! 19: * This file contains the routines which handle the client/frame windows, ! 20: * the dialog routines, and the clipboard rendering code. ! 21: */ ! 22: ! 23: ! 24: /* Currently MLE control are not implemented in OS/2 2.0 therefore ! 25: * all references to MLE have been #defined out of the picture ! 26: * as soon as they become implemented uncomment MLE_OK and everything ! 27: * should work as originally intended ! 28: */ ! 29: ! 30: ! 31: /***************** ! 32: ! 33: ! 34: #define MLE_OK ! 35: ! 36: ! 37: ******************/ ! 38: ! 39: ! 40: ! 41: ! 42: #define INCL_GPIBITMAPS ! 43: #define INCL_GPIMETAFILES ! 44: #define INCL_WINATOM ! 45: #define INCL_WINCLIPBOARD ! 46: #define INCL_WINFRAMEMGR ! 47: #define INCL_WINLISTBOXES ! 48: #define INCL_WINMENUS ! 49: #define INCL_WINMLE ! 50: #define INCL_WINSCROLLBARS ! 51: #define INCL_WINSYS ! 52: #define INCL_WINWINDOWMGR ! 53: #define INCL_GPILCIDS ! 54: #include <os2.h> ! 55: #include <string.h> ! 56: #include <ctype.h> ! 57: #include "clipview.h" ! 58: /* ! 59: * Globals ! 60: */ ! 61: BITMAPINFOHEADER vbmp; // Dimensions of current BITMAP ! 62: BOOL vfUpdate = FALSE; // Are we updating the clipboard? ! 63: BOOL vfViewBitmap = FALSE; // Are we currently viewing a...? ! 64: BOOL vfViewText = FALSE; // Are we currently viewing text ! 65: HAB vhab; // Anchor block ! 66: HDC vhdcMemory; // A memory DC for BitBlt-ing images ! 67: HDC vhdcWindow = NULL; // Client window DC ! 68: HMQ vhmqClip; // Message queue ! 69: HPS vhpsMemory; // A PS associated with vhdcMemory ! 70: HWND vhwndClient; // Main client area ! 71: HWND vhwndClipFrame = NULL; // Main frame window ! 72: HWND vhwndHSB = NULL; // Horizontal scroll bar ! 73: ! 74: ! 75: ! 76: HWND vhwndMLE = NULL; // Handle to the MLE ! 77: ! 78: ! 79: ! 80: HWND vhwndTitlebar = NULL; // Title-bar handle ! 81: HWND vhwndVSB = NULL; // Vertical scroll bar ! 82: SHORT vcMaxHSB; // Maximum scroll range for HSB ! 83: SHORT vcMaxVSB; // ...and for the VSB ! 84: SHORT vcUpdate = -1; // Counter for scroll bar updating ! 85: USHORT vausFormats[MAXFORMATS]; // All available formats ! 86: USHORT vcFmts; // How many formats? ! 87: USHORT vusFormat; // What is the current format? ! 88: USHORT vfsFmtInfo; // Clipboard Format Information ! 89: /* ! 90: Macros ! 91: */ ! 92: #define LOADSTRING(id, sz) WinLoadString(vhab, NULL, id, MAXLEN, sz) ! 93: #define MESSAGE(sz) WinMessageBox(HWND_DESKTOP, vhwndClient, sz, NULL, NULL, \ ! 94: MB_OK | MB_ICONASTERISK | MB_SYSTEMMODAL); ! 95: /* ! 96: * Main routine...initializes window and message queue ! 97: */ ! 98: int cdecl main( ) { ! 99: QMSG qmsg; /* Message queue */ ! 100: ULONG ctldata; /* FCF_ flags */ ! 101: BOOL fViewer; /* Does a viewer already exist? */ ! 102: UCHAR szAlready[MAXLEN]; /* Already extant... message */ ! 103: UCHAR szClassName[MAXLEN]; /* New class name */ ! 104: /* ! 105: Start up our PM application ! 106: */ ! 107: vhab = WinInitialize(NULL); ! 108: vhmqClip = WinCreateMsgQueue(vhab, 0); ! 109: /* ! 110: We create the client window first to try to avoid ! 111: synchronization problems. ! 112: */ ! 113: LOADSTRING(IDS_CLIPCLASS, szClassName); ! 114: if (!WinRegisterClass( vhab, (PCH)szClassName, (PFNWP)ClipWndProc, ! 115: CS_SIZEREDRAW, 0)) ! 116: return( 0 ); ! 117: /* ! 118: Create the window (hidden) ! 119: */ ! 120: ctldata = (FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL) ! 121: & ~(FCF_ACCELTABLE); ! 122: ! 123: vhwndClipFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE, &ctldata, ! 124: szClassName, "", ! 125: WS_VISIBLE, NULL, ID_RESOURCE, ! 126: (PHWND) &vhwndClient ); ! 127: /* ! 128: If there is no other clipboard viewer... ! 129: */ ! 130: if (fViewer = !WinQueryClipbrdViewer(vhab, FALSE)) { ! 131: /* ! 132: ...we'll be the viewer. Show the clipboard window. ! 133: */ ! 134: WinSetClipbrdViewer(vhab, vhwndClient); ! 135: /* ! 136: Poll messages from event queue ! 137: */ ! 138: while( WinGetMsg( vhab, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) ) ! 139: WinDispatchMsg( vhab, (PQMSG)&qmsg ); ! 140: /* ! 141: Stop being the clipboard viewer. ! 142: */ ! 143: ! 144: ! 145: #ifdef MLE_OK ! 146: ! 147: if (vhwndMLE) ! 148: WinDestroyWindow(vhwndMLE); ! 149: ! 150: #endif ! 151: ! 152: ! 153: WinSetClipbrdViewer(vhab, NULL); ! 154: ! 155: } else { ! 156: /* ! 157: ...otherwise, notify the user, then terminate. ! 158: */ ! 159: LOADSTRING(IDS_ALREADY, szAlready); ! 160: MESSAGE(szAlready); ! 161: } ! 162: /* ! 163: Clean up ! 164: */ ! 165: WinDestroyWindow( vhwndClipFrame ); ! 166: WinDestroyMsgQueue( vhmqClip ); ! 167: WinTerminate( vhab ); ! 168: ! 169: return !fViewer; ! 170: } ! 171: ! 172: MRESULT EXPENTRY ClipWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) { ! 173: /* ! 174: ! 175: * This routine processes WM_COMMAND, WM_CREATE, WM_DRAWCLIPBOARD, WM_PAINT. ! 176: * Everything else is passed to the Default Window Procedure. ! 177: */ ! 178: HPS hpsWindow; ! 179: RECTL rcl; ! 180: SWP swp; ! 181: SIZEL sizl; ! 182: UCHAR szMessage[MAXLEN]; ! 183: ! 184: switch (msg) { ! 185: ! 186: case WM_CREATE: ! 187: /* ! 188: Create a memory DC/PS to BitBlt BITMAPs around. ! 189: */ ! 190: sizl.cx = sizl.cy = 0L; ! 191: vhdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL); ! 192: vhpsMemory = GpiCreatePS(vhab, vhdcMemory, &sizl, ! 193: GPIA_ASSOC | GPIF_DEFAULT | GPIT_MICRO | PU_PELS); ! 194: break; ! 195: ! 196: case WM_COMMAND: ! 197: switch ((USHORT) SHORT1FROMMP (mp1)) { ! 198: /* ! 199: About... dialog box ! 200: */ ! 201: case IDM_ABOUT: ! 202: WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, ! 203: NULL, IDD_ABOUT, NULL); ! 204: return 0; ! 205: /* ! 206: Render... dialog box ! 207: */ ! 208: case IDM_RENDER: ! 209: WinDlgBox(HWND_DESKTOP, hwnd, RenderDlgProc, ! 210: NULL, IDD_RENDER, NULL); ! 211: return 0; ! 212: /* ! 213: Save... dialog box ! 214: */ ! 215: case IDM_SAVE: ! 216: if (!SaveClipboard(hwnd, vusFormat)) { ! 217: LOADSTRING(IDS_NOTSAVED, szMessage); ! 218: MESSAGE(szMessage); ! 219: } ! 220: return 0; ! 221: ! 222: default: break; ! 223: } ! 224: break; ! 225: ! 226: case WM_ERASEBACKGROUND: ! 227: return MRFROMSHORT (TRUE) ; ! 228: break; ! 229: ! 230: case WM_PAINT: ! 231: /* Open the presentation space */ ! 232: hpsWindow = WinBeginPaint(hwnd, NULL, &rcl); ! 233: ! 234: /* Fill in the background */ ! 235: WinFillRect(hpsWindow, &rcl, CLR_BACKGROUND); ! 236: ! 237: /* Paint in the clipboard */ ! 238: UpdateScreen(hwnd, vusFormat); ! 239: ! 240: /* Finish painting */ ! 241: WinEndPaint(hpsWindow); ! 242: break; ! 243: ! 244: case WM_DRAWCLIPBOARD: ! 245: /* Update the clipboard contents */ ! 246: GetAllFormats(); ! 247: vfUpdate = TRUE; ! 248: WinPostMsg(hwnd, WM_PAINT, 0L, 0L); ! 249: break; ! 250: ! 251: case WM_HSCROLL: ! 252: if (vfViewBitmap) { ! 253: /* ! 254: Handle the appropriate scrolling messages ! 255: */ ! 256: DoScrolling(hwnd, TRUE, HIUSHORT(mp2)); ! 257: } ! 258: else if ( vfViewText ) { ! 259: DoScrolling(hwnd, TRUE, HIUSHORT(mp2)); ! 260: } else ! 261: /* ! 262: If an ownerdraw format, let the owner handle it. ! 263: */ ! 264: SendOwnerMsg(WM_HSCROLLCLIPBOARD, (MPARAM) hwnd, mp2); ! 265: break; ! 266: ! 267: case WM_VSCROLL: ! 268: if (vfViewBitmap) { ! 269: /* ! 270: Handle the appropriate scrolling messages ! 271: */ ! 272: DoScrolling(hwnd, FALSE, HIUSHORT(mp2)); ! 273: } ! 274: else if ( vfViewText ) { ! 275: DoScrolling(hwnd, FALSE, HIUSHORT(mp2)); ! 276: } else ! 277: /* ! 278: If an ownerdraw format, let the owner handle it. ! 279: */ ! 280: SendOwnerMsg(WM_VSCROLLCLIPBOARD, (MPARAM) hwnd, mp2); ! 281: break; ! 282: ! 283: case WM_SIZE: ! 284: ! 285: ! 286: /* ! 287: If the MLE is processing a text selector, ! 288: tell it to resize itself. If we have ! 289: owner-draw data, tell the clipboard owner. ! 290: If we have a BITMAP, readjust the scroll ! 291: bar ranges. ! 292: */ ! 293: ! 294: ! 295: if (vhwndMLE) { ! 296: WinQueryWindowPos(vhwndMLE, &swp); ! 297: swp.cx = SHORT1FROMMP(mp2); ! 298: swp.cy = SHORT2FROMMP(mp2); ! 299: WinSetMultWindowPos(vhab, &swp, 1); ! 300: } else if (vfViewBitmap) { ! 301: WinQueryWindowPos(hwnd, &swp); ! 302: if ((vcMaxHSB = vbmp.cx - swp.cx) < 0) ! 303: vcMaxHSB = 0; ! 304: if ((vcMaxVSB = vbmp.cy - swp.cy) < 0) ! 305: vcMaxVSB = 0; ! 306: WinSendMsg(vhwndHSB, SBM_SETSCROLLBAR, ! 307: 0L, MPFROM2SHORT(0, vcMaxHSB)); ! 308: WinSendMsg(vhwndVSB, SBM_SETSCROLLBAR, ! 309: MPFROMSHORT(vcMaxVSB), ! 310: MPFROM2SHORT(0, vcMaxVSB)); ! 311: } else { ! 312: rcl.xLeft = rcl.yBottom = 0L; ! 313: rcl.xLeft = (LONG) SHORT1FROMMP(mp2) - 1; ! 314: rcl.yTop = (LONG) SHORT2FROMMP(mp2) - 1; ! 315: SendOwnerMsg(WM_SIZECLIPBOARD, (MPARAM) hwnd, &rcl); ! 316: } ! 317: ! 318: ! 319: break; ! 320: ! 321: default: ! 322: return WinDefWindowProc(hwnd, msg, mp1, mp2); ! 323: break; ! 324: } ! 325: return 0L; ! 326: } ! 327: ! 328: MRESULT EXPENTRY RenderDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2) ! 329: { ! 330: /* ! 331: Render... dialog procedure ! 332: */ ! 333: HWND hwndListbox; /* Listbox of possible formats */ ! 334: UCHAR szFmtName[MAXLEN]; /* Format name */ ! 335: UCHAR szMessage[MAXLEN]; ! 336: USHORT i; ! 337: USHORT usFormat; /* Format to render */ ! 338: MRESULT mrItem; /* Which listbox item selected? */ ! 339: ! 340: switch(msg) { ! 341: ! 342: case WM_INITDLG: ! 343: /* ! 344: Put all the possible formats into the listbox, and ! 345: select the first item by default. ! 346: */ ! 347: hwndListbox = WinWindowFromID(hwndDlg, IDL_RENDER); ! 348: WinSendMsg(hwndListbox, LM_DELETEALL, 0L, 0L); ! 349: for (i = 0; i < vcFmts; i++) { ! 350: GetFormatName(vausFormats[i], szFmtName); ! 351: WinSendMsg(hwndListbox, LM_INSERTITEM, ! 352: MPFROMSHORT(LIT_END), MPFROMP((PVOID) szFmtName)); ! 353: } ! 354: WinSendMsg(hwndListbox, LM_SELECTITEM, 0L, MPFROMSHORT(TRUE)); ! 355: break; ! 356: ! 357: case WM_CONTROL: ! 358: /* ! 359: If the user makes a selection, quit! ! 360: */ ! 361: if ((SHORT1FROMMP(mp1) == IDL_RENDER) ! 362: && (SHORT2FROMMP(mp1) == LN_ENTER)) ! 363: WinPostMsg(hwndDlg, WM_COMMAND, MPFROMSHORT(DID_OK), 0L); ! 364: break; ! 365: ! 366: case WM_COMMAND: ! 367: switch( (USHORT) SHORT1FROMMP (mp1) ) { ! 368: case DID_OK: ! 369: /* ! 370: Since the user chose a selection, try to render it. ! 371: */ ! 372: hwndListbox = WinWindowFromID(hwndDlg, IDL_RENDER); ! 373: mrItem = WinSendMsg(hwndListbox, LM_QUERYSELECTION, 0L, 0L); ! 374: if (mrItem != MPFROMSHORT (LIT_NONE) ) { ! 375: usFormat = vausFormats[(USHORT) mrItem]; ! 376: if (usFormat != vusFormat) { ! 377: /* ! 378: If the clipboard format is not rendered, ! 379: tell the user. ! 380: */ ! 381: vfUpdate = TRUE; ! 382: if (!UpdateScreen(vhwndClient, usFormat)) { ! 383: LOADSTRING(IDS_NODISPLAY, szMessage); ! 384: MESSAGE(szMessage); ! 385: } ! 386: } ! 387: } ! 388: ! 389: /* fall through */ ! 390: ! 391: case DID_CANCEL: ! 392: WinDismissDlg(hwndDlg, TRUE); ! 393: ! 394: default: break; ! 395: } ! 396: default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2); ! 397: } ! 398: return FALSE; ! 399: } ! 400: ! 401: MRESULT EXPENTRY AboutDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2) ! 402: { ! 403: /* ! 404: About... dialog procedure ! 405: */ ! 406: switch(msg) { ! 407: case WM_COMMAND: ! 408: switch( (USHORT) SHORT1FROMMP (mp1) ) { ! 409: case DID_OK: WinDismissDlg(hwndDlg, TRUE); ! 410: default: break; ! 411: } ! 412: default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2); ! 413: } ! 414: return FALSE; ! 415: } ! 416: ! 417: ! 418: ! 419: ! 420: #ifdef MLE_OK ! 421: ! 422: VOID ReadSelector(HWND hwndMLE, PSZ pszText) { ! 423: /* ! 424: Compute the length of the text selector, in bytes. ! 425: Allocate space, and copy the text selector into an MLE. ! 426: */ ! 427: IPT ipt = 0L ; ! 428: ULONG ulcch = 0; ! 429: PSZ pszCounter; ! 430: ! 431: pszCounter = pszText; ! 432: while (*pszCounter++) ulcch++; ! 433: WinSendMsg(hwndMLE, MLM_FORMAT, MPFROMSHORT(MLFIE_CFTEXT), 0L); ! 434: WinSendMsg(hwndMLE, MLM_SETIMPORTEXPORT, pszText, (MPARAM) ulcch); ! 435: WinSendMsg(hwndMLE, MLM_IMPORT, (MPARAM) &ipt, (MPARAM) ulcch); ! 436: } ! 437: ! 438: #endif ! 439: ! 440: ! 441: ! 442: VOID FixFrame(VOID) { ! 443: /* ! 444: This routine tells the frame to update the scroll bars. ! 445: ! 446: First, make it so that the scroll bars cannot update themselves. ! 447: Let the frame update the controls. Then, re-enable the scroll bars. ! 448: */ ! 449: if (!(vcUpdate--)) { ! 450: WinEnableWindowUpdate(vhwndHSB, FALSE); ! 451: WinEnableWindowUpdate(vhwndVSB, FALSE); ! 452: } ! 453: ! 454: ! 455: WinSendMsg(vhwndClipFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_HORZSCROLL), 0L); ! 456: WinSendMsg(vhwndClipFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_VERTSCROLL), 0L); ! 457: ! 458: ! 459: if (!(++vcUpdate)) { ! 460: WinEnableWindowUpdate(vhwndHSB, TRUE); ! 461: WinEnableWindowUpdate(vhwndVSB, TRUE); ! 462: } ! 463: } ! 464: ! 465: VOID NeedScrollBars(BOOL fNeed) { ! 466: /* ! 467: This routine hides changes the scroll bar state to correspond with ! 468: fNeed, showing or hiding them as necessary. ! 469: */ ! 470: static BOOL fNeeded = TRUE; /* The last scroll bar state */ ! 471: ! 472: /* ! 473: Get the scroll bar handles, if we haven't already. ! 474: */ ! 475: if (!vhwndHSB) { ! 476: vhwndHSB = WinWindowFromID(vhwndClipFrame, FID_HORZSCROLL); ! 477: vhwndVSB = WinWindowFromID(vhwndClipFrame, FID_VERTSCROLL); ! 478: } ! 479: /* ! 480: Case 1: We need scroll bars, so enable them. ! 481: */ ! 482: if (fNeed) { ! 483: if (!fNeeded) { ! 484: WinSetParent(vhwndHSB, vhwndClipFrame, TRUE); ! 485: WinSetParent(vhwndVSB, vhwndClipFrame, TRUE); ! 486: FixFrame(); ! 487: } ! 488: /* ! 489: Case 2: We don't need scroll bars, so hide them. ! 490: */ ! 491: } else { ! 492: if (fNeeded) { ! 493: WinSetParent(vhwndHSB, HWND_OBJECT, TRUE); ! 494: WinSetParent(vhwndVSB, HWND_OBJECT, TRUE); ! 495: FixFrame(); ! 496: } ! 497: } ! 498: /* ! 499: Save state for next invocation ! 500: */ ! 501: fNeeded = fNeed; ! 502: } ! 503: ! 504: /* ! 505: RenderFormat() ! 506: ! 507: Input: Clipboard format to render, and handle to client area ! 508: Side effects: Renders the image in the client area ! 509: */ ! 510: BOOL RenderFormat(HWND hwnd, USHORT usFormat) { ! 511: BOOL fRendered = TRUE; ! 512: HMF hmfCopy; ! 513: HPS hpsWindow; ! 514: LONG alOptions[8]; ! 515: RECTL rclWindow; ! 516: SIZEL sizl; ! 517: SWP swpWindow; ! 518: ULONG hItem; ! 519: POINTL aptl[3]; ! 520: ! 521: ! 522: #ifndef MLE_OK ! 523: ! 524: ! 525: HPS hps ; ! 526: RECTL rcl ; ! 527: POINTL ptl ; ! 528: FONTMETRICS fm ; ! 529: PSZ pszText ; ! 530: SHORT cxCaps, cyChar, cyDesc, line ; ! 531: ! 532: #endif ! 533: ! 534: /* ! 535: Open the clipboard ! 536: */ ! 537: if (!WinOpenClipbrd(vhab)) ! 538: return FALSE; ! 539: /* ! 540: Open up the window DC and PS ! 541: */ ! 542: if (!vhdcWindow) ! 543: vhdcWindow = WinOpenWindowDC(hwnd); ! 544: ! 545: sizl.cx = sizl.cy = 0L; ! 546: hpsWindow = GpiCreatePS(vhab, vhdcWindow, &sizl, GPIA_ASSOC | PU_ARBITRARY); ! 547: /* ! 548: Enable the scroll bars, if necessary. This affects the size ! 549: of the client area. ! 550: */ ! 551: if (vfUpdate) ! 552: NeedScrollBars( (vfViewBitmap = ! 553: (usFormat == CF_BITMAP) || (usFormat == CF_DSPBITMAP) || ! 554: ! 555: /* The following line should be deleted when MLE are implemented */ ! 556: ! 557: (usFormat == CF_DSPTEXT) || (usFormat == CF_TEXT) ) ); ! 558: ! 559: WinQueryWindowRect(hwnd, &rclWindow); ! 560: /* ! 561: Get the clipboard data ! 562: */ ! 563: WinQueryClipbrdFmtInfo(vhab, usFormat, &vfsFmtInfo); ! 564: if (!(hItem = WinQueryClipbrdData(vhab, usFormat))) { ! 565: fRendered = FALSE; ! 566: } else { ! 567: /* ! 568: Display the new format, as appropriate. ! 569: */ ! 570: switch (usFormat) { ! 571: case CF_TEXT: ! 572: case CF_DSPTEXT: ! 573: if (vfUpdate) { ! 574: ! 575: ! 576: #ifdef MLE_OK ! 577: ! 578: ! 579: Create a new MLE and read the text into it. ! 580: ! 581: vhwndMLE = WinCreateWindow(hwnd, WC_MLE, "", ! 582: WS_VISIBLE | MLS_READONLY | MLS_HSCROLL | MLS_VSCROLL, ! 583: 0, 0, ! 584: (SHORT) rclWindow.xRight, (SHORT) rclWindow.yTop, ! 585: hwnd, HWND_TOP, 0, NULL, NULL); ! 586: ! 587: ReadSelector(vhwndMLE, (PSZ) hItem ) ; ! 588: ! 589: #else ! 590: vfViewText = TRUE ; ! 591: hps = WinGetPS ( hwnd ) ; ! 592: WinQueryWindowRect ( hwnd, &rcl ) ; ! 593: GpiQueryFontMetrics ( hps, (LONG) sizeof (fm), &fm ) ; ! 594: cxCaps = (SHORT) fm.lEmInc ; ! 595: cyChar = (SHORT) fm.lMaxBaselineExt ; ! 596: cyDesc = (SHORT) fm.lMaxDescender ; ! 597: line = 0 ; ! 598: ! 599: while ( *(PSZ) hItem ) { ! 600: pszText = (PSZ) hItem ; ! 601: ptl.x = cxCaps ; ! 602: ptl.y = rcl.yTop - cyChar * (line + 1) + cyDesc ; ! 603: ! 604: while ( isprint ( *(PSZ) hItem) ) ! 605: hItem++ ; ! 606: ! 607: if ( *(PSZ) hItem ) ! 608: GpiCharStringAt ( hps, ! 609: &ptl, ! 610: hItem - (ULONG) pszText, ! 611: pszText ) ; ! 612: ! 613: while ( isspace ( *(PSZ) hItem ) ) ! 614: hItem++ ; ! 615: ! 616: line += 1 ; ! 617: } ! 618: ! 619: hItem = (ULONG) pszText ; ! 620: while ( isprint ( *(PSZ) hItem ) ) ! 621: hItem++ ; ! 622: ! 623: GpiCharStringAt ( hps, &ptl, hItem - (ULONG) pszText, pszText ) ; ! 624: ! 625: WinReleasePS ( hps ) ; ! 626: #endif ! 627: ! 628: ! 629: } ! 630: break; ! 631: ! 632: case CF_BITMAP: ! 633: case CF_DSPBITMAP: ! 634: if (vfUpdate) { ! 635: /* ! 636: Get the BITMAP dimensions, for scroll bar processing ! 637: */ ! 638: if (GpiQueryBitmapParameters((HBITMAP) hItem, &vbmp) ! 639: != GPI_OK) { ! 640: return FALSE; ! 641: } ! 642: /* ! 643: Set the scroll bar ranges from 0 to vbmp.max - client.max ! 644: */ ! 645: WinQueryWindowPos(hwnd, &swpWindow); ! 646: ! 647: if ((vcMaxHSB = vbmp.cx - swpWindow.cx) < 0) ! 648: vcMaxHSB = 0; ! 649: if ((vcMaxVSB = vbmp.cy - swpWindow.cy) < 0) ! 650: vcMaxVSB = 0; ! 651: WinSendMsg(vhwndHSB, SBM_SETSCROLLBAR, ! 652: 0L, MPFROM2SHORT(0, vcMaxHSB)); ! 653: WinSendMsg(vhwndVSB, SBM_SETSCROLLBAR, ! 654: MPFROMSHORT(vcMaxVSB), ! 655: MPFROM2SHORT(0, vcMaxVSB)); ! 656: } ! 657: /* ! 658: Draw the BITMAP, based on the scroll bar settings. ! 659: */ ! 660: GpiSetBitmap(vhpsMemory, (HBITMAP) hItem); ! 661: ! 662: aptl[0].x = rclWindow.xLeft; /* Target bottom left */ ! 663: aptl[0].y = rclWindow.yBottom; ! 664: aptl[1].x = rclWindow.xRight; /* Target top right */ ! 665: aptl[1].y = rclWindow.yTop; ! 666: /* Source bottom left */ ! 667: aptl[2].x = (LONG) WinSendMsg(vhwndHSB, SBM_QUERYPOS, 0L, 0L); ! 668: aptl[2].y = vcMaxVSB ! 669: - (LONG) WinSendMsg(vhwndVSB, SBM_QUERYPOS, 0L, 0L); ! 670: ! 671: GpiBitBlt(hpsWindow, vhpsMemory, 3L, aptl, ROP_SRCCOPY, 0L); ! 672: GpiSetBitmap(vhpsMemory, NULL); ! 673: break; ! 674: ! 675: case CF_METAFILE: ! 676: case CF_DSPMETAFILE: ! 677: /* ! 678: Set up the alOptions for displaying the metafile, and ! 679: let the system do the rest of the work. ! 680: */ ! 681: alOptions[PMF_SEGBASE] = 0L; ! 682: alOptions[PMF_LOADTYPE] = LT_DEFAULT; ! 683: alOptions[PMF_RESOLVE] = 0L; ! 684: alOptions[PMF_LCIDS] = LC_LOADDISC; ! 685: alOptions[PMF_RESET] = RES_DEFAULT; ! 686: alOptions[PMF_SUPPRESS] = SUP_DEFAULT; ! 687: alOptions[PMF_COLORTABLES] = CTAB_NOMODIFY; ! 688: alOptions[PMF_COLORREALIZABLE] = CREA_DEFAULT; ! 689: hmfCopy = GpiCopyMetaFile((HMF) hItem); ! 690: GpiPlayMetaFile(hpsWindow, hmfCopy, 8L, alOptions, 0L, 0L, NULL); ! 691: break; ! 692: ! 693: case CF_EMPTY: ! 694: /* ! 695: Don't do anything. ! 696: */ ! 697: break; ! 698: ! 699: default: ! 700: /* ! 701: If it's an owner-draw format that we can display... ! 702: ...try to get the owner to paint the clipboard. ! 703: (return if we were successful or not) ! 704: */ ! 705: fRendered = SendOwnerMsg(WM_PAINTCLIPBOARD, MPFROMHWND(hwnd), 0L); ! 706: break; ! 707: } ! 708: } ! 709: /* ! 710: Tell everybody that the client area is valid now ! 711: */ ! 712: WinValidateRect(hwnd, (PRECTL) NULL, FALSE); ! 713: /* ! 714: Clean up ! 715: */ ! 716: GpiAssociate(hpsWindow, NULL); ! 717: GpiDestroyPS(hpsWindow); ! 718: WinCloseClipbrd(vhab); ! 719: return fRendered; ! 720: } ! 721: ! 722: BOOL UpdateScreen(HWND hwnd, USHORT usFormat) { ! 723: /* ! 724: Render the format, change the title bar. ! 725: The title bar will look like: "<appname> (<format>)" ! 726: */ ! 727: BOOL fRendered = TRUE; ! 728: HPS hpsWindow; ! 729: RECTL rcl; ! 730: UCHAR szFormat[MAXLEN]; ! 731: UCHAR szTitle[MAXTITLELEN]; ! 732: ! 733: if (vfUpdate) { ! 734: ! 735: ! 736: #ifdef MLE_OK ! 737: ! 738: /* If the MLE exists, destroy it */ ! 739: if (vhwndMLE) { ! 740: WinDestroyWindow(vhwndMLE); ! 741: vhwndMLE = NULL; ! 742: } ! 743: #endif ! 744: ! 745: /* Clear the client area */ ! 746: WinQueryWindowRect(hwnd, &rcl); ! 747: WinInvalidateRect(hwnd, &rcl, FALSE); ! 748: hpsWindow = WinBeginPaint(hwnd, NULL, NULL); ! 749: WinFillRect(hpsWindow, &rcl, CLR_BACKGROUND); ! 750: WinEndPaint(hpsWindow); ! 751: } ! 752: if (usFormat) // Check that usFormat != CF_EMPTY ! 753: fRendered = RenderFormat(hwnd, usFormat); ! 754: /* ! 755: Set the title bar appropriately ! 756: */ ! 757: if (!vhwndTitlebar && vhwndClipFrame) ! 758: vhwndTitlebar = WinWindowFromID(vhwndClipFrame, FID_TITLEBAR); ! 759: ! 760: if (vhwndTitlebar) { ! 761: GetFormatName(usFormat, szFormat); ! 762: LOADSTRING(IDS_APPNAME, szTitle); ! 763: strcat(szTitle, "("); strcat(szTitle, szFormat); strcat(szTitle, ")"); ! 764: WinSetWindowText(vhwndTitlebar, szTitle); ! 765: } ! 766: /* ! 767: Save the rendered format. ! 768: */ ! 769: vusFormat = usFormat; ! 770: return fRendered; ! 771: } ! 772: ! 773: VOID GetAllFormats(VOID) { ! 774: USHORT usFormat; // Temporary used when enumerating ! 775: /* ! 776: Put ourselves into a clean state ! 777: */ ! 778: usFormat = vcFmts = 0; ! 779: /* ! 780: Cycle through the available clipboard formats ! 781: */ ! 782: while (usFormat = WinEnumClipbrdFmts(vhab, usFormat)) { ! 783: vausFormats[vcFmts++] = usFormat; ! 784: } ! 785: /* ! 786: Set the current clipboard format to the first one, if possible ! 787: (in preparation for the WM_PAINT which will follow). ! 788: */ ! 789: vusFormat = (vcFmts ? vausFormats[0] : CF_EMPTY); ! 790: } ! 791: ! 792: VOID GetFormatName(USHORT usFormat, UCHAR szFmtName[]) { ! 793: /* ! 794: GetFormatName() ! 795: ! 796: This routine returns a format name in szFmtName which corresponds ! 797: to the format usFormat. Basically, either we know the format, or ! 798: we get the name from the system atom table. If we can't find it, ! 799: we set it to CF_UNKNOWN. ! 800: */ ! 801: switch (usFormat) { ! 802: /* ! 803: If we know the format, we can read it from the string table. ! 804: */ ! 805: case CF_EMPTY: ! 806: case CF_TEXT: ! 807: case CF_DSPTEXT: ! 808: case CF_BITMAP: ! 809: case CF_DSPBITMAP: ! 810: case CF_METAFILE: ! 811: case CF_DSPMETAFILE: ! 812: LOADSTRING(usFormat, szFmtName); ! 813: break; ! 814: ! 815: default: ! 816: /* ! 817: Get the format name from the system atom table. ! 818: If not found, tag it as an unknown format. ! 819: */ ! 820: if (!WinQueryAtomName(WinQuerySystemAtomTable(), ! 821: usFormat, szFmtName, MAXLEN)) ! 822: ! 823: LOADSTRING(CF_UNKNOWN, szFmtName); ! 824: ! 825: break; ! 826: } ! 827: } ! 828: ! 829: BOOL SendOwnerMsg(USHORT msg, MPARAM mp1, MPARAM mp2) { ! 830: BOOL rc; ! 831: HWND hwndOwner; ! 832: /* ! 833: If we are an OWNERDISPLAY format, ! 834: lock the owner window, tell it to perform the operation, return ! 835: */ ! 836: if ( rc = ( (vfsFmtInfo & CFI_OWNERDISPLAY) ! 837: && (hwndOwner = WinQueryClipbrdOwner(vhab, TRUE)) ) ) { ! 838: ! 839: WinSendMsg(hwndOwner, msg, mp1, mp2); ! 840: WinLockWindow(hwndOwner, FALSE); ! 841: } ! 842: return rc; ! 843: } ! 844: ! 845: BOOL DoScrolling(HWND hwnd, BOOL fHorz, USHORT sbCmd) { ! 846: /* ! 847: This routine depends on the fact that the thumb cannot be set past the ! 848: range of the scroll bar. Since this is handled in the system SBM_SETPOS ! 849: code already, we need not worry about it. ! 850: ! 851: We return TRUE if the scroll bar message is processed. ! 852: */ ! 853: HWND hwndSB; /* Scroll bar handle */ ! 854: USHORT cpels; /* Page length/width for PAGExxxx commands */ ! 855: SWP swp; /* Dimensions of the client area */ ! 856: USHORT usOld; /* The current scroll bar position */ ! 857: USHORT usNew; /* The new scroll bar position */ ! 858: /* ! 859: Set the scroll bar-specific parameters ! 860: */ ! 861: WinQueryWindowPos(hwnd, &swp); ! 862: if (fHorz) { /* Horizontal scroll bar */ ! 863: hwndSB = vhwndHSB; ! 864: cpels = swp.cx; ! 865: } else { /* Vertical scroll bar */ ! 866: hwndSB = vhwndVSB; ! 867: cpels = swp.cy; ! 868: } ! 869: /* ! 870: Handle both scroll bars with one common routine ! 871: ! 872: Basically, the scroll bar has been set so that ! 873: the thumb value corresponds to the offset that ! 874: the bitmap is drawn from. So, to scroll by a ! 875: page, compute the number of pels of the page, ! 876: and move the thumb by that amount. ! 877: ! 878: This code is simplified by the fact that SB_SETPOS ! 879: will not allow the thumb to be set outside of the ! 880: range of the scroll bar, but will "stop" it at the ! 881: appropriate bound. ! 882: */ ! 883: usOld = (USHORT) WinSendMsg(hwndSB, SBM_QUERYPOS, 0L, 0L); ! 884: ! 885: switch (sbCmd) { ! 886: case SB_PAGERIGHT: /* SB_PAGEDOWN */ ! 887: WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld + cpels), 0L); ! 888: break; ! 889: ! 890: case SB_PAGELEFT: /* SB_PAGEUP */ ! 891: WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld - cpels), 0L); ! 892: break; ! 893: ! 894: case SB_LINERIGHT: /* SB_LINEDOWN */ ! 895: WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld + LINE), 0L); ! 896: break; ! 897: ! 898: case SB_LINELEFT: /* SB_LINEUP */ ! 899: WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld - LINE), 0L); ! 900: break; ! 901: ! 902: case SB_SLIDERPOSITION: ! 903: /* ! 904: It would be nice to be consistent with the other ! 905: SB_ cases, but the problem is that when this message ! 906: is sent, the position is *already* set to "usPosition". ! 907: ! 908: So, just invalidate the entire region, and hope that most ! 909: of these types of operations will be large scrolls. ! 910: */ ! 911: // WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(LOUSHORT(mp2)), 0L); ! 912: WinInvalidateRect(hwnd, NULL, TRUE); ! 913: break; ! 914: ! 915: default: ! 916: return FALSE; ! 917: } ! 918: /* ! 919: Now, we find out where the new thumb position is, ! 920: scroll the window contents appropriately, and specify ! 921: SW_INVALIDATERGN so that the remainder will be ! 922: invalidated/repainted. ! 923: */ ! 924: usNew = (USHORT) WinSendMsg(hwndSB, SBM_QUERYPOS, 0L, 0L); ! 925: if (fHorz) ! 926: WinScrollWindow(hwnd, (SHORT) (usOld - usNew), 0, ! 927: NULL, NULL, NULL, NULL, SW_INVALIDATERGN); ! 928: else ! 929: WinScrollWindow(hwnd, 0, (SHORT) (usNew - usOld), ! 930: NULL, NULL, NULL, NULL, SW_INVALIDATERGN); ! 931: ! 932: return TRUE; ! 933: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.