|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.