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号