当前位置: 首页 > 图文教程 > 开发语言 > VC++ > think window procedure

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 think window procedure


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 50 ::
收藏到网摘: n/a

think window procedure
作者:温昱

1. 用Win32 API编程时,window procedure比较明显,那就是程序员自定义window procedure,但Win32提供了一个API函数DefWindowProc(),缺省的处理要交给它。

int APIENTRY WinMain(HINSTANCE hInstance,	HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){	WNDCLASSEX wcex;	wcex.lpszClassName = "MyClass";	wcex.lpfnWndProc = (WNDPROC)MyWndProc;	...	RegisterClassEx(&wcex);	HWND hWnd;	hWnd = CreateWindow("MyClass", szTitle, WS_OVERLAPPEDWINDOW,	CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);	if (!hWnd)	return FALSE;	ShowWindow(hWnd, nCmdShow);	UpdateWindow(hWnd);	while (GetMessage(&msg, NULL, 0, 0))	{	TranslateMessage(&msg);	DispatchMessage(&msg);	}	return msg.wParam;}LRESULT CALLBACK MyWndProc(HWND hWnd,	UINT message, WPARAM wParam, LPARAM lParam){	switch (message)	{	...	default:	return DefWindowProc(hWnd, message, wParam, lParam);	}	return 0;}
2. 用MFC,window procedure会复杂一些,先看静态的,就是MFC预注册过的那些类,一句话,MFC替你打点好了window procedure的事。

2.1 最抽象的,MFC把window procedure封装了起来,程序员只需"programming by difference",你对哪个消息感兴趣,就建立哪个消息的响应函数。(当然还有虚函数override...)
void CMyClass::OnLButtonDown(UINT nFlags, CPoint pt){	...}
2.2 往底层一点,我们可以说CWnd::WindowProc()是现在的window procedure,它是一个template method,被你"programming by difference"的消息,会被它交给CWnd::OnWndMsg()处理,缺省的,会被它交给CWnd::DefWindowProc()处理。当然,上面说的没有考虑多态的情况,其实CWnd::OnWndMsg()和CWnd::DefWindowProc()都是虚函数。我们也注意到CWnd::DefWindowProc()中调用了::DefWindowProc(),也就是Win32 API的DefWindowProc()。
class CWnd : public CCmdTarget{...protected:	// for processing Windows messages	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);	virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);...};///template methodLRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam){	LRESULT lResult = 0;	if (!OnWndMsg(message, wParam, lParam, &lResult))	lResult = DefWindowProc(message, wParam, lParam);	return lResult;}//primitive method	LRESULT CWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam){	if (m_pfnSuper != NULL)	return ::CallWindowProc(m_pfnSuper, m_hWnd, nMsg, wParam, lParam);	...}
2.3 往更底层,来看看MFC预注册的那些类,window procedure是谁。注意,Pre-Registers Window Classes没有什么神秘的,因为Window Classes就是一个struct,而当你想用某个Pre-Registers Window Classes时,无非是传一个parameter过去,某段程序一判断,给wc结构赋值,调用AfxRegisterClass( & wc),OK。哈哈,我看到了,用的还是Win32 API的::DefWindowProc()。
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,	LPCTSTR lpszWindowName, DWORD dwStyle,	int x, int y, int nWidth, int nHeight,	HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam){	CREATESTRUCT cs;	cs.lpszClass = lpszClassName;	...	PreCreateWindow(cs); //########pass a cs with lpszClass null	...}BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs) //########pass a cs with lpszClass NULL{	if (cs.lpszClass == NULL) //########pass a cs with lpszClass NULL	{	// make sure the default window class is registered	VERIFY(AfxDeferRegisterClass(AFX_WND_REG));//########pass a para AFX_WND_REG	// no WNDCLASS provided - use child window default	ASSERT(cs.style & WS_CHILD);	cs.lpszClass = _afxWnd;	}	return TRUE;}#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)//########pass a para AFX_WND_REG{	...	// common initialization	WNDCLASS wndcls;	memset( & wndcls, 0, sizeof(WNDCLASS));	wndcls.lpfnWndProc = DefWindowProc; //########## here,Win32 API ::DefWindowProc()	wndcls.hInstance = AfxGetInstanceHandle();	wndcls.hCursor = afxData.hcurArrow;	...	if (fToRegister & AFX_WND_REG) //########pass a para AFX_WND_REG	{	wndcls.st