你是否厌烦了mfc 的过度封装,类太多,想修改增加功能很繁琐。可是直接用winapi 编程,只能使用c语言,而且要熟悉winapi 的底层函数,消息封装等等。selfLib 类库恰好解决了你的烦恼,selfLib类库直接简单的用c++封装了winapi 底层函数,用sfCracker.h 文件提供windows 消息的参数转换,转换成c++ 数据的类型。在sfWnd.h文件中,CWnd 类把全局的windows消息处理函数移到 你派生的 CWnd子类,下面就介绍 CWnd 类和 sfCracker.h 文件。其他的类的使用与 mfc 中的相应类用法完全相同。
我没有使用thunk 技术,把全局的消息处理转换到CWnd 类中,而是在窗口消息处理函数 sfWndMsgProc 中把消息处理转移到CWnd 类的 OnWndMsg函数,你需要在OnWndMsg函数中由自己决定,把哪些消息传送给你的CWnd子类。传送消息时,可以根据 sfCracker.h 中的宏定义,转换函数参数。sfWndMsgProc 窗口消息处理函数的工作过程如下:
在函数中,定义了一个映射表 CSimpleMap,函数正在处理的窗口句柄与CWnd 类指针的映射表。
还定义了 static CWnd* s_pCWndRcv 保存当前处理的 CWnd 类
LRESULT CALLBACK sfWndMsgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK sfWndMsgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static CWnd* s_pCWndRcv= NULL; //the CWnd class to receive dispatch win message
static CSimpleMap<HWND,CWnd*,0> s_HWNDMap;
if(message== 0) //is operate the s_pCWnd or s_HWNDMap
{
switch(wParam)
{
case OP_SET: s_pCWndRcv= (CWnd*)lParam; return 0;
case OP_ADD: s_HWNDMap.Add(hWnd, (CWnd*)lParam); return 0;
case OP_REMOVE: s_HWNDMap.RemoveKey(hWnd); return 0;
case OP_LOOKUP: return (LRESULT)s_HWNDMap.Lookup((HWND)lParam);
}
}
//in first message, add hWnd and s_pCWnd into handleMap
if(s_pCWndRcv!= NULL && hWnd != NULL)
{
s_HWNDMap.Add(hWnd, s_pCWndRcv);
s_pCWndRcv= NULL;
}
CWnd *pWnd= s_HWNDMap[hWnd];
if( pWnd == NULL )
return 0;
switch(message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc= ::BeginPaint(hWnd, &ps);
pWnd->OnWndMsg(hWnd, message,(WPARAM) hdc, (LPARAM)&ps) ;
::EndPaint(hWnd, &ps);
return 0;
}
case WM_DESTROY: //this is last message
{
pWnd->OnWndMsg(hWnd, message, wParam, lParam) ;
s_HWNDMap.RemoveKey(hWnd);
::PostQuitMessage(0);
return 0;
}
}
return pWnd->OnWndMsg(hWnd, message, wParam, lParam) ;
}
使用CWnd 类的 Create 函数时,先把CWnd 的this 指针传给 sfWndMsgProc 函数中的静态变量s_pCWndRcv, 然后在接受到第一个窗口句柄(hWnd)不是null的消息时,以hWnd 为关键字 加入s_HWNDMap 映射表,在接收到后续的窗口消息都用该消息的窗口句柄(hWnd),在s_HWNDMap 映射表中查询,得到 CWnd 类指针 pWnd,再调用 pWnd->OnWndMsg(),完成在 CWnd 子类中处理窗口消息。
使用sfLib 类库的CWnd 创建窗口,首先建立你的窗口类(如 CMainWnd),派生于 CWnd 类,添加你需要的变量、函数,比如在 Create 函数在定义自己窗口的类型,标题,样式等等,然后在OnWndMsg 函数在接受窗口消息,并且分发到各自的处理函数。
具体请参考 sample 目录下的例子。
sflib的代码可以去百度下载,很多
|