Annotation of os232sdk/toolkt20/c/samples/clipview/clipview.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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