📄 dsofcontrol.cpp
字号:
if ((m_pDocObjFrame) && (m_pDocObjFrame->InPrintPreview()))
{
// If we don't have UI focus, take it...
if (!m_fUIActive) UIActivate(TRUE);
// Create a temp popup menu. We do this on fly to save resources since
// this is only needed in rare cases...
if ((m_fShowTitlebar) && ((x < 22) && (y < 22)))
{
hCurMenu = CreatePopupMenu();
if (hCurMenu)
{
// Add the command to the menu...
AppendMenu(hCurMenu, MF_STRING, MNU_PRINTPV, "E&xit Preview");
// Display the menu...
GetSizeRectAfterTitlebar(NULL, &rc);
MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
TrackPopupMenu(hCurMenu, 0, rc.left, rc.top - 1, 0, m_hwnd, NULL);
// Cleanup...
DestroyMenu(hCurMenu);
hCurMenu = NULL;
}
}
}
// Otherwise we do nothing when m_fNoInteractive == TRUE.
return;
}
// We know we must be app active if user clicked on control...
if (!m_fAppActive) m_fAppActive = TRUE;
// If we don't have UI focus, take it...
if (!m_fUIActive) UIActivate(TRUE);
// If the caption is showing, we are not modal, and user clicked in the
// area around the office doc icon, show the popup menu...
if ((m_fShowTitlebar) && (!m_fShowMenuBar) && ((x < 22) && (y < 22)))
{
// This will get the File menu or the merged menu based on current state...
hCurMenu = GetActivePopupMenu();
if (hCurMenu)
{
// We'll place it right below the titlebar just like sys menu...
GetSizeRectAfterTitlebar(NULL, &rc);
MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
TrackPopupMenu(hCurMenu, 0, rc.left, rc.top - 1, 0, m_hwnd, NULL);
}
}
else if ((m_fShowMenuBar) && (m_wSelMenuItem))
{
POINT pt;
UINT item = m_wSelMenuItem - 1;
// If we are over a visible menu bar item, find the right popup
// menu for the item using the selitem as an index...
if (item == 0)
{ hCurMenu = m_hmenuFilePopup; }
else
{
hCurMenu = GetActivePopupMenu();
if (hCurMenu) hCurMenu = GetSubMenu(hCurMenu, item);
}
// Map the location to display the popup into screen points...
pt.x = m_rgrcMenuItems[item].left;
pt.y = m_rgrcMenuItems[item].bottom;
MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&pt, 1);
HWND hwndCurFocus = GetFocus();
m_fInFocusChange = TRUE;
if (hwndCurFocus && (hwndCurFocus != m_hwnd))
SetFocus(m_hwnd);
// Display the menu...
TrackPopupMenu(hCurMenu, 0, pt.x, pt.y, 0, m_hwnd, NULL);
if (hwndCurFocus && (hwndCurFocus != m_hwnd))
SetFocus(hwndCurFocus);
m_fInFocusChange = FALSE;
// When user clicks off, we will resolve the mouse location to
// our control coordinates and call mousemove to free/reset selection...
if (GetCursorPos(&pt))
{
RECT rcMenu; GetSizeRectForMenuBar(NULL, &rcMenu);
MapWindowPoints(HWND_DESKTOP, m_hwnd, (POINT*)&pt, 1);
if (!PtInRect(&rcMenu, pt)) {pt.x = 0; pt.y = 0;}
}
else {pt.x = 0; pt.y = 0;}
OnMouseMove(pt.x, pt.y);
}
return;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnMenuMessage
//
// We should get these messages when we are displaying the popup menu.
// The "File" menu is ours, but the popup may have other menus copied
// from the merged menu set by the ui active docobject, so we need to
// forward those messages (as needed) to the right window handler.
//
// In addition, code is added to enable/disable File menu items based
// on flags set by developer in EnableFileCommand, and/or call the
// correct function if one of those commands was selected by user.
//
STDMETHODIMP_(void) CDsoFramerControl::OnMenuMessage(UINT msg, WPARAM wParam, LPARAM lParam)
{
HMENU hmenu, hmenuMerged = NULL;
BOOL fAlwaysSendMessage = FALSE;
HWND hwndObjectMenu = NULL;
if (m_pDocObjFrame)
{
hwndObjectMenu = m_pDocObjFrame->GetMenuHWND();
hmenuMerged = m_pDocObjFrame->GetMergedMenu();
}
switch (msg)
{
case WM_INITMENU: m_fObjectMenu = FALSE; //fall through...
case WM_ENTERIDLE: fAlwaysSendMessage = TRUE;
break;
case WM_MENUSELECT:
if ((lParam == 0) && (HIWORD(wParam) == 0xFFFF))
fAlwaysSendMessage = TRUE;
break;
case WM_INITMENUPOPUP:
hmenu = (HMENU)wParam;
m_fObjectMenu = ((hmenu != m_hmenuFilePopup) && (hmenu != hmenuMerged));
if ((!m_fObjectMenu) && (hmenu == m_hmenuFilePopup))
{
EnableMenuItem(hmenu, MNU_NEW, MF_BYCOMMAND | ((m_wFileMenuFlags & 1) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_OPEN, MF_BYCOMMAND | ((m_wFileMenuFlags & 2) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_CLOSE, MF_BYCOMMAND | (((m_wFileMenuFlags & 4) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_SAVE, MF_BYCOMMAND | (((m_wFileMenuFlags & 8) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_SAVEAS, MF_BYCOMMAND | (((m_wFileMenuFlags & 16) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_PGSETUP, MF_BYCOMMAND | (((m_wFileMenuFlags & 64) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_PRINTPV, MF_BYCOMMAND | (((m_wFileMenuFlags & 256) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_PRINT, MF_BYCOMMAND | (((m_wFileMenuFlags & 32) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
EnableMenuItem(hmenu, MNU_PROPS, MF_BYCOMMAND | (((m_wFileMenuFlags & 128) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
}
/* Create dengll 08.07.07 */
m_fObjectMenu = ((hmenu != m_hmenuDefinePopup) && (hmenu != hmenuMerged));
if ((!m_fObjectMenu) && (hmenu == m_hmenuDefinePopup))
{
EnableMenuItem(hmenu, MNU_OpenComments, MF_BYCOMMAND | ((m_wFileMenuFlags & 1) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
}
break;
case WM_COMMAND:
// We handle one special case for print preview exit, but otherwise
// we need to either forward to the merged menu handler (if enabled),
// or handle command through an asynchronous callback...
if ((m_fNoInteractive) && (LOWORD(wParam) == MNU_PRINTPV))
{
PrintPreviewExit();
}
else if ((m_fObjectMenu) && (hwndObjectMenu))
{
PostMessage(hwndObjectMenu, msg, wParam, lParam);
}
else
{
DWORD dwCmd = 0;
switch ((int)LOWORD(wParam))
{
case MNU_NEW: dwCmd = OLECMDID_NEW; break;
case MNU_OPEN: dwCmd = OLECMDID_OPEN; break;
case MNU_SAVE: dwCmd = OLECMDID_SAVE; break;
case MNU_SAVEAS: dwCmd = OLECMDID_SAVEAS; break;
case MNU_PGSETUP: dwCmd = OLECMDID_PAGESETUP; break;
case MNU_PRINT: dwCmd = OLECMDID_PRINT; break;
case MNU_PROPS: dwCmd = OLECMDID_PROPERTIES; break;
case MNU_PRINTPV: dwCmd = OLECMDID_PRINTPREVIEW; break;
case MNU_OpenComments:dwCmd = OLECMDID_OpenComments; break;//Create dengll 08.07.08
}
PostMessage(m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, dwCmd, 0);
}
return; // we just return
}
if ((hwndObjectMenu) && ((m_fObjectMenu) || (fAlwaysSendMessage)))
SendMessage(hwndObjectMenu, msg, wParam, lParam);
return;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnToolbarAction
//
// Does an associated OLECMDID action and raises the OnFileCommand event
// for developer to override as needed. The name comes from the fact that
// most Office servers will call this (via IOleCommandTarget) when user
// clicks on a toolbar button for file-command item. It also serves for
// our menu commands to keep the code consistant. Both menu and toolbar
// call this method asynchronously (via PostMessage) to avoid blocking the
// remote docobject server.
//
STDMETHODIMP_(void) CDsoFramerControl::OnToolbarAction(DWORD cmd)
{
ODS("CDsoFramerControl::OnToolbarAction\n");
HRESULT hr = S_OK;
VARIANT_BOOL wCancelAction = VARIANT_FALSE;
VARIANT rgargs[2];
VARIANT vtT = {0};
// We don't reenter if in a modal state already...
if (m_fModalState) return;
// If not interactive, we cannot run command...
if (m_fNoInteractive)
{
// unless we are in preview, in which case we can force exit
// and then run command after preview completes...
if ((m_pDocObjFrame) && (m_pDocObjFrame->InPrintPreview()))
{
PrintPreviewExit();
if (cmd != OLECMDID_PRINTPREVIEW)
PostMessage(m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, cmd, 0);
}
return;
}
// We will do a default action by default, but give developer a chance
// to override in OnFileCommand event...
rgargs[0].vt = VT_BOOL|VT_BYREF;
rgargs[0].pboolVal = &wCancelAction;
// Map the OLECMDID to one of our values...
rgargs[1].vt = VT_I4;
switch (cmd)
{
case OLECMDID_NEW: rgargs[1].lVal = dsoFileNew; break;
case OLECMDID_OPEN: rgargs[1].lVal = dsoFileOpen; break;
case OLECMDID_SAVE: rgargs[1].lVal = dsoFileSave; break;
case OLECMDID_SAVEAS: rgargs[1].lVal = dsoFileSaveAs; break;
case OLECMDID_PRINT: rgargs[1].lVal = dsoFilePrint; break;
case OLECMDID_PAGESETUP: rgargs[1].lVal = dsoFilePageSetup; break;
case OLECMDID_PROPERTIES: rgargs[1].lVal = dsoFileProperties; break;
case OLECMDID_PRINTPREVIEW: rgargs[1].lVal = dsoFilePrintPreview; break;
default: rgargs[1].lVal = dsoFileClose;
}
// Only do action if item is enabled...
if ((1 << rgargs[1].lVal) & m_wFileMenuFlags)
{
// Let control developer handle the event first...
hr = RaiseAutomationEvent(DSOF_DISPID_FILECMD, 2, rgargs);
TRACE1("Disp event returned 0x%X \n", hr);
// If the event was canceled (or event handler threw an
// unhandled error from user code), bail out now...
if ((wCancelAction) || (hr == DISP_E_EXCEPTION))
return;
// Do the action based on the event...
switch (rgargs[1].lVal)
{
case dsoFileClose: hr = Close(); break;
case dsoFilePrint: hr = ShowDialog(dsoDialogPrint); break;
case dsoFilePageSetup: hr = ShowDialog(dsoDialogPageSetup); break;
case dsoFileProperties: hr = ShowDialog(dsoDialogProperties); break;
case dsoFilePrintPreview: hr = PrintPreview(); break;
case dsoFileSave:
hr = Save(vtT, vtT, vtT, vtT);
if ((hr != DSO_E_DOCUMENTREADONLY) &&
(hr != DSO_E_NOTBEENSAVED))
break; // fall through to SaveAs if file is read-only or never been saved...
default:
hr = DoDialogAction(
(rgargs[1].lVal == dsoFileNew) ? dsoDialogNew :
(rgargs[1].lVal == dsoFileOpen) ? dsoDialogOpen : dsoDialogSave);
}
// Display error information to user if we failed...
if (FAILED(hr) && (hr != E_ABORT))
FAlertUser(hr, NULL);
}
return;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::FAlertUser
//
// Display an error alert to the user based on failed HRESULT.
//
STDMETHODIMP_(BOOL) CDsoFramerControl::FAlertUser(HRESULT hr, LPWSTR pwsFileName)
{
LPSTR pszError = NULL;
LPSTR pszTitle = NULL;
DWORD dwFlags = MB_ICONINFORMATION|MB_SETFOREGROUND;
switch (hr)
{
case STG_E_ACCESSDENIED:
case STG_E_SHAREVIOLATION:
case STG_E_LOCKVIOLATION:
case MK_E_CANTOPENFILE:
case E_ACCESSDENIED:
pszError = "Unable to Open/Save the file selected due to security permissions or a share violation.";
pszTitle = "Access Denied";
break;
case DSO_E_DOCUMENTNOTOPEN:
pszError = "The operation could not be performed because no document is currently open.";
pszTitle = "Unable to Perform Command";
break;
case DSO_E_DOCUMENTREADONLY:
pszError = "The operation could not be performed because the document was opened read-only.";
pszTitle = "Unable to Update Document";
break;
case CO_E_MSI_ERROR:
case DSO_E_INVALIDSERVER:
case DSO_E_INVALIDPROGID:
case STG_E_NOTFILEBASEDSTORAGE:
pszError = "There is no ActiveX Document server currently registered or installed for the item selected. "
"It cannot be loaded into the control.";
pszTitle = "Unable to Insert Document";
break;
case DSO_E_INMODALSTATE:
MessageBeep(0);
return FALSE; // Unable to alert user if in a modal condition!
case DSO_E_COMMANDNOTSUPPORTED:
pszError = "This operation could not be performed because the document server "
"does not support the command, or it is disabled when embedded.";
pszTitle = "Command Not Supported";
break;
case STG_E_TOOMANYOPENFILES:
pszError = "You can only open one document at a time. Please choose a single file to open.";
pszTitle = "Command Not Supported";
break;
case DSO_E_REQUIRESMSDAIPP:
pszError = "You cannot open/save to a web folder unless MDAC 2.5 is installed. The operation cannot be performed.";
pszTitle = "Unable to Gain Write Access for URL";
break;
default:
pszError = "The program encountered an error trying to perform the command. "
"If the problem persists, contact the program vendor for a possible solution.";
pszTitle = "Command Error";
dwFlags = MB_ICONHAND|MB_SETFOREGROUND;
}
MessageBox(m_hwnd, pszError, pszTitle, dwFlags);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -