📄 ctlcore.cpp
字号:
SIZEL szlHimetric;
SIZEL szlPixels;
szlHimetric.cx = m_cxExtent;
szlHimetric.cy = m_cyExtent;
_AfxXformSizeInHimetricToPixels(NULL, &szlHimetric, &szlPixels);
CRect rcPos(0, 0, (int)szlPixels.cx, (int)szlPixels.cy);
CreateControlWindow(hWndParent, rcPos);
}
}
}
int COleControl::OnMouseActivate(CWnd *pDesktopWnd, UINT nHitTest, UINT message)
{
if (m_bInPlaceActive && !m_bUIActive)
m_bPendingUIActivation = TRUE;
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
void COleControl::PreModalDialog(HWND hWndParent)
{
if (m_pInPlaceFrame != NULL)
{
m_pInPlaceFrame->EnableModeless(FALSE);
}
else
{
HWND hWndTop = _AfxGetTopLevelWindow(hWndParent);
if (hWndTop != NULL)
::EnableWindow(hWndTop, FALSE);
}
}
void COleControl::PostModalDialog(HWND hWndParent)
{
if (m_pInPlaceFrame != NULL)
{
m_pInPlaceFrame->EnableModeless(TRUE);
}
else
{
HWND hWndTop = _AfxGetTopLevelWindow(hWndParent);
if (hWndTop != NULL)
::EnableWindow(hWndTop, TRUE);
}
}
void COleControl::SetModifiedFlag(BOOL bModified)
{
m_bModified = (BYTE)bModified;
}
BOOL COleControl::IsModified()
{
return m_bModified;
}
BOOL COleControl::WillAmbientsBeValidDuringLoad()
{
return m_bCountOnAmbients;
}
void COleControl::EnableSimpleFrame()
{
m_bSimpleFrame = TRUE;
}
BOOL COleControl::IgnoreWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam,
LRESULT* plResult)
{
if (!m_bUIDead)
return FALSE;
switch (msg)
{
case WM_NCHITTEST:
*plResult = HTNOWHERE;
return TRUE;
case WM_SETCURSOR:
*plResult = ::SendMessage(::GetParent(m_hWnd), msg, wParam, lParam);
return TRUE;
}
if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST))
{
*plResult = 0;
return TRUE;
}
return FALSE;
}
LRESULT COleControl::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
DWORD dwCookie;
LRESULT lResult;
HRESULT hr;
ExternalAddRef(); // "Insurance" addref -- keeps control alive
// allow OCM_ reflections to be handled by ON_XXX_REFLECT macros
switch (msg)
{
case OCM_COMMAND:
case OCM_CTLCOLORBTN:
case OCM_CTLCOLOREDIT:
case OCM_CTLCOLORDLG:
case OCM_CTLCOLORLISTBOX:
case OCM_CTLCOLORMSGBOX:
case OCM_CTLCOLORSCROLLBAR:
case OCM_CTLCOLORSTATIC:
case OCM_DRAWITEM:
case OCM_MEASUREITEM:
case OCM_DELETEITEM:
case OCM_VKEYTOITEM:
case OCM_CHARTOITEM:
case OCM_COMPAREITEM:
case OCM_HSCROLL:
case OCM_VSCROLL:
case OCM_PARENTNOTIFY:
case OCM_NOTIFY:
if (ReflectChildNotify(msg-OCM__BASE, wParam, lParam, &lResult))
{
ExternalRelease();
return lResult;
}
}
// Give the simple frame site the opportunity to filter the message
if ((m_pSimpleFrameSite != NULL) &&
SUCCEEDED(hr = m_pSimpleFrameSite->PreMessageFilter(
m_hWnd, msg, wParam, lParam, &lResult, &dwCookie)))
{
if (hr == S_OK)
{
if (!IgnoreWindowMessage(msg, wParam, lParam, &lResult))
lResult = CWnd::WindowProc(msg, wParam, lParam);
// Simple frame site may have been cleared...
// check before calling again.
if (m_pSimpleFrameSite != NULL)
m_pSimpleFrameSite->PostMessageFilter(
m_hWnd, msg, wParam, lParam, &lResult, dwCookie);
}
}
else
{
if (!IgnoreWindowMessage(msg, wParam, lParam, &lResult))
lResult = CWnd::WindowProc(msg, wParam, lParam);
}
ExternalRelease();
return lResult;
}
LRESULT COleControl::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
{
if (m_hWnd != NULL)
return CWnd::DefWindowProc(nMsg, wParam, lParam);
else
return 0;
}
int COleControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (IsSubclassedControl())
return CWnd::OnCreate(lpCreateStruct);
else
return 0;
}
void COleControl::OnSize(UINT nType, int cx, int cy)
{
if (IsSubclassedControl())
CWnd::OnSize(nType, cx, cy);
}
void COleControl::OnMove(int x, int y)
{
if (IsSubclassedControl())
CWnd::OnMove(x, y);
}
void COleControl::OnShowWindow(BOOL bShow, UINT nStatus)
{
if (IsSubclassedControl())
CWnd::OnShowWindow(bShow, nStatus);
}
/////////////////////////////////////////////////////////////////////////////
// Command prompts
void COleControl::OnInitMenuPopup(CMenu* pMenu, UINT, BOOL bSysMenu)
{
AfxCancelModes(m_hWnd);
if (bSysMenu)
return; // don't support system menu
ASSERT(pMenu != NULL);
// check the enabled state of various menu items
CCmdUI state;
state.m_pMenu = pMenu;
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pParentMenu == NULL);
// determine if menu is popup in top-level menu and set m_pOther to
// it if so (m_pParentMenu == NULL indicates that it is secondary popup)
HMENU hParentMenu;
if (_afxTrackingMenu == pMenu->m_hMenu)
state.m_pParentMenu = pMenu; // parent == child for tracking popup
else
{
CWnd* pParent = GetTopLevelParent();
// child windows don't have menus -- need to go to the top!
if (pParent != NULL &&
(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
{
int nIndexMax = ::GetMenuItemCount(hParentMenu);
for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
{
if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
{
// when popup is found, m_pParentMenu is containing menu
state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
break;
}
}
}
}
state.m_nIndexMax = pMenu->GetMenuItemCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
if (state.m_nID == 0)
continue; // menu separator or invalid cmd - ignore it
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pMenu != NULL);
if (state.m_nID == (UINT)-1)
{
// possibly a popup menu, route to first item of that popup
state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
if (state.m_pSubMenu == NULL ||
(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
state.m_nID == (UINT)-1)
{
continue; // first item of popup can't be routed to
}
state.DoUpdate(this, FALSE); // popups are never auto disabled
}
else
{
// normal menu item
// Auto enable/disable if frame window has 'm_bAutoMenuEnable'
// set and command is _not_ a system command.
state.m_pSubMenu = NULL;
state.DoUpdate(this, m_bAutoMenuEnable && state.m_nID < 0xF000);
}
}
}
void COleControl::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU /*hSysMenu*/)
{
// set the tracking state (update on idle)
if (nFlags == 0xFFFF)
{
m_nIDTracking = AFX_IDS_IDLEMESSAGE;
SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
ASSERT(m_nIDTracking == m_nIDLastMessage);
}
else if (nItemID == 0 ||
nFlags & (MF_SEPARATOR|MF_POPUP|MF_MENUBREAK|MF_MENUBARBREAK))
{
// nothing should be displayed
m_nIDTracking = 0;
}
else if (nItemID >= 0xF000 && nItemID < 0xF1F0) // max of 31 SC_s
{
// special strings table entries for system commands
m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
m_nIDTracking < AFX_IDS_SCFIRST + 31);
}
else if (nItemID >= AFX_IDM_FIRST_MDICHILD)
{
// all MDI Child windows map to the same help id
m_nIDTracking = AFX_IDS_MDICHILD;
}
else
{
// track on idle
m_nIDTracking = nItemID;
}
// when running in-place, it is necessary to cause a message to
// be pumped through the queue.
if (m_nIDTracking != m_nIDLastMessage && GetParent() != NULL)
PostMessage(WM_NULL);
}
void COleControl::GetMessageString(UINT nID, CString& rMessage) const
{
// load appropriate string
LPTSTR lpsz = rMessage.GetBuffer(255);
if (AfxLoadString(nID, lpsz) != 0)
{
// first newline terminates actual string
lpsz = _tcschr(lpsz, '\n');
if (lpsz != NULL)
*lpsz = '\0';
}
else
{
// not found
TRACE1("Warning: no message line prompt for ID 0x%04X.\n", nID);
}
rMessage.ReleaseBuffer();
}
LRESULT COleControl::OnSetMessageString(WPARAM wParam, LPARAM lParam)
{
USES_CONVERSION;
if (m_pInPlaceFrame != NULL)
{
LPCTSTR lpsz = NULL;
CString strMessage;
// set the message bar text
if (lParam != 0)
{
ASSERT(wParam == 0); // can't have both an ID and a string
lpsz = (LPCTSTR)lParam; // set an explicit string
}
else if (wParam != 0)
{
// use the wParam as a string ID
GetMessageString(wParam, strMessage);
lpsz = strMessage;
}
// notify container of new status text
m_pInPlaceFrame->SetStatusText(T2COLE(lpsz));
}
UINT nIDLast = m_nIDLastMessage;
m_nIDLastMessage = (UINT)wParam; // new ID (or 0)
m_nIDTracking = (UINT)wParam; // so F1 on toolbar buttons work
return nIDLast;
}
void COleControl::OnEnterIdle(UINT nWhy, CWnd* /*pWho*/)
{
if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
return;
SendMessage(WM_SETMESSAGESTRING, (WPARAM)m_nIDTracking);
ASSERT(m_nIDTracking == m_nIDLastMessage);
}
/////////////////////////////////////////////////////////////////////////////
// COleControl::XSpecifyPropertyPages
STDMETHODIMP_(ULONG) COleControl::XSpecifyPropertyPages::AddRef()
{
// Delegate to our exported AddRef.
METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COleControl::XSpecifyPropertyPages::Release()
{
// Delegate to our exported Release.
METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP COleControl::XSpecifyPropertyPages::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
// Delegate to our exported QueryInterface.
METHOD_PROLOGUE_EX_(COleControl, SpecifyPropertyPages)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP COleControl::XSpecifyPropertyPages::GetPages(CAUUID* pPages)
{
METHOD_PROLOGUE_EX(COleControl, SpecifyPropertyPages)
ASSERT(pPages != NULL);
if (pPages == NULL)
return E_POINTER;
pPages->cElems = 0;
pPages->pElems = NULL;
HRESULT hr = S_OK;
ULONG cElems;
LPCLSID pClassID = pThis->GetPropPageIDs(cElems);
if (cElems > 0)
{
if ((pPages->pElems = (LPCLSID)(CoTaskMemAlloc(cElems * sizeof(CLSID)))) != NULL)
{
ASSERT(pPages->pElems != NULL);
pPages->cElems = cElems;
memcpy(pPages->pElems, pClassID, (int)(cElems * sizeof(CLSID)));
}
else
hr = E_OUTOFMEMORY;
}
else
{
pPages->cElems = 0;
pPages->pElems = NULL;
}
return hr;
}
void COleControl::OnDestroy()
{
// Release hfont, if any.
if (m_hFontPrev != NULL)
{
SendMessage(WM_SETFONT, (WPARAM)NULL, 0);
InternalGetFont().m_pFont->ReleaseHfont(m_hFontPrev);
m_hFontPrev = NULL;
}
CWnd::OnDestroy();
}
void COleControl::OnKillFocus(CWnd* pNewWnd)
{
CWnd::OnKillFocus(pNewWnd);
if (m_pControlSite != NULL)
m_pControlSite->OnFocus(FALSE);
}
void COleControl::OnSetFocus(CWnd* pOldWnd)
{
CWnd::OnSetFocus(pOldWnd);
if (m_pControlSite != NULL)
m_pControlSite->OnFocus(TRUE);
}
LRESULT COleControl::OnOcmCtlColorBtn(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLORBTN, wParam, lParam);
}
LRESULT COleControl::OnOcmCtlColorDlg(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLORDLG, wParam, lParam);
}
LRESULT COleControl::OnOcmCtlColorEdit(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLOREDIT, wParam, lParam);
}
LRESULT COleControl::OnOcmCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLORLISTBOX, wParam, lParam);
}
LRESULT COleControl::OnOcmCtlColorMsgBox(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLORMSGBOX, wParam, lParam);
}
LRESULT COleControl::OnOcmCtlColorScrollBar(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLORSCROLLBAR, wParam, lParam);
}
LRESULT COleControl::OnOcmCtlColorStatic(WPARAM wParam, LPARAM lParam)
{
return ::DefWindowProc(m_hWnd, WM_CTLCOLORSTATIC, wParam, lParam);
}
void COleControl::ThrowError(SCODE sc, UINT nDescriptionID, UINT nHelpID)
{
TCHAR szBuffer[256];
AfxLoadString(nDescriptionID, szBuffer);
if (nHelpID == -1)
nHelpID = nDescriptionID;
ThrowError(sc, szBuffer, nHelpID);
}
void COleControl::ThrowError(SCODE sc, LPCTSTR pszDescription, UINT nHelpID)
{
COleDispatchException* pExcept = new COleDispatchException(pszDescription,
nHelpID, 0);
pExcept->m_scError = sc;
THROW(pExcept);
}
BOOL COleControl::IsInvokeAllowed(DISPID)
{
return m_bInitialized;
}
/////////////////////////////////////////////////////////////////////////////
// Force any extra compiler-generated code into AFX_INIT_SEG
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(COleControl, CWnd)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -