WTL 向导生成代码的理解

来源:互联网 发布:linux启动光盘制作 编辑:程序博客网 时间:2024/06/03 15:57

通过生成一个单文档举例说明。

包括一个frame,一个view,和关于窗口。

 

 

class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,

public CMessageFilter, public CIdleHandler

{

... ....

 

};

 

CFrameWindowImpl定义在atlframe.h里,是CWindow的派生,同时设置默认的frame属性CFrameWinTraits。在CreateEx里做了LoadAccelerators加速键的处理,同时创建了toolbar;处理了WM_SIZE消息。CUpdateUI处理menu和toobar的命令。CMessageFilter类实现了一个虚函数,作为消息过滤,也就是如果一个类(不管是否是窗口类)想实现消息过滤,继承此类即可。

 

 

 

class CSingleWtlView : public CWindowImpl<CSingleWtlView>

{

public:

DECLARE_WND_CLASS(NULL)

 

BOOL PreTranslateMessage(MSG* pMsg)

{

pMsg;

return FALSE;

}

 

BEGIN_MSG_MAP(CSingleWtlView)

MESSAGE_HANDLER(WM_PAINT, OnPaint)

END_MSG_MAP()

 

// Handler prototypes (uncomment arguments if needed):

//LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

//LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)

//LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

 

LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)

{

CPaintDC dc(m_hWnd);

 

//TODO: Add your drawing code here

 

return 0;

}

};

这个视图类从窗口实现类继承,实现了PAINT消息的处理。重载了PreTranslateMessage。

 

 

 

class CAboutDlg : public CDialogImpl<CAboutDlg>

{

... ....

};

 

 

对话框类没什么可说的了。

 

关于入口函数和界面线程

 

CAppModule _Module;

_Module是一个全局变量,这里是CAppModule的一个实例。而CAppModule类是对应用程序的封装。它封装了诸如初始化模块等功能。一个_Module还维持一个消息循环Map。 

 

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)

{

CMessageLoop theLoop;

_Module.AddMessageLoop(&theLoop);

该函数创建了一个CMessageLoop实例,该实例包含了这个线程的消息循环。这些消息循环都放在模块的全局消息循环中,通过线程的ID来索引。这样,该线程的其它代码就能访问得到。 

每一个应用程序维护一个消息循环队列Map,应用程序中的每个线程都通过"_Module.AddMessageLoop(&theLoop);",把该线程的消息循环加入到_Module的消息循环Map中。 

 

CMainFrame wndMain;

创建frame

if(wndMain.CreateEx() == NULL)

{

ATLTRACE(_T("Main window creation failed!/n"));

return 0;

}

 

wndMain.ShowWindow(nCmdShow);

 

int nRet = theLoop.Run();

界面线程的消息循环,知道WM_QUIT

 

_Module.RemoveMessageLoop();

从全局消息链删除

return nRet;

}

 

程序入口函数,根据是否是UNICODE编译器会编译成不同的形式

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)

{

HRESULT hRes = ::CoInitialize(NULL);

// If you are running on NT 4.0 or higher you can use the following call instead to 

// make the EXE free threaded. This means that calls come in on a random RPC thread.

//HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);

ATLASSERT(SUCCEEDED(hRes));

 

// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used

::DefWindowProc(NULL, 0, 0, 0L);

 

AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);// add flags to support other controls

 

hRes = _Module.Init(NULL, hInstance);

ATLASSERT(SUCCEEDED(hRes));

 

int nRet = Run(lpstrCmdLine, nCmdShow);

 

_Module.Term();

::CoUninitialize();

 

return nRet;

}

原创粉丝点击