1441 lines
45 KiB
C
1441 lines
45 KiB
C
/*---------------------------------------------------------------------------
|
||
| INPLACE.C
|
||
| This file has the InPlace activation related interfaces and functions.
|
||
| This file has the function DoInPlaceEdit which initiaites the server side
|
||
| operations for InPlace activation.
|
||
|
|
||
| Created By: Vij Rajarajan (VijR)
|
||
+---------------------------------------------------------------------------*/
|
||
#define SERVERONLY
|
||
#include <windows.h>
|
||
#include <windowsx.h>
|
||
#include "mpole.h"
|
||
#include <mmsystem.h>
|
||
|
||
#include "mplayer.h"
|
||
#include "toolbar.h"
|
||
#include "ole2ui.h"
|
||
|
||
#define DEF_HATCH_SZ 4 //Width of the hatch marks
|
||
#define EW_HATCH_HANDLE 10 //GetWindowWord offset to check
|
||
//if resize handle needed in hatch window
|
||
|
||
//#define DUMMY_TOOLBAR_WIDTH 58 //Width of dummy toolbar transferred during play.
|
||
#define DUMMY_TOOLBAR_WIDTH 0 //Width of dummy toolbar transferred during play.
|
||
|
||
HWND ghwndIPHatch = NULL; //Hatch window surrounding object.
|
||
HWND ghwndIPToolWindow; //The toolwindow appearing on top
|
||
HWND ghwndIPScrollWindow; //Tool window appearing at bottom with tthe scrollbar
|
||
//if the container does not give us space on top.
|
||
HMENU ghInPlaceMenu;
|
||
|
||
POINT gHatchOffset;
|
||
WNDPROC gfnHatchWndProc = NULL;
|
||
|
||
BOOL gfOle2Open = FALSE;
|
||
BOOL gfOle2IPEditing = FALSE;
|
||
BOOL gfOle2IPPlaying = FALSE;
|
||
BOOL gfInPlaceResize = FALSE; //TRUE: We have resized when InPlace
|
||
BOOL gfTopAndBottomTool = TRUE; // We have toolbars both on top and bottom
|
||
RECT gInPlacePosRect; //Our position in the container.
|
||
HWND ghwndCntr; //Container
|
||
HWND ghwndFrame = NULL; //Frame of the container.
|
||
int toolbarwidth;
|
||
BOOL gfPosRectChange = FALSE;
|
||
RECT gPrevPosRect;
|
||
|
||
BOOL gfInPPViewer; /* Hack to stop PowerPoint Viewer crashing */
|
||
|
||
extern TCHAR szToolBarClass[];
|
||
extern HMENU ghDeviceMenu; /* handle to the Device menu */
|
||
extern UINT gwPlaybarHeight; //tell playbar how tall to make
|
||
//itself so it covers the title
|
||
void AllocInPlaceDataBlock (LPDOC lpdoc);
|
||
void FreeInPlaceDataBlock (LPDOC lpdoc);
|
||
void DeactivateTools(LPDOC lpdoc);
|
||
HRESULT ActivateTools(LPDOC lpdoc, BOOL fPlayOnly);
|
||
void InPlaceCreateControls(BOOL fPlayOnly);
|
||
LONG_PTR FAR PASCAL SubClassedHatchWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
|
||
|
||
|
||
|
||
/**************************************************************************
|
||
* TransferTools:
|
||
* This function changes parents and positions the toolbar buttons
|
||
* from the main Mplayer window to the toolbar window/windows we will
|
||
* display in the client.
|
||
***************************************************************************/
|
||
void TransferTools(HWND hwndToolWindow)
|
||
{
|
||
SetParent(ghwndToolbar, hwndToolWindow);
|
||
MoveWindow(ghwndToolbar, 5,0,7*BUTTONWIDTH+15,TOOL_WIDTH,TRUE);
|
||
SetParent(ghwndMark, hwndToolWindow);
|
||
MoveWindow(ghwndMark, 7*BUTTONWIDTH+16,0,2*BUTTONWIDTH+15,TOOL_WIDTH,TRUE);
|
||
SetParent(ghwndFSArrows, hwndToolWindow);
|
||
MoveWindow(ghwndFSArrows, 9*BUTTONWIDTH+16+10+3,0,toolbarwidth-9*BUTTONWIDTH-25,TOOL_WIDTH,TRUE);
|
||
if(!ghwndMCI) {
|
||
toolbarModifyState(ghwndToolbar, BTN_EJECT, TBINDEX_MAIN, BTNST_GRAYED);
|
||
toolbarModifyState(ghwndToolbar, BTN_STOP, TBINDEX_MAIN, BTNST_GRAYED);
|
||
toolbarModifyState(ghwndToolbar, BTN_PLAY, TBINDEX_MAIN, BTNST_GRAYED);
|
||
toolbarModifyState(ghwndMark, BTN_MARKIN, TBINDEX_MARK, BTNST_GRAYED);
|
||
toolbarModifyState(ghwndMark, BTN_MARKOUT, TBINDEX_MARK, BTNST_GRAYED);
|
||
toolbarModifyState(ghwndFSArrows, ARROW_PREV, TBINDEX_ARROWS, BTNST_GRAYED);
|
||
toolbarModifyState(ghwndFSArrows, ARROW_NEXT, TBINDEX_ARROWS, BTNST_GRAYED);
|
||
}
|
||
if(hwndToolWindow == ghwndApp)
|
||
{
|
||
SetParent(ghwndTrackbar,ghwndApp);
|
||
SetParent(ghwndMap,ghwndApp);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**************************************************************************
|
||
* ActivateTools:
|
||
* This function negotiates for toolbar space with the client. If possible
|
||
* one broad toolbar is placed at the top of the client, if not the
|
||
* toolbar is split and one is placed on top and other at bottom. If even
|
||
* that is not possible then the function fails. The top toolbar window is
|
||
* ghwndIPToolWindow and the bottom one is ghwndIPScrollWindow (because it
|
||
* has the scrolling trackbar.
|
||
*
|
||
* fPlayOnly is TRUE if we are just going to play. In that case a dummy, empty
|
||
* tool bar is transferred. No, we don't want anything. But we have to
|
||
* negotiate space, even empty space, otherwise Word doesn't think we're
|
||
* in-place active.
|
||
***************************************************************************/
|
||
HRESULT ActivateTools(LPDOC lpdoc, BOOL fPlayOnly)
|
||
{
|
||
RECT rect, size;
|
||
SCODE sc;
|
||
|
||
|
||
size.left = 0;
|
||
size.top = 0;
|
||
size.bottom = 0;
|
||
size.right = 0;
|
||
IOleInPlaceFrame_GetBorder(lpdoc->lpIpData->lpFrame, &rect);
|
||
if (fPlayOnly)
|
||
size.top = DUMMY_TOOLBAR_WIDTH; /* This is now 0 - no toolbar space needed */
|
||
else
|
||
size.top = 3*TOOL_WIDTH+1;
|
||
size.bottom = 0;
|
||
sc = GetScode(IOleInPlaceFrame_RequestBorderSpace(lpdoc->lpIpData->lpFrame,
|
||
&size));
|
||
if (sc == S_OK)
|
||
{
|
||
size.bottom = size.left = size.right = 0;
|
||
if (fPlayOnly)
|
||
size.top = DUMMY_TOOLBAR_WIDTH;
|
||
else
|
||
size.top = 3*TOOL_WIDTH+1;
|
||
|
||
sc = GetScode(IOleInPlaceFrame_SetBorderSpace(lpdoc->lpIpData->lpFrame,
|
||
&size));
|
||
if (sc != S_OK)
|
||
goto ToolBottom;
|
||
|
||
IOleInPlaceFrame_GetBorder(lpdoc->lpIpData->lpFrame, &rect);
|
||
|
||
IOleInPlaceFrame_GetWindow (lpdoc->lpIpData->lpFrame, &ghwndFrame);
|
||
|
||
if (GetParent(ghwndIPToolWindow) != ghwndFrame)
|
||
SetParent(ghwndIPToolWindow, ghwndFrame);
|
||
|
||
if (!fPlayOnly)
|
||
MoveWindow(ghwndIPToolWindow, rect.left, rect.top,
|
||
toolbarwidth, 3*TOOL_WIDTH+1, TRUE);
|
||
else
|
||
return NOERROR; /* That's all folks, if we're just playing. */
|
||
|
||
if(ghwndIPToolWindow != GetParent(ghwndTrackbar))
|
||
{
|
||
SetParent(ghwndTrackbar,ghwndIPToolWindow);
|
||
SetWindowPos(ghwndTrackbar, NULL,3,TOOL_WIDTH+2,
|
||
11*BUTTONWIDTH+15,FSTRACK_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
|
||
SetParent(ghwndMap,ghwndIPToolWindow);
|
||
SetWindowPos(ghwndMap, NULL,3,TOOL_WIDTH+FSTRACK_HEIGHT+2+2,
|
||
11*BUTTONWIDTH+50,MAP_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
|
||
}
|
||
ShowWindow(ghwndIPToolWindow, SW_SHOW);
|
||
ShowWindow(ghwndMark, SW_SHOW);
|
||
ShowWindow(ghwndFSArrows, SW_SHOW);
|
||
|
||
gfTopAndBottomTool = FALSE;
|
||
return NOERROR;
|
||
|
||
}
|
||
else
|
||
{
|
||
ToolBottom:
|
||
if (!fPlayOnly)
|
||
{
|
||
size.top = TOOL_WIDTH+1;
|
||
size.bottom = 2*TOOL_WIDTH+1;
|
||
}
|
||
else
|
||
{
|
||
ShowWindow(ghwndFSArrows, SW_HIDE);
|
||
ShowWindow(ghwndStatic, SW_HIDE);
|
||
ShowWindow(ghwndMark, SW_HIDE);
|
||
return NOERROR;
|
||
}
|
||
sc = GetScode(IOleInPlaceFrame_RequestBorderSpace(lpdoc->lpIpData->lpFrame,
|
||
&size));
|
||
size.left = size.right = 0;
|
||
size.top = TOOL_WIDTH+1;
|
||
size.bottom = 2*TOOL_WIDTH+1;
|
||
if (sc != S_OK)
|
||
goto error;
|
||
|
||
sc = GetScode(IOleInPlaceFrame_SetBorderSpace(lpdoc->lpIpData->lpFrame,
|
||
&size));
|
||
if (sc != S_OK)
|
||
goto error;
|
||
|
||
IOleInPlaceFrame_GetBorder(lpdoc->lpIpData->lpFrame, &rect);
|
||
|
||
if (GetParent(ghwndIPToolWindow) != ghwndFrame)
|
||
{
|
||
SetParent(ghwndIPToolWindow, ghwndFrame);
|
||
SetParent(ghwndIPScrollWindow, ghwndFrame);
|
||
}
|
||
|
||
if(ghwndIPScrollWindow != GetParent(ghwndTrackbar))
|
||
{
|
||
SetParent(ghwndTrackbar,ghwndIPScrollWindow);
|
||
SetWindowPos(ghwndTrackbar, NULL,3,4,
|
||
11*BUTTONWIDTH+15,FSTRACK_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
|
||
SetParent(ghwndMap,ghwndIPScrollWindow);
|
||
SetWindowPos(ghwndMap, NULL,3,FSTRACK_HEIGHT+4+2,
|
||
11*BUTTONWIDTH+50,MAP_HEIGHT,SWP_NOZORDER | SWP_NOACTIVATE);
|
||
}
|
||
|
||
MoveWindow(ghwndIPToolWindow, rect.left, rect.top,
|
||
toolbarwidth, TOOL_WIDTH+1, TRUE);
|
||
ShowWindow(ghwndIPToolWindow, SW_SHOW);
|
||
MoveWindow(ghwndIPScrollWindow, rect.left,rect.bottom-2*TOOL_WIDTH,//-1,
|
||
toolbarwidth,2*TOOL_WIDTH+1,TRUE);
|
||
ShowWindow(ghwndIPScrollWindow, SW_SHOW);
|
||
gfTopAndBottomTool = TRUE;
|
||
return NOERROR;
|
||
}
|
||
error:
|
||
RETURN_RESULT(sc);
|
||
}
|
||
|
||
|
||
/**************************************************************************
|
||
* DeactivateTools:
|
||
* Hides the toolbars.
|
||
***************************************************************************/
|
||
void DeactivateTools(LPDOC lpdoc)
|
||
{
|
||
ShowWindow(ghwndIPToolWindow, SW_HIDE);
|
||
SetParent(ghwndIPToolWindow, NULL);
|
||
if (gfTopAndBottomTool)
|
||
{
|
||
ShowWindow(ghwndIPScrollWindow, SW_HIDE);
|
||
SetParent(ghwndIPScrollWindow, NULL);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/**************************************************************************
|
||
************ IOleInPlaceObject INTERFACE IMPLEMENTATION.
|
||
***************************************************************************/
|
||
//Delegate to the common IUnknown implementation.
|
||
STDMETHODIMP IPObjQueryInterface (
|
||
LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
|
||
REFIID riidReq, // IID required
|
||
LPVOID FAR * lplpUnk // pre for returning the interface
|
||
)
|
||
{
|
||
return UnkQueryInterface((LPUNKNOWN)lpIPObj, riidReq, lplpUnk);
|
||
}
|
||
|
||
|
||
STDMETHODIMP_(ULONG) IPObjAddRef(
|
||
LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
|
||
)
|
||
{
|
||
return UnkAddRef((LPUNKNOWN) lpIPObj);
|
||
}
|
||
|
||
|
||
STDMETHODIMP_(ULONG) IPObjRelease(
|
||
LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
|
||
)
|
||
{
|
||
return UnkRelease((LPUNKNOWN) lpIPObj);
|
||
}
|
||
|
||
|
||
STDMETHODIMP IPObjGetWindow(
|
||
LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
|
||
HWND FAR* lphwnd // window handle of the object
|
||
)
|
||
{
|
||
DPF("IPObjGetWindow\n");
|
||
*lphwnd = docMain.hwnd;
|
||
return NOERROR;
|
||
}
|
||
|
||
|
||
STDMETHODIMP IPObjContextSensitiveHelp(
|
||
LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
|
||
BOOL fEnable
|
||
)
|
||
{
|
||
//Not very useful at this time.
|
||
|
||
LPDOC lpdoc;
|
||
|
||
lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
|
||
lpdoc->lpIpData->fInContextHelpMode = fEnable;
|
||
return NOERROR;
|
||
}
|
||
|
||
|
||
STDMETHODIMP IPObjInPlaceDeactivate(
|
||
LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
|
||
)
|
||
{
|
||
LPDOC lpdoc;
|
||
LPINPLACEDATA lpIpData;
|
||
static int EntryCount; /* OLE sometimes calls us recursively. */
|
||
|
||
DPF("IPObjInPlaceDeactivate\n");
|
||
|
||
if (EntryCount++ == 0)
|
||
{
|
||
lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
|
||
lpIpData = lpdoc->lpIpData;
|
||
|
||
if (lpIpData)
|
||
{
|
||
// This stops PowerPoint crashing, since it forces UpdateObject
|
||
// to send change notification when there's an empty Media Clip.
|
||
if (gwDeviceID == 0)
|
||
fDocChanged = TRUE;
|
||
|
||
//Make sure the container has the correct metafile before we are hidden
|
||
UpdateObject();
|
||
IOleInPlaceObject_UIDeactivate ((LPOLEINPLACEOBJECT)&lpdoc->m_InPlace);
|
||
|
||
if (lpIpData && lpIpData->lpSite)
|
||
{
|
||
if (!gfInPPViewer)
|
||
IOleInPlaceSite_OnInPlaceDeactivate (lpIpData->lpSite);
|
||
|
||
IOleInPlaceSite_Release (lpIpData->lpSite);
|
||
}
|
||
|
||
FreeInPlaceDataBlock (lpdoc);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* This sometimes happens during the above OnInPlaceDeactivate call,
|
||
* which resulted in an access violation because the data block had
|
||
* been freed when the call returned.
|
||
* According to the OLE guys, apps should guard against this.
|
||
*/
|
||
DPF("Attempt to re-enter IPObjInPlaceDeactivate\n");
|
||
}
|
||
|
||
--EntryCount;
|
||
|
||
/* Dontcha just love these global variables!
|
||
*/
|
||
gfOle2IPEditing = FALSE;
|
||
gfOle2IPPlaying = FALSE;
|
||
gfPlayingInPlace = FALSE;
|
||
|
||
return NOERROR;
|
||
}
|
||
|
||
//Hide our inplace UI.
|
||
STDMETHODIMP IPObjUIDeactivate(
|
||
LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
|
||
)
|
||
{
|
||
LPDOC lpdoc;
|
||
|
||
DPF("IPObjUIDeactivate\n");
|
||
lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
|
||
|
||
if (!(lpdoc->lpIpData && lpdoc->lpIpData->lpFrame))
|
||
return NOERROR;
|
||
|
||
IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame, NULL, NULL, lpdoc->hwnd);
|
||
// clear inplace-state
|
||
|
||
IOleInPlaceFrame_SetActiveObject (lpdoc->lpIpData->lpFrame, NULL, NULL);
|
||
|
||
if (lpdoc->lpIpData->lpUIWindow)
|
||
IOleInPlaceUIWindow_SetActiveObject (lpdoc->lpIpData->lpUIWindow, NULL, NULL);
|
||
|
||
if(gfOle2IPPlaying)
|
||
PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
|
||
|
||
/* We could also be playing if we're in-place editing:
|
||
*/
|
||
else if(gfOle2IPEditing && (gwStatus == MCI_MODE_PLAY || gwStatus == MCI_MODE_SEEK))
|
||
PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
|
||
|
||
ShowWindow(ghwndIPHatch,SW_HIDE);
|
||
|
||
DeactivateTools(lpdoc);
|
||
DisassembleMenus (lpdoc);
|
||
|
||
if (lpdoc->lpIpData->lpUIWindow) {
|
||
IOleInPlaceUIWindow_Release (lpdoc->lpIpData->lpUIWindow);
|
||
lpdoc->lpIpData->lpUIWindow = NULL;
|
||
}
|
||
|
||
if (lpdoc->lpIpData->lpFrame) {
|
||
IOleInPlaceFrame_Release (lpdoc->lpIpData->lpFrame);
|
||
lpdoc->lpIpData->lpFrame = NULL;
|
||
}
|
||
|
||
// Set the parent back to hwndClient window
|
||
SetParent(ghwndIPHatch,NULL);
|
||
gPrevPosRect.left = gPrevPosRect.top =gPrevPosRect.right = gPrevPosRect.bottom = 0;
|
||
lpdoc->hwndParent = NULL;
|
||
|
||
if (!gfInPPViewer)
|
||
IOleInPlaceSite_OnUIDeactivate (lpdoc->lpIpData->lpSite, FALSE);
|
||
|
||
return NOERROR;
|
||
}
|
||
|
||
/**************************************************************************
|
||
* IPObjSetObjectRects:
|
||
* The client specifies our window position and size. Move our
|
||
* window accordingly. Also size the Hatch window to fit around the
|
||
* ghwndApp. If the change is very small compared to the previous
|
||
* size ignore and return. This account for slop speeds things up.
|
||
***************************************************************************/
|
||
STDMETHODIMP IPObjSetObjectRects(
|
||
LPOLEINPLACEOBJECT lpIPObj, // inplace object ptr
|
||
LPCRECT lprcPosRect,
|
||
LPCRECT lprcVisRect
|
||
)
|
||
{
|
||
LPDOC lpdoc;
|
||
RECT rc;
|
||
|
||
GetWindowRect(ghwndApp, (LPRECT)&rc);
|
||
|
||
DPFI("\n*IPObjSetObjectRects");
|
||
DPFI("\n^^^^^^^^ LPRECPOSRECT: %d, %d, %d, %d ^^^^\n", *lprcPosRect);
|
||
DPFI("\n^^^^^^^^ PREVRECT: %d, %d, %d, %d ^^^^\n", gPrevPosRect);
|
||
DPFI("\n^^^^^^^^ HWNDRECT: %d, %d, %d, %d ^^^^\n", rc);
|
||
|
||
lpdoc = ((struct COleInPlaceObjectImpl FAR*)lpIPObj)->lpdoc;
|
||
if (!ghwndIPHatch || (ghwndCntr != GetParent(ghwndIPHatch)))
|
||
return NOERROR;
|
||
if (!(lpdoc->lpIpData))
|
||
return NOERROR;
|
||
|
||
rc = *lprcPosRect;
|
||
|
||
if (!(gwDeviceID == (UINT)0 || !(gwDeviceType & DTMCI_CANWINDOW)))
|
||
SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rc,lprcVisRect, (LPPOINT)&gHatchOffset,TRUE);
|
||
else
|
||
SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rc,lprcVisRect, (LPPOINT)&gHatchOffset,FALSE);
|
||
|
||
|
||
if(!(gwDeviceType & DTMCI_CANWINDOW) && (gwOptions & OPT_BAR))
|
||
rc.top = rc.bottom - gwPlaybarHeight;
|
||
if(!(gwDeviceType & DTMCI_CANWINDOW) && !(gwOptions & OPT_BAR))
|
||
rc.bottom = rc.top = rc.left = rc.right = 0;
|
||
MapWindowPoints(ghwndCntr,ghwndIPHatch,(LPPOINT)&rc, 2);
|
||
gfPosRectChange = TRUE;
|
||
|
||
if (gwDeviceID)
|
||
MoveWindow(lpdoc->hwnd, rc.left, rc.top,
|
||
rc.right - rc.left,
|
||
rc.bottom - rc.top, TRUE);
|
||
else
|
||
MoveWindow(lpdoc->hwnd, rc.left, rc.top,
|
||
rc.right - rc.left,
|
||
rc.bottom - rc.top, FALSE);
|
||
|
||
GetWindowRect(lpdoc->hwnd, &gInPlacePosRect);
|
||
gPrevPosRect = *lprcPosRect;
|
||
|
||
/* I've commented out the below line, because PowerPoint calls
|
||
* SetObjectRects after we deactivate, and this was causing the
|
||
* MPlayer window to reappear when it was supposed to be hidden.
|
||
* This line seems to have been superfluous in any case.
|
||
*/
|
||
// ShowWindow(ghwndIPHatch,SW_SHOW);
|
||
|
||
return NOERROR;
|
||
}
|
||
|
||
//We don't have an Undo state.
|
||
STDMETHODIMP IPObjReactivateAndUndo(
|
||
LPOLEINPLACEOBJECT lpIPObj // inplace object ptr
|
||
)
|
||
{
|
||
RETURN_RESULT(INPLACE_E_NOTUNDOABLE);
|
||
}
|
||
|
||
|
||
|
||
/**************************************************************************
|
||
************** IOleInPlaceActiveObject INTERFACE IMPLEMENTATION.
|
||
***************************************************************************/
|
||
//delegate to the common IUnknown implementation.
|
||
STDMETHODIMP IPActiveQueryInterface (
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
REFIID riidReq, // IID required
|
||
LPVOID FAR * lplpUnk // pre for returning the interface
|
||
)
|
||
{
|
||
return UnkQueryInterface((LPUNKNOWN)lpIPActive, riidReq, lplpUnk);
|
||
}
|
||
|
||
|
||
STDMETHODIMP_(ULONG) IPActiveAddRef(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive // inplace active object ptr
|
||
)
|
||
{
|
||
return UnkAddRef((LPUNKNOWN) lpIPActive);
|
||
}
|
||
|
||
|
||
STDMETHODIMP_(ULONG) IPActiveRelease (
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive // inplace active object ptr
|
||
)
|
||
{
|
||
return UnkRelease((LPUNKNOWN) lpIPActive);
|
||
}
|
||
|
||
|
||
STDMETHODIMP IPActiveGetWindow(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
HWND FAR* lphwnd // window handle of the object
|
||
)
|
||
{
|
||
DPF("IPActiveGetWindow\n");
|
||
*lphwnd = ghwndIPHatch;
|
||
return NOERROR;
|
||
}
|
||
|
||
//Not very useful at this time.
|
||
STDMETHODIMP IPActiveContextSensitiveHelp(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
BOOL fEnable
|
||
)
|
||
{
|
||
LPDOC lpdoc;
|
||
|
||
lpdoc = ((struct COleInPlaceActiveObjectImpl FAR*)lpIPActive)->lpdoc;
|
||
lpdoc->lpIpData->fInContextHelpMode = fEnable;
|
||
return NOERROR;
|
||
}
|
||
|
||
|
||
|
||
STDMETHODIMP IPActiveTranslateAccelerator(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
LPMSG lpmsg
|
||
)
|
||
{
|
||
// This will never be called because this server is implemented as an EXE
|
||
RETURN_RESULT(S_FALSE);
|
||
}
|
||
|
||
STDMETHODIMP IPActiveOnFrameWindowActivate(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
BOOL fActivate
|
||
)
|
||
{
|
||
DPF("IPActiveOnFrameWindowActivate = %d **\r\n", (int)fActivate);
|
||
if (gwStatus == MCI_MODE_PAUSE)
|
||
PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
|
||
|
||
return NOERROR;
|
||
}
|
||
|
||
|
||
//If activating show the toolbar and menu. If not hide the toolbar and menu.
|
||
STDMETHODIMP IPActiveOnDocWindowActivate(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
BOOL fActivate
|
||
)
|
||
{
|
||
LPDOC lpdoc;
|
||
RECT rc;
|
||
DPF("IPActiveOnDocWindowActivate\n");
|
||
lpdoc = ((struct COleInPlaceActiveObjectImpl FAR*)lpIPActive)->lpdoc;
|
||
GetWindowRect(lpdoc->hwnd, &rc);
|
||
ScreenToClient(lpdoc->hwndParent, (POINT FAR *)&rc);
|
||
ScreenToClient(lpdoc->hwndParent, (POINT FAR *)&(rc.right));
|
||
if (fActivate) {
|
||
|
||
if(gfOle2IPEditing)
|
||
{
|
||
ActivateTools(lpdoc,FALSE);
|
||
TransferTools(ghwndIPToolWindow);
|
||
}
|
||
else
|
||
{
|
||
ActivateTools(lpdoc,TRUE);
|
||
TransferTools(ghwndApp);
|
||
}
|
||
|
||
Layout();
|
||
|
||
IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
|
||
lpdoc->lpIpData->hmenuShared,
|
||
lpdoc->lpIpData->holemenu,
|
||
lpdoc->hwnd);
|
||
}
|
||
else {
|
||
DeactivateTools(lpdoc);
|
||
if(gfOle2IPPlaying)
|
||
PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
|
||
IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
|
||
NULL, NULL, lpdoc->hwnd);
|
||
}
|
||
return NOERROR;
|
||
}
|
||
|
||
//If we have a toolwindow at the bottom reposition that window to match
|
||
//the new frame window size.
|
||
STDMETHODIMP IPActiveResizeBorder(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
LPCRECT lprectBorder,
|
||
LPOLEINPLACEUIWINDOW lpIPUiWnd,
|
||
BOOL fFrameWindow
|
||
)
|
||
{
|
||
DPF("IPActiveResizeBorder\n");
|
||
|
||
if (fFrameWindow)
|
||
{
|
||
LPDOC lpdoc;
|
||
|
||
lpdoc = ((struct COleInPlaceActiveObjectImpl FAR*)lpIPActive)->lpdoc;
|
||
if (gfTopAndBottomTool && (GetParent(ghwndIPScrollWindow) != NULL))
|
||
MoveWindow(ghwndIPScrollWindow, lprectBorder->left,lprectBorder->bottom-2*TOOL_WIDTH,
|
||
toolbarwidth,2*TOOL_WIDTH+1,TRUE);
|
||
|
||
}
|
||
return NOERROR;
|
||
}
|
||
|
||
STDMETHODIMP IPActiveEnableModeless(
|
||
LPOLEINPLACEACTIVEOBJECT lpIPActive, // inplace active object ptr
|
||
BOOL fEnable
|
||
)
|
||
{
|
||
return NOERROR;
|
||
}
|
||
|
||
|
||
/**************************************************************************
|
||
* DoInplaceEdit:
|
||
* This is the function that initiates the InPlace activation from the
|
||
* server side. It sets up the InPlace data structures required by us,
|
||
* makes sure that the client supports the required interfaces and
|
||
* can provide the space we require. It also prepares the toolbar to be
|
||
* displayed and the layout of the Mplayer window.
|
||
***************************************************************************/
|
||
STDMETHODIMP DoInPlaceEdit(
|
||
LPDOC lpdoc,
|
||
LPMSG lpmsg,
|
||
LPOLECLIENTSITE lpActiveSite,
|
||
LONG verb,
|
||
HWND FAR * lphwnd,
|
||
LPRECT lprect
|
||
)
|
||
{
|
||
SCODE error = S_OK;
|
||
LPOLEINPLACESITE lpIPSite;
|
||
RECT rcPos;
|
||
RECT rcVis;
|
||
RECT hatchrc;
|
||
LPWSTR lpObjName;
|
||
|
||
if (!(lpdoc->lpoleclient))
|
||
RETURN_RESULT( E_FAIL);
|
||
|
||
if (!(lpdoc->lpIpData))
|
||
{
|
||
if ((error = GetScode(IOleClientSite_QueryInterface(
|
||
lpdoc->lpoleclient,
|
||
&IID_IOleInPlaceSite,
|
||
(void FAR* FAR*) &lpIPSite))) != S_OK)
|
||
RETURN_RESULT( error);
|
||
|
||
if ((error = GetScode(IOleInPlaceSite_CanInPlaceActivate(lpIPSite))) != S_OK)
|
||
goto errActivate;
|
||
|
||
if (!gfInPPViewer)
|
||
IOleInPlaceSite_OnInPlaceActivate(lpIPSite);
|
||
|
||
AllocInPlaceDataBlock (lpdoc);
|
||
lpdoc->lpIpData->lpSite = lpIPSite;
|
||
}
|
||
|
||
if ((error = GetScode(IOleInPlaceSite_GetWindow (lpdoc->lpIpData->lpSite, &lpdoc->hwndParent))) != S_OK)
|
||
goto errRtn;
|
||
|
||
if (!(lpdoc->hwndParent))
|
||
goto errRtn;
|
||
|
||
if (!gfInPPViewer)
|
||
IOleInPlaceSite_OnUIActivate(lpdoc->lpIpData->lpSite);
|
||
|
||
if ((error = GetScode(IOleInPlaceSite_GetWindowContext(
|
||
lpdoc->lpIpData->lpSite,
|
||
&lpdoc->lpIpData->lpFrame,
|
||
&lpdoc->lpIpData->lpUIWindow,
|
||
&rcPos, &rcVis,
|
||
&lpdoc->lpIpData->frameInfo))) != S_OK)
|
||
goto errRtn;
|
||
|
||
#ifdef LATER
|
||
if (gscaleInitXY[SCALE_X].denom)
|
||
{
|
||
gscaleInitXY[SCALE_X].num = (rcPos.right - rcPos.left) * HIMETRIC_PER_INCH / giXppli;
|
||
gscaleInitXY[SCALE_Y].num = (rcPos.bottom - rcPos.top) * HIMETRIC_PER_INCH / giYppli;
|
||
|
||
DPF0("Scale: %d%c X %d%c (%d/%d X %d/%d)\n",
|
||
gscaleInitXY[SCALE_X].num * 100 / gscaleInitXY[SCALE_X].denom, '%',
|
||
gscaleInitXY[SCALE_Y].num * 100 / gscaleInitXY[SCALE_Y].denom, '%',
|
||
gscaleInitXY[SCALE_X].num,
|
||
gscaleInitXY[SCALE_X].denom,
|
||
gscaleInitXY[SCALE_Y].num,
|
||
gscaleInitXY[SCALE_Y].denom);
|
||
}
|
||
#endif
|
||
|
||
#ifdef UNICODE
|
||
lpObjName = gachClassRoot;
|
||
#else
|
||
lpObjName = AllocateUnicodeString(gachClassRoot);
|
||
if (!lpObjName)
|
||
RETURN_RESULT(E_OUTOFMEMORY);
|
||
#endif /* UNICODE */
|
||
|
||
IOleInPlaceFrame_SetActiveObject (lpdoc->lpIpData->lpFrame,
|
||
(LPOLEINPLACEACTIVEOBJECT) &lpdoc->m_IPActive,
|
||
lpObjName);
|
||
if (lpdoc->lpIpData->lpUIWindow) {
|
||
IOleInPlaceUIWindow_SetActiveObject (lpdoc->lpIpData->lpUIWindow,
|
||
(LPOLEINPLACEACTIVEOBJECT) &lpdoc->m_IPActive,
|
||
lpObjName);
|
||
}
|
||
|
||
#ifndef UNICODE
|
||
FreeUnicodeString(lpObjName);
|
||
#endif
|
||
|
||
ghwndCntr = lpdoc->hwndParent;
|
||
|
||
//Create and initialize the hatch window to surround the Mplayer window.
|
||
if (!ghwndIPHatch)
|
||
{
|
||
RegisterHatchWindowClass(ghInst);
|
||
if ( !(ghwndIPHatch = CreateHatchWindow(lpdoc->hwndParent,ghInst)))
|
||
goto errRtn;
|
||
gfnHatchWndProc = (WNDPROC)GetWindowLongPtr(ghwndIPHatch, GWLP_WNDPROC);
|
||
SetWindowLongPtr(ghwndIPHatch, GWLP_WNDPROC, (LONG_PTR)SubClassedHatchWndProc);
|
||
}
|
||
|
||
|
||
SetParent(ghwndIPHatch, ghwndCntr);
|
||
|
||
SetFocus(ghwndIPHatch);
|
||
|
||
CopyRect(&hatchrc, &rcPos);
|
||
|
||
#define EB_HATCHWIDTH (0 * sizeof(INT))
|
||
if (verb == OLEIVERB_PRIMARY)
|
||
{
|
||
/* I don't want to show the hatch window on play, because it looks
|
||
* really bad in PowerPoint. Can't make it invisible, because
|
||
* the app window is its child, and it inherits the flag.
|
||
* Instead, just make it of zero width.
|
||
*/
|
||
SETWINDOWUINT(ghwndIPHatch, EB_HATCHWIDTH, 0);
|
||
}
|
||
else
|
||
{
|
||
SETWINDOWUINT(ghwndIPHatch, EB_HATCHWIDTH, DEF_HATCH_SZ);
|
||
InflateRect(&hatchrc, DEF_HATCH_SZ, DEF_HATCH_SZ);
|
||
}
|
||
|
||
|
||
SetHatchRect(ghwndIPHatch,(LPRECT)&hatchrc);
|
||
|
||
|
||
*lphwnd = ghwndIPHatch;
|
||
|
||
//If we are going to Play inplace, do the minimum stuff and return.
|
||
if (verb == OLEIVERB_PRIMARY)
|
||
{
|
||
gfOle2IPPlaying = TRUE;
|
||
|
||
GetWindowRect(ghwndCntr,(LPRECT)&rcVis);
|
||
MapWindowPoints(NULL,ghwndCntr,(LPPOINT)&rcVis, 2);
|
||
SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rcPos,(LPRECT)&rcVis, (LPPOINT)&gHatchOffset,FALSE);
|
||
MoveWindow(ghwndApp, 0, 0, rcPos.right - rcPos.left, rcPos.bottom - rcPos.top, TRUE);
|
||
InPlaceCreateControls(TRUE);
|
||
ActivateTools(lpdoc, TRUE);
|
||
TransferTools(ghwndApp);
|
||
|
||
ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos);
|
||
ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos+1);
|
||
|
||
lpdoc->hwndParent = NULL;
|
||
|
||
/* MENU STUFF */
|
||
/* We have to set the menus even if we're only playing, because otherwise
|
||
* Word doesn't believe we're in-place active, and doesn't send us any
|
||
* deactivation notification when the user clicks outside us.
|
||
*/
|
||
AssembleMenus (lpdoc, TRUE);
|
||
|
||
if ((error = GetScode(IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
|
||
lpdoc->lpIpData->hmenuShared,
|
||
lpdoc->lpIpData->holemenu,
|
||
lpdoc->hwnd))) != S_OK)
|
||
goto errRtn;
|
||
/* END MENU STUFF */
|
||
|
||
*lprect = rcPos;
|
||
|
||
ShowWindow(ghwndIPHatch, SW_SHOW);
|
||
return NOERROR;
|
||
}
|
||
|
||
//Edit InPlace.
|
||
|
||
|
||
if (!(gwDeviceID == (UINT)0 || !(gwDeviceType & DTMCI_CANWINDOW)))
|
||
//No resize handles.
|
||
SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rcPos,(LPRECT)&rcVis, (LPPOINT)&gHatchOffset,TRUE);
|
||
else
|
||
//There will be resize handles.
|
||
SetHatchWindowSize(ghwndIPHatch, (LPRECT)&rcPos,(LPRECT)&rcVis, (LPPOINT)&gHatchOffset,FALSE);
|
||
|
||
gfOle2IPEditing = TRUE;
|
||
|
||
if (!SkipInPlaceEdit) //don't layout and transfer the tools
|
||
{ // if we are just reactivating.
|
||
DestroyWindow(ghwndStatic);
|
||
ghwndStatic = CreateStaticStatusWindow(ghwndApp, FALSE);
|
||
SendMessage(ghwndStatic, WM_SETFONT, (UINT_PTR)ghfontMap, 0);
|
||
Layout();
|
||
InPlaceCreateControls(FALSE);
|
||
}
|
||
|
||
else
|
||
SetParent (lpdoc->hwnd, ghwndIPHatch);
|
||
|
||
TransferTools(ghwndIPToolWindow);
|
||
|
||
if ((error = GetScode(AssembleMenus (lpdoc, FALSE))) != S_OK)
|
||
goto errRtn;
|
||
|
||
ShowWindow (lpdoc->hwnd, SW_HIDE);
|
||
// currently we are not using the pane
|
||
|
||
// prevent OnDataChange() notification
|
||
lpdoc->lpIpData->fNoNotification = FALSE;
|
||
|
||
if ((error = GetScode(IOleInPlaceFrame_SetMenu (lpdoc->lpIpData->lpFrame,
|
||
lpdoc->lpIpData->hmenuShared,
|
||
lpdoc->lpIpData->holemenu,
|
||
lpdoc->hwnd))) != S_OK)
|
||
goto errRtn;
|
||
|
||
if ((error = GetScode(ActivateTools(lpdoc,FALSE))) != S_OK)
|
||
goto errRtn;
|
||
|
||
ShowWindow(ghwndIPHatch,SW_SHOW);
|
||
ShowWindow(ghwndMCI,SW_SHOW);
|
||
|
||
ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos);
|
||
ClientToScreen(lpdoc->hwndParent, (LPPOINT)&rcPos+1);
|
||
|
||
*lprect = rcPos;
|
||
if (SkipInPlaceEdit)
|
||
OffsetRect(&gInPlacePosRect,rcPos.left-gInPlacePosRect.left,
|
||
rcPos.top-gInPlacePosRect.top);
|
||
|
||
else
|
||
gInPlacePosRect = rcPos;
|
||
return NOERROR;
|
||
|
||
errRtn:
|
||
DoInPlaceDeactivate(lpdoc);
|
||
TransferTools(ghwndApp);
|
||
RETURN_RESULT(error);
|
||
|
||
errActivate:
|
||
IOleInPlaceSite_Release(lpIPSite);
|
||
|
||
FreeInPlaceDataBlock (lpdoc);
|
||
RETURN_RESULT( error);
|
||
}
|
||
|
||
#if 0
|
||
HMENU GetInPlaceMenu(void)
|
||
{
|
||
if (ghInPlaceMenu)
|
||
return GetSubMenu(ghInPlaceMenu,0);
|
||
else
|
||
{
|
||
ghInPlaceMenu = LoadMenu(ghInst, TEXT("InPlaceMenu"));
|
||
return GetSubMenu(ghInPlaceMenu,0);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/**************************************************************************
|
||
* AssembleMenus:
|
||
* This function merges our menu with that of the client.
|
||
***************************************************************************/
|
||
STDMETHODIMP AssembleMenus (LPDOC lpdoc, BOOL fPlayOnly)
|
||
{
|
||
|
||
HMENU hmenuMain = ghMenu;
|
||
HMENU hmenuEditPopup = GetSubMenu(hmenuMain, menuposEdit);
|
||
HMENU hmenuDevicePopup = GetSubMenu(hmenuMain, menuposDevice);
|
||
HMENU hmenuScalePopup = GetSubMenu(hmenuMain, menuposScale);
|
||
//HMENU hmenuCommandPopup = GetInPlaceMenu();
|
||
HMENU hmenuHelpPopup = GetSubMenu(hmenuMain, menuposHelp);
|
||
|
||
HMENU hmenuShared;
|
||
LONG FAR* lpMenuWidths;
|
||
SCODE error = S_OK;
|
||
UINT uPos;
|
||
UINT uPosStart;
|
||
static TCHAR szEdit[40] = TEXT("");
|
||
static TCHAR szInsert[40] = TEXT("");
|
||
static TCHAR szScale[40] = TEXT("");
|
||
//static TCHAR szCommand[40] = TEXT("");
|
||
static TCHAR szHelp[40] = TEXT("");
|
||
|
||
if (szEdit[0] == TEXT('\0'))
|
||
{
|
||
LOADSTRING(IDS_EDITMENU, szEdit);
|
||
LOADSTRING(IDS_INSERTMENU, szInsert);
|
||
LOADSTRING(IDS_SCALEMENU, szScale);
|
||
//LOADSTRING(IDS_COMMANDMENU, szCommand);
|
||
LOADSTRING(IDS_HELPMENU, szHelp);
|
||
}
|
||
|
||
lpMenuWidths = lpdoc->lpIpData->menuWidths.width;
|
||
hmenuShared = CreateMenu();
|
||
if((error = GetScode(IOleInPlaceFrame_InsertMenus (lpdoc->lpIpData->lpFrame,
|
||
hmenuShared, &lpdoc->lpIpData->menuWidths))) !=S_OK)
|
||
{
|
||
if (hmenuShared)
|
||
DestroyMenu(hmenuShared);
|
||
RETURN_RESULT( error);
|
||
}
|
||
|
||
if(fPlayOnly)
|
||
{
|
||
/* No server menu items if we're only playing:
|
||
*/
|
||
lpMenuWidths[1] = lpMenuWidths[3] = lpMenuWidths[5] = 0;
|
||
}
|
||
else
|
||
{
|
||
uPos = (UINT)lpMenuWidths[0]; /* # of menus in the FILE group */
|
||
uPosStart = uPos;
|
||
|
||
InsertMenu (hmenuShared, (WORD)uPos,
|
||
MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuEditPopup, szEdit);
|
||
uPos++;
|
||
|
||
lpMenuWidths[1] = uPos - uPosStart;
|
||
|
||
/* Insert OBJECT group menus */
|
||
|
||
uPos += (UINT)lpMenuWidths[2];
|
||
uPosStart = uPos;
|
||
|
||
InsertMenu (hmenuShared, (WORD)uPos,
|
||
MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuDevicePopup, szInsert);
|
||
uPos++;
|
||
InsertMenu (hmenuShared, (WORD)uPos,
|
||
MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuScalePopup, szScale);
|
||
uPos++;
|
||
//InsertMenu (hmenuShared, (WORD)uPos,
|
||
// MF_BYPOSITION | MF_POPUP, (UINT)hmenuCommandPopup, szCommand);
|
||
//uPos++;
|
||
lpMenuWidths[3] = uPos - uPosStart;
|
||
|
||
/* Insert HELP group menus */
|
||
|
||
uPos += (UINT) lpMenuWidths[4]; /* # of menus in WINDOW group */
|
||
uPosStart = uPos;
|
||
|
||
InsertMenu (hmenuShared, (WORD)uPos, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hmenuHelpPopup,
|
||
szHelp);
|
||
uPos++;
|
||
|
||
lpMenuWidths[5] = uPos - uPosStart;
|
||
}
|
||
|
||
if(!(lpdoc->lpIpData->holemenu = OleCreateMenuDescriptor (hmenuShared,
|
||
&lpdoc->lpIpData->menuWidths)))
|
||
RETURN_RESULT( E_OUTOFMEMORY);
|
||
|
||
lpdoc->lpIpData->hmenuShared = hmenuShared;
|
||
RETURN_RESULT( error);
|
||
}
|
||
|
||
//Removes our menu from the shared menu,
|
||
STDMETHODIMP DisassembleMenus (LPDOC lpdoc)
|
||
{
|
||
|
||
HMENU hmenuMain = ghMenu;
|
||
HMENU hmenuEditPopup = GetSubMenu(hmenuMain, menuposEdit);
|
||
HMENU hmenuDevicePopup = GetSubMenu(hmenuMain, menuposDevice);
|
||
HMENU hmenuScalePopup = GetSubMenu(hmenuMain, menuposScale);
|
||
//HMENU hmenuCommandPopup = GetInPlaceMenu();
|
||
HMENU hmenuHelpPopup = GetSubMenu(hmenuMain, menuposHelp);
|
||
HMENU hmenuTmp;
|
||
HMENU hmenuShared = lpdoc->lpIpData->hmenuShared;
|
||
int i, n, cnt;
|
||
SCODE error = S_OK;
|
||
|
||
OleDestroyMenuDescriptor (lpdoc->lpIpData->holemenu);
|
||
lpdoc->lpIpData->holemenu = NULL;
|
||
|
||
if(!(lpdoc->lpIpData->hmenuShared))
|
||
RETURN_RESULT( error);
|
||
n = GetMenuItemCount(hmenuShared);
|
||
cnt = 0;
|
||
i = 0;
|
||
while (i < n) {
|
||
hmenuTmp = GetSubMenu(hmenuShared, i);
|
||
if (hmenuTmp == hmenuEditPopup
|
||
|| hmenuTmp == hmenuDevicePopup
|
||
|| hmenuTmp == hmenuHelpPopup
|
||
//|| hmenuTmp == hmenuCommandPopup
|
||
|| hmenuTmp == hmenuScalePopup ) {
|
||
RemoveMenu (hmenuShared, i, MF_BYPOSITION);
|
||
++cnt;
|
||
if (cnt == 4) { // added 3 (4 if command menu included) popup menus.
|
||
break;
|
||
}
|
||
--n;
|
||
}
|
||
else
|
||
++i;
|
||
}
|
||
|
||
IOleInPlaceFrame_RemoveMenus (lpdoc->lpIpData->lpFrame,
|
||
lpdoc->lpIpData->hmenuShared);
|
||
DestroyMenu(lpdoc->lpIpData->hmenuShared);
|
||
lpdoc->lpIpData->hmenuShared = NULL;
|
||
RETURN_RESULT( error);
|
||
}
|
||
|
||
|
||
void AllocInPlaceDataBlock (LPDOC lpdoc)
|
||
{
|
||
// When this app is ready to support mutiple objects (documents), these
|
||
// structures should be allocated dynamically one per object.
|
||
|
||
static INPLACEDATA IpData;
|
||
|
||
lpdoc->lpIpData = (LPINPLACEDATA) &IpData;
|
||
lpdoc->lpIpData->lpFrame = NULL;
|
||
lpdoc->lpIpData->lpUIWindow = NULL;
|
||
lpdoc->lpIpData->fInContextHelpMode = FALSE;
|
||
}
|
||
|
||
|
||
void FreeInPlaceDataBlock (LPDOC lpdoc)
|
||
{
|
||
lpdoc->lpIpData = NULL;
|
||
}
|
||
|
||
|
||
void DoInPlaceDeactivate (LPDOC lpdoc)
|
||
{
|
||
if (!(lpdoc->lpIpData))
|
||
return;
|
||
ShowWindow(ghwndApp,SW_HIDE);
|
||
IOleInPlaceObject_InPlaceDeactivate ((LPOLEINPLACEOBJECT)&lpdoc->m_InPlace);
|
||
}
|
||
|
||
|
||
/**************************************************************************
|
||
* ToolWndProc:
|
||
* This is the Window proc for the ToolWindow/Windows we will be trasnferring
|
||
* to the client window. Some messages are routed to the MPlayer main window
|
||
* to ensure proper operation.
|
||
***************************************************************************/
|
||
LONG_PTR FAR PASCAL ToolWndProc (HWND hwnd, unsigned message, WPARAM wparam,
|
||
LPARAM lparam)
|
||
{
|
||
switch(message)
|
||
{
|
||
case WM_COMMAND:
|
||
PostMessage(ghwndApp,WM_COMMAND,
|
||
wparam,lparam);
|
||
break;
|
||
case WM_NEXTDLGCTL:
|
||
case WM_CTLCOLOR:
|
||
case WM_HSCROLL:
|
||
return (SendMessage(ghwndApp,message,wparam,lparam));
|
||
default:
|
||
return DefWindowProc(hwnd,message,wparam,lparam);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**************************************************************************
|
||
* RegisterToolWinClasses:
|
||
* Register the WindowClasses for the Toolbar windows we use to display
|
||
* in the client document.
|
||
***************************************************************************/
|
||
BOOL RegisterToolWinClasses()
|
||
{
|
||
WNDCLASS wc;
|
||
|
||
|
||
wc.lpszClassName = TEXT("ObjTool");
|
||
wc.lpfnWndProc = ToolWndProc;
|
||
wc.style = 0;
|
||
wc.hInstance = ghInst;
|
||
wc.hIcon = NULL;
|
||
wc.cbClsExtra = 4;
|
||
wc.cbWndExtra = 0;
|
||
wc.lpszMenuName = NULL;
|
||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
||
|
||
if (!RegisterClass(&wc))
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
/**************************************************************************
|
||
* InPlaceCreateControls:
|
||
* This function creates the toolbar windows we will display in the client
|
||
* and transfers the tool button to these windows by changing parents
|
||
* and repositioning them.
|
||
* If fPlayOnly is true all we need is a Dummy toolbar to fill space on
|
||
* the top of the container. Don't transfer the tools.
|
||
***************************************************************************/
|
||
void InPlaceCreateControls(BOOL fPlayOnly)
|
||
{
|
||
RECT rc;
|
||
|
||
if(IsWindow(ghwndIPToolWindow))
|
||
return;
|
||
RegisterToolWinClasses();
|
||
GetWindowRect(GetDesktopWindow(),&rc);
|
||
toolbarwidth = 2*(rc.right - rc.left);
|
||
IOleInPlaceFrame_GetWindow (docMain.lpIpData->lpFrame, &ghwndFrame);
|
||
|
||
ghwndIPToolWindow = CreateWindowEx(gfdwFlagsEx,
|
||
TEXT("ObjTool"),
|
||
NULL,
|
||
WS_CHILD | WS_BORDER,
|
||
0, 0,
|
||
toolbarwidth,
|
||
3*TOOL_WIDTH+1,
|
||
ghwndFrame,
|
||
NULL,
|
||
ghInst,
|
||
NULL);
|
||
|
||
ShowWindow(ghwndIPToolWindow, SW_HIDE);
|
||
if (fPlayOnly)
|
||
return;
|
||
|
||
ghwndIPScrollWindow = CreateWindowEx(gfdwFlagsEx,
|
||
TEXT("ObjTool"),
|
||
NULL,
|
||
WS_CHILD | WS_BORDER,
|
||
0, 0,
|
||
toolbarwidth,
|
||
3*TOOL_WIDTH+1,
|
||
ghwndFrame,
|
||
NULL,
|
||
ghInst,
|
||
NULL);
|
||
|
||
ShowWindow(ghwndIPScrollWindow, SW_HIDE);
|
||
}
|
||
|
||
|
||
|
||
|
||
/**************************************************************************
|
||
* SubClassedHatchWndProc:
|
||
* The Hatch Window is created in the OLE2UI.LIB. The window proc
|
||
* is also specified there. But in order to do things like resizing
|
||
* the Mplayer when the handles in the hatch window are dragged
|
||
* we need to subclass the window.
|
||
***************************************************************************/
|
||
LONG_PTR FAR PASCAL SubClassedHatchWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
static BOOL fCapture = FALSE;
|
||
static RECT hatchRC;
|
||
RECT rc;
|
||
static POINT ptLast;
|
||
POINT pt;
|
||
HDC hdcDeskTop;
|
||
HPEN hpenOld;
|
||
HBRUSH hbrushOld;
|
||
int nropOld;
|
||
int nBkOld;
|
||
HPEN hpen;
|
||
static int dL,dR, dT, dB;
|
||
static int left, right, top, bottom;
|
||
|
||
|
||
switch(wMsg)
|
||
{
|
||
case WM_LBUTTONDOWN: //Check to see if the click is on the resize handles.
|
||
//If yes then capture the mouse.
|
||
|
||
if(!GETWINDOWUINT(ghwndIPHatch,EW_HATCH_HANDLE))
|
||
break;
|
||
|
||
if(gfOle2IPPlaying)
|
||
break;
|
||
|
||
GetHatchRect(ghwndIPHatch, &hatchRC);
|
||
|
||
pt.x = (int)(SHORT)LOWORD(lParam);
|
||
pt.y = (int)(SHORT)HIWORD(lParam);
|
||
|
||
left = right = top = bottom = 0;
|
||
|
||
rc.left = hatchRC.left;
|
||
rc.top = hatchRC.top;
|
||
rc.right = rc.left + DEF_HATCH_SZ + 1;
|
||
rc.bottom = rc.top + DEF_HATCH_SZ + 1;
|
||
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
left = top = 1;
|
||
|
||
rc.top = hatchRC.top+(hatchRC.bottom-hatchRC.top-DEF_HATCH_SZ-1)/2;
|
||
rc.bottom = rc.top + DEF_HATCH_SZ + 1;
|
||
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
left = 1;
|
||
|
||
rc.top = hatchRC.bottom-DEF_HATCH_SZ-1;
|
||
rc.bottom = rc.top + DEF_HATCH_SZ + 1;
|
||
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
{
|
||
bottom = 1;
|
||
left = 1;
|
||
}
|
||
|
||
rc.left = hatchRC.right - DEF_HATCH_SZ-1;
|
||
rc.right = rc.left + DEF_HATCH_SZ + 1;
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
{
|
||
bottom = 1;
|
||
right = 1;
|
||
}
|
||
rc.top = hatchRC.top+(hatchRC.bottom-hatchRC.top-DEF_HATCH_SZ-1)/2;
|
||
rc.bottom = rc.top + DEF_HATCH_SZ + 1;
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
right = 1;
|
||
|
||
rc.top = hatchRC.top;
|
||
rc.bottom = rc.top + DEF_HATCH_SZ + 1;
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
{
|
||
top = 1;
|
||
right = 1;
|
||
}
|
||
|
||
rc.left = hatchRC.left + (hatchRC.right - hatchRC.left - DEF_HATCH_SZ-1)/2;
|
||
rc.right = rc.left + DEF_HATCH_SZ + 1;
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
top = 1;
|
||
|
||
rc.top = hatchRC.bottom-DEF_HATCH_SZ-1;
|
||
rc.bottom = rc.top + DEF_HATCH_SZ + 1;
|
||
if(PtInRect((LPRECT)&rc,pt))
|
||
bottom = 1;
|
||
|
||
if (!(left || right || top || bottom))
|
||
break;
|
||
fCapture = TRUE;
|
||
SetCapture(hwnd);
|
||
ptLast = pt;
|
||
MapWindowPoints(hwnd,NULL,(LPPOINT)&hatchRC,2);
|
||
dL = dR = dT = dB = 0;
|
||
hpen = CreatePen(PS_DASH, 1, 0x00000000);
|
||
|
||
hdcDeskTop = GetDC(NULL);
|
||
hpenOld = SelectObject (hdcDeskTop, hpen);
|
||
hbrushOld = SelectObject (hdcDeskTop,
|
||
GetStockObject(HOLLOW_BRUSH));
|
||
nropOld = GetROP2(hdcDeskTop);
|
||
SetROP2(hdcDeskTop, R2_NOT);
|
||
nBkOld = GetBkMode(hdcDeskTop);
|
||
SetBkMode(hdcDeskTop, TRANSPARENT);
|
||
|
||
Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
|
||
hatchRC.right+dR, hatchRC.bottom+dB);
|
||
|
||
|
||
SetBkMode(hdcDeskTop, nBkOld);
|
||
SetROP2(hdcDeskTop, nropOld);
|
||
SelectObject(hdcDeskTop, hbrushOld);
|
||
SelectObject(hdcDeskTop, hpenOld);
|
||
DeleteObject (hpen);
|
||
ReleaseDC(NULL, hdcDeskTop);
|
||
|
||
break;
|
||
|
||
case WM_MOUSEMOVE: //If we have the capture draw the resize rectangles.
|
||
if (!fCapture)
|
||
break;
|
||
else {
|
||
|
||
pt.x = (int)(SHORT)LOWORD(lParam);
|
||
pt.y = (int)(SHORT)HIWORD(lParam);
|
||
|
||
hpen = CreatePen(PS_DASH, 1, 0x00000000);
|
||
|
||
hdcDeskTop = GetDC(NULL);
|
||
hpenOld = SelectObject (hdcDeskTop, hpen);
|
||
hbrushOld = SelectObject (hdcDeskTop,
|
||
GetStockObject(HOLLOW_BRUSH));
|
||
nropOld = GetROP2(hdcDeskTop);
|
||
SetROP2(hdcDeskTop, R2_NOT);
|
||
nBkOld = GetBkMode(hdcDeskTop);
|
||
SetBkMode(hdcDeskTop, TRANSPARENT);
|
||
|
||
Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
|
||
hatchRC.right+dR, hatchRC.bottom+dB);
|
||
|
||
dL = dR = pt.x - ptLast.x;
|
||
dT = dB = pt.y - ptLast.y;
|
||
dL *= left;
|
||
dR *= right;
|
||
dT *= top;
|
||
dB *= bottom;
|
||
|
||
Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
|
||
hatchRC.right+dR, hatchRC.bottom+dB);
|
||
|
||
SetBkMode(hdcDeskTop, nBkOld);
|
||
SetROP2(hdcDeskTop, nropOld);
|
||
SelectObject(hdcDeskTop, hbrushOld);
|
||
SelectObject(hdcDeskTop, hpenOld);
|
||
if (hpen)
|
||
DeleteObject (hpen);
|
||
ReleaseDC(NULL, hdcDeskTop);
|
||
}
|
||
|
||
break;
|
||
|
||
case WM_LBUTTONUP: //release capture and resize.
|
||
if (!fCapture)
|
||
break;
|
||
else {
|
||
hpen = CreatePen(PS_DASH, 1, 0x00000000);
|
||
|
||
hdcDeskTop = GetDC(NULL);
|
||
hpenOld = SelectObject (hdcDeskTop, hpen);
|
||
hbrushOld = SelectObject (hdcDeskTop,
|
||
GetStockObject(HOLLOW_BRUSH));
|
||
nropOld = GetROP2(hdcDeskTop);
|
||
SetROP2(hdcDeskTop, R2_NOT);
|
||
nBkOld = GetBkMode(hdcDeskTop);
|
||
SetBkMode(hdcDeskTop, TRANSPARENT);
|
||
|
||
Rectangle(hdcDeskTop, hatchRC.left+dL, hatchRC.top+dT,
|
||
hatchRC.right+dR, hatchRC.bottom+dB);
|
||
|
||
|
||
SetBkMode(hdcDeskTop, nBkOld);
|
||
SetROP2(hdcDeskTop, nropOld);
|
||
SelectObject(hdcDeskTop, hbrushOld);
|
||
SelectObject(hdcDeskTop, hpenOld);
|
||
DeleteObject (hpen);
|
||
ReleaseDC(NULL, hdcDeskTop);
|
||
ReleaseCapture();
|
||
}
|
||
fCapture = FALSE;
|
||
|
||
GetWindowRect(ghwndApp,&hatchRC);
|
||
hatchRC.left += dL;
|
||
hatchRC.right += dR;
|
||
hatchRC.top += dT;
|
||
hatchRC.bottom += dB;
|
||
MapWindowPoints(NULL,ghwndCntr,(LPPOINT)&hatchRC, 2);
|
||
|
||
if (gwStatus != MCI_MODE_STOP)
|
||
PostMessage(ghwndApp, WM_COMMAND, ID_STOP, 0L);
|
||
|
||
// Negotiate with client for space. We accept the size specified by client.
|
||
DPFI("Hatch Resize: Before OnPosRectChange: %d, %d, %d, %d\r\n", hatchRC);
|
||
if (!gfInPPViewer)
|
||
IOleInPlaceSite_OnPosRectChange(docMain.lpIpData->lpSite, &hatchRC);
|
||
|
||
SendDocMsg((LPDOC)&docMain, OLE_CHANGED);
|
||
|
||
break;
|
||
|
||
case WM_PAINT:
|
||
{
|
||
HDC hdc;
|
||
HDC hdcmem;
|
||
RECT rcH;
|
||
HBITMAP hbm;
|
||
BITMAP bm;
|
||
|
||
if(ghwndMCI)
|
||
break;
|
||
CallWindowProc(gfnHatchWndProc, hwnd, wMsg, wParam, lParam);
|
||
hdc = GetDC(hwnd);
|
||
GetHatchRect(hwnd, (LPRECT)&rcH);
|
||
InflateRect((LPRECT)&rcH,-DEF_HATCH_SZ,-DEF_HATCH_SZ);
|
||
hbm = BitmapMCI();
|
||
|
||
hdcmem = CreateCompatibleDC(hdc);
|
||
if(!hdcmem)
|
||
return(E_FAIL);
|
||
SelectObject(hdcmem,hbm);
|
||
GetObject(hbm,sizeof(bm),(LPVOID)&bm);
|
||
StretchBlt(hdc,rcH.left,rcH.top,rcH.right-rcH.left,rcH.bottom-rcH.top,hdcmem,
|
||
0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
|
||
DeleteDC(hdcmem);
|
||
ReleaseDC(ghwndIPHatch,hdc);
|
||
|
||
|
||
return 0L;
|
||
|
||
}
|
||
|
||
}
|
||
return CallWindowProc(gfnHatchWndProc, hwnd, wMsg, wParam, lParam);
|
||
}
|
||
|