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

1.1.1.3 ! root        1: /*
        !             2:  * object.c - OLE object support routines
1.1       root        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.3 ! root       23: #define HIMETRIC_PER_INCH       2540
1.1.1.2   root       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:  *
1.1.1.3 ! root       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
1.1       root       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:  *
1.1.1.3 ! root       49:  * Returns int - see below
1.1       root       50:  *
1.1.1.3 ! root       51:  * The return value is generally ignored, except for these notifications:
        !            52:  * OLE_QUERY_PAINT and  OLE_QUERY_RETRY. For these two notifications,
1.1       root       53:  * returning TRUE means continue the current operation(eg painting or retry)
1.1.1.3 ! root       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
1.1       root       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: 
1.1.1.3 ! root       66: 
1.1       root       67:    pItem = (APPITEMPTR)lpClient;
1.1.1.3 ! root       68:    switch (flags)
1.1       root       69:    {
                     70:       case OLE_CLOSED:                 //* server has closed
                     71:          if (!pItem->fVisible)
                     72:          {
1.1.1.3 ! root       73:             PostMessage(hwndFrame, WM_DELETE, 0L, (DWORD)pItem);
1.1       root       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;
1.1.1.3 ! root       83:          PostMessage(pItem->hwnd, WM_CHANGE, 0, 0L);
1.1       root       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);
1.1.1.3 ! root       97:          }
1.1       root       98:          break;
                     99: 
                    100:       case OLE_QUERY_RETRY:          //* Continue retrying.
                    101:          ToggleBlockTimer(FALSE);    //* toggle timer off
                    102:          if (!hRetry && pItem->fRetry)
1.1.1.3 ! root      103:             PostMessage(hwndFrame,WM_RETRY,0L, (DWORD)pItem);
1.1       root      104:          return (pItem->fRetry);
1.1.1.3 ! root      105: 
1.1       root      106:       case OLE_QUERY_PAINT:          //* continue repainting
                    107:          return TRUE;                //* a false return terminates either
                    108: 
                    109:         default:
                    110:             break;
                    111:     }
1.1.1.3 ! root      112:     return 0;                          //* return value is ignored in
1.1       root      113:                                        //* most cases, see header
                    114: }
                    115: 
                    116: /***************************************************************************
                    117:  * Release()
                    118:  *
1.1.1.3 ! root      119:  * Check for an error on the OLE_RELEASE notification.
1.1       root      120:  **************************************************************************/
                    121: 
                    122: static VOID Release(                   //* ENTRY:
                    123:    APPITEMPTR     pItem                //* Item pointer
                    124: ){                                     //* LOCAL:
                    125:    DWORD wParam;              //* error code parameter
                    126: 
1.1.1.3 ! root      127:    if ((wParam = OleQueryReleaseError(pItem->lpObject)) == OLE_OK)
1.1       root      128:       return;
                    129: 
1.1.1.3 ! root      130:    switch (OleQueryReleaseMethod(pItem->lpObject))
1.1       root      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++;
1.1.1.3 ! root      140:          PostMessage(hwndFrame, WM_DELETE,1L, (DWORD)pItem);
1.1       root      141:          Dirty(DOC_UNDIRTY);
                    142:    }
                    143:                                   //* post a message to the main window
                    144:                                   //* which will display a message box
1.1.1.3 ! root      145:    PostMessage(hwndFrame,WM_ERROR,wParam,0);
1.1       root      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: 
1.1.1.3 ! root      166:    switch (olestat)
1.1       root      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()
1.1.1.3 ! root      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
1.1       root      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
1.1.1.3 ! root      254:    UINT           msg,
        !           255:    DWORD          wParam,
1.1       root      256:    LONG           lParam
                    257: ){                                     //* LOCAL:
1.1.1.3 ! root      258:    static POINT   dragPt;              //* Mouse drag point
        !           259:    static RECT    dragRect;            //* Mouse drag rectangle
1.1       root      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: 
1.1.1.3 ! root      267:    switch (msg)
        !           268:    {
1.1       root      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);
1.1.1.3 ! root      282:          if (!Error(OleQueryBounds(pItem->lpObject, &rc)))
1.1       root      283:          {
                    284:             ConvertToClient(&rc);
                    285: 
                    286:             SetWindowPos(
1.1.1.3 ! root      287:                hwnd,
        !           288:                NULL,
        !           289:                0,
1.1       root      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: 
1.1.1.3 ! root      319:       case WM_LBUTTONDBLCLK:           //* execute a verb
1.1       root      320:          ANY_OBJECT_BUSY;
                    321:          ExecuteVerb(OLEVERB_PRIMARY,(APPITEMPTR)GetWindowLong(hwnd,0));
                    322:          break;
                    323: 
1.1.1.3 ! root      324:       case WM_LBUTTONDOWN:
1.1       root      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);
1.1.1.3 ! root      353: 
1.1       root      354:          ClientToScreen(hwnd, (LPPOINT)&pt);
                    355:          ScreenToClient(hwndFrame, (LPPOINT)&pt);
                    356: 
                    357:          OffsetRect(
1.1.1.3 ! root      358:                (LPRECT)&dragRect,
        !           359:                pt.x - dragPt.x,
1.1       root      360:                pt.y - dragPt.y
                    361:          );
                    362: 
                    363:          MoveWindow(
1.1.1.3 ! root      364:             hwnd,
1.1       root      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;
1.1.1.3 ! root      373: 
        !           374:       default:
1.1       root      375:          return (DefWindowProc(hwnd, msg, wParam, lParam));
                    376:    }
                    377:    return 0L;
                    378: 
                    379: }
                    380: 
                    381: /****************************************************************************
                    382:  * PostItemCreate()
                    383:  *
1.1.1.3 ! root      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
1.1       root      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
1.1.1.3 ! root      406:    else if (OleQueryBounds(lpObject, &rc) == OLE_OK)
1.1       root      407:       ConvertToClient(&rc);
1.1.1.3 ! root      408:    else
1.1       root      409:       SetRect(&rc, 0, 0, 0, 0);
                    410: 
1.1.1.3 ! root      411:    if (!(pItem->hwnd = CreateWindow(   //* Create the child window
1.1       root      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:    }
1.1.1.3 ! root      439:    else if (pItem->otObject == OT_LINK)//* if the object is linked
1.1       root      440:    {                                   //* retrieve update options
                    441: 
                    442:       WaitForObject(pItem);
                    443:       if(Error(OleGetLinkUpdateOptions(pItem->lpObject, &pItem->uoObject)))
                    444:          goto Error;
1.1.1.3 ! root      445: 
1.1       root      446:       if (ObjGetData(pItem,pData))
                    447:       {
1.1.1.3 ! root      448:          for (i=0; pData[i];i++);      //* Skip past the server name
1.1       root      449:          pItem->aLinkName = AddAtom(&pData[++i]);
1.1.1.3 ! root      450:       }
1.1       root      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);
1.1.1.3 ! root      463: 
1.1       root      464:    return FALSE;                       //* ERROR return
                    465: 
                    466: }
1.1.1.3 ! root      467: 
1.1       root      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.3 ! 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);
1.1.1.3 ! root      481:    else
1.1       root      482:    {
1.1.1.3 ! root      483:       //* We got the himetric units, converts them to pixels now.
1.1.1.2   root      484:       lprc->right   = MulDiv (giXppli, (lprc->right - lprc->left),
                    485:                           HIMETRIC_PER_INCH);
1.1.1.3 ! root      486: 
1.1.1.2   root      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;
1.1.1.3 ! root      491:       lprc->top     = 0;
1.1.1.2   root      492:     }
1.1       root      493: }
                    494: 
                    495: /***************************************************************************
                    496:  * ObjInsert()
1.1.1.3 ! root      497:  *
1.1       root      498:  * Query the user for object type to insert and insert the new OLE object
                    499:  ***************************************************************************/
                    500: 
                    501: VOID FAR ObjInsert(                    //* ENTRY:
1.1.1.3 ! root      502:    LHCLIENTDOC    lhcDoc,              //* OLE document handle
1.1       root      503:    LPOLECLIENT    lpClient             //* pointer to OLE client structure
1.1.1.3 ! root      504: ){                                     //* LOCAL:
        !           505:    LPOLEOBJECT    lpObject;            //* pointer to OLE object
1.1       root      506:    APPITEMPTR     pItem;               //* item pointer
1.1.1.3 ! root      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,
        !           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);
1.1.1.3 ! root      518:          if ( Error( OleCreate(STDFILEEDITING,(LPOLECLIENT)&(pItem->oleclient),
        !           519:             (LPSTR)szClassName, lhcDoc,CreateNewUniqueName(szTmp),
        !           520:             &lpObject,olerender_draw, 0)))
1.1       root      521:          {
                    522:             ErrorMessage(E_FAILED_TO_CREATE_OBJECT);
                    523:             FreeAppItem(pItem);
                    524:          }
                    525:          else
                    526:             PostItemCreate(lpObject, OT_EMBEDDED, NULL, pItem);
                    527:       }
1.1.1.3 ! root      528:    }
1.1       root      529: 
                    530: 
                    531: }
                    532: 
                    533: /***************************************************************************
                    534:  *  ObjDelete()
                    535:  *
1.1.1.3 ! root      536:  * Delete an OLE object. For this application, all OLE objects
        !           537:  * are associated with a child window; therefore the window must be
1.1       root      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
1.1.1.3 ! root      542:  * a document and OleDelete when removing an object from a document.
1.1       root      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: 
1.1.1.3 ! root      557:    if (fDelete ? Error(OleDelete(pItem->lpObject))
1.1       root      558:                      : Error(OleRelease(pItem->lpObject)))
                    559:    {
                    560:       ErrorMessage(E_FAILED_TO_DELETE_OBJECT);
                    561:       return;                          //* ERROR return
                    562:    }
                    563: 
                    564:    if (pItem->fVisible)
                    565:    {
1.1.1.3 ! root      566:       ShowWindow(pItem->hwnd, SW_HIDE);
1.1       root      567:       pItem->fVisible = FALSE;
                    568:    }
                    569:                                        //* the operation has to complete
                    570:    WaitForObject(pItem);               //* before the application structure
1.1.1.3 ! root      571: 
        !           572:    FreeAppItem(pItem);
1.1       root      573:    iObjects--;
                    574: 
1.1.1.3 ! root      575: }
1.1       root      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:
1.1.1.3 ! root      589:    BOOL           fPaste,              //* Paste/PasteLink flag
1.1       root      590:    LHCLIENTDOC    lhcDoc,              //* client document handle
                    591:    LPOLECLIENT    lpClient             //* pointer to client
1.1.1.3 ! root      592: ){                                     //* LOCAL:
1.1       root      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
1.1.1.3 ! root      600: 
1.1       root      601:    if (!OpenClipboard(hwndFrame))
                    602:       goto Error;                      //* ERROR jump
                    603: 
                    604: 
1.1.1.3 ! root      605:    if (fPaste)                         //* PASTE the object.
1.1       root      606:    {                                   //* Try "StdFileEditing" protocol
                    607:       if (Error(OleCreateFromClip(STDFILEEDITING,(LPOLECLIENT)&(pItem->oleclient),lhcDoc,
1.1.1.3 ! root      608:          CreateNewUniqueName(szTmp),&lpObject, olerender_draw,0)))
1.1       root      609:       {
                    610:                                        //* next try "Static" protocol
                    611:          if (Error(OleCreateFromClip(
                    612:                   STATICP, (LPOLECLIENT)&(pItem->oleclient), lhcDoc,
1.1.1.3 ! root      613:                   CreateNewUniqueName(szTmp), &lpObject, olerender_draw, 0)))
1.1       root      614:             goto Error;               //* ERROR jump
                    615:       }
1.1.1.3 ! root      616:    }
        !           617:    else
        !           618:    {                                   //* LINK therefore must be
1.1       root      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);
1.1.1.3 ! root      641: 
1.1       root      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
1.1.1.3 ! root      659: 
        !           660:    if (!OpenClipboard(hwndFrame))
1.1       root      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: 
1.1.1.3 ! root      688:    *szFileName = 0;
1.1       root      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
1.1.1.3 ! root      695: 
1.1       root      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()
1.1.1.3 ! root      711:  *
1.1       root      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:
1.1.1.3 ! root      723:    HANDLE         hData;               //* handle to OLE link data
1.1       root      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;
1.1.1.3 ! root      729: 
        !           730:    switch (Error(OleGetData(pItem->lpObject,
1.1       root      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);
1.1.1.3 ! root      740: 
1.1       root      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)
1.1.1.3 ! root      753:                for (i=0L; i<(INT)lSize; i++)
1.1       root      754:                   *(lpWork+i)=*(lpData+i);
                    755: 
                    756:             GlobalUnlock(hData);       //* free the linked data as needed
                    757:             if (fFree)
                    758:                GlobalFree(hData);
                    759: 
1.1.1.3 ! root      760:             return TRUE;               //* SUCCESS
1.1       root      761:          }
                    762:       default:
                    763:          return FALSE;                 //* FAILURE
1.1.1.3 ! root      764:    }
1.1       root      765: 
                    766: }
                    767: 
                    768: /***************************************************************************
                    769:  * ObjChangeLink()
                    770:  *
                    771:  * Change the linkdata.  This routine will change the document portion of
1.1.1.3 ! root      772:  * link data to lpDoc.  The old linkdata is expected to be in
        !           773:  * lpaItem->lpLinkData
1.1       root      774:  **************************************************************************/
                    775: 
                    776: VOID FAR ObjChangeLinkData(            //* ENTRY:
1.1.1.3 ! root      777:    APPITEMPTR     pItem,               //* OLE object
1.1       root      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
1.1.1.3 ! root      784:    HANDLE         hData;
        !           785: 
1.1       root      786:    pItem->aLinkName = AddAtom(lpDoc);
                    787: 
                    788:    for (
1.1.1.3 ! root      789:       lpLinkData = pItem->lpLinkData, i=0;
        !           790:       pWork[i] = *lpLinkData;
1.1       root      791:       lpLinkData++, i++
                    792:    );
                    793:                                        //* into working buffer.
1.1.1.3 ! root      794:    lstrcpy((LPSTR)&pWork[++i],lpDoc);  //* copy new document name.
        !           795: 
1.1       root      796:    for (; pWork[i]; i++);              //* skip to end of document name
                    797:    for (++lpLinkData;*lpLinkData;lpLinkData++);
                    798:                                        //* copy item name.
                    799:    lstrcpy((LPSTR)&pWork[++i],++lpLinkData);
                    800:    for (; pWork[i]; i++);              //* skip to end of buffer
                    801:                                        //* which is the end of item info.
1.1.1.3 ! root      802:    pWork[++i] = 0;                  //* add extra null.
1.1       root      803: 
1.1.1.3 ! root      804:    lSize = SizeOfLinkData(pWork);      //* reallocate space so there is
1.1       root      805:    ReallocLinkData(pItem,lSize);       //* a properly sized block of info
                    806:                                        //* to send the linked data to the
                    807:    if (lpLinkData = pItem->lpLinkData) //* OLE DLL.
                    808:       for (i=0; i<(INT)lSize; i++)     //* copy new linkdata into this space
                    809:          *lpLinkData++ = pWork[i];
                    810:    else
                    811:       return;                          //* ERROR return
1.1.1.3 ! root      812: 
1.1       root      813:    Error(OleSetData(pItem->lpObject, vcfLink, GlobalHandle(pItem->lpLinkData)));
1.1.1.3 ! root      814: 
        !           815:    /*
        !           816:     * The handle passed into OleSetData is owned by the OLE client library
        !           817:     * and should not be used after the call.  On win32s, it is inaccessible
        !           818:     * after the call, so restore it by calling OleGetData.  Note that the
        !           819:     * data is *still* owned by the library, but we will now have access
        !           820:     * to the memory.
        !           821:     */
        !           822:    Error(OleGetData(pItem->lpObject, vcfLink, &hData));
        !           823:    if (hData) {
        !           824:        pItem->lpLinkData = GlobalLock(hData);
        !           825:    }
1.1       root      826: }                                      //* SUCCESS return
                    827: 
                    828: /****************************************************************************
                    829:  * ObjSaveUndo()
                    830:  *
                    831:  * Clone the OLE object so that any changes to object can be undone if the
1.1.1.3 ! root      832:  * user choses to exit without update.
1.1       root      833:  ***************************************************************************/
1.1.1.3 ! root      834: 
1.1       root      835: VOID FAR ObjSaveUndo(                  //* ENTRY:
                    836:    APPITEMPTR     pItem                //* application item
                    837: ){                                     //* LOCAL:
                    838:    CHAR           szTmp[CBOBJNAMEMAX]; //* holder of object name
                    839:    LPSTR          lpClone;             //* pointer to clond object name
                    840:    UINT           i=CBOBJNAMEMAX;
                    841: 
                    842:    if (!pItem->lpObjectUndo)
                    843:    {
                    844:       OleQueryName(pItem->lpObject, szTmp, &i);
1.1.1.3 ! root      845:                                        //* give clone a unique name by
1.1       root      846:                                        //* altering object name prefix.
1.1.1.3 ! root      847:       for (lpClone = OBJCLONE, i=0; *lpClone; szTmp[i++] = *lpClone++);
1.1       root      848: 
                    849:       if (Error(OleClone(pItem->lpObject, (LPOLECLIENT)pItem,
                    850:          pItem->lhcDoc, szTmp, &(pItem->lpObjectUndo))))
                    851:       return;                          //* ERROR return
                    852: 
                    853:       pItem->otObjectUndo  = pItem->otObject;
                    854:       pItem->uoObjectUndo  = pItem->uoObject;
                    855:       pItem->aLinkUndo     = pItem->aLinkName;
                    856: 
                    857:       GetClientRect(pItem->hwnd, &pItem->rect);
                    858: 
                    859:       if (OleQueryOpen(pItem->lpObject) == OLE_OK)
                    860:          pItem->fOpen = TRUE;
1.1.1.3 ! root      861: 
1.1       root      862:    }
                    863: 
                    864: }                                      //* SUCCESS return
                    865: 
                    866: /****************************************************************************
                    867:  * ObjUndo()
                    868:  *
1.1.1.3 ! root      869:  * Restore an object to its state before changes.  The lpObject Undo is a
1.1       root      870:  * clone to the original object with a different name, therefore, all we
                    871:  * have to do is rename that object and ditch the changed object.
                    872:  ***************************************************************************/
1.1.1.3 ! root      873: 
1.1       root      874: VOID FAR ObjUndo(                      //* ENTRY:
                    875:    APPITEMPTR     pItem                //* application item
                    876: ){                                     //* LOCAL:
                    877:    CHAR           szTmp[CBOBJNAMEMAX]; //* object name holder
                    878:    UINT           i = CBOBJNAMEMAX;
1.1.1.3 ! root      879: 
1.1       root      880:    OleQueryName(pItem->lpObject, szTmp, &i);
                    881:    if (Error(OleDelete(pItem->lpObject)))
                    882:       return;                          //* ERROR return
                    883:                                        //* reset app item vars
1.1.1.3 ! root      884:    pItem->lpObject      = pItem->lpObjectUndo;
1.1       root      885:    pItem->otObject      = pItem->otObjectUndo;
                    886:    pItem->uoObject      = pItem->uoObjectUndo;
                    887:    pItem->aLinkName     = pItem->aLinkUndo;
                    888:    pItem->lpObjectUndo  = (LPOLEOBJECT)NULL;
                    889:    pItem->otObjectUndo  = (LONG)NULL;
                    890: 
                    891:    if (Error(OleRename(pItem->lpObject,szTmp)))
                    892:       return;                          //* ERROR return
                    893: 
                    894:    if (pItem->fOpen)
                    895:    {
                    896:       Error(OleReconnect(pItem->lpObject));
                    897:       pItem->fOpen = FALSE;
                    898:    }
                    899: 
                    900:    SetWindowPos(
1.1.1.3 ! root      901:       pItem->hwnd,
1.1       root      902:       NULL, 0, 0,
                    903:       pItem->rect.right - pItem->rect.left + 2*GetSystemMetrics(SM_CXFRAME),
                    904:       pItem->rect.bottom - pItem->rect.top + 2*GetSystemMetrics(SM_CYFRAME),
                    905:       SWP_NOZORDER | SWP_NOMOVE | SWP_DRAWFRAME
                    906:    );
                    907: 
                    908:    InvalidateRect(pItem->hwnd,NULL,TRUE);
                    909: 
                    910: }                                      //* SUCCESS return
                    911: 
                    912: 
                    913: /****************************************************************************
                    914:  * ObjDelUndo()
                    915:  *
                    916:  * Delete the undo object if the user is happy with the changes he/she made.
                    917:  ***************************************************************************/
                    918: 
                    919: VOID FAR ObjDelUndo(                   //* ENTRY:
                    920:    APPITEMPTR     pItem                //* application item
                    921: ){
                    922: 
                    923:    if (Error(OleDelete(pItem->lpObjectUndo)))
                    924:       return;                          //* ERROR return
                    925: 
                    926:    pItem->lpObjectUndo = (LPOLEOBJECT)NULL;
                    927:    pItem->otObjectUndo = (LONG)NULL;
                    928:    DeleteAtom(pItem->aLinkUndo);
                    929:    pItem->lpObjectUndo = NULL;
1.1.1.3 ! root      930: 
1.1       root      931: }                                      //* SUCCESS return
                    932: 
                    933: /****************************************************************************
                    934:  * ObjFreeze()
                    935:  *
                    936:  * Convert an object to a static object.
                    937:  ***************************************************************************/
1.1.1.3 ! root      938: 
1.1       root      939: VOID FAR ObjFreeze(                    //* ENTRY:
                    940:    APPITEMPTR     pItem                //* application item
                    941: ){                                     //* LOCAL:
                    942:    CHAR           szTmp[CBOBJNAMEMAX]; //* temporary object name
                    943:    LPSTR          lpTemp;              //* temporary prefix string
                    944:    LPOLEOBJECT    lpObjectTmp;         //* temporary object pointer
                    945:    UINT           i=CBOBJNAMEMAX;
1.1.1.3 ! root      946: 
1.1       root      947:    OleQueryName(pItem->lpObject, szTmp, &i);
1.1.1.3 ! root      948:                                        //* create a unique name by changing
1.1       root      949:                                        //* the object name prefix
1.1.1.3 ! root      950:    for (lpTemp = OBJTEMP, i=0; *lpTemp; szTmp[i++] = *lpTemp++);
1.1       root      951: 
                    952:                                        //* this API creates a static object
                    953:    if (Error(OleObjectConvert(pItem->lpObject, STATICP, (LPOLECLIENT)pItem,
                    954:       pItem->lhcDoc, szTmp, &lpObjectTmp)))
                    955:       return;
                    956:                                        //* delete old object
                    957:    if (Error(OleDelete(pItem->lpObject)))
                    958:       return;
                    959: 
1.1.1.3 ! root      960:    WaitForObject(pItem);
1.1       root      961: 
                    962:    pItem->lpObject = lpObjectTmp;
                    963:    pItem->otObject = OT_STATIC;
                    964:    pItem->uoObject = -1L;
                    965: 
1.1.1.3 ! root      966:    for (lpTemp = OBJPREFIX, i=0; *lpTemp; szTmp[i++] = *lpTemp++);
1.1       root      967:    if (Error(OleRename(pItem->lpObject,szTmp)))
                    968:       return;
1.1.1.3 ! root      969: 
        !           970: 
1.1       root      971: }
                    972: 
                    973: /***************************************************************************
                    974:  *  ObjCreateWrap()
                    975:  *
                    976:  * Create a wrapped object from the drag and drop feature of the 3.1 shell.
                    977:  * NOTE: We are assuming that only one file has been dropped.  See the SDK
                    978:  * documentation for instructions on how to deal with multiple files.
                    979:  ***************************************************************************/
                    980: 
                    981: VOID FAR ObjCreateWrap(                //* ENTRY:
                    982:    HANDLE         hdrop,               //* handle to dropped object
                    983:    LHCLIENTDOC    lhcDoc,              //* document handle
                    984:    LPOLECLIENT    lpClient             //* pointer to client structure
                    985: ){                                     //* LOCAL:
1.1.1.3 ! root      986:    CHAR           szDragDrop[CBPATHMAX];//* Drag and drop file name
        !           987:    LPOLEOBJECT    lpObject;            //* pointer to OLE object
1.1       root      988:    POINT          pt;                  //* position of dropped object
1.1.1.3 ! root      989:    RECT           rc;                  //* object size and position
        !           990:    CHAR           szTmp[CBOBJNAMEMAX]; //* buffer for unique object name
1.1       root      991:    APPITEMPTR     pItem;               //* application item pointer
                    992:    INT            x,y;                 //* icon sizes
1.1.1.3 ! root      993: 
1.1       root      994:    x = GetSystemMetrics(SM_CXICON) / 2;
                    995:    y = GetSystemMetrics(SM_CYICON) / 2;
                    996:                                        //* Get the drag and drop filename
1.1.1.3 ! root      997:                                        //* position
1.1       root      998:    DragQueryPoint(hdrop, &pt);
                    999:    DragQueryFile(hdrop, 0, szDragDrop, CBPATHMAX);
                   1000:    DragFinish(hdrop);
                   1001: 
                   1002:    SetRect(&rc, pt.x - x, pt.y - y, pt.x + x, pt.y + y);
                   1003: 
                   1004:    if (!(pItem = PreItemCreate(lpClient, TRUE, lhcDoc)))
                   1005:       return;                          //* ERROR return
                   1006:                                        //* create OLE object
1.1.1.3 ! root     1007:    if (Error(OleCreateFromFile(STDFILEEDITING, (LPOLECLIENT)pItem,
        !          1008:          "Package", szDragDrop, lhcDoc, CreateNewUniqueName(szTmp),
1.1       root     1009:          &lpObject, olerender_draw, 0)))
                   1010:    {
                   1011:       ErrorMessage(E_FAILED_TO_CREATE_OBJECT);
                   1012:       FreeAppItem(pItem);
                   1013:       return;                          //* ERROR return
                   1014:    }
                   1015: 
1.1.1.3 ! root     1016:    if (PostItemCreate(lpObject, OT_EMBEDDED, &rc, pItem))
1.1       root     1017:       ShowNewWindow(pItem);
1.1.1.3 ! root     1018: 
1.1       root     1019: }                                      //* SUCCESS return
                   1020: 
                   1021: /***************************************************************************
                   1022:  *  UpdateObjectMenuItem()
                   1023:  *
                   1024:  *  Add an object popup menu for the chosen object if multiple verbs exist.
                   1025:  *  The registration system is used to determine which verbs exist for the
1.1.1.3 ! root     1026:  *   given object.
1.1       root     1027:  **************************************************************************/
                   1028: 
                   1029: VOID FAR UpdateObjectMenuItem(         //* ENTRY:
                   1030:    HMENU       hMenu                   //* main menu
                   1031: ){                                     //* LOCAL
                   1032:    INT         cVerbs;                 //* verb
                   1033:    APPITEMPTR  pItem;                  //* application item ponter
                   1034:    DWORD       dwSize = KEYNAMESIZE;
                   1035:    CHAR        szClass[KEYNAMESIZE], szBuffer[200];
                   1036:    CHAR        szVerb[KEYNAMESIZE];
                   1037:    HMENU       hPopupNew=NULL;
                   1038:    HKEY        hkeyTemp;
                   1039:    CHAR        pLinkData[OBJECT_LINK_MAX];
1.1.1.3 ! root     1040:                                        //* delete current item and submenu
1.1       root     1041:    DeleteMenu(hMenu, POS_OBJECT, MF_BYPOSITION );
1.1.1.3 ! root     1042: 
1.1       root     1043:    if (!(pItem = GetTopItem()) )
                   1044:       goto Error;                      //* ERROR jump
                   1045:    else if (!pItem->fVisible)
                   1046:       goto Error;                      //* ERROR jump
                   1047:                                        //* if STATIC ?
1.1.1.3 ! root     1048:    if ((pItem->otObject != OT_EMBEDDED) && (pItem->otObject != OT_LINK))
1.1       root     1049:       goto Error;                      //* ERROR jump
                   1050: 
                   1051:    if (!ObjGetData(pItem, pLinkData))  //* get linkdata as key reg database
                   1052:       goto Error;                      //* ERROR jump
1.1.1.3 ! root     1053:                                        //* open reg database
        !          1054:    szClass[0] = 0;
        !          1055:    if (RegOpenKey(HKEY_CLASSES_ROOT, szClass, &hkeyTemp))
1.1       root     1056:       goto Error;                      //* ERROR jump
                   1057:                                        //* check if class is reg-db
                   1058:    if (RegQueryValue(HKEY_CLASSES_ROOT, pLinkData, szClass, &dwSize))
                   1059:    {
                   1060:       RegCloseKey(hkeyTemp);
1.1.1.3 ! root     1061:       goto Error;                      //* ERROR jump
1.1       root     1062:    }
                   1063: 
                   1064:    for (cVerbs=0; ;++cVerbs)           //* extract all verbs from reg-db
                   1065:    {
                   1066:       dwSize = KEYNAMESIZE;
                   1067:       wsprintf(szBuffer, "%s\\protocol\\StdFileEditing\\verb\\%d",
                   1068:                                      (LPSTR)pLinkData,cVerbs);
                   1069: 
                   1070:       if (RegQueryValue(HKEY_CLASSES_ROOT, szBuffer, szVerb, &dwSize))
                   1071:          break;
                   1072: 
                   1073:       if (!hPopupNew)
                   1074:          hPopupNew = CreatePopupMenu();
                   1075: 
                   1076:       InsertMenu(hPopupNew, (UINT)-1, MF_BYPOSITION, IDM_VERBMIN+cVerbs, szVerb);
                   1077:    }
                   1078: 
                   1079:    //* NOTE: For International versions the following  verb menu
                   1080:    //* may need to be formatted differently.
                   1081: 
                   1082:    switch (cVerbs)                     //* determine how many verbs found
                   1083:    {
                   1084:       case 0:                          //* none
                   1085:          wsprintf(szBuffer, "Edit %s %s", (LPSTR)szClass, (LPSTR)"&Object");
                   1086:          InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION, IDM_VERBMIN, szBuffer);
                   1087:          break;
                   1088: 
                   1089:       case 1:                          //* one
1.1.1.3 ! root     1090:          wsprintf(szBuffer, "%s %s %s", (LPSTR)szVerb, (LPSTR)szClass,
1.1       root     1091:             (LPSTR)"&Object");
                   1092:          DestroyMenu(hPopupNew);
                   1093:          InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION, IDM_VERBMIN, szBuffer);
                   1094:          break;
                   1095: 
                   1096:      default:                          //* > 1
                   1097:          wsprintf(szBuffer, "%s %s", (LPSTR)szClass, (LPSTR)"&Object");
                   1098:          InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION | MF_POPUP, (UINT)hPopupNew, szBuffer);
                   1099:          EnableMenuItem(hMenu, POS_OBJECT, MF_ENABLED|MF_BYPOSITION);
1.1.1.3 ! root     1100:          break;
1.1       root     1101:    }
                   1102: 
                   1103:    RegCloseKey(hkeyTemp);              //* close reg-db
                   1104:    return;                             //* SUCCESS return
                   1105: 
                   1106: Error:                                 //* ERROR tag
1.1.1.3 ! root     1107:    InsertMenu(hMenu, POS_OBJECT, MF_BYPOSITION, 0, "&Object");
1.1       root     1108:    EnableMenuItem(hMenu, POS_OBJECT, MF_GRAYED | MF_BYPOSITION);
                   1109: 
                   1110: }                                      //* ERROR return
                   1111: 
                   1112: /***************************************************************************
                   1113:  *  ExecuteVerb()
                   1114:  *
                   1115:  *  Execute the verb for the given object.
                   1116:  ***************************************************************************/
                   1117: 
                   1118: VOID FAR ExecuteVerb(                  //* ENTRY:
                   1119:    UINT iVerb,                          //* verb
                   1120:    APPITEMPTR pItem                    //* application item pointer
                   1121: ){                                     //* LOCAL
                   1122:    RECT        rc;                     //* holds client area bounding rect
                   1123: 
                   1124:    if (pItem->otObject == OT_STATIC)   //* if the object is static beep
                   1125:    {
                   1126:       ErrorMessage(W_STATIC_OBJECT);
                   1127:       return;                          //* return
                   1128:    }
                   1129:                                        //* get cliet area rectangle
                   1130:    GetClientRect(hwndFrame, (LPRECT)&rc);
                   1131:                                        //* execute OLE verb
1.1.1.3 ! root     1132:    if (Error(OleActivate(pItem->lpObject, iVerb, TRUE, TRUE, hwndFrame, &rc)))
1.1       root     1133:       return;
1.1.1.3 ! root     1134: 
1.1       root     1135:    WaitForObject(pItem);               //* wait for async. operation
                   1136: 
                   1137:    ObjSetBounds(pItem);
1.1.1.3 ! root     1138: 
1.1       root     1139: 
                   1140: }                                      //* SUCCESS return
                   1141: 
                   1142: /****************************************************************************
                   1143:  * ObjSetBounds
                   1144:  *
                   1145:  * Set the object bounds.  The object bounds are the child windos bounding
                   1146:  * rectangle.  OLE servers recieve need the bounding rectangle in HIMETRIC
                   1147:  * coordinates.  So, we convert from screen coordinates to HIMETRIC.
                   1148:  *
                   1149:  * Returns BOOL - TRUE if successful.
                   1150:  ***************************************************************************/
                   1151: BOOL FAR ObjSetBounds(                 //* ENTRY:
1.1.1.3 ! root     1152:    APPITEMPTR     pItem                //* application item pointer
1.1       root     1153: ){                                     //* LOCAL:
1.1.1.3 ! root     1154:    RECT           itemRect;            //* bounding rectangle
1.1       root     1155: 
                   1156:    GetWindowRect(pItem->hwnd,&itemRect);//* get item window react
                   1157: 
1.1.1.2   root     1158:    itemRect.right -= GetSystemMetrics(SM_CXFRAME);
                   1159:    itemRect.left += GetSystemMetrics(SM_CXFRAME);
                   1160:    itemRect.top += GetSystemMetrics(SM_CYFRAME);
                   1161:    itemRect.bottom -= GetSystemMetrics(SM_CYFRAME);
                   1162: 
                   1163:    itemRect.right  = MulDiv ((itemRect.right - itemRect.left),
                   1164:                         HIMETRIC_PER_INCH, giXppli);
                   1165:    itemRect.bottom = - MulDiv((itemRect.bottom - itemRect.top),
1.1.1.3 ! root     1166:                         HIMETRIC_PER_INCH, giYppli);
        !          1167:    itemRect.top    = 0;
        !          1168:    itemRect.left   = 0;
1.1       root     1169:                                        //* set the rect for the server
                   1170:    if (Error(OleSetBounds(pItem->lpObject,(LPRECT)&itemRect)))
                   1171:       return FALSE;                    //* ERROR return
                   1172: 
                   1173:    WaitForObject(pItem);               //* wait for async. operation
                   1174:    return TRUE;                        //* SUCCESS return
                   1175: 
                   1176: }
1.1.1.2   root     1177: 

unix.superglobalmegacorp.com

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