Annotation of mstools/samples/ole/clidemo/object.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * object.c - OLE object support routines 
        !             3:  *
        !             4:  * Created by Microsoft Corporation.
        !             5:  * (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved
        !             6:  */
        !             7: 
        !             8: //*** INCLUDES ****
        !             9: 
        !            10: #include <windows.h>                   //* WINDOWS
        !            11: #include <shellapi.h>                  //* SHELL
        !            12: #include <ole.h>                       //* OLE
        !            13: 
        !            14: #include "global.h"                    //* global variables and structures
        !            15: #include "stream.h"                    //* application includes:
        !            16: #include "dialog.h"
        !            17: #include "object.h"
        !            18: #include "clidemo.h"
        !            19: #include "demorc.h"
        !            20: #include "utility.h"
        !            21: #include "register.h"
        !            22: 
        !            23: //*** VARIABLES ***
        !            24: 
        !            25: //*** Globals
        !            26: INT     cOleWait     = 0;
        !            27: 
        !            28: 
        !            29: /***************************************************************************
        !            30:  * CallBack()
        !            31:  *
        !            32:  * This routine will be called whenever an object has been changed, 
        !            33:  * saved, renamed, is being painted, or an  asynchronous operation has 
        !            34:  * completed. This routine is called by the OLE client DLL in the 
        !            35:  * above situations.  A pointer to this function is kept in the client
        !            36:  * vtbl.  It is our obligation as a client application to insure that a
        !            37:  * pointer to this procedure is in the vtbl.
        !            38:  *
        !            39:  * IMMPORTANT: notice that we are posting messages here rather that doing
        !            40:  * the work right away.  Well, this is done to avoid any possibility of
        !            41:  * getting into another dispatch message loop.  A MessageBox woul do this!
        !            42:  *
        !            43:  * Returns int - see below 
        !            44:  *
        !            45:  * The return value is generally ignored, except for these notifications:  
        !            46:  * OLE_QUERY_PAINT and  OLE_QUERY_RETRY. For these two notifications, 
        !            47:  * returning TRUE means continue the current operation(eg painting or retry)
        !            48:  * Returning FALSE means stop the current operation. This is useful as an 
        !            49:  * object which takes a long time to paint can be interrupted in order to 
        !            50:  * perform other operations.
        !            51:  ***************************************************************************/
        !            52: 
        !            53: INT  APIENTRY CallBack(               //* ENTRY:
        !            54:    LPOLECLIENT      lpClient,         //* client application pointer
        !            55:    OLE_NOTIFICATION flags,            //* notification code being sent
        !            56:    LPOLEOBJECT      lpObject          //* OLE object pointer
        !            57: ){                                    //* LOCAL:
        !            58:    APPITEMPTR     pItem;              //* application item pointer
        !            59: 
        !            60:                                  
        !            61:    pItem = (APPITEMPTR)lpClient;
        !            62:    switch (flags) 
        !            63:    {
        !            64:       case OLE_CLOSED:                 //* server has closed
        !            65:          if (!pItem->fVisible)
        !            66:          {
        !            67:             PostMessage(hwndFrame, WM_DELETE, (DWORD)pItem,0L);
        !            68:             Dirty(DOC_UNDIRTY);
        !            69:          }
        !            70:          SetFocus( hwndFrame );
        !            71:          break;
        !            72: 
        !            73:       case OLE_SAVED:                  //* server has saved object
        !            74:       case OLE_CHANGED:                //* object has changes
        !            75:          cOleWait++;
        !            76:          pItem->fServerChangedBounds = pItem->fVisible = TRUE;
        !            77:          PostMessage(pItem->hwnd, WM_CHANGE, NULL, 0L);
        !            78:          break;
        !            79: 
        !            80:       case OLE_RELEASE:                //* notification that an asynchronous
        !            81:          ToggleBlockTimer(FALSE);      //* toggle timer off
        !            82:          if (hRetry)
        !            83:             PostMessage(hRetry,WM_COMMAND,IDCANCEL,0L);
        !            84: 
        !            85:          if (cOleWait)                 //* operation has completed
        !            86:          {
        !            87:             pItem->fRetry = TRUE;
        !            88:             if (!--cOleWait)
        !            89:                Hourglass(FALSE);
        !            90:             Release(pItem);
        !            91:          } 
        !            92:          break;
        !            93: 
        !            94:       case OLE_QUERY_RETRY:          //* Continue retrying.
        !            95:          ToggleBlockTimer(FALSE);    //* toggle timer off
        !            96:          if (!hRetry && pItem->fRetry)
        !            97:             PostMessage(hwndFrame,WM_RETRY,(DWORD)pItem,0L);
        !            98:          return (pItem->fRetry);
        !            99:              
        !           100:       case OLE_QUERY_PAINT:          //* continue repainting
        !           101:          return TRUE;                //* a false return terminates either
        !           102: 
        !           103:         default:
        !           104:             break;
        !           105:     }
        !           106:     return 0;                          //* return value is ignored in 
        !           107:                                        //* most cases, see header
        !           108: }
        !           109: 
        !           110: /***************************************************************************
        !           111:  * Release()
        !           112:  *
        !           113:  * Check for an error on the OLE_RELEASE notification. 
        !           114:  **************************************************************************/
        !           115: 
        !           116: static VOID Release(                   //* ENTRY:
        !           117:    APPITEMPTR     pItem                //* Item pointer
        !           118: ){                                     //* LOCAL:
        !           119:    DWORD wParam;              //* error code parameter
        !           120: 
        !           121:    if ((wParam = OleQueryReleaseError(pItem->lpObject)) == OLE_OK) 
        !           122:       return;
        !           123: 
        !           124:    switch (OleQueryReleaseMethod(pItem->lpObject)) 
        !           125:    {
        !           126:       case OLE_LNKPASTE:
        !           127:          pItem->fVisible = FALSE;
        !           128:          break;
        !           129: 
        !           130:       case OLE_CREATEFROMTEMPLATE:
        !           131:       case OLE_CREATE:
        !           132:          pItem->fVisible = FALSE;
        !           133:          cOleWait++;
        !           134:          PostMessage(hwndFrame, WM_DELETE,(DWORD)pItem,1L);
        !           135:          Dirty(DOC_UNDIRTY);
        !           136:    }
        !           137:                                   //* post a message to the main window
        !           138:                                   //* which will display a message box
        !           139:    PostMessage(hwndFrame,WM_ERROR,wParam,NULL);
        !           140: 
        !           141: }
        !           142: 
        !           143: /***************************************************************************
        !           144:  *  Error()
        !           145:  *
        !           146:  *  This function checks for error conditions
        !           147:  *  generated by OLE API callsFor OLE_WAIT_FOR_RELEASE,
        !           148:  *  we keep track of the number of objects waiting, when
        !           149:  *  this count is zero, it is safe to exit the application.
        !           150:  *
        !           151:  *  Returns OLESTATUS -  0 if OLE_WAIT_FOR_RELEASE or OLE_OK
        !           152:  *                       otherwise the OLESTATUS returned after an action
        !           153:  *                       is taken.
        !           154:  *************************************************************************/
        !           155: 
        !           156: OLESTATUS FAR Error(                   //* ENTRY
        !           157:    OLESTATUS      olestat              //* OLE status
        !           158: ){
        !           159: 
        !           160:    switch (olestat) 
        !           161:    {
        !           162:       case OLE_WAIT_FOR_RELEASE:
        !           163:          if (!cOleWait)
        !           164:             Hourglass(TRUE);
        !           165:          cOleWait++;                   //* increment wait count
        !           166: 
        !           167:       case OLE_OK:
        !           168:          return 0;
        !           169: 
        !           170:       case OLE_ERROR_STATIC:           //* static object
        !           171:          ErrorMessage(W_STATIC_OBJECT);
        !           172:          break;
        !           173: 
        !           174:       case OLE_ERROR_REQUEST_PICT:
        !           175:       case OLE_ERROR_ADVISE_RENAME:
        !           176:       case OLE_ERROR_DOVERB:
        !           177:       case OLE_ERROR_SHOW:
        !           178:       case OLE_ERROR_OPEN:
        !           179:       case OLE_ERROR_NETWORK:
        !           180:       case OLE_ERROR_ADVISE_PICT:
        !           181:       case OLE_ERROR_COMM:             //* Invalid links
        !           182:          InvalidLink();
        !           183:          break;
        !           184: 
        !           185:       case OLE_BUSY:
        !           186:          RetryMessage(NULL,RD_CANCEL);
        !           187: 
        !           188:       default:
        !           189:          break;
        !           190:     }
        !           191:     return olestat;
        !           192: }
        !           193: 
        !           194: 
        !           195: /****************************************************************************
        !           196:  * PreItemCreate()
        !           197:  * 
        !           198:  * This routine allocates an application item structure. A pointer to this 
        !           199:  * structure is passed as the client structure, therefore we need to 
        !           200:  * have a pointer to the vtbl as the first entry. We are doing this 
        !           201:  * to allow acess to the application item information during a OLE
        !           202:  * DLL callback.  This approach simplifies matters.
        !           203:  *
        !           204:  * Returns APPITEMPTR - a pointer to a new application item structure
        !           205:  *                      which can operate as a client structure.
        !           206:  ***************************************************************************/
        !           207: 
        !           208: APPITEMPTR FAR PreItemCreate(          //* ENTRY:
        !           209:    LPOLECLIENT    lpClient,            //* OLE client pointer
        !           210:    BOOL           fShow,               //* show/no-show flag
        !           211:    LHCLIENTDOC    lhcDoc               //* client document handle
        !           212: ){                                     //* LOCAL:
        !           213:    HANDLE         hitem;               //* temp handle for new item
        !           214:    APPITEMPTR     pItem;               //* application item pointer
        !           215: 
        !           216: 
        !           217:    if (hitem = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof(APPITEM)))
        !           218:       if (pItem = (APPITEMPTR)LocalLock(hitem))
        !           219:       {                                //* set the vtbl pointer
        !           220:          pItem->oleclient.lpvtbl     = lpClient->lpvtbl;
        !           221:          pItem->lpObjectUndo         = NULL;
        !           222:          pItem->fVisible             = fShow;
        !           223:          pItem->fServerChangedBounds = FALSE;
        !           224:          pItem->lhcDoc               = lhcDoc;
        !           225: 
        !           226:          return pItem;                 //* SUCCESS return
        !           227:       }
        !           228: 
        !           229:    ErrorMessage(E_FAILED_TO_ALLOC);
        !           230:    return NULL;                        //* ERROR return
        !           231: 
        !           232: }
        !           233: 
        !           234: 
        !           235: /***************************************************************************
        !           236:  * ItemWndProc()
        !           237:  *
        !           238:  * This function handles item window message processing.
        !           239:  * There is an item window for each OLE object. This was done to
        !           240:  * to simplify hit testing and repainting. These windows are child
        !           241:  * windows.
        !           242: 
        !           243:  * returns long - standard child routine
        !           244:  **************************************************************************/
        !           245: 
        !           246: LONG  APIENTRY ItemWndProc(           //* ENTRY:
        !           247:    HWND           hwnd,                //* standard windows parameters
        !           248:    UINT           msg, 
        !           249:    DWORD          wParam, 
        !           250:    LONG           lParam
        !           251: ){                                     //* LOCAL:
        !           252:    static POINT   dragPt;              //* Mouse drag point 
        !           253:    static RECT    dragRect;            //* Mouse drag rectangle 
        !           254:    static BOOL    fCaptured;           //* captured flag
        !           255:    APPITEMPTR     pItem;               //* application item pointer
        !           256:    PAINTSTRUCT    ps;                  //* paint structure
        !           257:    POINT          pt;                  //* point
        !           258:    RECT           rc;                  //* bounding rectangle
        !           259: 
        !           260:    switch (msg) 
        !           261:    {     
        !           262:       case WM_SIZE:
        !           263:          if (pItem = (APPITEMPTR)GetWindowLong(hwnd,0))
        !           264:          {
        !           265:             if (!pItem->fServerChangedBounds && pItem->otObject == OT_EMBEDDED)
        !           266:                ObjSetBounds(pItem);
        !           267:             else
        !           268:                pItem->fServerChangedBounds = FALSE;
        !           269:          }
        !           270:          break;
        !           271: 
        !           272:       case WM_CHANGE:
        !           273:          --cOleWait;
        !           274:          pItem = (APPITEMPTR)GetWindowLong(hwnd,0);
        !           275:          if (!Error(OleQueryBounds(pItem->lpObject, &rc))) 
        !           276:          {
        !           277:             ConvertToClient(&rc);
        !           278: 
        !           279:             SetWindowPos(
        !           280:                hwnd, 
        !           281:                NULL, 
        !           282:                0, 
        !           283:                0,
        !           284:                rc.right - rc.left + 2*GetSystemMetrics(SM_CXFRAME),
        !           285:                rc.bottom - rc.top + 2*GetSystemMetrics(SM_CYFRAME),
        !           286:                SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME
        !           287:             );
        !           288: 
        !           289:             if (!pItem->fNew && !fLoadFile)
        !           290:                ShowNewWindow(pItem);
        !           291:             else
        !           292:                InvalidateRect(hwnd, NULL, TRUE);
        !           293: 
        !           294:             Dirty(DOC_DIRTY);
        !           295:          }
        !           296:          break;
        !           297: 
        !           298:       case WM_NCLBUTTONDOWN:
        !           299:          SetTopItem((APPITEMPTR)GetWindowLong(hwnd,0));
        !           300:          return (DefWindowProc(hwnd, msg, wParam, lParam));
        !           301: 
        !           302:       case WM_PAINT:
        !           303:          BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
        !           304:          GetClientRect(hwnd, &rc);
        !           305:          pItem = (APPITEMPTR)GetWindowLong(hwnd, 0);
        !           306:                                        //* Call OLE draw
        !           307:          Error(OleDraw(pItem->lpObject, ps.hdc, &rc, NULL, NULL));
        !           308: 
        !           309:          EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
        !           310:          break;
        !           311: 
        !           312:       case WM_LBUTTONDBLCLK:           //* execute a verb 
        !           313:          ANY_OBJECT_BUSY;
        !           314:          ExecuteVerb(OLEVERB_PRIMARY,(APPITEMPTR)GetWindowLong(hwnd,0));
        !           315:          break;
        !           316: 
        !           317:       case WM_LBUTTONDOWN:    
        !           318:          GetWindowRect(hwnd, (LPRECT)&dragRect);
        !           319:          ScreenToClient(hwndFrame, (LPPOINT)&dragRect);
        !           320:          ScreenToClient(hwndFrame, (LPPOINT)&dragRect.right);
        !           321: 
        !           322:          dragPt.x = LOWORD(lParam);
        !           323:          dragPt.y = HIWORD(lParam);
        !           324: 
        !           325:          ClientToScreen(hwnd, (LPPOINT)&dragPt);
        !           326:          ScreenToClient(hwndFrame, (LPPOINT)&dragPt);
        !           327: 
        !           328:          SetCapture(hwnd);
        !           329:          fCaptured = TRUE;
        !           330:          SetTopItem((APPITEMPTR)GetWindowLong(hwnd,0));
        !           331:          break;
        !           332: 
        !           333:       case WM_LBUTTONUP:
        !           334:          if (!fCaptured)
        !           335:                 break;
        !           336:          ReleaseCapture();
        !           337:          fCaptured = FALSE;
        !           338:          Dirty(DOC_DIRTY);
        !           339:          break;
        !           340: 
        !           341:       case WM_MOUSEMOVE:
        !           342:          if (!fCaptured)
        !           343:             break;
        !           344:          pt.x = LOWORD(lParam);
        !           345:          pt.y = HIWORD(lParam);
        !           346: 
        !           347:          ClientToScreen(hwnd, (LPPOINT)&pt);
        !           348:          ScreenToClient(hwndFrame, (LPPOINT)&pt);
        !           349: 
        !           350:          OffsetRect(
        !           351:                (LPRECT)&dragRect, 
        !           352:                pt.x - dragPt.x, 
        !           353:                pt.y - dragPt.y
        !           354:          );
        !           355: 
        !           356:          MoveWindow(
        !           357:             hwnd, 
        !           358:             dragRect.left, dragRect.top,
        !           359:             dragRect.right - dragRect.left,
        !           360:             dragRect.bottom - dragRect.top, TRUE
        !           361:          );
        !           362: 
        !           363:          dragPt.x = pt.x;
        !           364:          dragPt.y = pt.y;
        !           365:          break;
        !           366:    
        !           367:       default: 
        !           368:          return (DefWindowProc(hwnd, msg, wParam, lParam));
        !           369:    }
        !           370:    return 0L;
        !           371: 
        !           372: }
        !           373: 
        !           374: /****************************************************************************
        !           375:  * PostItemCreate()
        !           376:  *
        !           377:  * This function creates a child window which will contain the newly 
        !           378:  * created OLE object. A pointer to our item information is stored in the 
        !           379:  * extra bytes of this window. This is where we internally keep track
        !           380:  * of information related to the object as well as the
        !           381:  * pointer to the object for subsequent OLE API calls.  This routine is
        !           382:  * called after an OLE object has been created by the client library.
        !           383:  *
        !           384:  * Returns BOOL - TRUE if application item has been created.
        !           385:  ****************************************************************************/
        !           386: 
        !           387: BOOL FAR PostItemCreate(               //* ENTRY:
        !           388:    LPOLEOBJECT    lpObject,            //* OLE object pointer
        !           389:    LONG           otObject,            //* OLE object type
        !           390:    LPRECT         lprcObject,          //* object bounding rect
        !           391:    APPITEMPTR     pItem                //* application item pointer
        !           392: ){                                     //* LOCAL:
        !           393:    INT            i;                   //* index
        !           394:    RECT           rc;                  //* bounding rectangle
        !           395:    CHAR           pData[OBJECT_LINK_MAX];//* copy of link data
        !           396: 
        !           397:    if (lprcObject)                     //* if the size of the objects
        !           398:       rc = *lprcObject;                //* bounding rectangle is not
        !           399:    else if (OleQueryBounds(lpObject, &rc) == OLE_OK) 
        !           400:       ConvertToClient(&rc);
        !           401:    else 
        !           402:       SetRect(&rc, 0, 0, 0, 0);
        !           403: 
        !           404:    if (!(pItem->hwnd = CreateWindow(   //* Create the child window 
        !           405:          szItemClass, "",
        !           406:          WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_THICKFRAME,
        !           407:          rc.left,rc.top,
        !           408:          rc.right - rc.left + 2 * GetSystemMetrics(SM_CXFRAME),
        !           409:          rc.bottom - rc.top + 2 * GetSystemMetrics(SM_CYFRAME),
        !           410:          hwndFrame, NULL, hInst, NULL
        !           411:    ))) goto Error;
        !           412: 
        !           413:                                        //* in windows extra bytes
        !           414:    SetWindowLong(pItem->hwnd, 0, (LONG)pItem);
        !           415: 
        !           416:    pItem->otObject = otObject;
        !           417:    pItem->lpObject = lpObject;
        !           418:    pItem->fRetry  = TRUE;
        !           419: 
        !           420:    if( pItem->otObject == OT_EMBEDDED )//* if object is embedded tell library
        !           421:    {                                   //* the container name and object name.
        !           422:       UINT  cb=CBOBJNAMEMAX;           //* The name will be the server window title.
        !           423:       CHAR  sz[CBOBJNAMEMAX];          //* when the object is edited.
        !           424: 
        !           425:       OleQueryName(lpObject, (LPSTR)sz, (UINT FAR *)&cb );
        !           426: 
        !           427: 
        !           428:       WaitForObject(pItem);
        !           429:       Error(OleSetHostNames(lpObject, (LPSTR)szAppName, (LPSTR)sz ));
        !           430:       WaitForObject(pItem);
        !           431:    }
        !           432:    else if (pItem->otObject == OT_LINK)//* if the object is linked  
        !           433:    {                                   //* retrieve update options
        !           434: 
        !           435:       WaitForObject(pItem);
        !           436:       if(Error(OleGetLinkUpdateOptions(pItem->lpObject, &pItem->uoObject)))
        !           437:          goto Error;
        !           438:       
        !           439:       if (ObjGetData(pItem,pData))
        !           440:       {
        !           441:          for (i=0; pData[i];i++);      //* Skip past the server name 
        !           442:          pItem->aLinkName = AddAtom(&pData[++i]);
        !           443:       } 
        !           444:       else
        !           445:          pItem->aLinkName = AddAtom("");
        !           446:    }
        !           447:    iObjects++;
        !           448:    Dirty(DOC_DIRTY);
        !           449:                                        //* a user interface recommendations.
        !           450:    return TRUE;                        //* SUCCESS return
        !           451: 
        !           452: Error:                                 //* ERROR Tag
        !           453: 
        !           454:    ErrorMessage(E_FAILED_TO_CREATE_CHILD_WINDOW);
        !           455:    FreeAppItem(pItem);
        !           456:    
        !           457:    return FALSE;                       //* ERROR return
        !           458: 
        !           459: }
        !           460:    
        !           461: /***************************************************************************
        !           462:  * ConvertToClient()
        !           463:  *
        !           464:  * This function will convert to client from himetric.
        !           465:  **************************************************************************/
        !           466: 
        !           467: VOID FAR ConvertToClient(              //* ENTRY:
        !           468:    LPRECT         lprc                 //* pointer to bounding rectangle
        !           469: ){                                     //* LOCAL
        !           470: 
        !           471:    if (!(lprc->left || lprc->top || lprc->right || lprc->bottom))
        !           472:       SetRect(lprc, 0, 0, CXDEFAULT, CYDEFAULT);
        !           473:    else 
        !           474:    {
        !           475:       HDC  hdc      = GetDC(NULL);
        !           476: 
        !           477:       lprc->right  -= lprc->left;
        !           478:       lprc->bottom -= lprc->top ;
        !           479:       lprc->top     = lprc->left = NULL;
        !           480:       
        !           481:       SetMapMode ( hdc, MM_HIMETRIC );
        !           482:       LPtoDP ( hdc, (LPPOINT)&lprc->right, 1 );
        !           483: 
        !           484:       ReleaseDC(NULL, hdc);
        !           485:    }
        !           486: }
        !           487: 
        !           488: /***************************************************************************
        !           489:  * ObjInsert()
        !           490:  * 
        !           491:  * Query the user for object type to insert and insert the new OLE object
        !           492:  ***************************************************************************/
        !           493: 
        !           494: VOID FAR ObjInsert(                    //* ENTRY:
        !           495:    LHCLIENTDOC    lhcDoc,              //* OLE document handle              
        !           496:    LPOLECLIENT    lpClient             //* pointer to OLE client structure
        !           497: ){                                     //* LOCAL:   
        !           498:    LPOLEOBJECT    lpObject;            //* pointer to OLE object 
        !           499:    APPITEMPTR     pItem;               //* item pointer
        !           500:    CHAR           szServerName[CBPATHMAX];//* Class name for OleCreate() 
        !           501:    CHAR           szClassName[CBPATHMAX];//* Class name for OleCreate() 
        !           502:    CHAR           szTmp[CBOBJNAMEMAX]; //* buffer to unique object name 
        !           503:     
        !           504:    if (DialogBoxParam(hInst, MAKEINTRESOURCE(DTCREATE),hwndFrame, 
        !           505:            fnInsertNew, (LONG)((LPSTR)szClassName)) != IDCANCEL)
        !           506:    {
        !           507:       if (pItem = PreItemCreate(lpClient, FALSE, lhcDoc))
        !           508:       {
        !           509:          RegGetClassId(szServerName, szClassName);
        !           510:          pItem->aServer = AddAtom(szServerName);
        !           511:          if ( Error( OleCreate(STDFILEEDITING,(LPOLECLIENT)&(pItem->oleclient), 
        !           512:             (LPSTR)szClassName, lhcDoc,CreateNewUniqueName(szTmp), 
        !           513:             &lpObject,olerender_draw, 0))) 
        !           514:          {
        !           515:             ErrorMessage(E_FAILED_TO_CREATE_OBJECT);
        !           516:             FreeAppItem(pItem);
        !           517:          }
        !           518:          else
        !           519:             PostItemCreate(lpObject, OT_EMBEDDED, NULL, pItem);
        !           520:       }
        !           521:    }  
        !           522: 
        !           523:    FreeProcInstance(lpfnInsertNew);
        !           524: 
        !           525: }
        !           526: 
        !           527: /***************************************************************************
        !           528:  *  ObjDelete()
        !           529:  *
        !           530:  * Delete an OLE object. For this application, all OLE objects 
        !           531:  * are associated with a child window; therefore the window must be 
        !           532:  * destroyed.
        !           533:  *
        !           534:  * NOTE: There is one case when we call OleRelease and the other when
        !           535:  * we call OleDelete.  We call OleRelease when we are deregistering
        !           536:  * a document and OleDelete when removing an object from a document. 
        !           537:  **************************************************************************/
        !           538: 
        !           539: VOID FAR ObjDelete(                    //* ENTRY:
        !           540:    APPITEMPTR     pItem,               //* pointer to application item
        !           541:    BOOL           fDelete              //* delete or release flag
        !           542: ){                                     //* LOCAL:
        !           543: 
        !           544:    if (pItem->lpObjectUndo)
        !           545:    {
        !           546:       Error(OleDelete(pItem->lpObjectUndo));
        !           547:                                        //* wait for asynchronous operation
        !           548:       WaitForObject(pItem);
        !           549:    }
        !           550: 
        !           551:    if (fDelete ? Error(OleDelete(pItem->lpObject)) 
        !           552:                      : Error(OleRelease(pItem->lpObject)))
        !           553:    {
        !           554:       ErrorMessage(E_FAILED_TO_DELETE_OBJECT);
        !           555:       return;                          //* ERROR return
        !           556:    }
        !           557: 
        !           558:    if (pItem->fVisible)
        !           559:    {
        !           560:       ShowWindow(pItem->hwnd, SW_HIDE); 
        !           561:       pItem->fVisible = FALSE;
        !           562:    }
        !           563:                                        //* the operation has to complete
        !           564:    WaitForObject(pItem);               //* before the application structure
        !           565:   
        !           566:    FreeAppItem(pItem); 
        !           567:    iObjects--;
        !           568: 
        !           569: }   
        !           570: 
        !           571: 
        !           572: /***************************************************************************
        !           573:  *  ObjPaste()
        !           574:  *
        !           575:  *  This function obtains an object from the clipboard.
        !           576:  *  Handles both embedded and linked objects. An item window is
        !           577:  *  created for each new object.
        !           578:  *
        !           579:  *  Returns BOOL  - TRUE if object was pasted succesfully.
        !           580:  **************************************************************************/
        !           581: 
        !           582: VOID FAR ObjPaste(                     //* ENTRY:
        !           583:    BOOL           fPaste,              //* Paste/PasteLink flag 
        !           584:    LHCLIENTDOC    lhcDoc,              //* client document handle
        !           585:    LPOLECLIENT    lpClient             //* pointer to client
        !           586: ){                                     //* LOCAL:          
        !           587:    LPOLEOBJECT    lpObject;            //* object pointer
        !           588:    LONG           otObject;            //* object type
        !           589:    APPITEMPTR     pItem;               //* application item pointer
        !           590:    CHAR           szTmp[CBOBJNAMEMAX]; //* temporary object name string
        !           591: 
        !           592:    if (!(pItem = PreItemCreate(lpClient, TRUE, lhcDoc)))
        !           593:       return;                          //* ERROR return
        !           594:        
        !           595:    if (!OpenClipboard(hwndFrame))
        !           596:       goto Error;                      //* ERROR jump
        !           597: 
        !           598: 
        !           599:    if (fPaste)                         //* PASTE the object. 
        !           600:    {                                   //* Try "StdFileEditing" protocol
        !           601:       if (Error(OleCreateFromClip(STDFILEEDITING,(LPOLECLIENT)&(pItem->oleclient),lhcDoc,
        !           602:          CreateNewUniqueName(szTmp),&lpObject, olerender_draw,0))) 
        !           603:       {
        !           604:                                        //* next try "Static" protocol
        !           605:          if (Error(OleCreateFromClip(
        !           606:                   STATICP, (LPOLECLIENT)&(pItem->oleclient), lhcDoc,
        !           607:                   CreateNewUniqueName(szTmp), &lpObject, olerender_draw, 0))) 
        !           608:             goto Error;               //* ERROR jump
        !           609:       }
        !           610:    } 
        !           611:    else 
        !           612:    {                                   //* LINK therefore must be 
        !           613:                                        // "STdFileEditing" protocol
        !           614:         if (Error(OleCreateLinkFromClip(
        !           615:             STDFILEEDITING,(LPOLECLIENT)&(pItem->oleclient), lhcDoc,
        !           616:             CreateNewUniqueName(szTmp), &lpObject, olerender_draw, 0)))
        !           617:             goto Error;                //* ERROR jump
        !           618:    }
        !           619: 
        !           620:    OleQueryType(lpObject, &otObject);
        !           621:    CloseClipboard();
        !           622: 
        !           623:    if (!PostItemCreate(lpObject, otObject, NULL, pItem))
        !           624:       return;                          //* ERROR return
        !           625: 
        !           626:    ShowNewWindow(pItem);
        !           627:    return;                             //* SUCCESS return
        !           628: 
        !           629: 
        !           630: Error:                                 //* TAG Error
        !           631: 
        !           632:    ErrorMessage(E_GET_FROM_CLIPBOARD_FAILED);
        !           633:    CloseClipboard();
        !           634:    FreeAppItem(pItem);
        !           635:    
        !           636:    return;                             //* ERROR return
        !           637: 
        !           638: }
        !           639: 
        !           640: /***************************************************************************
        !           641:  * ObjCopy()
        !           642:  *
        !           643:  * This function places an OLE object on the clipboard via the \
        !           644:  * OleCopyToClipboard() function.
        !           645:  *
        !           646:  * Returns BOOL - TRUE if object successfully placed on clipboard
        !           647:  **************************************************************************/
        !           648: 
        !           649: BOOL FAR ObjCopy(                      //* ENTRY:
        !           650:    APPITEMPTR     pItem                //* pointer to app item
        !           651: ){                                     //* LOCAL:
        !           652:    BOOL           fReturn = TRUE;      //* return value
        !           653:    
        !           654:    if (!OpenClipboard(hwndFrame)) 
        !           655:       return FALSE;                    //* ERROR return
        !           656: 
        !           657:    EmptyClipboard();
        !           658: 
        !           659:    if (Error(OleCopyToClipboard(pItem->lpObject)))
        !           660:       fReturn = FALSE;                 //* prepare for ERROR out
        !           661: 
        !           662:    CloseClipboard();
        !           663:    return fReturn;                     //* ERROR or SUCCESS
        !           664: 
        !           665: }
        !           666: 
        !           667: /***************************************************************************
        !           668:  *  ObjCreateFromTemplate()
        !           669:  *
        !           670:  *  Creates an embedded object from file.
        !           671:  **************************************************************************/
        !           672: 
        !           673: VOID FAR ObjCreateFromTemplate(        //* ENTRY:
        !           674:    LHCLIENTDOC    lhcDoc,              //* client document handle
        !           675:    LPOLECLIENT    lpClient             //* client vtbl. pointer
        !           676: ){                                     //* LOCAL:
        !           677:    LPOLEOBJECT    lpObject;            //* OLE object pointer
        !           678:    APPITEMPTR     pItem;               //* application item pointer
        !           679:    CHAR           szTmp[CBOBJNAMEMAX]; //* temporary object name string
        !           680:    CHAR           szFileName[CBPATHMAX];//* file name string
        !           681: 
        !           682:    *szFileName = NULL;
        !           683: 
        !           684:    if (!OfnGetName(hwndFrame, szFileName, IDM_INSERTFILE))
        !           685:       return;                          //* ERROR operation aborted by user
        !           686: 
        !           687:    if (!(pItem = PreItemCreate(lpClient, FALSE, lhcDoc)))
        !           688:       return;                          //* ERROR
        !           689:              
        !           690:    if (Error(OleCreateFromTemplate(STDFILEEDITING, (LPOLECLIENT)pItem, szFileName,
        !           691:          lhcDoc, CreateNewUniqueName(szTmp), &lpObject, olerender_draw, 0)))
        !           692:    {
        !           693:       ErrorMessage(E_CREATE_FROM_TEMPLATE);
        !           694:       FreeAppItem(pItem);
        !           695:       return;                          //* ERROR
        !           696:    }
        !           697: 
        !           698:    PostItemCreate(lpObject, OT_EMBEDDED, NULL, pItem);
        !           699: 
        !           700: }                                      //* SUCCESS
        !           701: 
        !           702: 
        !           703: /****************************************************************************
        !           704:  * ObjGetData()
        !           705:  * 
        !           706:  * Get the object link data.  The data that is retrieved from OLE is copied
        !           707:  * into lpLinkData if lpLinkData is not NULL.  Otherwise, space is dynamically
        !           708:  * allocated or reallocated; space is allocated if pItem->lpLinkData is NULL
        !           709:  * otherwise the pointer is reallocated. The data is returned is freed if
        !           710:  * there has been an OLE_WARN_DELETE_DATA error.
        !           711:  ***************************************************************************/
        !           712: 
        !           713: BOOL FAR ObjGetData(                   //* ENTRY:
        !           714:    APPITEMPTR     pItem,               //* OLE object
        !           715:    LPSTR          lpLinkData           //* pointer to linkdata
        !           716: ){                                     //* LOCAL:
        !           717:    HANDLE         hData;               //* handle to OLE link data 
        !           718:    LPSTR          lpData;              //* pointer to OLE link data
        !           719:    LPSTR          lpWork;              //* copy of OLE link data
        !           720:    BOOL           fFree = FALSE;       //* free OLE memory flag
        !           721:    LONG           lSize;               //* size of OLE link data
        !           722:    INT            i;
        !           723:    
        !           724:    switch (Error(OleGetData(pItem->lpObject, 
        !           725:       (OLECLIPFORMAT)(pItem->otObject == OT_LINK ? vcfLink : vcfOwnerLink), &hData)))
        !           726:    {
        !           727:       case OLE_WARN_DELETE_DATA:
        !           728:          fFree = TRUE;
        !           729:       case OLE_OK:
        !           730:          if(lpData = GlobalLock(hData))
        !           731:          {
        !           732:                                        //* copy the link data to new buffer
        !           733:             lSize=SizeOfLinkData(lpData);
        !           734:             
        !           735:             if (!lpLinkData)
        !           736:             {
        !           737:                if (!pItem->lpLinkData)  //* allocate
        !           738:                   AllocLinkData(pItem,lSize);
        !           739:                else                     //* otherwise reallocate
        !           740:                   ReallocLinkData(pItem,lSize);
        !           741:                lpWork = pItem->lpLinkData;
        !           742:             }
        !           743:             else
        !           744:                lpWork = lpLinkData;
        !           745: 
        !           746:             if (lpWork)
        !           747:                for (i=0L; i<(INT)lSize; i++)     
        !           748:                   *(lpWork+i)=*(lpData+i);
        !           749: 
        !           750:             GlobalUnlock(hData);       //* free the linked data as needed
        !           751:             if (fFree)
        !           752:                GlobalFree(hData);
        !           753: 
        !           754:             return TRUE;               //* SUCCESS      
        !           755:          }
        !           756:       default:
        !           757:          return FALSE;                 //* FAILURE
        !           758:    }   
        !           759: 
        !           760: }
        !           761: 
        !           762: /***************************************************************************
        !           763:  * ObjChangeLink()
        !           764:  *
        !           765:  * Change the linkdata.  This routine will change the document portion of
        !           766:  * link data to lpDoc.  The old linkdata is expected to be in 
        !           767:  * lpaItem->lpLinkData    
        !           768:  **************************************************************************/
        !           769: 
        !           770: VOID FAR ObjChangeLinkData(            //* ENTRY:
        !           771:    APPITEMPTR     pItem,               //* OLE object   
        !           772:    LPSTR          lpDoc                //* document name
        !           773: ){                                     //* LOCAL:
        !           774:    LONG           lSize;               //* used to link data size
        !           775:    LPSTR          lpLinkData;          //* OLE link data pointer
        !           776:    static CHAR    pWork[OBJECT_LINK_MAX]; //* used to construct new link data
        !           777:    INT            i;                   //* index
        !           778:   
        !           779:    pItem->aLinkName = AddAtom(lpDoc);
        !           780: 
        !           781:    for (
        !           782:       lpLinkData = pItem->lpLinkData, i=0; 
        !           783:       pWork[i] = *lpLinkData; 
        !           784:       lpLinkData++, i++
        !           785:    );
        !           786:                                        //* into working buffer.
        !           787:    lstrcpy((LPSTR)&pWork[++i],lpDoc);  //* copy new document name. 
        !           788:                                       
        !           789:    for (; pWork[i]; i++);              //* skip to end of document name
        !           790:    for (++lpLinkData;*lpLinkData;lpLinkData++);
        !           791:                                        //* copy item name.
        !           792:    lstrcpy((LPSTR)&pWork[++i],++lpLinkData);
        !           793:    for (; pWork[i]; i++);              //* skip to end of buffer
        !           794:                                        //* which is the end of item info.
        !           795:    pWork[++i] = NULL;                  //* add extra null.
        !           796: 
        !           797:    lSize = SizeOfLinkData(pWork);      //* reallocate space so there is 
        !           798:    ReallocLinkData(pItem,lSize);       //* a properly sized block of info
        !           799:                                        //* to send the linked data to the
        !           800:    if (lpLinkData = pItem->lpLinkData) //* OLE DLL.
        !           801:       for (i=0; i<(INT)lSize; i++)     //* copy new linkdata into this space
        !           802:          *lpLinkData++ = pWork[i];
        !           803:    else
        !           804:       return;                          //* ERROR return
        !           805:     
        !           806:    Error(OleSetData(pItem->lpObject, vcfLink, GlobalHandle(pItem->lpLinkData)));
        !           807:       
        !           808: }                                      //* SUCCESS return
        !           809: 
        !           810: /****************************************************************************
        !           811:  * ObjSaveUndo()
        !           812:  *
        !           813:  * Clone the OLE object so that any changes to object can be undone if the
        !           814:  * user choses to exit without update.                                        
        !           815:  ***************************************************************************/
        !           816:   
        !           817: VOID FAR ObjSaveUndo(                  //* ENTRY:
        !           818:    APPITEMPTR     pItem                //* application item
        !           819: ){                                     //* LOCAL:
        !           820:    CHAR           szTmp[CBOBJNAMEMAX]; //* holder of object name
        !           821:    LPSTR          lpClone;             //* pointer to clond object name
        !           822:    UINT           i=CBOBJNAMEMAX;
        !           823: 
        !           824:    if (!pItem->lpObjectUndo)
        !           825:    {
        !           826:       OleQueryName(pItem->lpObject, szTmp, &i);
        !           827:                                        //* give clone a unique name by 
        !           828:                                        //* altering object name prefix.
        !           829:       for (lpClone = OBJCLONE, i=0; *lpClone; szTmp[i++] = *lpClone++);  
        !           830: 
        !           831:       if (Error(OleClone(pItem->lpObject, (LPOLECLIENT)pItem,
        !           832:          pItem->lhcDoc, szTmp, &(pItem->lpObjectUndo))))
        !           833:       return;                          //* ERROR return
        !           834: 
        !           835:       pItem->otObjectUndo  = pItem->otObject;
        !           836:       pItem->uoObjectUndo  = pItem->uoObject;
        !           837:       pItem->aLinkUndo     = pItem->aLinkName;
        !           838: 
        !           839:       GetClientRect(pItem->hwnd, &pItem->rect);
        !           840: 
        !           841:       if (OleQueryOpen(pItem->lpObject) == OLE_OK)
        !           842:          pItem->fOpen = TRUE;
        !           843:       
        !           844:    }
        !           845: 
        !           846: }                                      //* SUCCESS return
        !           847: 
        !           848: /****************************************************************************
        !           849:  * ObjUndo()
        !           850:  *
        !           851:  * Restore an object to its state before changes.  The lpObject Undo is a 
        !           852:  * clone to the original object with a different name, therefore, all we
        !           853:  * have to do is rename that object and ditch the changed object.
        !           854:  ***************************************************************************/
        !           855:   
        !           856: VOID FAR ObjUndo(                      //* ENTRY:
        !           857:    APPITEMPTR     pItem                //* application item
        !           858: ){                                     //* LOCAL:
        !           859:    CHAR           szTmp[CBOBJNAMEMAX]; //* object name holder
        !           860:    UINT           i = CBOBJNAMEMAX;
        !           861:    
        !           862:    OleQueryName(pItem->lpObject, szTmp, &i);
        !           863:    if (Error(OleDelete(pItem->lpObject)))
        !           864:       return;                          //* ERROR return
        !           865:                                        //* reset app item vars
        !           866:    pItem->lpObject      = pItem->lpObjectUndo;      
        !           867:    pItem->otObject      = pItem->otObjectUndo;
        !           868:    pItem->uoObject      = pItem->uoObjectUndo;
        !           869:    pItem->aLinkName     = pItem->aLinkUndo;
        !           870:    pItem->lpObjectUndo  = (LPOLEOBJECT)NULL;
        !           871:    pItem->otObjectUndo  = (LONG)NULL;
        !           872: 
        !           873:    if (Error(OleRename(pItem->lpObject,szTmp)))
        !           874:       return;                          //* ERROR return
        !           875: 
        !           876:    if (pItem->fOpen)
        !           877:    {
        !           878:       Error(OleReconnect(pItem->lpObject));
        !           879:       pItem->fOpen = FALSE;
        !           880:    }
        !           881: 
        !           882:    SetWindowPos(
        !           883:       pItem->hwnd, 
        !           884:       NULL, 0, 0,
        !           885:       pItem->rect.right - pItem->rect.left + 2*GetSystemMetrics(SM_CXFRAME),
        !           886:       pItem->rect.bottom - pItem->rect.top + 2*GetSystemMetrics(SM_CYFRAME),
        !           887:       SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME
        !           888:    );
        !           889: 
        !           890:    InvalidateRect(pItem->hwnd,NULL,TRUE);
        !           891: 
        !           892: }                                      //* SUCCESS return
        !           893: 
        !           894: 
        !           895: /****************************************************************************
        !           896:  * ObjDelUndo()
        !           897:  *
        !           898:  * Delete the undo object if the user is happy with the changes he/she made.
        !           899:  ***************************************************************************/
        !           900: 
        !           901: VOID FAR ObjDelUndo(                   //* ENTRY:
        !           902:    APPITEMPTR     pItem                //* application item
        !           903: ){
        !           904: 
        !           905:    if (Error(OleDelete(pItem->lpObjectUndo)))
        !           906:       return;                          //* ERROR return
        !           907: 
        !           908:    pItem->lpObjectUndo = (LPOLEOBJECT)NULL;
        !           909:    pItem->otObjectUndo = (LONG)NULL;
        !           910:    DeleteAtom(pItem->aLinkUndo);
        !           911:    pItem->lpObjectUndo = NULL;
        !           912:    
        !           913: }                                      //* SUCCESS return
        !           914: 
        !           915: /****************************************************************************
        !           916:  * ObjFreeze()
        !           917:  *
        !           918:  * Convert an object to a static object.
        !           919:  ***************************************************************************/
        !           920:   
        !           921: VOID FAR ObjFreeze(                    //* ENTRY:
        !           922:    APPITEMPTR     pItem                //* application item
        !           923: ){                                     //* LOCAL:
        !           924:    CHAR           szTmp[CBOBJNAMEMAX]; //* temporary object name
        !           925:    LPSTR          lpTemp;              //* temporary prefix string
        !           926:    LPOLEOBJECT    lpObjectTmp;         //* temporary object pointer
        !           927:    UINT           i=CBOBJNAMEMAX;
        !           928:        
        !           929:    OleQueryName(pItem->lpObject, szTmp, &i);
        !           930:                                        //* create a unique name by changing 
        !           931:                                        //* the object name prefix
        !           932:    for (lpTemp = OBJTEMP, i=0; *lpTemp; szTmp[i++] = *lpTemp++);  
        !           933: 
        !           934:                                        //* this API creates a static object
        !           935:    if (Error(OleObjectConvert(pItem->lpObject, STATICP, (LPOLECLIENT)pItem,
        !           936:       pItem->lhcDoc, szTmp, &lpObjectTmp)))
        !           937:       return;
        !           938:                                        //* delete old object
        !           939:    if (Error(OleDelete(pItem->lpObject)))
        !           940:       return;
        !           941: 
        !           942:    WaitForObject(pItem);  
        !           943: 
        !           944:    pItem->lpObject = lpObjectTmp;
        !           945:    pItem->otObject = OT_STATIC;
        !           946:    pItem->uoObject = -1L;
        !           947: 
        !           948:    for (lpTemp = OBJPREFIX, i=0; *lpTemp; szTmp[i++] = *lpTemp++);  
        !           949:    if (Error(OleRename(pItem->lpObject,szTmp)))
        !           950:       return;
        !           951:    
        !           952:    
        !           953: }
        !           954: 
        !           955: /***************************************************************************
        !           956:  *  ObjCreateWrap()
        !           957:  *
        !           958:  * Create a wrapped object from the drag and drop feature of the 3.1 shell.
        !           959:  * NOTE: We are assuming that only one file has been dropped.  See the SDK
        !           960:  * documentation for instructions on how to deal with multiple files.
        !           961:  ***************************************************************************/
        !           962: 
        !           963: VOID FAR ObjCreateWrap(                //* ENTRY:
        !           964:    HANDLE         hdrop,               //* handle to dropped object
        !           965:    LHCLIENTDOC    lhcDoc,              //* document handle
        !           966:    LPOLECLIENT    lpClient             //* pointer to client structure
        !           967: ){                                     //* LOCAL:
        !           968:    CHAR           szDragDrop[CBPATHMAX];//* Drag and drop file name 
        !           969:    LPOLEOBJECT    lpObject;            //* pointer to OLE object 
        !           970:    POINT          pt;                  //* position of dropped object
        !           971:    RECT           rc;                  //* object size and position 
        !           972:    CHAR           szTmp[CBOBJNAMEMAX]; //* buffer for unique object name 
        !           973:    APPITEMPTR     pItem;               //* application item pointer
        !           974:    INT            x,y;                 //* icon sizes
        !           975:       
        !           976:    x = GetSystemMetrics(SM_CXICON) / 2;
        !           977:    y = GetSystemMetrics(SM_CYICON) / 2;
        !           978:                                        //* Get the drag and drop filename
        !           979:                                        //* position 
        !           980:    DragQueryPoint(hdrop, &pt);
        !           981:    DragQueryFile(hdrop, 0, szDragDrop, CBPATHMAX);
        !           982:    DragFinish(hdrop);
        !           983: 
        !           984:    SetRect(&rc, pt.x - x, pt.y - y, pt.x + x, pt.y + y);
        !           985: 
        !           986:    if (!(pItem = PreItemCreate(lpClient, TRUE, lhcDoc)))
        !           987:       return;                          //* ERROR return
        !           988:                                        //* create OLE object
        !           989:    if (Error(OleCreateFromFile(STDFILEEDITING, (LPOLECLIENT)pItem, 
        !           990:          "Package", szDragDrop, lhcDoc, CreateNewUniqueName(szTmp), 
        !           991:          &lpObject, olerender_draw, 0)))
        !           992:    {
        !           993:       ErrorMessage(E_FAILED_TO_CREATE_OBJECT);
        !           994:       FreeAppItem(pItem);
        !           995:       return;                          //* ERROR return
        !           996:    }
        !           997: 
        !           998:    if (PostItemCreate(lpObject, OT_EMBEDDED, &rc, pItem))    
        !           999:       ShowNewWindow(pItem);
        !          1000:    
        !          1001: }                                      //* SUCCESS return
        !          1002: 
        !          1003: /***************************************************************************
        !          1004:  *  UpdateObjectMenuItem()
        !          1005:  *
        !          1006:  *  Add an object popup menu for the chosen object if multiple verbs exist.
        !          1007:  *  The registration system is used to determine which verbs exist for the
        !          1008:  *   given object. 
        !          1009:  **************************************************************************/
        !          1010: 
        !          1011: VOID FAR UpdateObjectMenuItem(         //* ENTRY:
        !          1012:    HMENU       hMenu                   //* main menu
        !          1013: ){                                     //* LOCAL
        !          1014:    INT         cVerbs;                 //* verb
        !          1015:    APPITEMPTR  pItem;                  //* application item ponter
        !          1016:    DWORD       dwSize = KEYNAMESIZE;
        !          1017:    CHAR        szClass[KEYNAMESIZE], szBuffer[200];
        !          1018:    CHAR        szVerb[KEYNAMESIZE];
        !          1019:    HMENU       hPopupNew=NULL;
        !          1020:    HKEY        hkeyTemp;
        !          1021:    CHAR        pLinkData[OBJECT_LINK_MAX];
        !          1022:                                        //* delete current item and submenu 
        !          1023:    DeleteMenu(hMenu, POS_OBJECT, MF_BYPOSITION );
        !          1024:    
        !          1025:    if (!(pItem = GetTopItem()) )
        !          1026:       goto Error;                      //* ERROR jump
        !          1027:    else if (!pItem->fVisible)
        !          1028:       goto Error;                      //* ERROR jump
        !          1029:                                        //* if STATIC ?
        !          1030:    if ((pItem->otObject != OT_EMBEDDED) && (pItem->otObject != OT_LINK)) 
        !          1031:       goto Error;                      //* ERROR jump
        !          1032: 
        !          1033:    if (!ObjGetData(pItem, pLinkData))  //* get linkdata as key reg database
        !          1034:       goto Error;                      //* ERROR jump
        !          1035:                                        //* open reg database   
        !          1036:    szClass[0] = NULL;
        !          1037:    if (RegOpenKey(HKEY_CLASSES_ROOT, szClass, &hkeyTemp)) 
        !          1038:       goto Error;                      //* ERROR jump
        !          1039:                                        //* check if class is reg-db
        !          1040:    if (RegQueryValue(HKEY_CLASSES_ROOT, pLinkData, szClass, &dwSize))
        !          1041:    {
        !          1042:       RegCloseKey(hkeyTemp);
        !          1043:       goto Error;                      //* ERROR jump    
        !          1044:    }
        !          1045: 
        !          1046:    for (cVerbs=0; ;++cVerbs)           //* extract all verbs from reg-db
        !          1047:    {
        !          1048:       dwSize = KEYNAMESIZE;
        !          1049:       wsprintf(szBuffer, "%s\\protocol\\StdFileEditing\\verb\\%d",
        !          1050:                                      (LPSTR)pLinkData,cVerbs);
        !          1051: 
        !          1052:       if (RegQueryValue(HKEY_CLASSES_ROOT, szBuffer, szVerb, &dwSize))
        !          1053:          break;
        !          1054: 
        !          1055:       if (!hPopupNew)
        !          1056:          hPopupNew = CreatePopupMenu();
        !          1057: 
        !          1058:       InsertMenu(hPopupNew, (UINT)-1, MF_BYPOSITION, IDM_VERBMIN+cVerbs, szVerb);
        !          1059:    }
        !          1060: 
        !          1061:    //* NOTE: For International versions the following  verb menu
        !          1062:    //* may need to be formatted differently.
        !          1063: 
        !          1064:    switch (cVerbs)                     //* determine how many verbs found
        !          1065:    {
        !          1066:       case 0:                          //* none
        !          1067:          wsprintf(szBuffer, "Edit %s %s", (LPSTR)szClass, (LPSTR)"&Object");
        !          1068:          InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION, IDM_VERBMIN, szBuffer);
        !          1069:          break;
        !          1070: 
        !          1071:       case 1:                          //* one
        !          1072:          wsprintf(szBuffer, "%s %s %s", (LPSTR)szVerb, (LPSTR)szClass, 
        !          1073:             (LPSTR)"&Object");
        !          1074:          DestroyMenu(hPopupNew);
        !          1075:          InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION, IDM_VERBMIN, szBuffer);
        !          1076:          break;
        !          1077: 
        !          1078:      default:                          //* > 1
        !          1079:          wsprintf(szBuffer, "%s %s", (LPSTR)szClass, (LPSTR)"&Object");
        !          1080:          InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION | MF_POPUP, (UINT)hPopupNew, szBuffer);
        !          1081:          EnableMenuItem(hMenu, POS_OBJECT, MF_ENABLED|MF_BYPOSITION);
        !          1082:          break;           
        !          1083:    }
        !          1084: 
        !          1085:    RegCloseKey(hkeyTemp);              //* close reg-db
        !          1086:    return;                             //* SUCCESS return
        !          1087: 
        !          1088: Error:                                 //* ERROR tag
        !          1089:    InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION, NULL, "&Object");
        !          1090:    EnableMenuItem(hMenu, POS_OBJECT, MF_GRAYED | MF_BYPOSITION);
        !          1091: 
        !          1092: }                                      //* ERROR return
        !          1093: 
        !          1094: /***************************************************************************
        !          1095:  *  ExecuteVerb()
        !          1096:  *
        !          1097:  *  Execute the verb for the given object.
        !          1098:  ***************************************************************************/
        !          1099: 
        !          1100: VOID FAR ExecuteVerb(                  //* ENTRY:
        !          1101:    UINT iVerb,                          //* verb
        !          1102:    APPITEMPTR pItem                    //* application item pointer
        !          1103: ){                                     //* LOCAL
        !          1104:    RECT        rc;                     //* holds client area bounding rect
        !          1105: 
        !          1106:    if (pItem->otObject == OT_STATIC)   //* if the object is static beep
        !          1107:    {
        !          1108:       ErrorMessage(W_STATIC_OBJECT);
        !          1109:       return;                          //* return
        !          1110:    }
        !          1111:                                        //* get cliet area rectangle
        !          1112:    GetClientRect(hwndFrame, (LPRECT)&rc);
        !          1113:                                        //* execute OLE verb
        !          1114:    if (Error(OleActivate(pItem->lpObject, iVerb, TRUE, TRUE, hwndFrame, &rc))) 
        !          1115:       return;
        !          1116:   
        !          1117:    WaitForObject(pItem);               //* wait for async. operation
        !          1118: 
        !          1119:    ObjSetBounds(pItem);
        !          1120:  
        !          1121: 
        !          1122: }                                      //* SUCCESS return
        !          1123: 
        !          1124: /****************************************************************************
        !          1125:  * ObjSetBounds
        !          1126:  *
        !          1127:  * Set the object bounds.  The object bounds are the child windos bounding
        !          1128:  * rectangle.  OLE servers recieve need the bounding rectangle in HIMETRIC
        !          1129:  * coordinates.  So, we convert from screen coordinates to HIMETRIC.
        !          1130:  *
        !          1131:  * Returns BOOL - TRUE if successful.
        !          1132:  ***************************************************************************/
        !          1133: 
        !          1134: BOOL FAR ObjSetBounds(                 //* ENTRY:
        !          1135:    APPITEMPTR     pItem                //* application item pointer 
        !          1136: ){                                     //* LOCAL:
        !          1137:    RECT           itemRect;            //* bounding rectangle
        !          1138:    HDC            hdc;
        !          1139: 
        !          1140:    GetWindowRect(pItem->hwnd,&itemRect);//* get item window react
        !          1141: 
        !          1142:    itemRect.right  = ( itemRect.right  - itemRect.left ) - 2 * GetSystemMetrics(SM_CXFRAME);
        !          1143:    itemRect.bottom = ( itemRect.bottom - itemRect.top  ) - 2 * GetSystemMetrics(SM_CYFRAME);
        !          1144:    itemRect.top    = NULL;
        !          1145:    itemRect.left   = NULL;
        !          1146: 
        !          1147:    hdc = GetDC(NULL);
        !          1148:    SetMapMode(hdc,MM_HIMETRIC);
        !          1149: 
        !          1150:    DPtoLP(hdc,(LPPOINT)&itemRect.right,1);
        !          1151: 
        !          1152:    ReleaseDC(NULL,hdc);
        !          1153:                                        //* set the rect for the server
        !          1154:    if (Error(OleSetBounds(pItem->lpObject,(LPRECT)&itemRect)))
        !          1155:       return FALSE;                    //* ERROR return
        !          1156: 
        !          1157:    WaitForObject(pItem);               //* wait for async. operation
        !          1158:    return TRUE;                        //* SUCCESS return
        !          1159: 
        !          1160: }

unix.superglobalmegacorp.com

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