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

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

unix.superglobalmegacorp.com

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