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

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

unix.superglobalmegacorp.com

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