⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nwnd.cpp

📁 EVC环境下用SDK开发WINCE的应用程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***********************************************
* 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 + -