📄 patron.cpp
字号:
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CPatronFrame::Release(void)
{
/*
* We don't do anything with this since we're not controlled
* by a reference count as far as in-place stuff is concerned.
*/
return --m_cRef;
}
/*
* CPatronFrame::GetWindow
*
* Purpose:
* Retrieves the handle of the window associated with the object
* on which this interface is implemented.
*
* Parameters:
* phWnd HWND * in which to store the window handle.
*
* Return Value:
* HRESULT NOERROR if successful, E_FAIL if there is no
* window.
*/
STDMETHODIMP CPatronFrame::GetWindow(HWND *phWnd)
{
*phWnd=m_hWnd;
return NOERROR;
}
/*
* CPatronFrame::ContextSensitiveHelp
*
* Purpose:
* Instructs the object on which this interface is implemented to
* enter or leave a context-sensitive help mode.
*
* Parameters:
* fEnterMode BOOL TRUE to enter the mode, FALSE otherwise.
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::ContextSensitiveHelp(BOOL fEnterMode)
{
/*
* Don't bother if there is no active object since we don't do
* context help on our own.
*/
if (NULL==m_pIOleIPActiveObject)
return NOERROR;
/*
* If the state changes, an MDI frame should call the same
* function in all documents. An SDI frame should just call
* the active object, if it has one.
*/
if (m_fInContextHelp!=fEnterMode)
{
m_fInContextHelp=fEnterMode;
#ifdef MDI
((PCPatronClient)m_pCL)->CallContextHelpOnDocuments
(fEnterMode);
#else
m_pIOleIPActiveObject->ContextSensitiveHelp(fEnterMode);
#endif
}
return NOERROR;
}
/*
* CPatronFrame::GetBorder
*
* Purpose:
* Returns the rectangle in which the container is willing to
* negotiate about an object's adornments.
*
* Parameters:
* prcBorder LPRECT in which to store the rectangle.
*
* Return Value:
* HRESULT NOERROR if all is well, INPLACE_E_NOTOOLSPACE
* if there is no negotiable space.
*/
STDMETHODIMP CPatronFrame::GetBorder(LPRECT prcBorder)
{
if (NULL==prcBorder)
return ResultFromScode(E_INVALIDARG);
/*
* We return all the client area space sans the StatStrip,
* which we control
*/
GetClientRect(m_hWnd, prcBorder);
prcBorder->bottom-=CYSTATSTRIP;
return NOERROR;
}
/*
* CPatronFrame::RequestBorderSpace
*
* Purpose:
* Asks the container if it can surrender the amount of space
* in pBW that the object would like for it's adornments. The
* container does nothing but validate the spaces on this call.
*
* Parameters:
* pBW LPCBORDERWIDTHS containing the requested space.
* The values are the amount of space requested
* from each side of the relevant window.
*
* Return Value:
* HRESULT NOERROR if we can give up space,
* INPLACE_E_NOTOOLSPACE otherwise.
*/
STDMETHODIMP CPatronFrame::RequestBorderSpace(LPCBORDERWIDTHS pBW)
{
//Everything is fine with us, so always return an OK.
return NOERROR;
}
/*
* CPatronFrame::SetBorderSpace
*
* Purpose:
* Called when the object now officially requests that the
* container surrender border space it previously allowed
* in RequestBorderSpace. The container should resize windows
* appropriately to surrender this space.
*
* Parameters:
* pBW LPCBORDERWIDTHS containing the amount of space
* from each side of the relevant window that the
* object is now reserving.
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::SetBorderSpace(LPCBORDERWIDTHS pBW)
{
RECT rc;
POINT pt1, pt2;
PCPatronDoc pDoc;
pDoc=(PCPatronDoc)m_pCL->ActiveDocument();
/*
* If pBW is NULL, the object is not interested in tools, so we
* can just leave ours up if we want.
*/
if (NULL==pBW)
{
if (NULL!=pDoc)
{
pDoc->NoObjectFrameTools(TRUE, TRUE);
/*
* In some cases IOleInPlaceSite::OnUIActivate might
* have been called before SetBorderSpace, so we might
* have already hidden our tools (OnUIActivate calls
* pDoc->NoObjectFrameTools before we set it to TRUE
* here). So we have to insure they are visible now
* by a call to ShowUIAndTools.
*/
if (!m_fOurToolsShowing)
ShowUIAndTools(TRUE, FALSE);
}
return NOERROR;
}
if (NULL!=pDoc)
pDoc->NoObjectFrameTools(FALSE, TRUE);
/*
* This tells CFrame::FMessageHook (WM_SIZE) how much space
* to reserve off the sides when resizing the client when
* the frame is resized.
*/
m_cyTop =pBW->top;
m_cyBottom=pBW->bottom;
m_cxLeft =pBW->left;
m_cxRight =pBW->right;
//Get the current offset of the client
GetWindowRect(m_pCL->Window(), &rc);
SETPOINT(pt1, rc.left, rc.top);
SETPOINT(pt2, rc.right, rc.bottom);
ScreenToClient(m_hWnd, &pt1);
ScreenToClient(m_hWnd, &pt2);
/*
* Now move the client, keeping documents steady. pBW->left-pt.x
* and pBW->top-pt.y are the deltas for the documents.
*/
GetClientRect(m_hWnd, &rc);
rc.left+=pBW->left;
rc.right-=pBW->right;
rc.top+=pBW->top;
rc.bottom-=pBW->bottom+CYSTATSTRIP; //Remember the status line
//Only bother the client if necessary.
if (!(pt1.x==rc.left && pt1.y==rc.top
&& pt2.x==rc.right && pt2.y==rc.bottom))
{
((PCPatronClient)m_pCL)->MoveWithoutFamily(&rc
, pBW->left-pt1.x, pBW->top-pt1.y);
}
return NOERROR;
}
/*
* CPatronFrame::SetActiveObject
*
* Purpose:
* Provides the container with the object's IOleInPlaceActiveObject
* pointer
*
* Parameters:
* pIIPActiveObj LPOLEINPLACEACTIVEOBJECT of interest.
* pszObj LPCOLESTR naming the object. Not used.
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::SetActiveObject
(LPOLEINPLACEACTIVEOBJECT pIIPActiveObj, LPCOLESTR pszObj)
{
if (NULL!=m_pIOleIPActiveObject)
m_pIOleIPActiveObject->Release();
//NULLs m_pIOleIPActiveObject if pIIPActiveObj is NULL
m_pIOleIPActiveObject=pIIPActiveObj;
if (NULL!=m_pIOleIPActiveObject)
m_pIOleIPActiveObject->AddRef();
return NOERROR;
}
/*
* CPatronFrame::InsertMenus
*
* Purpose:
* Instructs the container to place its in-place menu items where
* necessary in the given menu and to fill in elements 0, 2, and 4
* of the OLEMENUGROUPWIDTHS array to indicate how many top-level
* items are in each group.
*
* Parameters:
* hMenu HMENU in which to add popups.
* pMGW LPOLEMENUGROUPWIDTHS in which to store the
* width of each container menu group.
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::InsertMenus(HMENU hMenu
, LPOLEMENUGROUPWIDTHS pMGW)
{
/*
* Here Patron needs to copy it's File, Page, and Window menu
* items into the object-supplied menu, meaning that we have
* three menu groups. The actual handles of these popup menus
* are already in CPatronFrame::m_phMenu where File is element
* 0 and Page is element 2, and in m_hMenuWindow which is the
* Window menu. The latter we do only for MDI, of course.
*/
InsertMenu(hMenu, 0, MF_BYPOSITION | MF_POPUP, (UINT)m_phMenu[0]
, PSZ(IDS_FILEMENU));
InsertMenu(hMenu, 1, MF_BYPOSITION | MF_POPUP, (UINT)m_phMenu[2]
, PSZ(IDS_PAGEMENU));
pMGW->width[0]=1;
pMGW->width[2]=1;
#ifdef MDI
InsertMenu(hMenu, 2, MF_BYPOSITION | MF_POPUP
, (UINT)m_hMenuWindow, PSZ(IDS_WINDOWMENU));
pMGW->width[4]=1;
#else
pMGW->width[4]=0;
#endif
return NOERROR;
}
/*
* CPatronFrame::SetMenu
*
* Purpose:
* Instructs the container to replace whatever menu it's currently
* using with the given menu and to call OleSetMenuDescritor so OLE
* knows to whom to dispatch messages.
*
* Parameters:
* hMenu HMENU to show.
* hOLEMenu HOLEMENU to the menu descriptor.
* hWndObj HWND of the active object to which messages are
* dispatched.
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::SetMenu(HMENU hMenu
, HOLEMENU hOLEMenu, HWND hWndObj)
{
HRESULT hr;
PCPatronClient pCL=(PCPatronClient)m_pCL;
/*
* Our responsibilities here are to put the menu on the frame
* window and call OleSetMenuDescriptor.
* CPatronClient::SetMenu which we call here takes care of
* MDI/SDI differences.
*
* We also want to save the object's hWnd for use in WM_SETFOCUS
* processing.
*/
if (NULL==hMenu)
{
m_hWndObj=NULL;
//Prevent redundant calls, or debug warnings on startup.
if (NULL==m_hMenuTop)
return NOERROR;
hMenu=m_hMenuTop;
m_hMenuTop=NULL;
}
else
{
m_hMenuTop=m_hMenuOrg;
m_hWndObj=hWndObj;
}
pCL->SetMenu(m_hWnd, hMenu, m_hMenuWindow);
hr=OleSetMenuDescriptor(hOLEMenu, m_hWnd, hWndObj, NULL, NULL);
return hr;
}
/*
* CPatronFrame::RemoveMenus
*
* Purpose:
* Asks the container to remove any menus it put into hMenu in
* InsertMenus.
*
* Parameters:
* hMenu HMENU from which to remove the container's
* items.
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::RemoveMenus(HMENU hMenu)
{
int cItems, i, j;
HMENU hMenuT;
/*
* To be defensive, loop through this menu removing anything
* we recognize (that is, anything in m_phMenu) just in case
* the server didn't clean it up right. At least we can
* give ourselves the prophylactic benefit.
*/
if (NULL==hMenu)
return NOERROR;
cItems=GetMenuItemCount(hMenu);
/*
* Walk backwards down the menu. For each popup, see if it
* matches any other popup we know about, and if so, remove
* it from the shared menu.
*/
for (i=cItems; i >=0; i--)
{
hMenuT=GetSubMenu(hMenu, i);
for (j=0; j <= CMENUS; j++)
{
if (hMenuT==m_phMenu[j])
RemoveMenu(hMenu, i, MF_BYPOSITION);
}
}
//The menu should now be empty.
return NOERROR;
}
/*
* CPatronFrame::SetStatusText
*
* Purpose:
* Asks the container to place some text in a status line, if one
* exists. If the container does not have a status line it
* should return E_FAIL here in which case the object could
* display its own.
*
* Parameters:
* pszText LPCOLESTR to display.
*
* Return Value:
* HRESULT NOERROR if successful, S_TRUNCATED if not all
* of the text could be displayed, or E_FAIL if
* the container has no status line.
*/
STDMETHODIMP CPatronFrame::SetStatusText(LPCOLESTR pszText)
{
/*
* Just send this to the StatStrip. Unfortunately it won't tell
* us about truncation. Oh well, we'll just act like it worked.
*/
#ifdef WIN32ANSI
TCHAR szTemp[256];
WideCharToMultiByte(CP_ACP, 0, pszText, -1, szTemp, 256
, NULL, NULL);
m_pSL->MessageSet(szTemp);
#else
m_pSL->MessageSet((LPTSTR)pszText);
#endif
return NOERROR;
}
/*
* CPatronFrame::EnableModeless
*
* Purpose:
* Instructs the container to show or hide any modeless popup
* windows that it may be using.
*
* Parameters:
* fEnable BOOL indicating to enable/show the windows
* (TRUE) or to hide them (FALSE).
*
* Return Value:
* HRESULT NOERROR
*/
STDMETHODIMP CPatronFrame::EnableModeless(BOOL fEnable)
{
return NOERROR;
}
/*
* CPatronFrame::TranslateAccelerator
*
* Purpose:
* When dealing with an in-place object from an EXE server, this
* is called to give the container a chance to process accelerators
* after the server has looked at the message.
*
* Parameters:
* pMSG LPMSG for the container to examine.
* wID WORD the identifier in the container's
* accelerator table (from IOleInPlaceSite
* ::GetWindowContext) for this message (OLE does
* some translation before calling).
*
* Return Value:
* HRESULT NOERROR if the keystroke was used,
* S_FALSE otherwise.
*/
STDMETHODIMP CPatronFrame::TranslateAccelerator(LPMSG pMSG, WORD wID)
{
SCODE sc;
/*
* wID already has anything translated from m_hAccelIP for us,
* so we can just check for the commands we want and process
* them instead of calling TranslateAccelerator which would be
* redundant and which also has a possibility of dispatching to
* the wrong window.
*/
if ((IDM_PAGENEWPAGE <= wID && IDM_PAGELASTPAGE >= wID)
|| IDM_OPENOBJECT==wID || IDM_ENTERCONTEXTHELP==wID
|| IDM_ESCAPECONTEXTHELP==wID)
{
//wID properly expands to 32-bits
OnCommand(m_hWnd, (WPARAM)wID, 0L);
sc=S_OK;
}
#ifdef MDI
else if (TranslateMDISysAccel(m_pCL->Window(), pMSG))
sc=S_OK;
#endif
else
sc=S_FALSE;
return ResultFromScode(sc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -