winx的你好
#define WINX_USE_APPMODULE
#include <winx.h>
class CHelloMainFrame: public winx::MainFrame<CHelloMainFrame>
{
WINX_CLASS("CHelloMainFrame");
public :
void OnPaint(HWND hWnd)
{
winx::PaintDC dc(hWnd);
dc.TextOut(1,1,_T("你好,WINX!"));
}
};
winx::CAppModule _Module;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
CAppModuleInit module;
CHelloMainFrame::RegisterClass();
CHelloMainFrame wndMain;
wndMain.Create(NULL,_T("你好"));
return module.Run();
}
编程模型
注册窗口类
WINX中RegisterClass是要主动调用的.
以下这些宏与WINX的RegisterClass有关:
WINX_CLASS/WINX_CLASS_EX(类),WINX_CLASS_STYLE(网格),WINX_DEFAULT_BKGND/WINX_DEFAULT_COLOR/WINX_DEFAULT_BRUSH(背景/颜色/刷),WINX_DEFAULT_CURSOR/WINX_DEFAULT_SYSCURSOR(光标),它们分别对应Windows窗口类(WNDCLASSEX)中的lpszClassName,style,hbrBackground,hCursor等成员.
用WINX_CLASS指定窗口类名,其他宏的用法完全一致.例如,默认鼠标光标是箭头(IDC_ARROW),就很容易用IDC_IBEAM改为像Edit控件一样:
class CHelloMainFrame : public winx::MainFrame<CHelloMainFrame>
{
WINX_DEFAULT_SYSCURSOR(IDC_IBEAM);
... //默认系统光标.
};
初化类
大致有:
类 | 作用 |
|---|---|
CComAppInit | COM初化类,即CoInitialize/CoUninitialize对 |
COleAppInit | OLE初化类,即OleInitialize/OleUninitialize对. |
CDebugAppInit | 启动内存泄漏调试(仅Debug版本,Release版本为空类). |
CComModuleInit | CComModuleInit/Term. |
CAppModuleInit | CAppModuleInit/Term. |
GdiplusAppInit | GdiplusStartup/GdiplusShutdown. |
消息循环
借用WTL的CMessageLoop::Run,藏在:CAppModuleInit里面.
class CAppModuleInit : public WTL::CMessageLoop
{
public :
CAppModuleInit(
_ATL_OBJMAP_ENTRY*p=NULL,
HINSTANCE hInst=GetThisModule(),
const GUID*plibid=NULL)
{
_Module.Init(p, hInst, plibid);
_Module.AddMessageLoop( this );
}
~ CAppModuleInit()
{
_Module.Term();
}
};
窗口过程
template <class WindowClass,class HandleClass=DefaultWindowHandle>
class Window
{
public :
static LRESULT CALLBACK WindowProc(
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
WindowClass*pWnd=(WindowClass*)WindowMap::GetWindow(hWnd);
if(pWnd==NULL){
if(message!=WM_NCCREATE)
return pWnd->InternalDefault(hWnd,message,wParam,lParam);
LPCREATESTRUCT lpCS=(LPCREATESTRUCT)lParam;
if(lpCS->lpCreateParams){
pWnd=(WindowClass*)lpCS->lpCreateParams;
lpCS->lpCreateParams=NULL;
}else{
if(WindowClass::StackWindowObject){
WINX_ASSERT( " WindowClass::StackWindowObject - unexpected! " );
return FALSE;
}else{
pWnd=WINX_NEW(WindowClass);
}
}
WindowMap::SetWindow(hWnd, pWnd);
}
return pWnd->ProcessMessage(hWnd,message,wParam,lParam);
}
};
WindowMap::GetWindow/SetWindow是什么?
UserData建立窗口句柄(hWnd)到窗口对象(pWnd)的映射.
还可用SetProp/GetProp或自己实现的其他方式建立映射.前者是WINX默认选择.
简单分析一下,这些方式的利弊.
通过HashMap建立映射,问题在于,其他DLL如何取到该HashMap对象?会导致bug或者强耦合结构.
用窗口的UserData建立映射,问题在于如果已占用UserData怎么办?机制上有点不安全.
使用SetProp/GetProp建立映射,性能比UserData方式慢,但极其安全.
WindowClass::StackWindowObject,放在栈上的窗口.
最后,pWnd->ProcessMessage(hWnd,message,wParam,lParam)处理处理消息.
ProcessMessage是消息机制的核心.
浙公网安备 33010602011771号