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

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: 
1.1.1.2 ! root      248: //   if (dctype == dctypeMetafile || dctype == dctypeEnhMetafile)
        !           249:    if (dctype == dctypeMetafile)
1.1       root      250:    {
                    251:       SetWindowOrgEx (hdc, 0, 0, NULL);
                    252:       // Paint entire object into the given rectangle.
                    253:       SetWindowExtEx (hdc, rc.right, rc.bottom, NULL);
                    254:    }
                    255:  
                    256:    if (lpobj->hpal)
                    257:    {
                    258:       hpalOld = SelectPalette (hdc, lpobj->hpal, TRUE);
                    259:       RealizePalette (hdc);
                    260:    }
                    261: 
                    262:    // Select brush of the color specified in the native data.
                    263:    SelectObject (hdc, hbrColor [lpobj->native.idmColor - IDM_RED] );
                    264: 
                    265:    hpen = CreatePen (PS_SOLID, 
                    266:                      /* Width */ (rc.bottom-rc.top) / 10,
                    267:                      /* Gray */ 0x00808080);
                    268:    hpenOld = SelectObject (hdc, hpen);
                    269: 
                    270:    // Draw rectangle with the gray pen and fill it in with the selected brush.
                    271:    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
                    272: 
                    273:    // Print name of object inside rectangle.
                    274:    SetBkMode (hdc, TRANSPARENT);
                    275:    SetTextAlign (hdc, TA_BASELINE | TA_CENTER);
                    276:    TextOut (hdc, 
                    277:             rc.right/2, 
                    278:             (rc.top+rc.bottom)/2, 
                    279:             lpobj->native.szName, 
                    280:             lstrlen (lpobj->native.szName));
                    281: 
                    282:    // Restore original objects
                    283:    SelectObject (hdc, 
                    284:                  (dctype == dctypeMetafile || dctype == dctypeEnhMetafile) 
                    285:                      ? GetStockObject (BLACK_PEN) : hpenOld);
                    286:    if (hpalOld)
                    287:    {
                    288:       SelectPalette (hdc, 
                    289:                      (dctype == dctypeMetafile || dctype == dctypeEnhMetafile) 
                    290:                         ? GetStockObject (DEFAULT_PALETTE) : hpalOld,
                    291:                      TRUE);
                    292:    }
                    293: 
                    294:    DeleteObject (hpen);
                    295: }
                    296: 
                    297: 
                    298: 
                    299: /* GetBitmap
                    300:  * ---------
                    301:  *
                    302:  * Return a handle to an object's picture data in bitmap format.
                    303:  *
                    304:  * LPOBJ lpobj - The object
                    305:  * 
                    306:  * RETURNS: A handle to the object's picture data
                    307:  * 
                    308:  * CUSTOMIZATION: Re-implement
                    309:  *
                    310:  */
                    311: static HBITMAP GetBitmap (LPOBJ lpobj)
                    312: {
                    313:     HDC         hdcObj;
                    314:     HDC         hdcMem;
                    315:     RECT        rc;
                    316:     HBITMAP     hbitmap;
                    317:     HBITMAP     hbitmapOld;
                    318: 
                    319: 
                    320:     hdcObj = GetDC (lpobj->hwnd);
                    321:     // Create a memory device context.
                    322:     hdcMem = CreateCompatibleDC (hdcObj);
                    323:     GetClientRect (lpobj->hwnd, (LPRECT)&rc);
                    324:     // Create new bitmap object based on the bitmap of the OLE object.
                    325:     hbitmap = CreateCompatibleBitmap 
                    326:       (hdcObj, rc.right - rc.left, rc.bottom - rc.top);
                    327:     // Select new bitmap as the bitmap object for the memory device context.
                    328:     hbitmapOld = SelectObject (hdcMem, hbitmap);
                    329: 
                    330:     // Paint directly into the memory dc using the new bitmap object.
                    331:     DrawObj (hdcMem, lpobj, rc, dctypeBitmap);
                    332: 
                    333:     // Restore old bitmap object.
                    334:     hbitmap = SelectObject (hdcMem, hbitmapOld);
                    335:     DeleteDC (hdcMem);
                    336:     ReleaseDC (lpobj->hwnd, hdcObj);
                    337: 
                    338:     // convert width and height to HIMETRIC units
                    339:     rc.right  = rc.right - rc.left;
                    340:     rc.bottom = rc.bottom - rc.top;
1.1.1.2 ! root      341:     DeviceToHiMetric ( (LPPOINT) &rc.right );
1.1       root      342:     
                    343:     // Set the 1/10 of HIMETRIC units for the bitmap
                    344:     SetBitmapDimensionEx (hbitmap, (DWORD) (rc.right/10), (DWORD) (rc.bottom/10), NULL);
                    345:         
                    346:     return hbitmap;
                    347: }
                    348: 
                    349: 
                    350: 
                    351: /* GetLink
                    352:  * -------
                    353:  *
                    354:  * Return a handle to an object's object or owner link data.
                    355:  * Link information is in the form of three zero-separated strings,
                    356:  * terminated with two zero bytes:  CLASSNAME\0DOCNAME\0OBJNAME\0\0
                    357:  *
                    358:  * LPOBJ lpobj - The object 
                    359:  * 
                    360:  * RETURNS: A handle to the object's link data
                    361:  * 
                    362:  * CUSTOMIZATION: Re-implement
                    363:  *
                    364:  */
                    365: static HANDLE GetLink (LPOBJ lpobj)
                    366: {
                    367: 
                    368:     CHAR   sz[cchFilenameMax];
                    369:     LPSTR  lpszLink = NULL;
                    370:     HANDLE hLink = NULL;
                    371:     INT    cchLen;
                    372:     INT    i;
                    373: 
                    374:     // First make the class name.
                    375:     lstrcpy (sz, szClassName);
                    376:     cchLen = lstrlen (sz) + 1;
                    377: 
                    378:     // Then the document name.
                    379:     cchLen += GlobalGetAtomName 
                    380:                (docMain.aName, (LPSTR)sz + cchLen, 
                    381:                 cchFilenameMax - cchLen) + 1;
                    382: 
                    383:     // Then the object name.
                    384:     lstrcpy (sz + cchLen, lpobj->native.szName);
                    385:     cchLen += lstrlen (lpobj->native.szName) + 1;
                    386: 
                    387:     // Add a second null to the end.
                    388:     sz[cchLen++] = 0;       
                    389: 
                    390: 
                    391:     hLink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, cchLen);
                    392:     if (hLink == NULL)
                    393:       return NULL;
                    394:     if ((lpszLink = GlobalLock (hLink)) == NULL)
                    395:     {
                    396:       GlobalFree (hLink);
                    397:       return NULL;
                    398:     }
                    399: 
                    400:     for (i=0; i < cchLen; i++)
                    401:         lpszLink[i] = sz[i];
                    402: 
                    403:     GlobalUnlock (hLink);
                    404: 
                    405:     return hLink;
                    406: }
                    407: 
                    408: 
                    409: 
                    410: /* GetMetafilePict
                    411:  * ---------------
                    412:  *
                    413:  * Return a handle to an object's picture data in metafile format.
                    414:  *
                    415:  * LPOBJ lpobj - The object
                    416:  * 
                    417:  * RETURNS: A handle to the object's data in metafile format.
                    418:  *
                    419:  * CUSTOMIZATION: Re-implement
                    420:  *
                    421:  */
                    422: static HANDLE GetMetafilePict (LPOBJ lpobj)
                    423: {
                    424: 
                    425:     LPMETAFILEPICT  lppict = NULL;
                    426:     HANDLE          hpict = NULL;
                    427:     HANDLE          hMF = NULL;
                    428:     RECT            rc;
                    429:     HDC             hdc;
                    430: 
                    431:     hdc = CreateMetaFile(NULL);
                    432: 
                    433:     GetClientRect (lpobj->hwnd, (LPRECT)&rc);
                    434: 
                    435:     // Paint directly into the metafile.
                    436:     DrawObj (hdc, lpobj, rc, dctypeMetafile);
                    437: 
                    438:     // Get handle to the metafile.
                    439:     if ((hMF = CloseMetaFile (hdc)) == NULL)
                    440:       return NULL;
                    441: 
                    442:     if(!(hpict = GlobalAlloc (GMEM_DDESHARE, sizeof (METAFILEPICT))))
                    443:     {
                    444:         DeleteMetaFile (hMF);
                    445:         return NULL;
                    446:     }
                    447: 
                    448:     if ((lppict = (LPMETAFILEPICT)GlobalLock (hpict)) == NULL)
                    449:     {
                    450:         DeleteMetaFile (hMF);
                    451:         GlobalFree (hpict);
                    452:         return NULL;
                    453:     }
                    454: 
                    455:     rc.right  = rc.right - rc.left;
                    456:     rc.bottom = rc.bottom - rc.top;
                    457:     
1.1.1.2 ! root      458:     DeviceToHiMetric ( (LPPOINT) &rc.right);
1.1       root      459: 
                    460:     lppict->mm   =  MM_ANISOTROPIC;
                    461:     lppict->hMF  =  hMF;
                    462:     lppict->xExt =  rc.right;
                    463:     lppict->yExt =  rc.bottom;
                    464:     GlobalUnlock (hpict);
                    465:     return hpict;
                    466: }
                    467: 
                    468: /* GetEnhMetafile
                    469:  * ---------------
                    470:  *
                    471:  * Return a handle to an object's picture data in metafile format.
                    472:  *
                    473:  * LPOBJ lpobj - The object
                    474:  * 
                    475:  * RETURNS: A handle to the object's data in metafile format.
                    476:  *
                    477:  * CUSTOMIZATION: Re-implement
                    478:  *
                    479:  */
                    480: static HANDLE GetEnhMetafile (LPOBJ lpobj)
                    481: {
                    482: 
                    483:     LPMETAFILEPICT  lppict = NULL;
                    484:     HANDLE          hemf   = NULL;
                    485:     HANDLE          hMF    = NULL;
1.1.1.2 ! root      486:     RECT            rc;
        !           487:     HDC             hdc, hdc2;
        !           488: 
1.1       root      489: 
                    490:     GetClientRect (lpobj->hwnd, (LPRECT)&rc);
                    491: 
1.1.1.2 ! root      492:     rc.right   -= rc.left;
        !           493:     rc.bottom  -= rc.top;
        !           494:     rc.left     = rc.top  = 0;
        !           495:         
        !           496:     DeviceToHiMetric ( (LPPOINT) &rc.right );
        !           497:         
        !           498:     hdc = CreateEnhMetaFile ( NULL, NULL, &rc, NULL );
1.1       root      499:     
1.1.1.2 ! root      500:                                        //* this is necessary because
        !           501:                                        //* we need to draw the object
        !           502:                                        //* in device coordinates that are
        !           503:                                        //* the same physical size as the HIMETRIC
        !           504:                                        //* logical space used in CreateEnhMetaFile.
        !           505:                                        //* In this case we have scaled the HIMETRIC
        !           506:                                        //* units down in order to use the logical
        !           507:                                        //* pixel ratio (which is recommended UI)
        !           508:                                        //* so we therefore have to convert the
        !           509:                                        //* scaled HIMETRIC units back to Device.
        !           510:                                       
        !           511:     hdc2 = GetDC(NULL);                                
        !           512: 
        !           513:     SetMapMode(hdc2, MM_HIMETRIC);
        !           514:     LPtoDP (hdc2, (LPPOINT)&rc.right, 1);
        !           515:     if (rc.bottom < 0) rc.bottom *= -1;
        !           516: 
        !           517:     ReleaseDC(NULL,hdc2);
        !           518: 
        !           519:        DrawObj (hdc, lpobj, rc, dctypeMetafile);
1.1       root      520: 
                    521:     if ((hemf = (HANDLE)CloseEnhMetaFile (hdc)) == NULL)
                    522:       return NULL;
                    523: 
                    524:     return hemf;
                    525: }
                    526: 
                    527: 
                    528: /* GetNative
                    529:  * ---------
                    530:  *
                    531:  * Return a handle to an object's native data.
                    532:  *
                    533:  * LPOBJ lpobj - The object whose native data is to be retrieved.
                    534:  * 
                    535:  * RETURNS: a handle to the object's native data.
                    536:  *
                    537:  * CUSTOMIZATION: The line "*lpnative = lpobj->native;" will change to 
                    538:  *                whatever code is necessary to copy an object's native data.
                    539:  *
                    540:  */
                    541: static HANDLE GetNative (LPOBJ lpobj)
                    542: {
                    543:    LPNATIVE lpnative = NULL;
                    544:    HANDLE   hNative  = NULL;
                    545: 
                    546:    hNative = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof (NATIVE));
                    547:    if (hNative == NULL)
                    548:       return NULL;
                    549:    if ((lpnative = (LPNATIVE) GlobalLock (hNative)) == NULL)
                    550:    {
                    551:       GlobalFree (hNative);
                    552:       return NULL;
                    553:    }
                    554: 
                    555:    // Copy the native data.
                    556:    *lpnative = lpobj->native;
                    557: 
                    558:    GlobalUnlock (hNative);
                    559:    return hNative;
                    560: }
                    561: 
                    562: 
                    563: 
                    564: /* GetObjNum
                    565:  * ---------
                    566:  *
                    567:  * LPSTR lpobj - The object whose number is desired
                    568:  *
                    569:  * RETURNS: The number of the object, i.e., the numerical portion of its name.
                    570:  *
                    571:  * CUSTOMIZATION: Server Demo specific
                    572:  */
                    573: static INT GetObjNum (LPOBJ lpobj)
                    574: {
                    575:    LPSTR lpsz;
                    576:    INT n=0;
                    577: 
                    578:    lpsz = lpobj->native.szName + 7;
                    579:    while (*lpsz && *lpsz>='0' && *lpsz<='9')
                    580:       n = 10*n + *lpsz++ - '0';
                    581:    return n;
                    582: }
                    583: 
                    584: 
                    585: 
                    586: /* GetText
                    587:  * -------
                    588:  *
                    589:  * Return a handle to an object's data in text form.
                    590:  * This function simply returns the name of the object.
                    591:  *
                    592:  * LPOBJ lpobj - The object
                    593:  * 
                    594:  * RETURNS: A handle to the object's text.
                    595:  *
                    596:  * CUSTOMIZATION: Re-implement, if your application supports CF_TEXT as a 
                    597:  *                presentation format.
                    598:  *
                    599:  */
                    600: static HANDLE GetText (LPOBJ lpobj)
                    601: {
                    602:     HANDLE hText    = NULL;
                    603:     LPSTR  lpszText = NULL;
                    604: 
                    605:     if(!(hText = GlobalAlloc (GMEM_DDESHARE, sizeof (lpobj->native.szName))))
                    606:       return NULL;
                    607: 
                    608:     if (!(lpszText = GlobalLock (hText)))
                    609:       return NULL;
                    610: 
                    611:     lstrcpy (lpszText, lpobj->native.szName);
                    612: 
                    613:     GlobalUnlock (hText);
                    614: 
                    615:     return hText;
                    616: }
                    617: 
                    618: 
                    619: 
                    620: /* ObjDoVerb                OBJECT "DoVerb" METHOD
                    621:  * ---------
                    622:  *
                    623:  * This method is called by the client, through the library, to either
                    624:  * PLAY, or EDIT the object.  PLAY is implemented as a beep, and
                    625:  * EDIT will bring up the server and show the object for editing.
                    626:  *
                    627:  * LPOLEOBJECT lpoleobject - The OLE object
                    628:  * WORD wVerb              - The verb acting on the object: PLAY or EDIT
                    629:  * BOOL fShow              - Should the object be shown?
                    630:  * BOOL fTakeFocus         - Should the object window get the focus?
                    631:  * 
                    632:  * RETURNS:        OLE_OK
                    633:  *
                    634:  * CUSTOMIZATION: Add any more verbs your application supports.
                    635:  *                Implement verbPlay if your application supports it.
                    636:  *
                    637:  */
                    638: OLESTATUS  APIENTRY ObjDoVerb 
                    639:    (LPOLEOBJECT lpoleobject, UINT wVerb, BOOL fShow, BOOL fTakeFocus)
                    640: {
                    641:     switch (wVerb) 
                    642:     {
                    643:          case verbPlay:
                    644:          {  // The application can do whatever is appropriate for the object.
                    645:             INT i;
                    646:             for (i=0; i<25;i++) MessageBeep (0);
                    647:             return OLE_OK;
                    648:          }
                    649: 
                    650:          case verbEdit:
                    651:             if (fShow)
                    652:                return objvtbl.Show (lpoleobject, fTakeFocus);
                    653:             else
                    654:                return OLE_OK;
                    655:          default:
                    656:             // Unknown verb.
                    657:             return OLE_ERROR_DOVERB;
                    658:     }
                    659: }
                    660: 
                    661: 
                    662: 
                    663: /* ObjEnumFormats        OBJECT "EnumFormats" METHOD
                    664:  * ---------------
                    665:  *
                    666:  * This method is used to enumerate all supported clipboard formats.
                    667:  * Terminate by returning NULL.
                    668:  *
                    669:  * LPOLEOBJECT lpoleobject - The OLE object
                    670:  * OLECLIPFORMAT cfFormat  - The 'current' clipboard format
                    671:  * 
                    672:  * RETURNS: The 'next' clipboard format which is supported.
                    673:  *
                    674:  * CUSTOMIZATION: Verify that the list of formats this function 
                    675:  *                returns matches the list of formats your application 
                    676:  *                supports.
                    677:  *
                    678:  */
                    679: OLECLIPFORMAT  APIENTRY ObjEnumFormats
                    680:    (LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat)
                    681: {
                    682:       if (cfFormat == 0)
                    683:         return cfNative;
                    684: 
                    685:       if (cfFormat == cfNative)
                    686:          return cfOwnerLink;
                    687: 
                    688:       if (cfFormat == cfOwnerLink)
                    689:          return CF_ENHMETAFILE;
                    690: 
                    691:       if (cfFormat == CF_ENHMETAFILE)
                    692:          return CF_METAFILEPICT;
                    693: 
                    694:       if (cfFormat == CF_METAFILEPICT)
                    695:          return CF_BITMAP;
                    696: 
                    697:       if (cfFormat == CF_BITMAP)
                    698:          return cfObjectLink;
                    699: 
                    700:       if (cfFormat == cfObjectLink)
                    701:          return NULL;
                    702: 
                    703:       return NULL;
                    704: }
                    705: 
                    706: 
                    707: 
                    708: /* ObjGetData                OBJECT "GetData" METHOD
                    709:  * -----------
                    710:  *
                    711:  * Return the data requested for the specified object in the specified format.
                    712:  *
                    713:  * LPOLEOBJECT lpoleobject - The OLE object
                    714:  * WORD cfFormat           - The data type requested in standard
                    715:  *                           clipboard format
                    716:  * LPHANDLE lphandle       - Pointer to handle to memory where data
                    717:  *                           will be stored
                    718:  * 
                    719:  * RETURNS: OLE_OK           if successful
                    720:  *          OLE_ERROR_MEMORY if there was an error getting the data.
                    721:  *          OLE_ERROR_FORMAT if the requested format is unknown.
                    722:  *
                    723:  * 
                    724:  * CUSTOMIZATION: Add any additional formats your application supports, and
                    725:  *                remove any formats it does not support.
                    726:  *
                    727:  */
                    728: OLESTATUS  APIENTRY ObjGetData
                    729:    (LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat, LPHANDLE lphandle)
                    730: {
                    731: 
                    732:    LPOBJ lpobj;
                    733: 
                    734:    lpobj = (LPOBJ) lpoleobject;
                    735: 
                    736:    if (cfFormat ==  cfNative)
                    737:    {
                    738:       if (!(*lphandle = GetNative (lpobj)))
                    739:          return OLE_ERROR_MEMORY;
                    740:       // The client has requested the data in native format, therefore
                    741:       // the data in the client and server are in sync.
                    742:       fDocChanged = FALSE;
                    743:       return OLE_OK; 
                    744:    }                
                    745: 
                    746:    if (cfFormat == CF_ENHMETAFILE)
                    747:    {
                    748:       if (!(*lphandle = GetEnhMetafile (lpobj)))
                    749:          return OLE_ERROR_MEMORY;
                    750:       return OLE_OK; 
                    751:    }
                    752: 
                    753:    if (cfFormat == CF_METAFILEPICT)
                    754:    {
                    755:       if (!(*lphandle = GetMetafilePict (lpobj)))
                    756:          return OLE_ERROR_MEMORY;
                    757:       return OLE_OK; 
                    758:    }
                    759: 
                    760:    if (cfFormat == CF_BITMAP)
                    761:    {
                    762:       if (!(*lphandle = (HANDLE)GetBitmap (lpobj)))
                    763:          return OLE_ERROR_MEMORY;
                    764:       return OLE_OK; 
                    765:    }
                    766: 
                    767:    if (cfFormat == CF_TEXT) 
                    768:    {
                    769:       if (!(*lphandle = GetText (lpobj)))
                    770:          return OLE_ERROR_MEMORY;
                    771:       return OLE_OK; 
                    772:    }
                    773: 
                    774:    if (cfFormat == cfObjectLink)
                    775:    {
                    776:       if (!(*lphandle = GetLink (lpobj)))
                    777:          return OLE_ERROR_MEMORY;
                    778:       return OLE_OK; 
                    779:    }
                    780: 
                    781:    if (cfFormat ==  cfOwnerLink)
                    782:    {
                    783:       if (!(*lphandle = GetLink (lpobj)))
                    784:          return OLE_ERROR_MEMORY;
                    785:       return OLE_OK; 
                    786:    }
                    787: 
                    788:    return OLE_ERROR_FORMAT;
                    789: }
                    790: 
                    791: 
                    792: 
                    793: /* ObjQueryProtocol                OBJECT "QueryProtocol" METHOD
                    794:  * ----------------
                    795:  *
                    796:  * LPOLEOBJECT lpoleobject - The OLE object
                    797:  * LPSTR lpszProtocol      - The protocol name, either "StdFileEditing"
                    798:  *                           or "StdExecute"
                    799:  * 
                    800:  * RETURNS: If lpszProtocol is supported, return a pointer to an OLEOBJECT 
                    801:  *          structure with an appropriate method table for that protocol.
                    802:  *          Otherwise, return NULL.
                    803:  *
                    804:  * CUSTOMIZATION: Allow any additional protocols your application supports.
                    805:  *
                    806:  *
                    807:  */
                    808: LPVOID  APIENTRY ObjQueryProtocol 
                    809:    (LPOLEOBJECT lpoleobject, LPSTR lpszProtocol)
                    810: {
                    811:    return lstrcmp (lpszProtocol, "StdFileEditing") ? NULL : lpoleobject ;
                    812: }
                    813: 
                    814: 
                    815: 
                    816: /* ObjRelease                OBJECT "Release" METHOD
                    817:  * -----------
                    818:  *
                    819:  * The server application should not destroy data when the library calls the 
                    820:  * ReleaseObj method.
                    821:  * The library calls the ReleaseObj method when no clients are connected 
                    822:  * to the object.
                    823:  *
                    824:  * LPOLEOBJECT lpoleobject - The OLE object
                    825:  * 
                    826:  * RETURNS: OLE_OK
                    827:  * 
                    828:  * CUSTOMIZATION: Re-implement.  Do whatever needs to be done, if anything,
                    829:  *                when no clients are connected to an object.
                    830:  *
                    831:  */
                    832: OLESTATUS  APIENTRY ObjRelease (LPOLEOBJECT lpoleobject)
                    833: {
                    834:    INT i;
                    835:    /* No client is connected to the object so break all assocaiations
                    836:       between clients and the object. */
                    837:    for (i=0; i < clpoleclient; i++)
                    838:       ((LPOBJ)lpoleobject)->lpoleclient[i] = NULL;
                    839:    return OLE_OK;
                    840: }
                    841: 
                    842: 
                    843: 
                    844: /* ObjSetBounds        OBJECT "SetBounds" METHOD
                    845:  * ------------
                    846:  *
                    847:  * This method is called to set new bounds for an object.
                    848:  * The bounds are in HIMETRIC units.
                    849:  * A call to this method is ignored for linked objects because the size of
                    850:  * a linked object depends only on the source file.
                    851:  *
                    852:  * LPOLEOBJECT lpoleobject - The OLE object
                    853:  * LPRECT lprect           - The new bounds
                    854:  * 
                    855:  * RETURNS: OLE_OK
                    856:  *
                    857:  * CUSTOMIZATION: Re-implement
                    858:  *                How an object is sized is application-specific. (Server Demo
                    859:  *                uses MoveWindow.)
                    860:  *
                    861:  */
                    862: OLESTATUS  APIENTRY ObjSetBounds (LPOLEOBJECT lpoleobj, LPRECT lprect)
                    863: {
                    864:    if (docMain.doctype == doctypeEmbedded)
                    865:    {
                    866:       RECT rect = *lprect;
                    867:       LPOBJ lpobj = (LPOBJ) lpoleobj;
                    868:       
                    869:       // the units are in HIMETRIC
                    870:       rect.right   = rect.right - rect.left;
                    871:       rect.bottom  = rect.top - rect.bottom;
1.1.1.2 ! root      872:       HiMetricToDevice ( (LPPOINT) &rect.right);
1.1       root      873:       MoveWindow (lpobj->hwnd, lpobj->native.nX, lpobj->native.nY, 
                    874:                   rect.right + 2 * GetSystemMetrics(SM_CXFRAME), 
                    875:                   rect.bottom + 2 * GetSystemMetrics(SM_CYFRAME), 
                    876:                   TRUE);
                    877:    }
                    878:    return OLE_OK;
                    879: }
                    880: 
                    881: 
                    882: 
                    883: /* ObjSetColorScheme                OBJECT "SetColorScheme" METHOD
                    884:  * -----------------
                    885:  *
                    886:  * The client calls this method to suggest a color scheme (palette) for
                    887:  * the server to use for the object.
                    888:  *
                    889:  * LPOLEOBJECT  lpoleobject       - The OLE object
                    890:  * LPLOGPALETTE lppal             - Suggested palette
                    891:  *
                    892:  * RETURNS: OLE_ERROR_PALETTE if CreatePalette fails, 
                    893:  *          OLE_OK otherwise
                    894:  *
                    895:  * 
                    896:  * CUSTOMIZATION: If your application supports color schemes, then this 
                    897:  *                function is a good example of how to create and store
                    898:  *                a palette.
                    899:  *
                    900:  */
                    901: OLESTATUS  APIENTRY ObjSetColorScheme 
                    902:    (LPOLEOBJECT lpoleobject, LPLOGPALETTE lppal)
                    903: {
                    904:    HPALETTE hpal = CreatePalette (lppal);
                    905:    LPOBJ lpobj   = (LPOBJ) lpoleobject;
                    906: 
                    907:    if (hpal==NULL)
                    908:       return OLE_ERROR_PALETTE;
                    909: 
                    910:    if (lpobj->hpal) 
                    911:       DeleteObject (lpobj->hpal);
                    912:    lpobj->hpal = hpal;
                    913:    return OLE_OK;
                    914: }
                    915: 
                    916: 
                    917: 
                    918: /* ObjSetData                OBJECT "SetData" METHOD
                    919:  * ----------
                    920:  *
                    921:  * This method is used to store data into the object in the specified
                    922:  * format.  This will be called with Native format after an embedded
                    923:  * object has been opened by the Edit method.
                    924:  *
                    925:  * LPOLEOBJECT lpoleobject      - The OLE object
                    926:  * WORD cfFormat                - Data type, i.e., clipboard format
                    927:  * HANDLE hdata                 - Handle to the data.
                    928:  * 
                    929:  * RETURNS:       OLE_OK if the data was stored properly
                    930:  *                OLE_ERROR_FORMAT if format was not cfNative.
                    931:  *                OLE_ERROR_MEMORY if memory could not be locked.
                    932:  * 
                    933:  * CUSTOMIZATION: The large then-clause will need to be re-implemented for
                    934:  *                your application.  You may wish to support additional
                    935:  *                formats besides cfNative.
                    936:  *
                    937:  */
                    938: OLESTATUS  APIENTRY ObjSetData 
                    939:    (LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat, HANDLE hdata)
                    940: {
                    941:     LPNATIVE lpnative;
                    942:     LPOBJ    lpobj;
                    943: 
                    944:     lpobj = (LPOBJ)lpoleobject;
                    945: 
                    946:     if (cfFormat != cfNative)
                    947:     {
                    948:       return OLE_ERROR_FORMAT;
                    949:     }
                    950: 
                    951:     lpnative = (LPNATIVE) GlobalLock (hdata);
                    952: 
                    953:     if (lpnative)
                    954:     {
                    955:         lpobj->native = *lpnative;
                    956:         if (lpobj->aName)
                    957:             GlobalDeleteAtom (lpobj->aName);
                    958:         lpobj->aName = GlobalAddAtom (lpnative->szName);
                    959:         // CreateNewObj made an "Object 1" but we may be changing its number.
                    960:         docMain.rgfObjNums[1] = FALSE;
                    961:         docMain.rgfObjNums [GetObjNum(lpobj)] = TRUE;
                    962: 
                    963:         MoveWindow (lpobj->hwnd, 0, 0,
1.1.1.2 ! root      964: //                    lpobj->native.nWidth + 2 * GetSystemMetrics(SM_CXFRAME), 
        !           965: //                    lpobj->native.nHeight+ 2 * GetSystemMetrics(SM_CYFRAME),
        !           966:                     lpobj->native.nWidth, 
        !           967:                     lpobj->native.nHeight,
        !           968: 
1.1       root      969:                     FALSE);
                    970:         GlobalUnlock (hdata);
                    971:     }
                    972:     // Server is responsible for deleting the data.
                    973:     GlobalFree(hdata);           
                    974:     return lpnative ? OLE_OK : OLE_ERROR_MEMORY;
                    975: }
                    976: 
                    977: 
                    978: 
                    979: /* ObjSetTargetDevice        OBJECT "SetTargetDevice" METHOD
                    980:  * -------------------
                    981:  *
                    982:  * This method is used to indicate the device type that an object
                    983:  * will be rendered on.  It is the server's responsibility to free hdata.
                    984:  *
                    985:  * LPOLEOBJECT lpoleobject - The OLE object
                    986:  * HANDLE hdata            - Handle to memory containing
                    987:  *                           a StdTargetDevice structure
                    988:  * 
                    989:  * RETURNS: OLE_OK
                    990:  * 
                    991:  * CUSTOMIZATION: Implement.  Server Demo currently does not do anything.
                    992:  *
                    993:  */
                    994: OLESTATUS  APIENTRY ObjSetTargetDevice (LPOLEOBJECT lpoleobject, HANDLE hdata)
                    995: {
                    996:     if (hdata == NULL)
                    997:     {
                    998:       // Rendering for the screen is requested.
                    999:     }
                   1000:     else
                   1001:     {
                   1002:       LPSTR lpstd = (LPSTR) GlobalLock (hdata);
                   1003:       // lpstd points to a StdTargetDevice structure.
                   1004:       // Use it to do whatever is appropriate to generate the best results 
                   1005:       // on the specified target device.
                   1006:       GlobalUnlock (hdata);
                   1007:       // Server is responsible for freeing the data.
                   1008:       GlobalFree (hdata);  
                   1009:     }
                   1010:     return OLE_OK;
                   1011: }
                   1012: 
                   1013: 
                   1014: 
                   1015: /* ObjShow                OBJECT "Show" METHOD
                   1016:  * --------
                   1017:  *
                   1018:  * This method is used to display the object.  
                   1019:  * The server application should be activated and brought to the top.
                   1020:  * Also, in a REAL server application, the object should be scrolled
                   1021:  * into view.  The object should be selected.
                   1022:  *
                   1023:  * LPOLEOBJECT lpoleobject - Pointer to the OLE object
                   1024:  * BOOL fTakeFocus         - Should server window get the focus?
                   1025:  * 
                   1026:  * RETURNS:        OLE_OK
                   1027:  *
                   1028:  * 
                   1029:  * CUSTOMIZATION: In your application, the document should be scrolled 
                   1030:  *                to bring the object into view.  Server Demo brings the 
                   1031:  *                object to the front, in case it is a linked object inside a 
                   1032:  *                document with other objects obscuring it.
                   1033:  *
                   1034:  */
                   1035: OLESTATUS  APIENTRY ObjShow (LPOLEOBJECT lpoleobject, BOOL fTakeFocus)
                   1036: {
                   1037:     LPOBJ lpobj;
                   1038:     HWND hwndOldFocus;
                   1039: 
                   1040:     hwndOldFocus = GetFocus();
                   1041:     lpobj = (LPOBJ) lpoleobject;
                   1042:     
                   1043:     if (fTakeFocus)
                   1044:        SetForegroundWindow (lpobj->hwnd);
                   1045: 
                   1046:     ShowWindow(hwndMain, SW_SHOWNORMAL);
                   1047: 
                   1048:     SetFocus (fTakeFocus ? lpobj->hwnd : hwndOldFocus);
                   1049:     return OLE_OK;
                   1050: }
                   1051: 
                   1052: 
                   1053: 
                   1054: /* PaintObj
                   1055:  * ---------
                   1056:  *
                   1057:  * This function is called by the WM_PAINT message to paint an object 
                   1058:  * on the screen.  
                   1059:  *
                   1060:  * HWND hwnd - The object window in which to paint the object
                   1061:  *
                   1062:  * CUSTOMIZATION: Server Demo specific
                   1063:  *
                   1064:  */
                   1065: VOID PaintObj (HWND hwnd)
                   1066: {
                   1067:     LPOBJ       lpobj;
                   1068:     RECT        rc;
                   1069:     HDC         hdc;
                   1070:     PAINTSTRUCT paintstruct;
                   1071: 
                   1072:     BeginPaint (hwnd, &paintstruct);
                   1073:     hdc = GetDC (hwnd);
                   1074: 
                   1075:     lpobj = HwndToLpobj (hwnd);
                   1076:     GetClientRect (hwnd, (LPRECT) &rc);
                   1077: 
                   1078:     DrawObj (hdc, lpobj, rc, dctypeScreen);
                   1079: 
                   1080:     ReleaseDC (hwnd, hdc);
                   1081:     EndPaint (hwnd, &paintstruct);
                   1082: }
                   1083: 
                   1084: 
                   1085: 
                   1086: /* RevokeObj
                   1087:  * ---------
                   1088:  *
                   1089:  * Call OleRevokeObject because the user has destroyed the object.
                   1090:  *
                   1091:  * LPOBJ lpobj - The object which has been destroyed
                   1092:  *
                   1093:  * 
                   1094:  * CUSTOMIZATION: You will only need to call OleRevokeObject once if there
                   1095:  *                is only one LPOLECLIENT in your OBJ structure, which there
                   1096:  *                should be.
                   1097:  *
                   1098:  */
                   1099: VOID RevokeObj (LPOBJ lpobj)
                   1100: {
                   1101:    INT i;
                   1102: 
                   1103:    for (i=0; i< clpoleclient; i++)
                   1104:    {
                   1105:       if (lpobj->lpoleclient[i])
                   1106:          OleRevokeObject (lpobj->lpoleclient[i]);
                   1107:       else 
                   1108:          /* if lpobj->lpoleclient[i]==NULL then there are no more non-NULLs
                   1109:             in the array. */
                   1110:          break;
                   1111:    }
                   1112: }
                   1113: 
                   1114: 
                   1115: 
                   1116: /* SendObjMsg
                   1117:  * ----------
                   1118:  *
                   1119:  * This function sends a message to a specific object.
                   1120:  *
                   1121:  * LPOBJ lpobj   - The object
                   1122:  * WORD wMessage - The message to send
                   1123:  * 
                   1124:  * CUSTOMIZATION: You will only need to call CallBack once if there
                   1125:  *                is only one LPOLECLIENT in your OBJ structure, which there
                   1126:  *                should be.
                   1127:  *
                   1128:  */
                   1129: VOID SendObjMsg (LPOBJ lpobj, WORD wMessage)
                   1130: {
                   1131:    INT i;
                   1132:    for (i=0; i < clpoleclient; i++)
                   1133:    {
                   1134:       if (lpobj->lpoleclient[i])
                   1135:       {
                   1136:          // Call the object's Callback function.
                   1137:          lpobj->lpoleclient[i]->lpvtbl->CallBack 
                   1138:             (lpobj->lpoleclient[i], wMessage, (LPOLEOBJECT) lpobj);
                   1139:       }
                   1140:       else
                   1141:          break;
                   1142:    }
                   1143: }
                   1144: 
                   1145: 
                   1146: 
                   1147: /* SizeObj
                   1148:  * -------
                   1149:  *
                   1150:  * Change the size of an object.
                   1151:  *
                   1152:  * HWND hwnd  - The object's window
                   1153:  * RECT rect  - The requested new size in device units
                   1154:  * BOOL fMove - Should the object be moved? (or just resized?)
                   1155:  *
                   1156:  * CUSTOMIZATION: Server Demo specific
                   1157:  *
                   1158:  */
                   1159: VOID SizeObj (HWND hwnd, RECT rect, BOOL fMove)
                   1160: {
                   1161:    LPOBJ lpobj;
                   1162: 
                   1163:    lpobj = HwndToLpobj (hwnd);
                   1164:    if (fMove)
                   1165:    {
                   1166:       lpobj->native.nX   = rect.left;
                   1167:       lpobj->native.nY   = rect.top;
                   1168:    }
                   1169:    lpobj->native.nWidth  = rect.right  - rect.left;
                   1170:    lpobj->native.nHeight = rect.bottom - rect.top ;
                   1171:    SetHiMetricFields (lpobj);
                   1172:    InvalidateRect (hwnd, (LPRECT)NULL, TRUE);
                   1173:    fDocChanged = TRUE;
                   1174:    if (docMain.doctype == doctypeFromFile)
                   1175:    {
                   1176:       // If object is linked, update it in client now. 
                   1177:       SendObjMsg (lpobj, OLE_CHANGED);
                   1178:    }
                   1179: }

unix.superglobalmegacorp.com

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