WTL for MFC Programmers, Part I - ATL GUI Classes[6]

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 orbit 的 blog

// main.cpp:
#include "mywindow.h"
ccommodule _module;
 
int winapi winmain(hinstance hinst, hinstance hinstprev,
                   lpstr szcmdline, int ncmdshow)
{
    _module.init(null, hinst);
 
    cmywindow wndmain;
    msg msg;
 
    // create & show our main window
    if ( null == wndmain.create ( null, cwindow::rcdefault, 
                                 _t("my first atl window") ))
    {
        // bad news, window creation failed
        return 1;
     }
 
    wndmain.showwindow(ncmdshow);
    wndmain.updatewindow();
 
    // run the message loop
    while ( getmessage(&msg, null, 0, 0) > 0 )
    {
        translatemessage(&msg);
        dispatchmessage(&msg);
    }
 
    _module.term();
    return msg.wparam;
}

上面的代码唯一需要说明的是cwindow::rcdefault,这是cwindow中的成员(静态数据成员),数据类型是rect。和调用createwindow() api时使用cw_usedefault指定窗口的宽度和高度一样,atl使用rcdefault作为窗口的最初大小。

在atl代码内部,atl使用了一些类似汇编语言的魔法将主窗口的句柄与相应的cmywindow对象联系起来,在外部看来就是可以毫无问题的在线程之间传递cwindow对象,而mfc的cwnd却不能这样作。

这就是我们的窗口:

 [first atl window - 4k]

我得承认这确实没有什么激动人心的地方。我们将添加一个about菜单并显示一个对话框,主要是为它增加一些情趣。

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命令。

本文关键:ATL WTL MFC
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top