|
|
/*---------------------------------------------------------------------------
| 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); }
|