📄 nwnd.cpp
字号:
/***********************************************
* Copyright (c) 2004,ShenZhen Namtek CO.,LTD
* All rights reserved.
*
* 文件名称:NWnd.cpp
* 文件标识:
* 摘 要:简要描述本文件的内容
*
* 当前版本:x.x
* 作 者:输入作者(或修改者)名字
* 完成日期:200x年x月x日
*
* 修改纪录:
* 原作者 :输入原作者(或修改者)名字
* 完成日期:200x年x月x日
************************************************/
#include "StdAfx.h"
#include "NWnd.h"
#include "UICommon.h"
#include "NDialog.h"
#include "resource.h"
CNWnd::CNWnd(void)
{
m_hWnd = NULL;
m_pfnSuper = NULL;
m_pParentWnd = NULL;
m_bIsMemWindow = TRUE;
}
CNWnd::~CNWnd(void)
{
}
BEGIN_MESSAGE_MAP_BASE(CNWnd)
END_MESSAGE_MAP()
LRESULT CNWnd::WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
if ( OnWndMsg(uMsg, wParam, lParam, &lResult) )
return lResult;
if( m_pfnSuper == NULL )
lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
else
lResult = ::CallWindowProc(m_pfnSuper, hWnd, uMsg, wParam, lParam);
return lResult;
}
BOOL CNWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
POINT pt;
LRESULT lResult = 0;
DWORD dwStyle;
switch ( message )
{
case WM_COMMAND:
if ( OnCommand(wParam, lParam) )
break;
else
goto LReturnFalse;
case WM_INITDIALOG:
lResult = (LRESULT)OnInitDialog();
break;
case WM_ACTIVATE:
OnActivate(LOWORD(wParam), (HWND)lParam, HIWORD(wParam));
break;
case WM_PAINT:
OnPaint();
break;
case WM_KEYDOWN:
OnKeyDown(wParam, lParam);
break;
case WM_TIMER:
OnTimer((UINT)wParam);
break;
case WM_MOUSEMOVE:
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
OnMouseMove((UINT)wParam, pt);
break;
case WM_LBUTTONDOWN:
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
OnLButtonDown((UINT)wParam, pt);
break;
case WM_LBUTTONUP:
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
OnLButtonUp((UINT)wParam, pt);
break;
case WM_LBUTTONDBLCLK:
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
OnLButtonDblClk((UINT)wParam, pt);
break;
case WM_RBUTTONDOWN:
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
OnRButtonDown((UINT)wParam, pt);
break;
case WM_RBUTTONUP:
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
OnRButtonUp((UINT)wParam, pt);
break;
case WM_ERASEBKGND:
if( IsMemWindow() )
{
HRGN hOldRgn = (HRGN)SelectObject(g_hdcUI, GetUpdateRgn());
//lResult = (LRESULT)OnEraseBkgnd( (HDC)wParam );
// draw in memDC
lResult = (LRESULT)OnEraseBkgnd( g_hdcUI );
SelectObject(g_hdcUI, hOldRgn);
}
else // following the windows philosophy
{
lResult = (LRESULT)OnEraseBkgnd( (HDC)wParam );
}
break;
case WM_DRAWITEM:
lResult = 1;
dwStyle = GetWindowLong(m_hWnd, GWL_STYLE);
if( (WS_CHILD & dwStyle) && IsMemWindow() )
{
LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam;
HDC hOldDC = pdis->hDC;
HFONT hOldFont = (HFONT)SelectObject(g_hdcUI, GetFont());
HRGN hOldRgn = (HRGN)SelectObject(g_hdcUI, GetUpdateRgn());
pdis->hDC = g_hdcUI;
OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam);
// restore original value
SelectObject(g_hdcUI, hOldFont);
SelectObject(g_hdcUI, hOldRgn);
pdis->hDC = hOldDC;
}
else
{
OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam);
}
//TRACE(_T("wm-drawitem %x\n"), GetSafeHwnd());
break;
case WM_CLOSE:
OnClose();
break;
case WM_DESTROY:
OnDestroy();
break;
case WM_SETCURSOR:
#ifdef PC_VERSION
SetCursor(g_hNavCursor);
#else
SetCursor(NULL);
#endif
break;
/* case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
*/
case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC:
lResult = (HRESULT)OnCtlColor((HDC)wParam,(HWND)lParam,message);
break;
default:
goto LReturnFalse;
};
// message has been handled, return TRUE
if (pResult != NULL)
*pResult = lResult;
return TRUE;
LReturnFalse:
return FALSE;
}
BOOL CNWnd::OnCommand(WPARAM wParam, LPARAM lParam)
// only map control notification message, ignore others.
{
UINT nID = LOWORD(wParam);
HWND hWndCtrl = (HWND)lParam;
UINT nCode = HIWORD(wParam);
// default routing for command messages (through closure table)
if (hWndCtrl == NULL)
{
//menu or accelerator
return FALSE;
}
else
{
// zero IDs for normal commands are not allowed
if (nID == 0 || ::IsWindow(hWndCtrl) == FALSE)
return FALSE;
}
return OnCmdMsg(nID, nCode, NULL, NULL);
}
BOOL CNWnd::OnCmdMsg(UINT nID, UINT nCode, void *pExtra, void *pHandlerInfo)
{
const NAV_MSGMAP* pMessageMap;
pMessageMap = GetMessageMap();
const NAV_MSGMAP_ENTRY* lpEntry ;
for (/* pMessageMap already init'ed */; pMessageMap != NULL;
pMessageMap = pMessageMap->pBaseMap)
{
// Note: catch not so common but fatal mistake!!
// BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd)
ASSERT( pMessageMap != pMessageMap->pBaseMap );
// constant window message
if ((lpEntry = NavFindMessageEntry(pMessageMap->lpEntries,
WM_COMMAND, nCode, nID)) != NULL)
{
goto LDispatch;
}
}
return FALSE;
LDispatch:
union MessageMapFunctions mmf;
mmf.pfn = lpEntry->pfn;
int nSig;
nSig = lpEntry->nSig;
switch (nSig)
{
default:
TRACE(_T("Message Map errors."));
ASSERT(FALSE);
break;
case NavSig_vv:
(this->*mmf.pfn_vv)();
break;
}
goto LReturnTrue;
LReturnTrue:
return TRUE;
}
LRESULT CALLBACK CNWnd::WindowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
// if(uMsg != WM_MOUSEMOVE && uMsg != 0x20 && uMsg != 0x84)
// TRACE(_T(".................msg = %x \n"), uMsg);
// MSG msg;
CNWnd * pWindow;
// Process key event or emulating key event.
if(uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)
{
if( ProcessKeyEvent(wParam) )
return 0;
}
if ( uMsg == WM_CREATE )
{
ASSERT( ! IsBadReadPtr((void *) lParam, sizeof(CNWnd)) );
pWindow = (CNWnd *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
pWindow->m_hWnd = hWnd;
SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
} else if ( uMsg == WM_INITDIALOG )
{
pWindow = (CNWnd *) (lParam);
ASSERT( ! IsBadReadPtr(pWindow, sizeof(CNWnd)) );
pWindow->m_hWnd = hWnd;
SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
}
else
pWindow=(CNWnd *)GetWindowLong(hWnd, GWL_USERDATA);
if ( pWindow )
return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
else
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
BOOL CNWnd::RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst)
{
WNDCLASS wc;
if ( ! GetClassInfo(hInst, lpszClass, &wc) )
{
GetWndClass(wc);
wc.hInstance = hInst;
wc.lpszClassName = lpszClass;
if ( !::RegisterClass(&wc) )
return FALSE;
}
return TRUE;
}
//
// Creates a Windows child window and attaches it to the CNWnd object
//
BOOL CNWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,
DWORD dwStyle, const RECT& rect,
CNWnd* pParentWnd, UINT nID)
{
// can't use for desktop or pop-up windows (use CreateEx instead)
ASSERT(pParentWnd != NULL);
ASSERT((dwStyle & WS_POPUP) == 0);
// set it's parent window if it has one.
m_pParentWnd = pParentWnd;
return CreateEx(0, lpszClassName, lpszWindowName,
dwStyle | WS_CHILD, rect.left, rect.top,
rect.right-rect.left, rect.bottom-rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID);
}
//
// Creates an overlapped, pop-up, or child window with the
// extended style specified in dwExStyle
//
BOOL CNWnd::CreateEx(DWORD dwExStyle,LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU hMenu)
{
if ( ! RegisterClass(lpszClassName, NGetInstanceHandle()) )
{
return FALSE;
}
// use MDICREATESTRUCT to pass this pointer, support MDI child window
// MDICREATESTRUCT mdic;
// memset(& mdic, 0, sizeof(mdic));
// mdic.lParam = (LPARAM) this;
m_hWnd = CreateWindowEx(dwExStyle, lpszClassName, lpszWindowName,
dwStyle, x, y, nWidth, nHeight,
hWndParent, hMenu, NGetInstanceHandle(), (LPVOID)this);
if ( NULL == m_hWnd )
{
return FALSE;
}
// if the window class is not registed by calling RegisterClass(),
// that's to say, it may be a window class regitered by system or
// by others way, we must subclass it.
WNDPROC oldWndProc = (WNDPROC)::GetWindowLong(m_hWnd, GWL_WNDPROC);
::SetWindowLong(m_hWnd, GWL_WNDPROC, (DWORD)NavGetNavWndProc());
WNDPROC tempWndProc = (WNDPROC)::GetWindowLong(m_hWnd, GWL_WNDPROC);
// the value returned by GetWidnowLong() is the address of window
// procedure or a handle representing the address of the window proc.
// so we check this value in this way.
if(oldWndProc != tempWndProc)
{
// hook our own window procedure
//::SetWindowLong(m_hWnd, GWL_WNDPROC, (DWORD)NavGetNavWndProc());
ASSERT( m_pfnSuper == NULL );
m_pfnSuper = oldWndProc;
// in this case, we can't capture WM_NCCREATE messasge, so set
// this value here directly.
::SetWindowLong(m_hWnd, GWL_USERDATA, (LONG) this);
}
else // regitered by calling RegisterClass().
{
// nothing to do.
}
// if not set parent window, set it here.
if(m_pParentWnd == NULL)
m_pParentWnd = (CNWnd*)CNDialog::FromHandle(hWndParent);
// if it's parent window it's not null(and derived from CNDialog)
// and it's a child window then add to parent's child window array.
if( m_pParentWnd != NULL && IsChild(hWndParent, m_hWnd) )
{
((CNDialog*)m_pParentWnd)->AddChildWnd(this);
}
return TRUE;
}
void CNWnd::GetWndClass(WNDCLASS & wc)
{
memset(& wc, 0, sizeof(wc));
// wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
#ifdef PC_VERSION
wc.hCursor = LoadCursor(NGetInstanceHandle(),(LPCTSTR)IDC_NAVCURSOR);
#else
wc.hCursor = NULL;
#endif
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = NULL;
// wc.hIconSm = NULL;
}
WPARAM CNWnd::MessageLoop(void)
{
MSG msg;
while ( GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
const NAV_MSGMAP_ENTRY*
NavFindMessageEntry(const NAV_MSGMAP_ENTRY* lpEntry,
UINT nMsg, UINT nCode, UINT nID)
{
if ( lpEntry == NULL )
return NULL;
for (/* lpEntry already init'ed */; lpEntry->nSig != NavSig_end; lpEntry++)
{
if ( lpEntry->nMessage == nMsg
&& lpEntry->nCode == nCode
&& lpEntry->nID == nID)
return lpEntry;
}
// not found in message map.
return NULL;
}
void CNWnd::PreSubclassWindow(void)
{
// Set the default font for all windows.
SetFont(NGetNavFont(), FALSE);
}
BOOL CNWnd::SubclassWindow(HWND hWnd)
{
if (!Attach(hWnd))
return FALSE;
// allow any other subclassing to occur
PreSubclassWindow();
// now hook into the NAV WndProc
WNDPROC oldWndProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC,
(DWORD)NavGetNavWndProc());
#ifdef _DEBUG
WNDPROC tempWndPorc = (WNDPROC)::GetWindowLong(hWnd, GWL_WNDPROC);
ASSERT(oldWndProc != tempWndPorc);
#endif
SetWindowLong(hWnd, GWL_USERDATA, (LONG) this);
if (m_pfnSuper == NULL)
m_pfnSuper = oldWndProc; // the first control of that type created
#ifdef _DEBUG
else if (m_pfnSuper != oldWndProc)
{
TRACE(_T("Error: Trying to use SubclassWindow with incorrect CNWnd\n"));
TRACE(_T("\tderived class.\n"));
ASSERT(FALSE);
// undo the subclassing if continuing after assert
::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc);
}
#endif
// set it's parent window
HWND hParent = ::GetParent(hWnd);
ASSERT(hParent != NULL);
// All top_level windows(dialogs here) created are stored in a
// a stack, so we search this stack to find out the CNWnd(or derived
// from CNWnd) object, if not found, return NULL.
//
m_pParentWnd = (CNWnd*)CNDialog::FromHandle(hParent);
// if it's parent window it's not null(and derived from CNDialog)
// and it's a child window then add to parent's child window array.
if( m_pParentWnd != NULL && IsChild(hParent, hWnd) )
{
((CNDialog*)m_pParentWnd)->AddChildWnd(this);
}
return TRUE;
}
BOOL CNWnd::SubclassDlgItem(UINT nID, CNWnd* pParent)
{
ASSERT(pParent != NULL);
ASSERT(::IsWindow(pParent->m_hWnd));
// check for normal dialog control
HWND hWndControl = ::GetDlgItem(pParent->m_hWnd, nID);
if (hWndControl != NULL)
return SubclassWindow(hWndControl);
TRACE(_T("Dialog control not found when subclass it.\n"));
return FALSE; // control not found
}
HWND CNWnd::UnsubclassWindow()
{
ASSERT(::IsWindow(m_hWnd));
// set WNDPROC back to original value
SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)m_pfnSuper);
m_pfnSuper = NULL;
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG) 0);
// and Detach the HWND from the CNWnd object
return Detach();
}
// Attach the HWND with the CWnd object
BOOL CNWnd::Attach(HWND hWndNew)
{
ASSERT(m_hWnd == NULL); // only attach once, detach on destroy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -