WTL
- 写个简单的窗口程序玩玩
1. 目标
通过向导生成个简单的窗口程序,然后剖析下程序。
2. 步骤
启动vc8, 新建工程,选择WTL, ATL/WTL Application Wizard. 输入工程名称和位置, 不选“创建
解决方案的目录”。我们把工程名称:test, 目录 :e:/project, 点确定。
在Application Type里选SDI Application. 即当文档程序。 勾上Generate .CPP Files, 勾上Add Common Control Manifest, 不要勾上“Unicode Character Set”. 下一步
在User Interface Feature里, 不要勾上toolbar/Rebar/Command Bar/Status Bar/User a view window. (为了程序简单,都不选)。 view type里选 Generic window. 点 Finish 就完成了
3. 编译运行,没有错,就可以看到窗口了。
如果编译出错,确保include目录在VC的搜索路径下。(上一节内容)
4. 工程里有两个类: CMainFrame, CAboutDlg. CMainFrame就是窗口类了。就是程序的窗口。
5. 程序流程是很简单的
转到test.cpp文件,程序入口代码如下:
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{//每一个WTL程序就从这进去运行了,就和C语言里的main一样简单
HRESULT hRes = ::CoInitialize(NULL); //初始化COM库,WTL里使用COM组件很方便,内置的支持
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();//释放COM环境
return nRet;
}
int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
CMainFrame wndMain; //这就是我们的主窗口
if(wndMain.CreateEx() == NULL)//创建窗口
{
ATLTRACE(_T("Main window creation failed!/n"));
return 0;
}
wndMain.ShowWindow(nCmdShow);//显示窗口
int nRet = theLoop.Run();//这就是消息循环, 只要程序在运行,就不会从这个函数返回。当关闭窗口时,程序从该函数返回。
_Module.RemoveMessageLoop();
return nRet;
}
6. 消息处理是简单的:
请去WTL源代码看 CMessageLoop 。里面主要有个GetMessage,作的消息循环。
在CMessageLoop 上右击,选择“转到定义”。
消息响应的宏是: BEGIN_MSG_MAP。 查看源代码发现,就是switch/case语句。
为了能看懂代码,读者得熟悉sdk编程相应概念。
编界面程序的内容主要就是处理消息。下面演示。
7. 画点东西看看
在stdafx.h中,包含atlstr.h文件, atlmisc.h文件。
(为了使编译不错,WTL库文件请下载推荐的资源)
点击工具条上的 VFC_WTL按钮。 选择 Class Name : CMainFrame. 消息选:WM_PAINT。
点Add Event按钮, 勾上 Use WTL new state(atlcrack.h). 点OK, 点ok. 添加完毕。
向导添加了 MSG_WM_PAINT(OnPaint), 和 void OnPaint(CDCHandle dc)。
然后在OnPaint()函数里添加代码:
CPaintDC dcdraw(m_hWnd);
//在客户区坐标(200,200)处显示文字
dcdraw.TextOut(200,200,"hello, 我这是在主窗口客户区显示!");
编译,运行,可以看到结果。
用同样的方法,添加鼠标单击消息试试 : WM_LBUTTONDOWN.
在 void OnLButtonDown(UINT nFlags, CPoint point) 里输入: MessageBox("hello ,鼠标按下");
编译运行,在窗口上点击鼠标左键可可以弹出MessageBox了。
8. 总结
WTL程序的流程是简单的。 就是SDK程序的流程。WTL对其作了简单封装,方便使用
WTL的消息流程是简单的,就是GetMessage消息循环, 和switch/case消息处理。wtl库通过
宏对其做了简单封装。
编程的主要任务就是作消息处理,通过vfc_wtl向导,轻松完成消息的添加。