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

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

unix.superglobalmegacorp.com

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