📄 wincore.cpp
字号:
{
CPoint point((DWORD)lParam);
lResult = (this->*mmf.pfn_wp)(point);
}
break;
case AfxSig_wv: // AfxSig_bv, AfxSig_wv
lResult = (this->*mmf.pfn_wv)();
break;
case AfxSig_vCALC:
(this->*mmf.pfn_vCALC)((BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam);
break;
case AfxSig_vPOS:
(this->*mmf.pfn_vPOS)((WINDOWPOS*)lParam);
break;
case AfxSig_vwwh:
(this->*mmf.pfn_vwwh)(LOWORD(wParam), HIWORD(wParam), (HANDLE)lParam);
break;
case AfxSig_vwp:
{
CPoint point((DWORD)lParam);
(this->*mmf.pfn_vwp)(wParam, point);
break;
}
case AfxSig_vwSIZING:
(this->*mmf.pfn_vwl)(wParam, lParam);
lResult = TRUE;
break;
case AfxSig_bwsp:
lResult = (this->*mmf.pfn_bwsp)(LOWORD(wParam), (short) HIWORD(wParam),
CPoint(LOWORD(lParam), HIWORD(lParam)));
if (!lResult)
return FALSE;
}
goto LReturnTrue;
LDispatchRegistered: // for registered windows messages
ASSERT(message >= 0xC000);
mmf.pfn = lpEntry->pfn;
lResult = (this->*mmf.pfn_lwl)(wParam, lParam);
LReturnTrue:
if (pResult != NULL)
*pResult = lResult;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CTestCmdUI - used to test for disabled commands before dispatching
class CTestCmdUI : public CCmdUI
{
public:
CTestCmdUI();
public: // re-implementations only
virtual void Enable(BOOL bOn);
virtual void SetCheck(int nCheck);
virtual void SetRadio(BOOL bOn);
virtual void SetText(LPCTSTR);
BOOL m_bEnabled;
};
CTestCmdUI::CTestCmdUI()
{
m_bEnabled = TRUE; // assume it is enabled
}
void CTestCmdUI::Enable(BOOL bOn)
{
m_bEnabled = bOn;
m_bEnableChanged = TRUE;
}
void CTestCmdUI::SetCheck(int)
{
// do nothing -- just want to know about calls to Enable
}
void CTestCmdUI::SetRadio(BOOL)
{
// do nothing -- just want to know about calls to Enable
}
void CTestCmdUI::SetText(LPCTSTR)
{
// do nothing -- just want to know about calls to Enable
}
/////////////////////////////////////////////////////////////////////////////
// CWnd command handling
BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)
// return TRUE if command invocation was attempted
{
UINT nID = LOWORD(wParam);
HWND hWndCtrl = (HWND)lParam;
int nCode = HIWORD(wParam);
// default routing for command messages (through closure table)
if (hWndCtrl == NULL)
{
// zero IDs for normal commands are not allowed
if (nID == 0)
return FALSE;
// make sure command has not become disabled before routing
CTestCmdUI state;
state.m_nID = nID;
OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);
if (!state.m_bEnabled)
{
TRACE1("Warning: not executing disabled command %d\n", nID);
return TRUE;
}
// menu or accelerator
nCode = CN_COMMAND;
}
else
{
// control notification
ASSERT(nID == 0 || ::IsWindow(hWndCtrl));
if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)
return TRUE; // locked out - ignore control notification
// reflect notification to child window control
if (ReflectLastMsg(hWndCtrl))
return TRUE; // eaten by child
// zero IDs for normal commands are not allowed
if (nID == 0)
return FALSE;
}
#ifdef _DEBUG
if (nCode < 0 && nCode != (int)0x8000)
TRACE1("Implementation Warning: control notification = $%X.\n",
nCode);
#endif
return OnCmdMsg(nID, nCode, NULL, NULL);
}
BOOL CWnd::OnNotify(WPARAM, LPARAM lParam, LRESULT* pResult)
{
ASSERT(pResult != NULL);
NMHDR* pNMHDR = (NMHDR*)lParam;
HWND hWndCtrl = pNMHDR->hwndFrom;
// get the child ID from the window itself
UINT nID = _AfxGetDlgCtrlID(hWndCtrl);
int nCode = pNMHDR->code;
ASSERT(hWndCtrl != NULL);
ASSERT(::IsWindow(hWndCtrl));
if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)
return TRUE; // locked out - ignore control notification
// reflect notification to child window control
if (ReflectLastMsg(hWndCtrl, pResult))
return TRUE; // eaten by child
AFX_NOTIFY notify;
notify.pResult = pResult;
notify.pNMHDR = pNMHDR;
return OnCmdMsg(nID, MAKELONG(nCode, WM_NOTIFY), ¬ify, NULL);
}
/////////////////////////////////////////////////////////////////////////////
// CWnd extensions
CFrameWnd* CWnd::GetParentFrame() const
{
if (GetSafeHwnd() == NULL) // no Window attached
return NULL;
ASSERT_VALID(this);
CWnd* pParentWnd = GetParent(); // start with one parent up
while (pParentWnd != NULL)
{
if (pParentWnd->IsFrameWnd())
return (CFrameWnd*)pParentWnd;
pParentWnd = pParentWnd->GetParent();
}
return NULL;
}
HWND AFXAPI AfxGetParentOwner(HWND hWnd)
{
// check for permanent-owned window first
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
if (pWnd != NULL)
return pWnd->GetOwner()->GetSafeHwnd();
// otherwise, return parent in the Windows sense
return (::GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ?
::GetParent(hWnd) : ::GetWindow(hWnd, GW_OWNER);
}
CWnd* CWnd::GetTopLevelParent() const
{
if (GetSafeHwnd() == NULL) // no Window attached
return NULL;
ASSERT_VALID(this);
HWND hWndParent = m_hWnd;
HWND hWndT;
while ((hWndT = AfxGetParentOwner(hWndParent)) != NULL)
hWndParent = hWndT;
return CWnd::FromHandle(hWndParent);
}
CWnd* CWnd::GetTopLevelOwner() const
{
if (GetSafeHwnd() == NULL) // no Window attached
return NULL;
ASSERT_VALID(this);
HWND hWndOwner = m_hWnd;
HWND hWndT;
while ((hWndT = ::GetWindow(hWndOwner, GW_OWNER)) != NULL)
hWndOwner = hWndT;
return CWnd::FromHandle(hWndOwner);
}
CWnd* CWnd::GetParentOwner() const
{
if (GetSafeHwnd() == NULL) // no Window attached
return NULL;
ASSERT_VALID(this);
HWND hWndParent = m_hWnd;
HWND hWndT;
while ((::GetWindowLong(hWndParent, GWL_STYLE) & WS_CHILD) &&
(hWndT = ::GetParent(hWndParent)) != NULL)
{
hWndParent = hWndT;
}
return CWnd::FromHandle(hWndParent);
}
BOOL CWnd::IsTopParentActive() const
{
ASSERT(m_hWnd != NULL);
ASSERT_VALID(this);
return CWnd::GetForegroundWindow() ==
GetTopLevelParent()->GetLastActivePopup();
}
void CWnd::ActivateTopParent()
{
// special activate logic for floating toolbars and palettes
CWnd* pTopLevel = GetTopLevelParent();
CWnd* pActiveWnd = GetForegroundWindow();
if (pActiveWnd == NULL ||
!(pActiveWnd->m_hWnd == m_hWnd || ::IsChild(pActiveWnd->m_hWnd, m_hWnd)))
{
// clicking on floating frame when it does not have
// focus itself -- activate the toplevel frame instead.
pTopLevel->SetForegroundWindow();
}
}
CFrameWnd* CWnd::GetTopLevelFrame() const
{
if (GetSafeHwnd() == NULL) // no Window attached
return NULL;
ASSERT_VALID(this);
CFrameWnd* pFrameWnd = (CFrameWnd*)this;
if (!IsFrameWnd())
pFrameWnd = GetParentFrame();
if (pFrameWnd != NULL)
{
CFrameWnd* pTemp;
while ((pTemp = pFrameWnd->GetParentFrame()) != NULL)
pFrameWnd = pTemp;
}
return pFrameWnd;
}
CWnd* PASCAL CWnd::GetSafeOwner(CWnd* pParent, HWND* pWndTop)
{
HWND hWnd = GetSafeOwner_(pParent->GetSafeHwnd(), pWndTop);
return CWnd::FromHandle(hWnd);
}
int CWnd::MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType)
{
if (lpszCaption == NULL)
lpszCaption = AfxGetAppName();
int nResult = ::MessageBox(GetSafeHwnd(), lpszText, lpszCaption, nType);
return nResult;
}
CWnd* PASCAL CWnd::GetDescendantWindow(HWND hWnd, int nID, BOOL bOnlyPerm)
{
// GetDlgItem recursive (return first found)
// breadth-first for 1 level, then depth-first for next level
// use GetDlgItem since it is a fast USER function
HWND hWndChild;
CWnd* pWndChild;
if ((hWndChild = ::GetDlgItem(hWnd, nID)) != NULL)
{
if (::GetTopWindow(hWndChild) != NULL)
{
// children with the same ID as their parent have priority
pWndChild = GetDescendantWindow(hWndChild, nID, bOnlyPerm);
if (pWndChild != NULL)
return pWndChild;
}
// return temporary handle if allowed
if (!bOnlyPerm)
return CWnd::FromHandle(hWndChild);
// return only permanent handle
pWndChild = CWnd::FromHandlePermanent(hWndChild);
if (pWndChild != NULL)
return pWndChild;
}
// walk each child
for (hWndChild = ::GetTopWindow(hWnd); hWndChild != NULL;
hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
{
pWndChild = GetDescendantWindow(hWndChild, nID, bOnlyPerm);
if (pWndChild != NULL)
return pWndChild;
}
return NULL; // not found
}
void PASCAL CWnd::SendMessageToDescendants(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam, BOOL bDeep, BOOL bOnlyPerm)
{
// walk through HWNDs to avoid creating temporary CWnd objects
// unless we need to call this function recursively
for (HWND hWndChild = ::GetTopWindow(hWnd); hWndChild != NULL;
hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
{
// if bOnlyPerm is TRUE, don't send to non-permanent windows
if (bOnlyPerm)
{
CWnd* pWnd = CWnd::FromHandlePermanent(hWndChild);
if (pWnd != NULL)
{
// call window proc directly since it is a C++ window
AfxCallWndProc(pWnd, pWnd->m_hWnd, message, wParam, lParam);
}
}
else
{
// send message with Windows SendMessage API
::SendMessage(hWndChild, message, wParam, lParam);
}
if (bDeep && ::GetTopWindow(hWndChild) != NULL)
{
// send to child windows after parent
SendMessageToDescendants(hWndChild, message, wParam, lParam,
bDeep, bOnlyPerm);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Scroll bar helpers
// hook for CWnd functions
// only works for derived class (eg: CView) that override 'GetScrollBarCtrl'
// if the window doesn't have a _visible_ windows scrollbar - then
// look for a sibling with the appropriate ID
CScrollBar* CWnd::GetScrollBarCtrl(int) const
{
return NULL; // no special scrollers supported
}
int CWnd::SetScrollPos(int nBar, int nPos, BOOL bRedraw)
{
CScrollBar* pScrollBar;
if ((pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
return pScrollBar->SetScrollPos(nPos, bRedraw);
else
return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
}
int CWnd::GetScrollPos(int nBar) const
{
CScrollBar* pScrollBar;
if ((pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
return pScrollBar->GetScrollPos();
else
return ::GetScrollPos(m_hWnd, nBar);
}
void CWnd::SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw)
{
CScrollBar* pScrollBar;
if ((pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
pScrollBar->SetScrollRange(nMinPos, nMaxPos, bRedraw);
else
::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
}
void CWnd::GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
{
CScrollBar* pScrollBar;
if ((pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
pScrollBar->GetScrollRange(lpMinPos, lpMaxPos);
else
::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
}
// Turn on/off non-control scrollbars
// for WS_?SCROLL scrollbars - show/hide them
// for control scrollbar - enable/disable them
void CWnd::EnableScrollBarCtrl(int nBar, BOOL bEnable)
{
CScrollBar* pScrollBar;
if (nBar == SB_BOTH)
{
EnableScrollBarCtrl(SB_HORZ, bEnable);
EnableScrollBarCtrl(SB_VERT, bEnable);
}
else if ((pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
{
// control scrollbar - enable or disable
pScrollBar->EnableWindow(bEnable);
}
else
{
// WS_?SCROLL scrollbar - show or hide
ShowScrollBar(nBar, bEnable);
}
}
BOOL CWnd::SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw)
{
ASSERT(lpScrollInfo != NULL);
if (afxData.nWinVer < 0x333)
return FALSE;
HWND hWnd = m_hWnd;
CScrollBar* pScrollBar;
if (nBar != SB_CTL && (pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
{
hWnd = pScrollBar->m_hWnd;
nBar = SB_CTL;
}
lpScrollInfo->cbSize = sizeof(*lpScrollInfo);
::SetScrollInfo(hWnd, nBar, lpScrollInfo, bRedraw);
return TRUE;
}
BOOL CWnd::GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, UINT nMask)
{
ASSERT(lpScrollInfo != NULL);
if (afxData.nWinVer < 0x333)
return FALSE;
HWND hWnd = m_hWnd;
CScrollBar* pScrollBar;
if (nBar != SB_CTL && (pScrollBar = GetScrollBarCtrl(nBar)) != NULL)
{
hWnd = pScrol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -