目录
接上:VC++消息映射机制 WindowProc的函数(wincore.cpp)
接下:VC++ 绘制线条 OnLButtonDown函数(DrawView.cpp) 利用SDK全局函数实现画线功能 利用MFC的CDC类实现画线功能 利用MFC的CClientDC类实现画线功能
OnWndMsg 函数(wincore.cpp)
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
LRESULT lResult = 0;
union MessageMapFunctions mmf;
mmf.pfn = 0;
CInternalGlobalLock winMsgLock;
// special case for commands
if (message == WM_COMMAND)
{
if (OnCommand(wParam, lParam))
{
lResult = 1;
goto LReturnTrue;
}
return FALSE;
}
if (message == WM_CREATE && m_pDynamicLayout != NULL)
{
ASSERT_VALID(m_pDynamicLayout);
if (!m_pDynamicLayout->Create(this))
{
delete m_pDynamicLayout;
m_pDynamicLayout = NULL;
}
else
{
InitDynamicLayout();
}
}
// special case for notifies
if (message == WM_NOTIFY)
{
NMHDR* pNMHDR = (NMHDR*)lParam;
if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))
goto LReturnTrue;
return FALSE;
}
// special case for activation
if (message == WM_ACTIVATE)
_AfxHandleActivate(this, wParam, CWnd::FromHandle((HWND)lParam));
// special case for set cursor HTERROR
if (message == WM_SETCURSOR &&
_AfxHandleSetCursor(this, (short)LOWORD(lParam), HIWORD(lParam)))
{
lResult = 1;
goto LReturnTrue;
}
// special case for windows that contain windowless ActiveX controls
BOOL bHandled;
bHandled = FALSE;
if ((m_pCtrlCont != NULL) && (m_pCtrlCont->m_nWindowlessControls > 0))
{
if (((message >= WM_MOUSEFIRST) && (message <= AFX_WM_MOUSELAST)) ||
((message >= WM_KEYFIRST) && (message <= WM_IME_KEYLAST)) ||
((message >= WM_IME_SETCONTEXT) && (message <= WM_IME_KEYUP)))
{
bHandled = m_pCtrlCont->HandleWindowlessMessage(message, wParam, lParam, &lResult);
}
}
if (bHandled)
{
goto LReturnTrue;
}
switch (message)
{
case WM_SIZE:
{
ResizeDynamicLayout();
CHwndRenderTarget* pRenderTarget = GetRenderTarget();
if (pRenderTarget != NULL && pRenderTarget->IsValid())
{
pRenderTarget->Resize(CD2DSizeU(UINT32(LOWORD(lParam)), UINT32(HIWORD(lParam))));
RedrawWindow();
}
}
break;
case WM_PAINT:
if (DoD2DPaint())
{
lResult = 1;
goto LReturnTrue;
}
break;
case WM_ERASEBKGND:
if (m_pRenderTarget != NULL && m_pRenderTarget->IsValid())
{
lResult = 1;
goto LReturnTrue;
}
break;
}
const AFX_MSGMAP* pMessageMap; pMessageMap = GetMessageMap();
UINT iHash; iHash = (LOWORD((DWORD_PTR)pMessageMap) ^ message) & (iHashMax-1);
winMsgLock.Lock(CRIT_WINMSGCACHE);
AFX_MSG_CACHE* pMsgCache; pMsgCache = &_afxMsgCache[iHash];
const AFX_MSGMAP_ENTRY* lpEntry;
if (message == pMsgCache->nMsg && pMessageMap == pMsgCache->pMessageMap)
{
// cache hit
lpEntry = pMsgCache->lpEntry;
winMsgLock.Unlock();
if (lpEntry == NULL)
return FALSE;
// cache hit, and it needs to be handled
if (message < 0xC000)
goto LDispatch;
else
goto LDispatchRegistered;
}
else
{
// not in cache, look for it
pMsgCache->nMsg = message;
pMsgCache->pMessageMap = pMessageMap;
for (/* pMessageMap already init'ed */; pMessageMap->pfnGetBaseMap != NULL;
pMessageMap = (*pMessageMap->pfnGetBaseMap)())
{
// Note: catch not so common but fatal mistake!!
// BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd)
ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());
if (message < 0xC000)
{
// constant window message
if ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,
message, 0, 0)) != NULL)
{
pMsgCache->lpEntry = lpEntry;
winMsgLock.Unlock();
goto LDispatch;
}
}
else
{
// registered windows message
lpEntry = pMessageMap->lpEntries;
while ((lpEntry = AfxFindMessageEntry(lpEntry, 0xC000, 0, 0)) != NULL)
{
UINT* pnID = (UINT*)(lpEntry->nSig);
ASSERT(*pnID >= 0xC000 || *pnID == 0);
// must be successfully registered
if (*pnID == message)
{
pMsgCache->lpEntry = lpEntry;
winMsgLock.Unlock();
goto LDispatchRegistered;
}
lpEntry++; // keep looking past this one
}
}
}
pMsgCache->lpEntry = NULL;
winMsgLock.Unlock();
return FALSE;
}
LDispatch:
ASSERT(message < 0xC000);
mmf.pfn = lpEntry->pfn;
switch (lpEntry->nSig)
{
default:
ASSERT(FALSE);
break;
case AfxSig_l_p:
{
CPoint point(lParam);
lResult = (this->*mmf.pfn_l_p)(point);
break;
}
case AfxSig_b_D_v:
lResult = (this->*mmf.pfn_b_D)(CDC::FromHandle(reinterpret_cast<HDC>(wParam)));
break;
case AfxSig_l_D_u:
lResult = (this->*mmf.pfn_l_D_u)(CDC::FromHandle(reinterpret_cast<HDC>(wParam)), (UINT)lParam);
break;
case AfxSig_b_b_v:
lResult = (this->*mmf.pfn_b_b)(static_cast<BOOL>(wParam));
break;
case AfxSig_b_u_v:
lResult = (this->*mmf.pfn_b_u)(static_cast<UINT>(wParam));
break;
case AfxSig_b_h_v:
lResult = (this->*mmf.pfn_b_h)(reinterpret_cast<HANDLE>(wParam));
break;
case AfxSig_i_u_v:
lResult = (this->*mmf.pfn_i_u)(static_cast<UINT>(wParam));
break;
case AfxSig_C_v_v:
lResult = reinterpret_cast<LRESULT>((this->*mmf.pfn_C_v)());
break;
case AfxSig_v_u_W:
(this->*mmf.pfn_v_u_W)(static_cast<UINT>(wParam),
CWnd::FromHandle(reinterpret_cast<HWND>(lParam)));
break;
case AfxSig_u_u_v:
lResult = (this->*mmf.pfn_u_u)(static_cast<UINT>(wParam));
break;
case AfxSig_b_v_v:
lResult = (this->*mmf.pfn_b_v)();
break;
case AfxSig_b_W_uu:
lResult = (this->*mmf.pfn_b_W_u_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)),
LOWORD(lParam), HIWORD(lParam));
break;
case AfxSig_b_W_COPYDATASTRUCT:
lResult = (this->*mmf.pfn_b_W_COPYDATASTRUCT)(
CWnd::FromHandle(reinterpret_cast<HWND>(wParam)),
reinterpret_cast<COPYDATASTRUCT*>(lParam));
break;
case AfxSig_b_v_HELPINFO:
lResult = (this->*mmf.pfn_b_HELPINFO)(reinterpret_cast<LPHELPINFO>(lParam));
break;
case AfxSig_CTLCOLOR:
{
// special case for OnCtlColor to avoid too many temporary objects
ASSERT(message == WM_CTLCOLOR);
AFX_CTLCOLOR* pCtl = reinterpret_cast<AFX_CTLCOLOR*>(lParam);
CDC dcTemp;
dcTemp.m_hDC = pCtl->hDC;
CWnd wndTemp;
wndTemp.m_hWnd = pCtl->hWnd;
UINT nCtlType = pCtl->nCtlType;
// if not coming from a permanent window, use stack temporary
CWnd* pWnd = CWnd::FromHandlePermanent(wndTemp.m_hWnd);
if (pWnd == NULL)
{
// determine the site of the OLE control if it is one
COleControlSite* pSite;
if (m_pCtrlCont != NULL && (pSite = (COleControlSite*)
m_pCtrlCont->m_siteMap.GetValueAt(wndTemp.m_hWnd)) != NULL)
{
wndTemp.m_pCtrlSite = pSite;
}
pWnd = &wndTemp;
}
HBRUSH hbr = (this->*mmf.pfn_B_D_W_u)(&dcTemp, pWnd, nCtlType);
// fast detach of temporary objects
dcTemp.m_hDC = NULL;
wndTemp.m_hWnd = NULL;
lResult = reinterpret_cast<LRESULT>(hbr);
}
break;
case AfxSig_CTLCOLOR_REFLECT:
{
// special case for CtlColor to avoid too many temporary objects
ASSERT(message == WM_REFLECT_BASE+WM_CTLCOLOR);
AFX_CTLCOLOR* pCtl = reinterpret_cast<AFX_CTLCOLOR*>(lParam);
CDC dcTemp;
dcTemp.m_hDC = pCtl->hDC;
UINT nCtlType = pCtl->nCtlType;
HBRUSH hbr = (this->*mmf.pfn_B_D_u)(&dcTemp, nCtlType);
// fast detach of temporary objects
dcTemp.m_hDC = NULL;
lResult = reinterpret_cast<LRESULT>(hbr);
}
break;
case AfxSig_i_u_W_u:
lResult = (this->*mmf.pfn_i_u_W_u)(LOWORD(wParam),
CWnd::FromHandle(reinterpret_cast<HWND>(lParam)), HIWORD(wParam));
break;
case AfxSig_i_uu_v:
lResult = (this->*mmf.pfn_i_u_u)(LOWORD(wParam), HIWORD(wParam));
break;
case AfxSig_i_W_uu:
lResult = (this->*mmf.pfn_i_W_u_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)),
LOWORD(lParam), HIWORD(lParam));
break;
case AfxSig_i_v_s:
lResult = (this->*mmf.pfn_i_s)(reinterpret_cast<LPTSTR>(lParam));
break;
case AfxSig_i_v_S:
lResult = (this->*mmf.pfn_i_S)(reinterpret_cast<LPCTSTR>(lParam));
break;
case AfxSig_v_F_b:
(this->*mmf.pfn_v_F_b)(CFont::FromHandle(reinterpret_cast<HFONT>(wParam)), (BOOL)LOWORD(lParam));
break;
case AfxSig_h_v_v:
{
HANDLE handle = (this->*mmf.pfn_h_v)();
lResult = reinterpret_cast<LRESULT>(handle);
}
break;
case AfxSig_h_b_h:
{
HANDLE handle = (this->*mmf.pfn_h_b_h)(static_cast<BOOL>(wParam), reinterpret_cast<HANDLE>(lParam));
lResult = reinterpret_cast<LRESULT>(handle);
}
break;
case AfxSig_h_h_h:
{
HANDLE handle = (this->*mmf.pfn_h_h_h)(reinterpret_cast<HANDLE>(wParam), reinterpret_cast<HANDLE>(lParam));
lResult = reinterpret_cast<LRESULT>(handle);
}
break;
case AfxSig_l_w_l:
lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam);
break;
case AfxSig_l_uu_M:
lResult = (this->*mmf.pfn_l_u_u_M)(LOWORD(wParam), HIWORD(wParam),
CMenu::FromHandle(reinterpret_cast<HMENU>(lParam)));
break;
case AfxSig_v_b_h:
(this->*mmf.pfn_v_b_h)(static_cast<BOOL>(wParam),
reinterpret_cast<HANDLE>(lParam));
break;
case AfxSig_v_h_v:
(this->*mmf.pfn_v_h)(reinterpret_cast<HANDLE>(wParam));
break;
case AfxSig_v_h_h:
(this->*mmf.pfn_v_h_h)(reinterpret_cast<HANDLE>(wParam),
reinterpret_cast<HANDLE>(lParam));
break;
case AfxSig_v_v_v:
(this->*mmf.pfn_v_v)();
break;
case AfxSig_v_u_v:
(this->*mmf.pfn_v_u)(static_cast<UINT>(wParam));
break;
case AfxSig_v_up_v:
(this->*mmf.pfn_v_up)(static_cast<UINT_PTR>(wParam));
break;
case AfxSig_v_u_u:
(this->*mmf.pfn_v_u_u)(static_cast<UINT>(wParam), static_cast<UINT>(lParam));
break;
case AfxSig_v_uu_v:
(this->*mmf.pfn_v_u_u)(LOWORD(wParam), HIWORD(wParam));
break;
case AfxSig_v_v_ii:
(this->*mmf.pfn_v_i_i)(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
case AfxSig_v_u_uu:
(this->*mmf.pfn_v_u_u_u)(static_cast<UINT>(wParam), LOWORD(lParam), HIWORD(lParam));
break;
case AfxSig_v_u_ii:
(this->*mmf.pfn_v_u_i_i)(static_cast<UINT>(wParam), LOWORD(lParam), HIWORD(lParam));
break;
case AfxSig_v_w_l:
(this->*mmf.pfn_v_w_l)(wParam, lParam);
break;
case AfxSig_MDIACTIVATE:
(this->*mmf.pfn_v_b_W_W)(m_hWnd == reinterpret_cast<HWND>(lParam),
CWnd::FromHandle(reinterpret_cast<HWND>(lParam)),
CWnd::FromHandle(reinterpret_cast<HWND>(wParam)));
break;
case AfxSig_MDINext:
(this->*mmf.pfn_v_W_b)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), static_cast<BOOL>(lParam));
break;
case AfxSig_v_D_v:
(this->*mmf.pfn_v_D)(CDC::FromHandle(reinterpret_cast<HDC>(wParam)));
break;
case AfxSig_v_M_v:
(this->*mmf.pfn_v_M)(CMenu::FromHandle(reinterpret_cast<HMENU>(wParam)));
break;
case AfxSig_v_M_ub:
(this->*mmf.pfn_v_M_u_b)(CMenu::FromHandle(reinterpret_cast<HMENU>(wParam)),
GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
case AfxSig_v_W_v:
(this->*mmf.pfn_v_W)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)));
break;
case AfxSig_v_v_W:
(this->*mmf.pfn_v_W)(CWnd::FromHandle(reinterpret_cast<HWND>(lParam)));
break;
case AfxSig_v_W_uu:
(this->*mmf.pfn_v_W_u_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), LOWORD(lParam),
HIWORD(lParam));
break;
case AfxSig_v_W_p:
{
CPoint point(lParam);
(this->*mmf.pfn_v_W_p)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), point);
}
break;
case AfxSig_v_W_h:
(this->*mmf.pfn_v_W_h)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)),
reinterpret_cast<HANDLE>(lParam));
break;
case AfxSig_ACTIVATE:
(this->*mmf.pfn_v_u_W_b)(LOWORD(wParam),
CWnd::FromHandle(reinterpret_cast<HWND>(lParam)), HIWORD(wParam));
break;
case AfxSig_SCROLL:
case AfxSig_SCROLL_REFLECT:
{
// special case for WM_VSCROLL and WM_HSCROLL
ASSERT(message == WM_VSCROLL || message == WM_HSCROLL ||
message == WM_VSCROLL+WM_REFLECT_BASE || message == WM_HSCROLL+WM_REFLECT_BASE);
int nScrollCode = (short)LOWORD(wParam);
int nPos = (short)HIWORD(wParam);
if (lpEntry->nSig == AfxSig_SCROLL)
(this->*mmf.pfn_v_u_u_W)(nScrollCode, nPos,
CWnd::FromHandle(reinterpret_cast<HWND>(lParam)));
else
(this->*mmf.pfn_v_u_u)(nScrollCode, nPos);
}
break;
case AfxSig_v_v_s:
(this->*mmf.pfn_v_s)(reinterpret_cast<LPTSTR>(lParam));
break;
case AfxSig_v_u_cs:
(this->*mmf.pfn_v_u_cs)(static_cast<UINT>(wParam), reinterpret_cast<LPCTSTR>(lParam));
break;
case AfxSig_OWNERDRAW:
(this->*mmf.pfn_v_i_s)(static_cast<int>(wParam), reinterpret_cast<LPTSTR>(lParam));
lResult = TRUE;
break;
case AfxSig_i_i_s:
lResult = (this->*mmf.pfn_i_i_s)(static_cast<int>(wParam), reinterpret_cast<LPTSTR>(lParam));
break;
case AfxSig_u_v_p:
{
CPoint point(lParam);
lResult = (this->*mmf.pfn_u_p)(point);
}
break;
case AfxSig_u_v_v:
lResult = (this->*mmf.pfn_u_v)();
break;
case AfxSig_v_b_NCCALCSIZEPARAMS:
(this->*mmf.pfn_v_b_NCCALCSIZEPARAMS)(static_cast<BOOL>(wParam),
reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam));
break;
case AfxSig_v_v_WINDOWPOS:
(this->*mmf.pfn_v_v_WINDOWPOS)(reinterpret_cast<WINDOWPOS*>(lParam));
break;
case AfxSig_v_uu_M:
(this->*mmf.pfn_v_u_u_M)(LOWORD(wParam), HIWORD(wParam), reinterpret_cast<HMENU>(lParam));
break;
case AfxSig_v_u_p:
{
CPoint point(lParam);
(this->*mmf.pfn_v_u_p)(static_cast<UINT>(wParam), point);
}
break;
case AfxSig_SIZING:
(this->*mmf.pfn_v_u_pr)(static_cast<UINT>(wParam), reinterpret_cast<LPRECT>(lParam));
lResult = TRUE;
break;
case AfxSig_MOUSEWHEEL:
lResult = (this->*mmf.pfn_b_u_s_p)(LOWORD(wParam), (short)HIWORD(wParam),
CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (!lResult)
return FALSE;
break;
case AfxSig_MOUSEHWHEEL:
(this->*mmf.pfn_MOUSEHWHEEL)(LOWORD(wParam), (short)HIWORD(wParam),
CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
break;
case AfxSig_l:
lResult = (this->*mmf.pfn_l_v)();
if (lResult != 0)
return FALSE;
break;
case AfxSig_u_W_u:
lResult = (this->*mmf.pfn_u_W_u)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), static_cast<UINT>(lParam));
break;
case AfxSig_v_u_M:
(this->*mmf.pfn_v_u_M)(static_cast<UINT>(wParam), CMenu::FromHandle(reinterpret_cast<HMENU>(lParam)));
break;
case AfxSig_u_u_M:
lResult = (this->*mmf.pfn_u_u_M)(static_cast<UINT>(wParam), CMenu::FromHandle(reinterpret_cast<HMENU>(lParam)));
break;
case AfxSig_u_v_MENUGETOBJECTINFO:
lResult = (this->*mmf.pfn_u_v_MENUGETOBJECTINFO)(reinterpret_cast<MENUGETOBJECTINFO*>(lParam));
break;
case AfxSig_v_M_u:
(this->*mmf.pfn_v_M_u)(CMenu::FromHandle(reinterpret_cast<HMENU>(wParam)), static_cast<UINT>(lParam));
break;
case AfxSig_v_u_LPMDINEXTMENU:
(this->*mmf.pfn_v_u_LPMDINEXTMENU)(static_cast<UINT>(wParam), reinterpret_cast<LPMDINEXTMENU>(lParam));
break;
case AfxSig_APPCOMMAND:
(this->*mmf.pfn_APPCOMMAND)(CWnd::FromHandle(reinterpret_cast<HWND>(wParam)), static_cast<UINT>(GET_APPCOMMAND_LPARAM(lParam)), static_cast<UINT>(GET_DEVICE_LPARAM(lParam)), static_cast<UINT>(GET_KEYSTATE_LPARAM(lParam)));
lResult = TRUE;
break;
case AfxSig_RAWINPUT:
(this->*mmf.pfn_RAWINPUT)(static_cast<UINT>(GET_RAWINPUT_CODE_WPARAM(wParam)), reinterpret_cast<HRAWINPUT>(lParam));
break;
case AfxSig_u_u_u:
lResult = (this->*mmf.pfn_u_u_u)(static_cast<UINT>(wParam), static_cast<UINT>(lParam));
break;
case AfxSig_u_u_l:
lResult = (this->*mmf.pfn_u_u_l)(static_cast<UINT>(wParam), lParam);
break;
case AfxSig_MOUSE_XBUTTON:
(this->*mmf.pfn_MOUSE_XBUTTON)(static_cast<UINT>(GET_KEYSTATE_WPARAM(wParam)), static_cast<UINT>(GET_XBUTTON_WPARAM(wParam)), CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
lResult = TRUE;
break;
case AfxSig_MOUSE_NCXBUTTON:
(this->*mmf.pfn_MOUSE_NCXBUTTON)(static_cast<short>(GET_NCHITTEST_WPARAM(wParam)), static_cast<UINT>(GET_XBUTTON_WPARAM(wParam)), CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
lResult = TRUE;
break;
case AfxSig_INPUTLANGCHANGE:
(this->*mmf.pfn_INPUTLANGCHANGE)(static_cast<UINT>(wParam), static_cast<UINT>(lParam));
lResult = TRUE;
break;
case AfxSig_INPUTDEVICECHANGE:
(this->*mmf.pfn_INPUTDEVICECHANGE)(LOWORD(wParam), reinterpret_cast<HANDLE>(lParam));
break;
case AfxSig_v_u_hkl:
(this->*mmf.pfn_v_u_h)(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam));
break;
case AfxSig_b_v_ii:
lResult = (this->*mmf.pfn_b_v_ii)(GET_Y_LPARAM(lParam), GET_X_LPARAM(lParam));
break;
}
goto LReturnTrue;
LDispatchRegistered: // for registered windows messages
ASSERT(message >= 0xC000);
ASSERT(sizeof(mmf) == sizeof(mmf.pfn));
mmf.pfn = lpEntry->pfn;
lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam);
LReturnTrue:
if (pResult != NULL)
*pResult = lResult;
return TRUE;
}