Annotation of mstools/samples/ole/srvrdemo/obj.c, revision 1.1.1.1

1.1       root        1: /*
                      2:   OLE SERVER DEMO           
                      3:   Obj.c             
                      4:                                                                      
                      5:   This file contains object methods and various object-related support 
                      6:   functions.
                      7:                                                                      
                      8:   (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved   
                      9: */                                                                     
                     10: 
                     11: /* 
                     12:    Important Note:
                     13: 
                     14:    No method should ever dispatch a DDE message or allow a DDE message to
                     15:    be dispatched.
                     16:    Therefore, no method should ever enter a message dispatch loop.
                     17:    Also, a method should not show a dialog or message box, because the 
                     18:    processing of the dialog box messages will allow DDE messages to be
                     19:    dispatched.
                     20: */
                     21: 
                     22: 
                     23: #define SERVERONLY
                     24: #include <windows.h>
                     25: #include <ole.h>
                     26: 
                     27: #include "srvrdemo.h"
                     28: 
                     29: 
                     30: 
                     31: // Static functions.
                     32: static HBITMAP GetBitmap (LPOBJ lpobj);
                     33: static HANDLE  GetLink (LPOBJ lpobj);
                     34: static HANDLE  GetMetafilePict (LPOBJ lpobj);
                     35: static HANDLE  GetEnhMetafile (LPOBJ lpobj);
                     36: static HANDLE  GetNative (LPOBJ lpobj);
                     37: static INT     GetObjNum (LPOBJ lpobj);
                     38: static HANDLE  GetText (LPOBJ lpobj);
                     39: static VOID    DrawObj (HDC hdc, LPOBJ lpobj, RECT rc, INT dctype);
                     40: 
                     41: 
                     42: 
                     43: /* CreateNewObj
                     44:  * ------------
                     45:  *
                     46:  * BOOL fDoc_Changed - The new value for the global variable fDocChanged.
                     47:  *                     When initializing a new document, we need to create 
                     48:  *                     a new object without the creation counting as a 
                     49:  *                     change to the document.
                     50:  *
                     51:  * RETURNS: A pointer to the new object
                     52:  *
                     53:  * 
                     54:  * CUSTOMIZATION: Re-implement
                     55:  *                Some applications (like Server Demo) have a finite number of
                     56:  *                fixed, distinct, non-overlapping objects.  Other applications
                     57:  *                allow the user to create an object from any section of the
                     58:  *                document.  For example, the user might select a portion of
                     59:  *                a bitmap from a paint program, or a few lines of text from
                     60:  *                a word processor.  This latter type of application probably
                     61:  *                will not have a function like CreateNewObj.
                     62:  *
                     63:  */
                     64: LPOBJ CreateNewObj (BOOL fDoc_Changed)
                     65: {
                     66:     HANDLE hObj = NULL;
                     67:     LPOBJ  lpobj = NULL;
                     68:     // index into an array of flags indicating if that object number is used.
                     69:     INT    ifObj = 0;    
                     70: 
                     71:     if ((hObj = LocalAlloc (LMEM_MOVEABLE|LMEM_ZEROINIT, sizeof (OBJ))) == NULL)
                     72:       return NULL;
                     73: 
                     74:     if ((lpobj = (LPOBJ) LocalLock (hObj)) == NULL)
                     75:     {
                     76:       LocalFree (hObj);
                     77:       return NULL;
                     78:     }
                     79: 
                     80:     // Fill the fields in the object structure.
                     81:     
                     82:     // Find an unused number.
                     83:     for (ifObj=1; ifObj <= cfObjNums; ifObj++)
                     84:     {
                     85:       if (docMain.rgfObjNums[ifObj]==FALSE)
                     86:       {
                     87:          docMain.rgfObjNums[ifObj]=TRUE;
                     88:          break;
                     89:       }
                     90:     }
                     91: 
                     92:     if (ifObj==cfObjNums+1)
                     93:     {
                     94:       // Cannot create any more objects.
                     95:       MessageBeep(0);
                     96:       return NULL;
                     97:     }
                     98: 
                     99:     wsprintf (lpobj->native.szName, "Object %d", ifObj);
                    100: 
                    101:     lpobj->aName            = GlobalAddAtom (lpobj->native.szName);
                    102:     lpobj->hObj             = hObj;
                    103:     lpobj->oleobject.lpvtbl = &objvtbl;
                    104:     lpobj->native.idmColor  = IDM_RED;    // Default color 
                    105:     lpobj->native.version   = version;
                    106:     lpobj->native.nWidth    = OBJECT_WIDTH;          // Default size
                    107:     lpobj->native.nHeight   = OBJECT_HEIGHT;
                    108:     SetHiMetricFields (lpobj);
                    109: 
                    110:     // Place object in a location corrsponding to its number, for aesthetics.
                    111:     lpobj->native.nX = (ifObj - 1) * 20;
                    112:     lpobj->native.nY = (ifObj - 1) * 20;
                    113: 
                    114:     if (!CreateWindow (
                    115:         "ObjClass",
                    116:         "Obj",
                    117:         WS_BORDER | WS_THICKFRAME | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
                    118:         lpobj->native.nX,
                    119:         lpobj->native.nY,
                    120:         lpobj->native.nWidth,
                    121:         lpobj->native.nHeight,
                    122:         hwndMain,
                    123:         NULL,
                    124:         hInst,
                    125:         (LPSTR) lpobj ))
                    126:          return FALSE;
                    127: 
                    128:     fDocChanged = fDoc_Changed;
                    129: 
                    130:     return lpobj;
                    131: }
                    132: 
                    133: 
                    134: 
                    135: /* CutOrCopyObj
                    136:  * ------------
                    137:  *
                    138:  * Put data onto clipboard in all the formats supported.  If the 
                    139:  * fOpIsCopy is TRUE, the operation is COPY, otherwise it is CUT.
                    140:  * This is important, because we cannot put the Object Link format
                    141:  * onto the clipboard if the object was cut from the document (there is
                    142:  * no longer anything to link to).
                    143:  *
                    144:  * BOOL fOpIsCopy - TRUE if the operation is COPY; FALSE if CUT
                    145:  * 
                    146:  * CUSTOMIZATION: None
                    147:  *
                    148:  *
                    149:  */
                    150: VOID CutOrCopyObj (BOOL fOpIsCopy)
                    151: {
                    152:     LPOBJ       lpobj;
                    153:     HANDLE     hData;
                    154: 
                    155:     if (OpenClipboard (hwndMain))
                    156:     {
                    157:         EmptyClipboard ();
                    158: 
                    159:         lpobj = SelectedObject();
                    160: 
                    161:         if ((hData = GetNative (lpobj)) != NULL)
                    162:             SetClipboardData(cfNative, hData);
                    163: 
                    164:         if ((hData = GetLink(lpobj)) != NULL)
                    165:             SetClipboardData(cfOwnerLink, hData);
                    166: 
                    167:         if (fOpIsCopy && docMain.doctype == doctypeFromFile)
                    168:         {
                    169:             // Can create a link if object exists in a file.
                    170:             if ((hData = GetLink(lpobj)) != NULL)
                    171:                SetClipboardData(cfObjectLink, hData);
                    172:         }
                    173: 
                    174:         if ((hData = GetEnhMetafile(lpobj)) != NULL)
                    175:         { 
                    176:             SetClipboardData(CF_ENHMETAFILE, hData);
                    177: //            GlobalFree(hData);
                    178:         }
                    179: 
                    180:         if ((hData = GetBitmap(lpobj)) != NULL)
                    181:         { 
                    182:             SetClipboardData(CF_BITMAP, hData);
                    183: //            DeleteObject(hData);
                    184:         }
                    185: 
                    186: 
                    187:         CloseClipboard ();
                    188:     }
                    189: }
                    190: 
                    191: 
                    192: /* DestroyObj
                    193:  * ----------
                    194:  *
                    195:  * Revoke an object, and free all memory that had been allocated for it.
                    196:  *
                    197:  * HWND hwnd - The object's window
                    198:  * 
                    199:  * CUSTOMIZATION: Re-implement, making sure you free all the memory that
                    200:  *                had been allocated for the OBJ structure and each of its
                    201:  *                fields.
                    202:  * 
                    203:  */
                    204: VOID DestroyObj (HWND hwnd)
                    205: {
                    206:    LPOBJ lpobj = HwndToLpobj (hwnd);
                    207: 
                    208:    if(lpobj->aName)
                    209:    {
                    210:       GlobalDeleteAtom (lpobj->aName);
                    211:       lpobj->aName = NULL;
                    212:    }
                    213: 
                    214:    if (lpobj->hpal) 
                    215:       DeleteObject (lpobj->hpal);
                    216:    // Allow the object's number to be reused.
                    217:    docMain.rgfObjNums [GetObjNum(lpobj)] = FALSE;
                    218: 
                    219: 
                    220:    // Free the memory that had been allocated for the object structure itself.
                    221:    LocalUnlock (lpobj->hObj);
                    222:    LocalFree (lpobj->hObj);
                    223: }
                    224: 
                    225: 
                    226: 
                    227: /* DrawObj
                    228:  * -------
                    229:  *
                    230:  * This function draws an object onto the screen, into a metafile, or into
                    231:  * a bitmap.
                    232:  * The object will always look the same.
                    233:  *
                    234:  * HDC    hdc    - The device context to render the object into
                    235:  * LPOBJ  lpobj  - The object to render
                    236:  * RECT   rc     - The rectangle bounds of the object
                    237:  * DCTYPE dctype - The type of device context.
                    238:  * 
                    239:  * CUSTOMIZATION: Server Demo specific
                    240:  *
                    241:  */
                    242: static VOID DrawObj (HDC hdc, LPOBJ lpobj, RECT rc, INT dctype)
                    243: {
                    244:    HPEN     hpen;
                    245:    HPEN     hpenOld;
                    246:    HPALETTE hpalOld = NULL;
                    247: 
                    248:    if (dctype == dctypeMetafile || dctype == dctypeEnhMetafile)
                    249:    {
                    250:       SetWindowOrgEx (hdc, 0, 0, NULL);
                    251:       // Paint entire object into the given rectangle.
                    252:       SetWindowExtEx (hdc, rc.right, rc.bottom, NULL);
                    253:    }
                    254:  
                    255:    if (lpobj->hpal)
                    256:    {
                    257:       hpalOld = SelectPalette (hdc, lpobj->hpal, TRUE);
                    258:       RealizePalette (hdc);
                    259:    }
                    260: 
                    261:    // Select brush of the color specified in the native data.
                    262:    SelectObject (hdc, hbrColor [lpobj->native.idmColor - IDM_RED] );
                    263: 
                    264:    hpen = CreatePen (PS_SOLID, 
                    265:                      /* Width */ (rc.bottom-rc.top) / 10,
                    266:                      /* Gray */ 0x00808080);
                    267:    hpenOld = SelectObject (hdc, hpen);
                    268: 
                    269:    // Draw rectangle with the gray pen and fill it in with the selected brush.
                    270:    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
                    271: 
                    272:    // Print name of object inside rectangle.
                    273:    SetBkMode (hdc, TRANSPARENT);
                    274:    SetTextAlign (hdc, TA_BASELINE | TA_CENTER);
                    275:    TextOut (hdc, 
                    276:             rc.right/2, 
                    277:             (rc.top+rc.bottom)/2, 
                    278:             lpobj->native.szName, 
                    279:             lstrlen (lpobj->native.szName));
                    280: 
                    281:    // Restore original objects
                    282:    SelectObject (hdc, 
                    283:                  (dctype == dctypeMetafile || dctype == dctypeEnhMetafile) 
                    284:                      ? GetStockObject (BLACK_PEN) : hpenOld);
                    285:    if (hpalOld)
                    286:    {
                    287:       SelectPalette (hdc, 
                    288:                      (dctype == dctypeMetafile || dctype == dctypeEnhMetafile) 
                    289:                         ? GetStockObject (DEFAULT_PALETTE) : hpalOld,
                    290:                      TRUE);
                    291:    }
                    292: 
                    293:    DeleteObject (hpen);
                    294: }
                    295: 
                    296: 
                    297: 
                    298: /* GetBitmap
                    299:  * ---------
                    300:  *
                    301:  * Return a handle to an object's picture data in bitmap format.
                    302:  *
                    303:  * LPOBJ lpobj - The object
                    304:  * 
                    305:  * RETURNS: A handle to the object's picture data
                    306:  * 
                    307:  * CUSTOMIZATION: Re-implement
                    308:  *
                    309:  */
                    310: static HBITMAP GetBitmap (LPOBJ lpobj)
                    311: {
                    312:     HDC         hdcObj;
                    313:     HDC         hdcMem;
                    314:     RECT        rc;
                    315:     HBITMAP     hbitmap;
                    316:     HBITMAP     hbitmapOld;
                    317: 
                    318: 
                    319:     hdcObj = GetDC (lpobj->hwnd);
                    320:     // Create a memory device context.
                    321:     hdcMem = CreateCompatibleDC (hdcObj);
                    322:     GetClientRect (lpobj->hwnd, (LPRECT)&rc);
                    323:     // Create new bitmap object based on the bitmap of the OLE object.
                    324:     hbitmap = CreateCompatibleBitmap 
                    325:       (hdcObj, rc.right - rc.left, rc.bottom - rc.top);
                    326:     // Select new bitmap as the bitmap object for the memory device context.
                    327:     hbitmapOld = SelectObject (hdcMem, hbitmap);
                    328: 
                    329:     // Paint directly into the memory dc using the new bitmap object.
                    330:     DrawObj (hdcMem, lpobj, rc, dctypeBitmap);
                    331: 
                    332:     // Restore old bitmap object.
                    333:     hbitmap = SelectObject (hdcMem, hbitmapOld);
                    334:     DeleteDC (hdcMem);
                    335:     ReleaseDC (lpobj->hwnd, hdcObj);
                    336: 
                    337:     // convert width and height to HIMETRIC units
                    338:     rc.right  = rc.right - rc.left;
                    339:     rc.bottom = rc.bottom - rc.top;
                    340:     DeviceToHiMetric (hwndMain, (LPPOINT) &rc.right);
                    341:     
                    342:     // Set the 1/10 of HIMETRIC units for the bitmap
                    343:     SetBitmapDimensionEx (hbitmap, (DWORD) (rc.right/10), (DWORD) (rc.bottom/10), NULL);
                    344:         
                    345:     return hbitmap;
                    346: }
                    347: 
                    348: 
                    349: 
                    350: /* GetLink
                    351:  * -------
                    352:  *
                    353:  * Return a handle to an object's object or owner link data.
                    354:  * Link information is in the form of three zero-separated strings,
                    355:  * terminated with two zero bytes:  CLASSNAME\0DOCNAME\0OBJNAME\0\0
                    356:  *
                    357:  * LPOBJ lpobj - The object 
                    358:  * 
                    359:  * RETURNS: A handle to the object's link data
                    360:  * 
                    361:  * CUSTOMIZATION: Re-implement
                    362:  *
                    363:  */
                    364: static HANDLE GetLink (LPOBJ lpobj)
                    365: {
                    366: 
                    367:     CHAR   sz[cchFilenameMax];
                    368:     LPSTR  lpszLink = NULL;
                    369:     HANDLE hLink = NULL;
                    370:     INT    cchLen;
                    371:     INT    i;
                    372: 
                    373:     // First make the class name.
                    374:     lstrcpy (sz, szClassName);
                    375:     cchLen = lstrlen (sz) + 1;
                    376: 
                    377:     // Then the document name.
                    378:     cchLen += GlobalGetAtomName 
                    379:                (docMain.aName, (LPSTR)sz + cchLen, 
                    380:                 cchFilenameMax - cchLen) + 1;
                    381: 
                    382:     // Then the object name.
                    383:     lstrcpy (sz + cchLen, lpobj->native.szName);
                    384:     cchLen += lstrlen (lpobj->native.szName) + 1;
                    385: 
                    386:     // Add a second null to the end.
                    387:     sz[cchLen++] = 0;       
                    388: 
                    389: 
                    390:     hLink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, cchLen);
                    391:     if (hLink == NULL)
                    392:       return NULL;
                    393:     if ((lpszLink = GlobalLock (hLink)) == NULL)
                    394:     {
                    395:       GlobalFree (hLink);
                    396:       return NULL;
                    397:     }
                    398: 
                    399:     for (i=0; i < cchLen; i++)
                    400:         lpszLink[i] = sz[i];
                    401: 
                    402:     GlobalUnlock (hLink);
                    403: 
                    404:     return hLink;
                    405: }
                    406: 
                    407: 
                    408: 
                    409: /* GetMetafilePict
                    410:  * ---------------
                    411:  *
                    412:  * Return a handle to an object's picture data in metafile format.
                    413:  *
                    414:  * LPOBJ lpobj - The object
                    415:  * 
                    416:  * RETURNS: A handle to the object's data in metafile format.
                    417:  *
                    418:  * CUSTOMIZATION: Re-implement
                    419:  *
                    420:  */
                    421: static HANDLE GetMetafilePict (LPOBJ lpobj)
                    422: {
                    423: 
                    424:     LPMETAFILEPICT  lppict = NULL;
                    425:     HANDLE          hpict = NULL;
                    426:     HANDLE          hMF = NULL;
                    427:     RECT            rc;
                    428:     HDC             hdc;
                    429: 
                    430:     hdc = CreateMetaFile(NULL);
                    431: 
                    432:     GetClientRect (lpobj->hwnd, (LPRECT)&rc);
                    433: 
                    434:     // Paint directly into the metafile.
                    435:     DrawObj (hdc, lpobj, rc, dctypeMetafile);
                    436: 
                    437:     // Get handle to the metafile.
                    438:     if ((hMF = CloseMetaFile (hdc)) == NULL)
                    439:       return NULL;
                    440: 
                    441:     if(!(hpict = GlobalAlloc (GMEM_DDESHARE, sizeof (METAFILEPICT))))
                    442:     {
                    443:         DeleteMetaFile (hMF);
                    444:         return NULL;
                    445:     }
                    446: 
                    447:     if ((lppict = (LPMETAFILEPICT)GlobalLock (hpict)) == NULL)
                    448:     {
                    449:         DeleteMetaFile (hMF);
                    450:         GlobalFree (hpict);
                    451:         return NULL;
                    452:     }
                    453: 
                    454:     rc.right  = rc.right - rc.left;
                    455:     rc.bottom = rc.bottom - rc.top;
                    456:     
                    457:     DeviceToHiMetric (hwndMain, (LPPOINT) &rc.right);
                    458: 
                    459:     lppict->mm   =  MM_ANISOTROPIC;
                    460:     lppict->hMF  =  hMF;
                    461:     lppict->xExt =  rc.right;
                    462:     lppict->yExt =  rc.bottom;
                    463:     GlobalUnlock (hpict);
                    464:     return hpict;
                    465: }
                    466: 
                    467: /* GetEnhMetafile
                    468:  * ---------------
                    469:  *
                    470:  * Return a handle to an object's picture data in metafile format.
                    471:  *
                    472:  * LPOBJ lpobj - The object
                    473:  * 
                    474:  * RETURNS: A handle to the object's data in metafile format.
                    475:  *
                    476:  * CUSTOMIZATION: Re-implement
                    477:  *
                    478:  */
                    479: static HANDLE GetEnhMetafile (LPOBJ lpobj)
                    480: {
                    481: 
                    482:     LPMETAFILEPICT  lppict = NULL;
                    483:     HANDLE          hemf   = NULL;
                    484:     HANDLE          hMF    = NULL;
                    485:     RECT            rc,rect;
                    486:     HDC             hdc;
                    487: 
                    488:     GetClientRect (lpobj->hwnd, (LPRECT)&rc);
                    489: 
                    490:     rect.left   = rect.top = 0;
                    491:     rect.right  = rc.right  - rc.left;
                    492:     rect.bottom = rc.bottom - rc.top;
                    493:     
                    494:     DeviceToHiMetric (hwndMain, (LPPOINT) &rect.right);
                    495: 
                    496:     hdc = CreateEnhMetaFile(NULL, NULL, &rect, NULL);
                    497:     DrawObj (hdc, lpobj, rc, dctypeMetafile);
                    498:     if ((hemf = (HANDLE)CloseEnhMetaFile (hdc)) == NULL)
                    499:       return NULL;
                    500: 
                    501:     return hemf;
                    502: }
                    503: 
                    504: 
                    505: /* GetNative
                    506:  * ---------
                    507:  *
                    508:  * Return a handle to an object's native data.
                    509:  *
                    510:  * LPOBJ lpobj - The object whose native data is to be retrieved.
                    511:  * 
                    512:  * RETURNS: a handle to the object's native data.
                    513:  *
                    514:  * CUSTOMIZATION: The line "*lpnative = lpobj->native;" will change to 
                    515:  *                whatever code is necessary to copy an object's native data.
                    516:  *
                    517:  */
                    518: static HANDLE GetNative (LPOBJ lpobj)
                    519: {
                    520:    LPNATIVE lpnative = NULL;
                    521:    HANDLE   hNative  = NULL;
                    522: 
                    523:    hNative = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof (NATIVE));
                    524:    if (hNative == NULL)
                    525:       return NULL;
                    526:    if ((lpnative = (LPNATIVE) GlobalLock (hNative)) == NULL)
                    527:    {
                    528:       GlobalFree (hNative);
                    529:       return NULL;
                    530:    }
                    531: 
                    532:    // Copy the native data.
                    533:    *lpnative = lpobj->native;
                    534: 
                    535:    GlobalUnlock (hNative);
                    536:    return hNative;
                    537: }
                    538: 
                    539: 
                    540: 
                    541: /* GetObjNum
                    542:  * ---------
                    543:  *
                    544:  * LPSTR lpobj - The object whose number is desired
                    545:  *
                    546:  * RETURNS: The number of the object, i.e., the numerical portion of its name.
                    547:  *
                    548:  * CUSTOMIZATION: Server Demo specific
                    549:  */
                    550: static INT GetObjNum (LPOBJ lpobj)
                    551: {
                    552:    LPSTR lpsz;
                    553:    INT n=0;
                    554: 
                    555:    lpsz = lpobj->native.szName + 7;
                    556:    while (*lpsz && *lpsz>='0' && *lpsz<='9')
                    557:       n = 10*n + *lpsz++ - '0';
                    558:    return n;
                    559: }
                    560: 
                    561: 
                    562: 
                    563: /* GetText
                    564:  * -------
                    565:  *
                    566:  * Return a handle to an object's data in text form.
                    567:  * This function simply returns the name of the object.
                    568:  *
                    569:  * LPOBJ lpobj - The object
                    570:  * 
                    571:  * RETURNS: A handle to the object's text.
                    572:  *
                    573:  * CUSTOMIZATION: Re-implement, if your application supports CF_TEXT as a 
                    574:  *                presentation format.
                    575:  *
                    576:  */
                    577: static HANDLE GetText (LPOBJ lpobj)
                    578: {
                    579:     HANDLE hText    = NULL;
                    580:     LPSTR  lpszText = NULL;
                    581: 
                    582:     if(!(hText = GlobalAlloc (GMEM_DDESHARE, sizeof (lpobj->native.szName))))
                    583:       return NULL;
                    584: 
                    585:     if (!(lpszText = GlobalLock (hText)))
                    586:       return NULL;
                    587: 
                    588:     lstrcpy (lpszText, lpobj->native.szName);
                    589: 
                    590:     GlobalUnlock (hText);
                    591: 
                    592:     return hText;
                    593: }
                    594: 
                    595: 
                    596: 
                    597: /* ObjDoVerb                OBJECT "DoVerb" METHOD
                    598:  * ---------
                    599:  *
                    600:  * This method is called by the client, through the library, to either
                    601:  * PLAY, or EDIT the object.  PLAY is implemented as a beep, and
                    602:  * EDIT will bring up the server and show the object for editing.
                    603:  *
                    604:  * LPOLEOBJECT lpoleobject - The OLE object
                    605:  * WORD wVerb              - The verb acting on the object: PLAY or EDIT
                    606:  * BOOL fShow              - Should the object be shown?
                    607:  * BOOL fTakeFocus         - Should the object window get the focus?
                    608:  * 
                    609:  * RETURNS:        OLE_OK
                    610:  *
                    611:  * CUSTOMIZATION: Add any more verbs your application supports.
                    612:  *                Implement verbPlay if your application supports it.
                    613:  *
                    614:  */
                    615: OLESTATUS  APIENTRY ObjDoVerb 
                    616:    (LPOLEOBJECT lpoleobject, UINT wVerb, BOOL fShow, BOOL fTakeFocus)
                    617: {
                    618:     switch (wVerb) 
                    619:     {
                    620:          case verbPlay:
                    621:          {  // The application can do whatever is appropriate for the object.
                    622:             INT i;
                    623:             for (i=0; i<25;i++) MessageBeep (0);
                    624:             return OLE_OK;
                    625:          }
                    626: 
                    627:          case verbEdit:
                    628:             if (fShow)
                    629:                return objvtbl.Show (lpoleobject, fTakeFocus);
                    630:             else
                    631:                return OLE_OK;
                    632:          default:
                    633:             // Unknown verb.
                    634:             return OLE_ERROR_DOVERB;
                    635:     }
                    636: }
                    637: 
                    638: 
                    639: 
                    640: /* ObjEnumFormats        OBJECT "EnumFormats" METHOD
                    641:  * ---------------
                    642:  *
                    643:  * This method is used to enumerate all supported clipboard formats.
                    644:  * Terminate by returning NULL.
                    645:  *
                    646:  * LPOLEOBJECT lpoleobject - The OLE object
                    647:  * OLECLIPFORMAT cfFormat  - The 'current' clipboard format
                    648:  * 
                    649:  * RETURNS: The 'next' clipboard format which is supported.
                    650:  *
                    651:  * CUSTOMIZATION: Verify that the list of formats this function 
                    652:  *                returns matches the list of formats your application 
                    653:  *                supports.
                    654:  *
                    655:  */
                    656: OLECLIPFORMAT  APIENTRY ObjEnumFormats
                    657:    (LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat)
                    658: {
                    659:       if (cfFormat == 0)
                    660:         return cfNative;
                    661: 
                    662:       if (cfFormat == cfNative)
                    663:          return cfOwnerLink;
                    664: 
                    665:       if (cfFormat == cfOwnerLink)
                    666:          return CF_ENHMETAFILE;
                    667: 
                    668:       if (cfFormat == CF_ENHMETAFILE)
                    669:          return CF_METAFILEPICT;
                    670: 
                    671:       if (cfFormat == CF_METAFILEPICT)
                    672:          return CF_BITMAP;
                    673: 
                    674:       if (cfFormat == CF_BITMAP)
                    675:          return cfObjectLink;
                    676: 
                    677:       if (cfFormat == cfObjectLink)
                    678:          return NULL;
                    679: 
                    680:       return NULL;
                    681: }
                    682: 
                    683: 
                    684: 
                    685: /* ObjGetData                OBJECT "GetData" METHOD
                    686:  * -----------
                    687:  *
                    688:  * Return the data requested for the specified object in the specified format.
                    689:  *
                    690:  * LPOLEOBJECT lpoleobject - The OLE object
                    691:  * WORD cfFormat           - The data type requested in standard
                    692:  *                           clipboard format
                    693:  * LPHANDLE lphandle       - Pointer to handle to memory where data
                    694:  *                           will be stored
                    695:  * 
                    696:  * RETURNS: OLE_OK           if successful
                    697:  *          OLE_ERROR_MEMORY if there was an error getting the data.
                    698:  *          OLE_ERROR_FORMAT if the requested format is unknown.
                    699:  *
                    700:  * 
                    701:  * CUSTOMIZATION: Add any additional formats your application supports, and
                    702:  *                remove any formats it does not support.
                    703:  *
                    704:  */
                    705: OLESTATUS  APIENTRY ObjGetData
                    706:    (LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat, LPHANDLE lphandle)
                    707: {
                    708: 
                    709:    LPOBJ lpobj;
                    710: 
                    711:    lpobj = (LPOBJ) lpoleobject;
                    712: 
                    713:    if (cfFormat ==  cfNative)
                    714:    {
                    715:       if (!(*lphandle = GetNative (lpobj)))
                    716:          return OLE_ERROR_MEMORY;
                    717:       // The client has requested the data in native format, therefore
                    718:       // the data in the client and server are in sync.
                    719:       fDocChanged = FALSE;
                    720:       return OLE_OK; 
                    721:    }                
                    722: 
                    723:    if (cfFormat == CF_ENHMETAFILE)
                    724:    {
                    725:       if (!(*lphandle = GetEnhMetafile (lpobj)))
                    726:          return OLE_ERROR_MEMORY;
                    727:       return OLE_OK; 
                    728:    }
                    729: 
                    730:    if (cfFormat == CF_METAFILEPICT)
                    731:    {
                    732:       if (!(*lphandle = GetMetafilePict (lpobj)))
                    733:          return OLE_ERROR_MEMORY;
                    734:       return OLE_OK; 
                    735:    }
                    736: 
                    737:    if (cfFormat == CF_BITMAP)
                    738:    {
                    739:       if (!(*lphandle = (HANDLE)GetBitmap (lpobj)))
                    740:          return OLE_ERROR_MEMORY;
                    741:       return OLE_OK; 
                    742:    }
                    743: 
                    744:    if (cfFormat == CF_TEXT) 
                    745:    {
                    746:       if (!(*lphandle = GetText (lpobj)))
                    747:          return OLE_ERROR_MEMORY;
                    748:       return OLE_OK; 
                    749:    }
                    750: 
                    751:    if (cfFormat == cfObjectLink)
                    752:    {
                    753:       if (!(*lphandle = GetLink (lpobj)))
                    754:          return OLE_ERROR_MEMORY;
                    755:       return OLE_OK; 
                    756:    }
                    757: 
                    758:    if (cfFormat ==  cfOwnerLink)
                    759:    {
                    760:       if (!(*lphandle = GetLink (lpobj)))
                    761:          return OLE_ERROR_MEMORY;
                    762:       return OLE_OK; 
                    763:    }
                    764: 
                    765:    return OLE_ERROR_FORMAT;
                    766: }
                    767: 
                    768: 
                    769: 
                    770: /* ObjQueryProtocol                OBJECT "QueryProtocol" METHOD
                    771:  * ----------------
                    772:  *
                    773:  * LPOLEOBJECT lpoleobject - The OLE object
                    774:  * LPSTR lpszProtocol      - The protocol name, either "StdFileEditing"
                    775:  *                           or "StdExecute"
                    776:  * 
                    777:  * RETURNS: If lpszProtocol is supported, return a pointer to an OLEOBJECT 
                    778:  *          structure with an appropriate method table for that protocol.
                    779:  *          Otherwise, return NULL.
                    780:  *
                    781:  * CUSTOMIZATION: Allow any additional protocols your application supports.
                    782:  *
                    783:  *
                    784:  */
                    785: LPVOID  APIENTRY ObjQueryProtocol 
                    786:    (LPOLEOBJECT lpoleobject, LPSTR lpszProtocol)
                    787: {
                    788:    return lstrcmp (lpszProtocol, "StdFileEditing") ? NULL : lpoleobject ;
                    789: }
                    790: 
                    791: 
                    792: 
                    793: /* ObjRelease                OBJECT "Release" METHOD
                    794:  * -----------
                    795:  *
                    796:  * The server application should not destroy data when the library calls the 
                    797:  * ReleaseObj method.
                    798:  * The library calls the ReleaseObj method when no clients are connected 
                    799:  * to the object.
                    800:  *
                    801:  * LPOLEOBJECT lpoleobject - The OLE object
                    802:  * 
                    803:  * RETURNS: OLE_OK
                    804:  * 
                    805:  * CUSTOMIZATION: Re-implement.  Do whatever needs to be done, if anything,
                    806:  *                when no clients are connected to an object.
                    807:  *
                    808:  */
                    809: OLESTATUS  APIENTRY ObjRelease (LPOLEOBJECT lpoleobject)
                    810: {
                    811:    INT i;
                    812:    /* No client is connected to the object so break all assocaiations
                    813:       between clients and the object. */
                    814:    for (i=0; i < clpoleclient; i++)
                    815:       ((LPOBJ)lpoleobject)->lpoleclient[i] = NULL;
                    816:    return OLE_OK;
                    817: }
                    818: 
                    819: 
                    820: 
                    821: /* ObjSetBounds        OBJECT "SetBounds" METHOD
                    822:  * ------------
                    823:  *
                    824:  * This method is called to set new bounds for an object.
                    825:  * The bounds are in HIMETRIC units.
                    826:  * A call to this method is ignored for linked objects because the size of
                    827:  * a linked object depends only on the source file.
                    828:  *
                    829:  * LPOLEOBJECT lpoleobject - The OLE object
                    830:  * LPRECT lprect           - The new bounds
                    831:  * 
                    832:  * RETURNS: OLE_OK
                    833:  *
                    834:  * CUSTOMIZATION: Re-implement
                    835:  *                How an object is sized is application-specific. (Server Demo
                    836:  *                uses MoveWindow.)
                    837:  *
                    838:  */
                    839: OLESTATUS  APIENTRY ObjSetBounds (LPOLEOBJECT lpoleobj, LPRECT lprect)
                    840: {
                    841:    if (docMain.doctype == doctypeEmbedded)
                    842:    {
                    843:       RECT rect = *lprect;
                    844:       LPOBJ lpobj = (LPOBJ) lpoleobj;
                    845:       
                    846:       // the units are in HIMETRIC
                    847:       rect.right   = rect.right - rect.left;
                    848:       rect.bottom  = rect.top - rect.bottom;
                    849:       HiMetricToDevice (hwndMain, (LPPOINT) &rect.right);
                    850:       MoveWindow (lpobj->hwnd, lpobj->native.nX, lpobj->native.nY, 
                    851:                   rect.right + 2 * GetSystemMetrics(SM_CXFRAME), 
                    852:                   rect.bottom + 2 * GetSystemMetrics(SM_CYFRAME), 
                    853:                   TRUE);
                    854:    }
                    855:    return OLE_OK;
                    856: }
                    857: 
                    858: 
                    859: 
                    860: /* ObjSetColorScheme                OBJECT "SetColorScheme" METHOD
                    861:  * -----------------
                    862:  *
                    863:  * The client calls this method to suggest a color scheme (palette) for
                    864:  * the server to use for the object.
                    865:  *
                    866:  * LPOLEOBJECT  lpoleobject       - The OLE object
                    867:  * LPLOGPALETTE lppal             - Suggested palette
                    868:  *
                    869:  * RETURNS: OLE_ERROR_PALETTE if CreatePalette fails, 
                    870:  *          OLE_OK otherwise
                    871:  *
                    872:  * 
                    873:  * CUSTOMIZATION: If your application supports color schemes, then this 
                    874:  *                function is a good example of how to create and store
                    875:  *                a palette.
                    876:  *
                    877:  */
                    878: OLESTATUS  APIENTRY ObjSetColorScheme 
                    879:    (LPOLEOBJECT lpoleobject, LPLOGPALETTE lppal)
                    880: {
                    881:    HPALETTE hpal = CreatePalette (lppal);
                    882:    LPOBJ lpobj   = (LPOBJ) lpoleobject;
                    883: 
                    884:    if (hpal==NULL)
                    885:       return OLE_ERROR_PALETTE;
                    886: 
                    887:    if (lpobj->hpal) 
                    888:       DeleteObject (lpobj->hpal);
                    889:    lpobj->hpal = hpal;
                    890:    return OLE_OK;
                    891: }
                    892: 
                    893: 
                    894: 
                    895: /* ObjSetData                OBJECT "SetData" METHOD
                    896:  * ----------
                    897:  *
                    898:  * This method is used to store data into the object in the specified
                    899:  * format.  This will be called with Native format after an embedded
                    900:  * object has been opened by the Edit method.
                    901:  *
                    902:  * LPOLEOBJECT lpoleobject      - The OLE object
                    903:  * WORD cfFormat                - Data type, i.e., clipboard format
                    904:  * HANDLE hdata                 - Handle to the data.
                    905:  * 
                    906:  * RETURNS:       OLE_OK if the data was stored properly
                    907:  *                OLE_ERROR_FORMAT if format was not cfNative.
                    908:  *                OLE_ERROR_MEMORY if memory could not be locked.
                    909:  * 
                    910:  * CUSTOMIZATION: The large then-clause will need to be re-implemented for
                    911:  *                your application.  You may wish to support additional
                    912:  *                formats besides cfNative.
                    913:  *
                    914:  */
                    915: OLESTATUS  APIENTRY ObjSetData 
                    916:    (LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat, HANDLE hdata)
                    917: {
                    918:     LPNATIVE lpnative;
                    919:     LPOBJ    lpobj;
                    920: 
                    921:     lpobj = (LPOBJ)lpoleobject;
                    922: 
                    923:     if (cfFormat != cfNative)
                    924:     {
                    925:       return OLE_ERROR_FORMAT;
                    926:     }
                    927: 
                    928:     lpnative = (LPNATIVE) GlobalLock (hdata);
                    929: 
                    930:     if (lpnative)
                    931:     {
                    932:         lpobj->native = *lpnative;
                    933:         if (lpobj->aName)
                    934:             GlobalDeleteAtom (lpobj->aName);
                    935:         lpobj->aName = GlobalAddAtom (lpnative->szName);
                    936:         // CreateNewObj made an "Object 1" but we may be changing its number.
                    937:         docMain.rgfObjNums[1] = FALSE;
                    938:         docMain.rgfObjNums [GetObjNum(lpobj)] = TRUE;
                    939: 
                    940:         MoveWindow (lpobj->hwnd, 0, 0,
                    941:                     lpobj->native.nWidth + 2 * GetSystemMetrics(SM_CXFRAME), 
                    942:                     lpobj->native.nHeight+ 2 * GetSystemMetrics(SM_CYFRAME), 
                    943:                     FALSE);
                    944:         GlobalUnlock (hdata);
                    945:     }
                    946:     // Server is responsible for deleting the data.
                    947:     GlobalFree(hdata);           
                    948:     return lpnative ? OLE_OK : OLE_ERROR_MEMORY;
                    949: }
                    950: 
                    951: 
                    952: 
                    953: /* ObjSetTargetDevice        OBJECT "SetTargetDevice" METHOD
                    954:  * -------------------
                    955:  *
                    956:  * This method is used to indicate the device type that an object
                    957:  * will be rendered on.  It is the server's responsibility to free hdata.
                    958:  *
                    959:  * LPOLEOBJECT lpoleobject - The OLE object
                    960:  * HANDLE hdata            - Handle to memory containing
                    961:  *                           a StdTargetDevice structure
                    962:  * 
                    963:  * RETURNS: OLE_OK
                    964:  * 
                    965:  * CUSTOMIZATION: Implement.  Server Demo currently does not do anything.
                    966:  *
                    967:  */
                    968: OLESTATUS  APIENTRY ObjSetTargetDevice (LPOLEOBJECT lpoleobject, HANDLE hdata)
                    969: {
                    970:     if (hdata == NULL)
                    971:     {
                    972:       // Rendering for the screen is requested.
                    973:     }
                    974:     else
                    975:     {
                    976:       LPSTR lpstd = (LPSTR) GlobalLock (hdata);
                    977:       // lpstd points to a StdTargetDevice structure.
                    978:       // Use it to do whatever is appropriate to generate the best results 
                    979:       // on the specified target device.
                    980:       GlobalUnlock (hdata);
                    981:       // Server is responsible for freeing the data.
                    982:       GlobalFree (hdata);  
                    983:     }
                    984:     return OLE_OK;
                    985: }
                    986: 
                    987: 
                    988: 
                    989: /* ObjShow                OBJECT "Show" METHOD
                    990:  * --------
                    991:  *
                    992:  * This method is used to display the object.  
                    993:  * The server application should be activated and brought to the top.
                    994:  * Also, in a REAL server application, the object should be scrolled
                    995:  * into view.  The object should be selected.
                    996:  *
                    997:  * LPOLEOBJECT lpoleobject - Pointer to the OLE object
                    998:  * BOOL fTakeFocus         - Should server window get the focus?
                    999:  * 
                   1000:  * RETURNS:        OLE_OK
                   1001:  *
                   1002:  * 
                   1003:  * CUSTOMIZATION: In your application, the document should be scrolled 
                   1004:  *                to bring the object into view.  Server Demo brings the 
                   1005:  *                object to the front, in case it is a linked object inside a 
                   1006:  *                document with other objects obscuring it.
                   1007:  *
                   1008:  */
                   1009: OLESTATUS  APIENTRY ObjShow (LPOLEOBJECT lpoleobject, BOOL fTakeFocus)
                   1010: {
                   1011:     LPOBJ lpobj;
                   1012:     HWND hwndOldFocus;
                   1013: 
                   1014:     hwndOldFocus = GetFocus();
                   1015:     lpobj = (LPOBJ) lpoleobject;
                   1016:     
                   1017:     if (fTakeFocus)
                   1018:        SetForegroundWindow (lpobj->hwnd);
                   1019: 
                   1020:     ShowWindow(hwndMain, SW_SHOWNORMAL);
                   1021: 
                   1022:     SetFocus (fTakeFocus ? lpobj->hwnd : hwndOldFocus);
                   1023:     return OLE_OK;
                   1024: }
                   1025: 
                   1026: 
                   1027: 
                   1028: /* PaintObj
                   1029:  * ---------
                   1030:  *
                   1031:  * This function is called by the WM_PAINT message to paint an object 
                   1032:  * on the screen.  
                   1033:  *
                   1034:  * HWND hwnd - The object window in which to paint the object
                   1035:  *
                   1036:  * CUSTOMIZATION: Server Demo specific
                   1037:  *
                   1038:  */
                   1039: VOID PaintObj (HWND hwnd)
                   1040: {
                   1041:     LPOBJ       lpobj;
                   1042:     RECT        rc;
                   1043:     HDC         hdc;
                   1044:     PAINTSTRUCT paintstruct;
                   1045: 
                   1046:     BeginPaint (hwnd, &paintstruct);
                   1047:     hdc = GetDC (hwnd);
                   1048: 
                   1049:     lpobj = HwndToLpobj (hwnd);
                   1050:     GetClientRect (hwnd, (LPRECT) &rc);
                   1051: 
                   1052:     DrawObj (hdc, lpobj, rc, dctypeScreen);
                   1053: 
                   1054:     ReleaseDC (hwnd, hdc);
                   1055:     EndPaint (hwnd, &paintstruct);
                   1056: }
                   1057: 
                   1058: 
                   1059: 
                   1060: /* RevokeObj
                   1061:  * ---------
                   1062:  *
                   1063:  * Call OleRevokeObject because the user has destroyed the object.
                   1064:  *
                   1065:  * LPOBJ lpobj - The object which has been destroyed
                   1066:  *
                   1067:  * 
                   1068:  * CUSTOMIZATION: You will only need to call OleRevokeObject once if there
                   1069:  *                is only one LPOLECLIENT in your OBJ structure, which there
                   1070:  *                should be.
                   1071:  *
                   1072:  */
                   1073: VOID RevokeObj (LPOBJ lpobj)
                   1074: {
                   1075:    INT i;
                   1076: 
                   1077:    for (i=0; i< clpoleclient; i++)
                   1078:    {
                   1079:       if (lpobj->lpoleclient[i])
                   1080:          OleRevokeObject (lpobj->lpoleclient[i]);
                   1081:       else 
                   1082:          /* if lpobj->lpoleclient[i]==NULL then there are no more non-NULLs
                   1083:             in the array. */
                   1084:          break;
                   1085:    }
                   1086: }
                   1087: 
                   1088: 
                   1089: 
                   1090: /* SendObjMsg
                   1091:  * ----------
                   1092:  *
                   1093:  * This function sends a message to a specific object.
                   1094:  *
                   1095:  * LPOBJ lpobj   - The object
                   1096:  * WORD wMessage - The message to send
                   1097:  * 
                   1098:  * CUSTOMIZATION: You will only need to call CallBack once if there
                   1099:  *                is only one LPOLECLIENT in your OBJ structure, which there
                   1100:  *                should be.
                   1101:  *
                   1102:  */
                   1103: VOID SendObjMsg (LPOBJ lpobj, WORD wMessage)
                   1104: {
                   1105:    INT i;
                   1106:    for (i=0; i < clpoleclient; i++)
                   1107:    {
                   1108:       if (lpobj->lpoleclient[i])
                   1109:       {
                   1110:          // Call the object's Callback function.
                   1111:          lpobj->lpoleclient[i]->lpvtbl->CallBack 
                   1112:             (lpobj->lpoleclient[i], wMessage, (LPOLEOBJECT) lpobj);
                   1113:       }
                   1114:       else
                   1115:          break;
                   1116:    }
                   1117: }
                   1118: 
                   1119: 
                   1120: 
                   1121: /* SizeObj
                   1122:  * -------
                   1123:  *
                   1124:  * Change the size of an object.
                   1125:  *
                   1126:  * HWND hwnd  - The object's window
                   1127:  * RECT rect  - The requested new size in device units
                   1128:  * BOOL fMove - Should the object be moved? (or just resized?)
                   1129:  *
                   1130:  * CUSTOMIZATION: Server Demo specific
                   1131:  *
                   1132:  */
                   1133: VOID SizeObj (HWND hwnd, RECT rect, BOOL fMove)
                   1134: {
                   1135:    LPOBJ lpobj;
                   1136: 
                   1137:    lpobj = HwndToLpobj (hwnd);
                   1138:    if (fMove)
                   1139:    {
                   1140:       lpobj->native.nX   = rect.left;
                   1141:       lpobj->native.nY   = rect.top;
                   1142:    }
                   1143:    lpobj->native.nWidth  = rect.right  - rect.left;
                   1144:    lpobj->native.nHeight = rect.bottom - rect.top ;
                   1145:    SetHiMetricFields (lpobj);
                   1146:    InvalidateRect (hwnd, (LPRECT)NULL, TRUE);
                   1147:    fDocChanged = TRUE;
                   1148:    if (docMain.doctype == doctypeFromFile)
                   1149:    {
                   1150:       // If object is linked, update it in client now. 
                   1151:       SendObjMsg (lpobj, OLE_CHANGED);
                   1152:    }
                   1153: }

unix.superglobalmegacorp.com

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