/* virtable.c - This module contains the OLE virtual table/private routines. * * Created by Microsoft Corporation. */ #include "packager.h" #include "dialogs.h" //#define OLESVR_SUPPORT /* enable support for OLE server files */ static CHAR szLink[] = "/Link"; // Appended to end of link packages /**************************** Server functions *****************************/ /* SrvrOpen() - Wraps a filename that is passed into a command line. */ OLESTATUS SrvrOpen( LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpdocname, LPOLESERVERDOC *lplpoledoc ) { LPSAMPDOC lpdoc; LPSTR lpstrLink = NULL; OLESTATUS retval = OLE_OK; LPOLEOBJECT lpObject = NULL; DPRINT("pkg: SrvrOpen"); if (lpstrLink = Contains(lpdocname, szLink)) *lpstrLink = '\0'; if (!(lpdoc = (LPSAMPDOC)CreateDocFromFile( (LPSAMPSRVR)lpolesrvr, lhdoc, lpdocname))) return OLE_ERROR_GENERIC; // Generate a command line BringWindowToTop(ghwndPane[CONTENT]); if (gpty[CONTENT]) DeletePane(CONTENT, TRUE); #ifdef OLESVR_SUPPORT if (IsOleServerDoc (lpdocname)) { gpty[CONTENT] = PICTURE; if (lpstrLink) { if (Error(OleCreateLinkFromFile(gszProtocol, glpclient, NULL, lpdocname, NULL, glhcdoc, gszCaption[CONTENT], &lpObject, olerender_draw, 0))) retval = OLE_ERROR_OPEN; } else { if (Error(OleCreateFromFile(gszProtocol, glpclient, NULL, lpdocname, glhcdoc, gszCaption[CONTENT], &lpObject, olerender_draw, 0))) retval = OLE_ERROR_OPEN; } if (retval == OLE_OK) { glpobj[CONTENT] = PicCreate(lpObject, NULL); ((LPPICT)glpobj[CONTENT])->fNotReady = TRUE; OleBlockServer(((LPSAMPSRVR)lpolesrvr)->lhsrvr); gfBlocked = TRUE; } else { DeregisterDoc(); return retval; } } else { #endif if (lpstrLink) { if (glpobj[CONTENT] = CmlCreateFromFilename(lpdocname, TRUE)) gpty[CONTENT] = CMDLINK; } else { if (glpobj[CONTENT] = (LPVOID)EmbCreate(lpdocname)) gpty[CONTENT] = PEMBED; } if (glpobj[CONTENT] == NULL) retval = OLE_ERROR_OPEN; #ifdef OLESVR_SUPPORT } #endif // If no appearance pane (which should be always), try to make one if (!gpty[APPEARANCE]) { if (glpobj[APPEARANCE] = IconCreateFromFile(lpdocname)) { gpty[APPEARANCE] = ICON; InvalidateRect(ghwndPane[APPEARANCE], NULL, TRUE); } } // Restore the character we so rudely mashed if (lpstrLink) *lpstrLink = szLink[0]; // Save the document and change the menus InitEmbedded(FALSE); *lplpoledoc = (LPOLESERVERDOC)lpdoc; return retval; } /* SrvrCreate() - Create a new (embedded) object. */ OLESTATUS SrvrCreate( LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpclassname, LPSTR lpdocname, LPOLESERVERDOC *lplpoledoc ) { DPRINT("pkg: SrvrCreate"); // Initialize the new image InitFile(); if (!(*lplpoledoc = (LPOLESERVERDOC)CreateNewDoc((LPSAMPSRVR)lpolesrvr, lhdoc, lpdocname))) return OLE_ERROR_GENERIC; InitEmbedded(TRUE); return OLE_OK; } /* SrvrCreateFromTemplate() - Create a new (embedded) object from a file. */ OLESTATUS SrvrCreateFromTemplate( LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpclassname, LPSTR lpdocname, LPSTR lptemplatename, LPOLESERVERDOC *lplpoledoc ) { LPSAMPDOC lpdoc; DPRINT("pkg: SrvrCreateFromTemplate"); if (!(lpdoc = (LPSAMPDOC)CreateDocFromFile((LPSAMPSRVR)lpolesrvr, lhdoc, lptemplatename))) return OLE_ERROR_GENERIC; // Save the document and change the menus *lplpoledoc = (LPOLESERVERDOC)lpdoc; InitEmbedded(FALSE); StringCchCopy(szUntitled, ARRAYSIZE(szUntitled), lpdocname); SetTitle(TRUE); return OLE_OK; } /* SrvrEdit() - Open an (embedded) object for editing. */ OLESTATUS SrvrEdit( LPOLESERVER lpolesrvr, LHSERVERDOC lhdoc, LPSTR lpclassname, LPSTR lpdocname, LPOLESERVERDOC *lplpoledoc ) { DPRINT("pkg: SrvrEdit"); if (!(*lplpoledoc = (LPOLESERVERDOC)CreateNewDoc((LPSAMPSRVR)lpolesrvr, lhdoc, lpdocname))) return OLE_ERROR_MEMORY; InitEmbedded(FALSE); return OLE_OK; } /* SrvrExit() - Called to cause the OLE server to be revoked. */ OLESTATUS SrvrExit( LPOLESERVER lpolesrvr ) { DPRINT("pkg: SrvrExit"); DeleteServer((LPSAMPSRVR)lpolesrvr); return OLE_OK; } /* SrvrRelease() - Called so that the server memory can be freed. * * Note: This call may occur in isolation without a SrvrExit() * call. If this occurs, we still revoke the server. */ OLESTATUS SrvrRelease( LPOLESERVER lpolesrvr ) { DPRINT("pkg: SrvrRelease"); if (gvlptempdoc) return OLE_OK; if (gfInvisible || (gfEmbeddedFlag && !gfDocExists)) DeleteServer((LPSAMPSRVR)lpolesrvr); if (ghServer) DestroyServer(); return OLE_OK; } /* SrvrExecute() - Called to execute DDE commands */ OLESTATUS SrvrExecute( LPOLESERVER lpolesrvr, HANDLE hCmds ) { DPRINT("pkg: SrvrExecute"); return OLE_ERROR_PROTOCOL; } /************************** Document functions *************************/ /* DocSave() - OLE callback to save the document. */ OLESTATUS DocSave( LPOLESERVERDOC lpoledoc ) { DPRINT("pkg: DocSave"); return OLE_OK; } /* DocClose() - OLE callback when the document is to be closed. * * This command has no additional effects; since we are not an MDI application * we don't close the child window. The window is destroyed when the server * function "Release" is called. */ OLESTATUS DocClose( LPOLESERVERDOC lpoledoc ) { DPRINT("pkg: DocClose"); DeregisterDoc(); return OLE_OK; } /* DocRelease() - Deallocate document memory. */ OLESTATUS DocRelease( LPOLESERVERDOC lpoledoc ) { LPSAMPDOC lpdoc = (LPSAMPDOC)lpoledoc; HANDLE hdoc; DPRINT("pkg: DocRelase"); if (lpdoc) { if (!gfDocCleared) { glpdoc = NULL; DeregisterDoc(); } GlobalDeleteAtom(lpdoc->aName); LocalUnlock(hdoc = lpdoc->hdoc); LocalFree(hdoc); gfDocExists = FALSE; } return OLE_OK; } /* DocGetObject() - Create a new object within the current document */ OLESTATUS DocGetObject( LPOLESERVERDOC lpoledoc, LPSTR lpitemname, LPOLEOBJECT *lplpoleobject, LPOLECLIENT lpoleclient ) { LPSAMPITEM lpitem; DPRINT("pkg: DocGetObject"); // // Always create a new item in this case, it's much easier than // worrying about the sub-rectangle bitmap. // lpitem = CreateNewItem((LPSAMPDOC)lpoledoc); lpitem->lpoleclient = lpoleclient; if (*lpitemname) { lpitem->aName = AddAtom(lpitemname); } else { lpitem->aName = 0; } if (!(*lplpoleobject = (LPOLEOBJECT)AddItem(lpitem))) return OLE_ERROR_GENERIC; return OLE_OK; } /* DocSetHostNames() - Sets the title bar to the correct document name. * * Note: The format is " - ". */ OLESTATUS DocSetHostNames( LPOLESERVERDOC lpoledoc, LPSTR lpclientName, LPSTR lpdocName ) { DPRINT("pkg: DocSetHostnames"); StringCchCopy(szUntitled, ARRAYSIZE(szUntitled), lpdocName); StringCchCopy(gszClientName, ARRAYSIZE(gszClientName), lpclientName); SetTitle(TRUE); return OLE_OK; } /* DocSetDocDimensions() - OLE callback to change the document dimensions. * * Note: This command is unsupported. It is the client application's * responsibility to report errors (as needed). */ OLESTATUS DocSetDocDimensions( LPOLESERVERDOC lpoledoc, LPRECT lprc ) { DPRINT("pkg: DocSetDocDimensions"); return OLE_ERROR_GENERIC; } /* DocSetColorScheme() - OLE callback to change the document colors. * * Note: This command is unsupported. It is the client application's * responsibility to report errors (as needed). */ OLESTATUS DocSetColorScheme( LPOLESERVERDOC lpoledoc, LPLOGPALETTE lppal ) { DPRINT("pkg: DocSetColorScheme"); return OLE_ERROR_GENERIC; } /* DocExecute() - Called to execute DDE commands */ OLESTATUS DocExecute( LPOLESERVERDOC lpoledoc, HANDLE hCmds ) { DPRINT("pkg: DocExecute"); return OLE_ERROR_PROTOCOL; } /**************************** Item functions ***************************/ /* ItemDelete() - Free memory associated with the current item. */ OLESTATUS ItemDelete( LPOLEOBJECT lpoleobject ) { DPRINT("pkg: ItemDelete"); DeleteItem((LPSAMPITEM)lpoleobject); return OLE_OK; /* Add error checking later */ } /* ItemGetData() - Used by the client to obtain the item data. */ OLESTATUS ItemGetData( LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat, LPHANDLE lphandle ) { DPRINT("pkg: ItemGetData"); if ((gpty[CONTENT] == PICTURE) && ((LPPICT)glpobj[CONTENT])->fNotReady) return OLE_BUSY; if (cfFormat == gcfNative) { if (*lphandle = GetNative(FALSE)) return OLE_OK; } else if (cfFormat == CF_METAFILEPICT) { if (*lphandle = GetMF()) return OLE_OK; } else if (cfFormat == gcfOwnerLink) { if (*lphandle = GetLink()) return OLE_OK; } // Clipboard format not supported return OLE_ERROR_GENERIC; } /* ItemSetData() - Used by the client to paste data into a server. * * Read in the embedded object data in Native format. This will * not be called unless we are editing the correct document. */ OLESTATUS ItemSetData( LPOLEOBJECT lpoleobject, OLECLIPFORMAT cfFormat, HANDLE hdata ) { LPSAMPITEM lpitem = (LPSAMPITEM)lpoleobject; DPRINT("pkg: ItemSetData"); if (cfFormat == gcfNative && !PutNative(hdata)) { SendMessage(ghwndFrame, WM_COMMAND, IDM_NEW, 0L); GlobalFree(hdata); return OLE_ERROR_GENERIC; } GlobalFree(hdata); return OLE_OK; } /* ItemDoVerb() - Play/Edit the object. * * This routine is called when the user tries to run an object that * is wrapped by the packager. */ OLESTATUS ItemDoVerb( LPOLEOBJECT lpoleobject, UINT wVerb, BOOL fShow, BOOL fActivate ) { DPRINT("pkg: ItemDoVerb"); switch (wVerb) { case OLE_PLAY: if (fShow) return (*(lpoleobject->lpvtbl->Show))(lpoleobject, fActivate); break; case OLE_EDIT: if (fShow && fActivate) { if (gfInvisible) { ShowWindow(ghwndFrame, gnCmdShowSave); gfInvisible = FALSE; } // If iconic, restore the window; then give it the focus. if (IsIconic(ghwndFrame)) SendMessage(ghwndFrame, WM_SYSCOMMAND, SC_RESTORE, 0L); BringWindowToTop(ghwndFrame); } default: break; } return OLE_OK; } /* ItemShow() - Show the item. * * This routine is called when the user tries to edit an object in a * client application, and the server is already active. */ OLESTATUS ItemShow( LPOLEOBJECT lpoleobject, BOOL fActivate ) { HWND hwndItem; DPRINT("pkg: ItemShow"); if (fActivate && (hwndItem = GetTopWindow(ghwndFrame)) && (gpty[(hwndItem == ghwndPane[CONTENT])] == NOTHING)) { // // Lets assume that in this case the client has // attempted an InsertObject operation with // the Package class. (5.30.91) v-dougk // if (gfInvisible) { ShowWindow(ghwndFrame, SW_SHOW); gfInvisible = FALSE; } BringWindowToTop(ghwndFrame); } else { PostMessage(hwndItem, WM_COMMAND, IDD_PLAY, 0L); } return OLE_OK; } /* ItemSetBounds() - Set the item's size. * * Note: This command is not supported. */ OLESTATUS ItemSetBounds( LPOLEOBJECT lpoleobject, LPRECT lprc ) { DPRINT("pkg: ItemSetBounds"); return OLE_ERROR_GENERIC; } /* ItemSetTargetDevice() - Changes the target device for item display. * * Note: This command is not supported. */ OLESTATUS ItemSetTargetDevice( LPOLEOBJECT lpoleobject, HANDLE h ) { DPRINT("pkg: ItemSetTargetDevice"); if (h) GlobalFree(h); return OLE_ERROR_GENERIC; } /* ItemEnumFormats() - Enumerate formats which are renderable. * * This is called by the OLE libraries to get a format for screen display. * Currently, only Metafile and Native are supported. */ OLECLIPFORMAT ItemEnumFormats( LPOLEOBJECT lpobject, OLECLIPFORMAT cfFormat ) { DPRINT("pkg: ItemEnumFormats"); if (!cfFormat) return CF_METAFILEPICT; if (cfFormat == CF_METAFILEPICT) return gcfNative; return 0; } /* ItemQueryProtocol() - Tells whether the given protocol is supported. * * Returns: lpoleobject iff the protocol is "StdFileEditing". */ LPVOID ItemQueryProtocol( LPOLEOBJECT lpoleobject, LPSTR lpprotocol ) { DPRINT("pkg: ItemQueryProtocol"); return (!lstrcmpi(lpprotocol, "StdFileEditing") ? lpoleobject : NULL); } /* ItemSetColorScheme() - Denotes the palette to be used for item display. * * Note: This command is not supported. */ OLESTATUS ItemSetColorScheme( LPOLEOBJECT lpoleobject, LPLOGPALETTE lppal ) { DPRINT("pkg: ItemSetColorScheme"); return OLE_ERROR_GENERIC; } BOOL IsOleServerDoc(LPSTR lpdocname) { // 06/11/02 The OLE code path does not execute in XPSP1. Further, we want to ensure that we are going // through the ShellExecute path so that we get the new ShellExecute security warning for // the termporary internet directory. Therefore, we will always return FALSE here, a least for now. return FALSE; }