WTL
WTL项目属性改动
在项目属性里,链接器里的所有选项,子系统改成窗口
然后在c/c++里,把CONSOLES改成WINDOWS
然后把int main()改成
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
从一个命令行程序改成一个窗口程序
win.ShowWindow(SW_SHOW)
改成
win.ShowWindow(nCmdShow)
所有代码如下所示:
//从一个命令行程序改成一个窗口程序 //int main() int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { HRESULT hRes = gModule.Init(NULL, GetModuleHandle(NULL)); if (hRes != 0) { std::cout << hRes << std::endl; } MyWindow win; HWND hwnd = win.Create(NULL, CWindow::rcDefault, _T("edoyun atl window!")); if (hwnd == NULL) { std::cout << "create window failed\r\n"; } win.ShowWindow(nCmdShow); win.UpdateWindow(); MSG msg; while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } gModule.Term(); return 0; }
把wtl9的源码放入到目录里
WTL第一个frame框架
头文件
#include <iostream> #include <atlbase.h> #include <atlapp.h> //基本的WTL类 #include <atlwin.h> #include <atlframe.h> //WTL的主框架类 #include <atlmisc.h> //WTL工具类 #include <atlcrack.h> //WTL增强类的宏 #include "resource.h"
frame框架
class CEDWin : public CFrameWindowImpl<CEDWin> { public: DECLARE_FRAME_WND_CLASS(_T("Edoyun WTL Window"), IDR_MAINFRAME); BEGIN_MSG_MAP_EX(CEDYWin) MSG_WM_CREATE(OnCreate) CHAIN_MSG_MAP(CFrameWindowImpl<CEDWin>) END_MSG_MAP() LRESULT OnCreate(LPCREATESTRUCT lpcs) { SetMsgHandled(false); return 0; } };
窗口程序
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { HRESULT hRes = gModule.Init(NULL, GetModuleHandle(NULL)); if (hRes != 0) { std::cout << hRes << std::endl; } //MyWindow win; //HWND hwnd = win.Create(NULL, CWindow::rcDefault, _T("edoyun atl window!")); CEDWin win; HWND hwnd = win.CreateEx(); if (hwnd == NULL) { std::cout << "create window failed\r\n"; } win.ShowWindow(nCmdShow); win.UpdateWindow(); MSG msg; while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } gModule.Term(); return 0; }
变量如何关联控件
绑定一个CWindow
把变量关联到列表控件,使用Attach
缺点是控件里的消息无法处理
HWND hwndList = GetDlgItem(IDC_LIST); CListViewCtrl wndList1 (hwndList); // use constructor CListViewCtrl wndList2, wndList3; wndList2.Attach ( hwndList ); // use Attach method wndList3 = hwndList; // use assignment operator
使用CContainedWindow
麻烦一点,但是可控性变强了
使用CContainedWindow或CContainedWindowT类定义一个变量。
使用的头文件是
#include<atlwin.h>
例如在CMainDlg类里声明两个个变量
CContainedWindow m_btnOK; CContainedWindow m_btnCancel;
初始化一下,1对应的是OK, 2对应的是Cancel。1和2是消息处理中使用ALT_MSG_MAP来添加的
CMainDlg():m_btnOK(this,1), m_btnCancel(this,2){}
在消息处理里,使用ATL_MSG_MAP来添加一下
ALT_MSG_MAP(1) MSG_WM_SETCURSOR(OnSetCursorOK) ALT_MSG_MAP(2) MSG_WM_SETCURSOR(OnSetCursorCancel)
还需要在OnInitDialog里初始化一下我们的控件
m_btnOK.SubclassWindow (GetDlgItem(ID_OK)); m_btnCancel.SubclassWindow (GetDlgItem(ID_Cancel));
子类化
比如创建一个CWindowImpl 派生类并使用它来子类化控件
CWindowImpl模板第一个填我们自己的类,第二个填base类,第三个填风格
class CEdyButton : public CWindowImpl<CEdyButton, CButton> { BEGIN_MSG_MAP_EX(CEdyButton) MSG_WM_SETCURSOR(OnSetCursor) END_MAG_MAP() LRESULT OnSetCursor(HWND hWnd, UINT uHitTest, UINT uMsg) { static HCURSOR hcur = LoadCursor(NULL, IDC_HELP); if(hcur != NULL) { SetCursor(hcur); return TRUE; } else { SetMsgHandled(FALSE); return FALSE; } } }
然后在dlg里添加自己写的类的变量
CEdyButton m_btnAbout;
然后在dlg里的OnInitDialog里初始化一下
m_btnAbout.SubclassWindow (GetDlgItem(ID_ABOUT));
使用DDX_CONTROL
需要使用头文件atlddx
#include <atlddx.h>
使用BEGIN_DDX_MAP关联一下变量
BEGIN_DDX_MAP(CMainDlg) DDX_CONTROL(IDC_EDIT2, m_edit2) END_DDX_MAP()
需要让dlg多继承一个父类CWinDataExchange
class CMainDlg : public CDialogImpl<CMainDlg> ,public CWinDataExchange<CMainDlg>
然后在dlg里的OnInitDialog里初始化一下
DoDataExchange(FALSE)
ddx的好处就是使用一个函数就可以,不像子类化,每个都要写一个自己的。