📄 dsofcontrol.cpp
字号:
return TRUE;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::EnableDropFile
//
// Decide when to allow file drop for open.
//
STDMETHODIMP_(void) CDsoFramerControl::EnableDropFile(BOOL fEnable)
{
TRACE1("CDsoFramerControl::EnableDropFile(%d)\n", fEnable);
DragAcceptFiles(m_hwnd, fEnable);
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnDropFile
//
// Open file dropped by user on the control.
//
STDMETHODIMP_(void) CDsoFramerControl::OnDropFile(HDROP hdrpFile)
{
DWORD cbItems;
CHAR szFileDrop[MAX_PATH];
VARIANT vtFile;
ODS("CDsoFramerControl::OnDropFile()\n");
cbItems = DragQueryFile(hdrpFile, 0xFFFFFFFF, NULL, 0);
if (cbItems == 0)
return;
if (cbItems > 1)
{
FAlertUser(STG_E_TOOMANYOPENFILES, NULL);
return;
}
szFileDrop[0] = 0;
vtFile.vt = VT_BSTR;
if (DragQueryFile(hdrpFile, 0, szFileDrop, MAX_PATH) &&
(vtFile.bstrVal = DsoConvertToBSTR(szFileDrop)))
{
HRESULT hr;
VARIANT vtMissing;
vtMissing.vt = VT_ERROR;
vtMissing.scode = DISP_E_PARAMNOTFOUND;
hr = Open(vtFile, vtMissing, vtMissing, vtMissing, vtMissing);
if (FAILED(hr)) FAlertUser(hr, vtFile.bstrVal);
VariantClear(&vtFile);
}
return;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnTimer
//
// Timer event fired.
//
STDMETHODIMP_(void) CDsoFramerControl::OnTimer(UINT id)
{
// TRACE1("CDsoFramerControl::OnTimer(%d)\n", id);
switch (id)
{
case SYNCPAINT_TIMER_ID:
{
DWORD dwTick = GetTickCount();
if ((dwTick - m_uiSyncPaint) > 300)
{
ODS("CDsoFramerControl::OnSyncPaint() Invalidate\n");
KillTimer(m_hwnd, SYNCPAINT_TIMER_ID);
m_fSyncPaintTimer = FALSE;
InvalidateAllChildWindows(m_hwnd);
}
}
break;
}
return;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnSyncPaint
//
// Notifies redraw is needed b/c of external window movement.
//
STDMETHODIMP_(void) CDsoFramerControl::OnSyncPaint()
{
// ODS("CDsoFramerControl::OnSyncPaint()\n");
m_uiSyncPaint = GetTickCount();
if ((!m_fSyncPaintTimer) && (!m_fAppActive))
{
SetTimer(m_hwnd, SYNCPAINT_TIMER_ID, 50, NULL);
m_fSyncPaintTimer = TRUE;
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnForegroundCompChange
//
// Shows/Hide embedding when window goes foreground/background active.
//
STDMETHODIMP_(void) CDsoFramerControl::OnForegroundCompChange(BOOL fCompActive)
{
ODS("CDsoFramerControl::OnForegroundCompChange\n");
if (m_pDocObjFrame)
{
HWND hwndEmbed = m_pDocObjFrame->GetDocWindow();
if (fCompActive)
{
// Make sure embed window is visible when active...
if (!IsWindowVisible(hwndEmbed))
ShowWindow(hwndEmbed, SW_SHOW);
if (m_hbmDeactive) DeleteObject(m_hbmDeactive);
m_hbmDeactive = NULL;
}
else if ((FDrawBitmapOnAppDeactive() || FIPDeactivateOnCompChange()) && (m_hbmDeactive == NULL))
{
// The default behavior on app deactive is to grap bitmap of active object before
// telling it we lost app activation. This allows us to draw the last state of the
// object while it is deactive. There is now an option to avoid this and keep object
// UI active while app deactive, but it may not work for all DocObj servers.
m_hbmDeactive = DsoGetBitmapFromWindow(hwndEmbed);
ShowWindow(hwndEmbed, SW_HIDE);
}
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnAppActivationChange
//
// Notifes embedded object when the host app gains/loses foreground status
// as the active application. This notification is critical to DocObjects since
// it is the primary means for the host and server to synch which top-level
// frame window (the host or the server's native main window) should be on the
// z-order stack for the shared thread input state. Thus allowing dialogs and tool
// windows to appear the correct order when displayed.
//
STDMETHODIMP_(void) CDsoFramerControl::OnAppActivationChange(BOOL fAppActive, DWORD dwThreadID)
{
TRACE2("CDsoFramerControl::OnAppActivationChange(fAppActive=%d, tid=0x%X)\n", fAppActive, dwThreadID);
m_fAppActive = fAppActive;
if ((m_pDocObjFrame) && (m_fComponentActive))
{
// Create/Free bitmap for background appearance..
OnForegroundCompChange(fAppActive);
// Notify it that it should be app active ofr deactive...
m_pDocObjFrame->OnNotifyAppActivate(fAppActive, (dwThreadID ? dwThreadID : GetCurrentThreadId()));
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnComponentActivationChange
//
// Handles showing/hiding doc object during activation state changes.
// This is needed to properly handle focus changes when more than one
// instance of the control is running on the same top-level window.
//
STDMETHODIMP_(void) CDsoFramerControl::OnComponentActivationChange(BOOL fActivate)
{
TRACE1("CDsoFramerControl::OnComponentActivationChange(fActive=%d)\n", fActivate);
if (fActivate)
{
// Set us active if we currently are not and raise activation change event...
if (!m_fComponentActive)
{
m_fComponentActive = TRUE;
OnForegroundCompChange(TRUE);
// Raise event to component host on state change...
PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_ACTIVATION, (LPARAM)fActivate);
}
// Notify the embedded object...
if (m_pDocObjFrame)
{
// Determine if we should restore from IP deactivation...
if (FIPDeactivateOnCompChange() && !(m_pDocObjFrame->IsIPActive()))
{
m_pDocObjFrame->IPActivateView();
OnForegroundCompChange(TRUE);
}
}
}
else
{
// Inform embedded object we lost activation...
if (m_pDocObjFrame)
{
// If we are in print preview, we need to exit in case other control will
// end up talking to same OLE server...
if (m_pDocObjFrame->InPrintPreview())
{
PrintPreviewExit();
UpdateWindow(m_hwnd);
}
// Provide control host option to IP deactive view when another framer control
// takes primary focus. This helps certain resource problems if you a lot of controls
// all IP active at the same time. This should not normally be used.
if (FIPDeactivateOnCompChange() && m_pDocObjFrame->IsIPActive())
{
OnForegroundCompChange(FALSE);
m_pDocObjFrame->IPDeactivateView();
}
}
// Change the current activation state and raise event...
if (m_fComponentActive)
{
m_fComponentActive = FALSE;
OnForegroundCompChange(FALSE);
// Raise event to component host on state change...
PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_ACTIVATION, (LPARAM)fActivate);
}
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnCtrlFocusChange
//
// Checks if window (or one of its children) is getting or losing focus so
// that can notify both the host and embed server using OnUIFocusChange.
//
STDMETHODIMP_(void) CDsoFramerControl::OnCtrlFocusChange(BOOL fCtlGotFocus, HWND hFocusWnd)
{
TRACE2("CDsoFramerControl::OnCtrlFocusChange(fCtlGotFocus=%d, hwndCurFocus=%x)\n", fCtlGotFocus, hFocusWnd);
if (!(m_fInFocusChange) && ((fCtlGotFocus) || !IsWindowChild(m_hwnd, hFocusWnd)))
{
OnUIFocusChange(fCtlGotFocus);
}
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::OnUIFocusChange
//
// Selectively handle focus changes to make sure both host and ui
// active docobject are in synch.
//
STDMETHODIMP_(void) CDsoFramerControl::OnUIFocusChange(BOOL fUIActive)
{
BOOL fFocusUpdated = FALSE;
TRACE1("CDsoFramerControl::OnUIFocusChange(fUIActive=%d)\n", fUIActive);
// We shouldn't try to do focus change when modal...
if ((m_fModalState) || (m_fInFocusChange))
{
ODS(" -- Got focus while modal or in change (do nothing) --\n");
return;
}
// When IP active, notify the control host of focus change...
if ((m_fInPlaceActive) && (m_pControlSite))
{
// Set flag to prevent recursion during focus changes...
m_fInFocusChange = TRUE;
if (fUIActive) // If we got focus...
{
// Notify host we have focus (we only need
// to do this if we are not already UI Active)...
if (!(m_fHasFocus))
{
ODS(" -- Tell host app we should have focus --\n");
m_fHasFocus = (fFocusUpdated = TRUE);
m_pControlSite->OnFocus(TRUE);
}
// Let the hook manager know that this control is the active object...
if (m_pHookManager)
m_pHookManager->SetActiveComponent(m_hwnd);
// If so configured, force component to show up active...
if (FChangeObjActiveOnFocusChange())
{
ODS(" -- Do component active on focus gain --\n");
OnComponentActivationChange(TRUE);
}
// If we have an active document, forward the focus...
if (m_pDocObjFrame)
m_pDocObjFrame->OnNotifyControlFocus(TRUE);
}
else // else we lost focus...
{
// When we lose focus, only notify host if we lost to window
// that does not belong to us...
if (m_pDocObjFrame)
m_pDocObjFrame->OnNotifyControlFocus(FALSE);
// If so configured, force component loss on focus loss...
if (FChangeObjActiveOnFocusChange())
{
ODS(" -- Do component deactive on focus loss --\n");
OnComponentActivationChange(FALSE);
m_fActivateOnStatus = TRUE;
}
// If we are UI active still, we need to tell host that we lost
// focus and are now UI deactive.
if (m_fHasFocus)
{
ODS(" -- Notify host of lost focus (ie, UI deactivate us) --\n");
m_fHasFocus = FALSE; fFocusUpdated = TRUE;
m_pControlSite->OnFocus(FALSE);
}
}
// Clear focus change flag...
m_fInFocusChange = FALSE;
// Redraw menu bar in case of state change
if ((fFocusUpdated) && (m_fShowMenuBar))
{
RECT rc; GetSizeRectForMenuBar(NULL, &rc);
InvalidateRect(m_hwnd, &rc, TRUE);
}
}
return;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::UpdateModalState
//
// Called either by developer (ModalState property) or by the embedded
// DocObject to notify host (VB/IE) that we are modal.
//
STDMETHODIMP_(void) CDsoFramerControl::UpdateModalState(BOOL fModeless, BOOL fNotifyIPObject)
{
TRACE2("CDsoFramerControl::UpdateModalState(AllowModeless=%d, NotifyIP=%d)\n", fModeless, fNotifyIPObject);
if (fModeless == (int)m_fModalState)
{
IOleInPlaceActiveObject* pipao;
m_fModalState = !(fModeless);
ODS("Modal state changed\n");
// Excel doesn't like us to notify the host of changes in modality
// if it is the one who initialied the call. So, we check the
// NotifyIPObj flag and only notify host when the IPObj is not the caller...
if ((fNotifyIPObject) && (m_pInPlaceFrame))
m_pInPlaceFrame->EnableModeless(fModeless);
// Again, if IPObj is not the caller and we have Ipobj, let it know
// of the change in modal state...
if ((fNotifyIPObject) && (m_pDocObjFrame) &&
(pipao = m_pDocObjFrame->GetActiveObject()))
pipao->EnableModeless(fModeless);
// Post notification of return from modal...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -