701 lines
14 KiB
C
701 lines
14 KiB
C
/* 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 "<lpclientName> <app name> - <lpdocName>".
|
|
*/
|
|
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;
|
|
}
|