WEB开发网
开发学院软件开发VC MFC程序员WTL指南(2)ATL界面类 阅读

MFC程序员WTL指南(2)ATL界面类

 2008-01-19 20:26:41 来源:WEB开发网   
核心提示:ATL中的对话框我们前面提到过,ATL有两个对话框类,MFC程序员WTL指南(2)ATL界面类(8),我们的About对话框使用CDialogImpl,生成一个新对话框和生成一个主窗口几乎一样,我将全面介绍基本的WTL窗口类和一个更好的消息映射宏,修改记录2003年3月22日,只有两点不同: 窗口的基类是CDia

ATL中的对话框

我们前面提到过,ATL有两个对话框类,我们的About对话框使用CDialogImpl。生成一个新对话框和生成一个主窗口几乎一样,只有两点不同:

  1. 窗口的基类是CDialogImpl而不是CWindowImpl。
  2. 你需要定义名称为IDD的公有成员用来保存对话框资源的ID。

现在开始为About对话框定义一个新类:

class CAboutDlg : public CDialogImpl<CAboutDlg>
{
public:
   enum { IDD = IDD_ABOUT };
   BEGIN_MSG_MAP(CAboutDlg)
   END_MSG_MAP()
};

ATL没有在内部实现对“OK”和“Cancel”两个按钮的响应处理,所以我们需要自己添加这些代码,如果用户用鼠标点击标题栏的关闭按钮,WM_CLOSE的响应函数就会被调用。我们还需要处理WM_INITDIALOG消息,这样我们就能够在对话框出现时正确的设置键盘焦点,下面是完整的类定义和消息响应函数。

class CAboutDlg : public CDialogImpl<CAboutDlg>
{
public:
   enum { IDD = IDD_ABOUT };
   BEGIN_MSG_MAP(CAboutDlg)
     MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
     MESSAGE_HANDLER(WM_CLOSE, OnClose)
     COMMAND_ID_HANDLER(IDOK, OnOKCancel)
     COMMAND_ID_HANDLER(IDCANCEL, OnOKCancel)
   END_MSG_MAP()
   LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
     CenterWindow();
     return TRUE;  // let the system set the focus
   }
   LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
     EndDialog(IDCANCEL);
     return 0;
   }
   LRESULT OnOKCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
   {
     EndDialog(wID);
     return 0;
   }
};

我使用一个消息响应函数同时处理“OK”和“Cancel”两个按钮的WM_COMMAND消息,因为命令响应函数的wID参数就已经指明了消息是来自“OK”按钮还是来自“Cancel”按钮。

显示对话框的方法与MFC相似,创建一个新对话框类的实例,然后调用DoModal()方法。现在我们返回主窗口,添加一个带有About菜单项的菜单用来显示我们的对话框,这需要再添加两个消息响应函数,一个是响应WM_CREATE,另一个是响应菜单的IDC_ABOUT命令。

class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CFrameWinTraits>,
          public CPaintBkgnd<CMyWindow,RGB(0,0,255)>
{
public:
   BEGIN_MSG_MAP(CMyWindow)
     MESSAGE_HANDLER(WM_CREATE, OnCreate)
     COMMAND_ID_HANDLER(IDC_ABOUT, OnAbout)
     // ...
     CHAIN_MSG_MAP(CPaintBkgndBase)
   END_MSG_MAP()
   LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
   HMENU hmenu = LoadMenu ( _Module.GetResourceInstance(),
               MAKEINTRESOURCE(IDR_MENU1) );
     SetMenu ( hmenu );
     return 0;
   }
   LRESULT OnAbout(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
   {
   CAboutDlg dlg;
     dlg.DoModal();
     return 0;
   }
   // ...
};

在指定对话框的父窗口的方式上有些不同,MFC是通过构造函数将父窗口的指针传递给对话框而在ATL中是将父窗口的指针作为DoModal()方法的第一个参数传递给对话框的,如果象上面的代码一样没有指定父窗口,ATL会使用GetActiveWindow()得到的窗口(也就是我们的主框架窗口)作为对话框的父窗口。

对LoadMenu()方法的调用展示了CComModule的另一个方法-GetResourceInstance(),它返回你的EXE的HINSTANCE实例,和MFC的AfxGetResourceHandle()方法相似。(当然还有CComModule::GetModuleInstance(),它相当于MFC的AfxGetInstanceHandle()。)

这就是主窗口和对话框的显示效果:

  • 我会继续讲WTL,我保证!

    我会继续讲WTL的,只是会在第二部分。我觉得既然这些文章是写给使用MFC的开发者的,所以有必要在投入WTL之前先介绍一些ATL。如果你是第一次接触到ATL,那现在你就可以尝试写一些小程序,处理消息和使用嵌入类,你也可以尝试用类向导支持消息映射链,使它能够自动添加消息响应。现在就开始,右键单击CMyWindow项,在弹出的上下文菜单中单击“Add Windows Message Handler”菜单项。

    在第二部分,我将全面介绍基本的WTL窗口类和一个更好的消息映射宏。

    修改记录

    2003年3月22日,本文第一次发表。

  • 上一页  3 4 5 6 7 8 

    Tags:MFC 程序员 WTL

    编辑录入:爽爽 [复制链接] [打 印]
    赞助商链接