- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
ATL中的窗口类及常见的窗口处理情况
1、ATL中的窗口类(CWindow):
CWindow类作为ATL中的窗口类,它主要实现了对窗口进行管理和操作的基本功能;它提供的很多方法都是对Win32 API函数的简单封装。
在实际的应用中,我们可以根据自己的需要,合理的使用CWindow类的子类CWindowImpl、CContainedWindow、CDialogImpl,etc来简化操作。
其各类的功能如下:
CWindow类:允许你通过窗口的句柄为其指定一个CWindow对象,并通过CWindow类的方法来管理该窗口。
CWindowImpl类:允许你创建一个新的窗口或者为存在的窗口创建一个子窗口,并将消息的处理放在消息链中进行。
CContainedWindow类:包容器窗口,你也可以用它创建一个新的窗口或为存在的窗口创建一个子窗口;它作为CWindow与CWindowImpl的一个折中,允许你将窗口的消息处理集中到父窗口中。
CDialogImpl类:允许你创建一个有模式或无模式对话框,并将消息的处理放在消息链中进行。
CAxDialogImpl:允许你为Active X控件创建一个有模式或无模式对话框。
其它的还有CWndClassInfo、CWinTraits,CWinTraitsOR,其各个类的具体使用,及它们提供的方法祥见MSDN。
2、常见的窗口处理情况:
(1)创建一个文件打开对话框:
在ATL工程中,我们通过使用API函数GetOpenFileName来实现一个类似与CFileDialog的文件选择对话框。下面我所讲到的都是在ATL工程中,为实现相应的功能,所列举的方法中的一种,其实现的细节可参考如下:
LRESULT OnButClicked_SelectSourceFile(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
OPENFILENAME ofn;
char szFile[260]; // buffer for file name
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "All File/0*.*/0Avi File/0*.avi/0";
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '/0';
ofn.nMaxFile = sizeof(szFile);
ofn.nFilterIndex = 2;
ofn.lpstrTitle = "打开";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
int nResult = ::GetOpenFileName(&ofn);
if (nResult != 0)
{
………………..
}
return 0;
}
(2)创建一个文件保存对话框:
与创建一个文件打开窗口类似,我们通过调用API函数GetSaveFileName来实现,其实现的细节可参考如下:
LRESULT OnButClicked_SelectDestFile(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
OPENFILENAME ofn;
char szFile[260]; // buffer for file name
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "All File/0*.*/0Avi File/0*.avi/0";
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '/0';
ofn.nMaxFile = sizeof(szFile);
ofn.nFilterIndex = 2;
ofn.lpstrTitle = "保存";
ofn.Flags = OFN_CREATEPROMPT;
int nResult = ::GetSaveFileName(&ofn);
if(nResult !=0)
{
……………….
}
return 0;
}
(3)创建一个文件夹浏览对话框:
在这里我们通过调用Shell API函数SHBrowseForFolder来实现我们所需要的功能,其实现的细节可参考如下:
LRESULT OnButClicked_DefaultFilePath(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
char lpszPath[MAX_PATH] = "";
BROWSEINFO sInfo;
::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
sInfo.lpszTitle = _T("请在下面目录选择:");
sInfo.ulFlags = BIF_RETURNONLYFSDIRS;
LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);
if(lpidlBrowse != NULL)
{
if(::SHGetPathFromIDList(lpidlBrowse,lpszPath)) //取得文件夹名
{
………………….
}
::CoTaskMemFree(lpidlBrowse);
}
return 0;
}
在ATL中,我们在调用Shell API函数时,应特别注意除了要包含头文件Shlobj.h和库文件shell32.lib;还应根据需要加入相应的宏NO_WIN32_LEAN_AND_MEAN,其实现细节可参考如下:
在头文件中:
#define NO_WIN32_LEAN_AND_MEAN //for SHBrowseForFolder
#include "Shlobj.h" //for SHBrowseForFolder
3、常见的消息映射宏:
(1)MESSAGE_HANDLER( msg, func )
LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
映射一个窗口消息到指定的消息处理函数中;
(2)MESSAGE_RANGE_HANDLER( msgFirst, msgLast, func )
与MESSAGE_HANDLER类似,只是它映射一系列窗口消息到一个单一的消息处理函数中;
(3)COMMAND_HANDLER( id, code, func )
LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
映射一个指定的WM_COMMAND消息到指定的消息处理函数中;
(4)COMMAND_RANGE_HANDLER( idFirst, idLast, func )
与COMMAND_HANDLER类似,只是它映射一系列窗口消息到一个单一的消息处理函数中,这些ID基于菜单、控件,加速器的ID。
(5)COMMAND_CODE_HANDLER( code, func )
与COMMAND_HANDLER类似,但它仅仅通过通知代码来发送WM_COMMAND消息。
(6)COMMAND_ID_HANDLER( id, func )
与COMMAND_HANDLER类似,但它仅仅通过菜单、控件,加速器的ID来发送WM_COMMAND消息。
(7)NOTIFY_HANDLER( id, cd, func )
LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
映射一个指定的NOTIFY_HANDLER消息到指定的消息处理函数中;
(8)NOTIFY_ID_HANDLER( id, func )
与NOTIFY_HANDLER类似,但它仅仅通过控件ID来发送WM_NOTIFY消息。
(9)NOTIFY_CODE_HANDLER( cd, func )
与NOTIFY_HANDLER类似,但它仅仅通过通知代码来发送WM_NOTIFY消息。
(10)NOTIFY_RANGE_HANDLER( idFirst, idLast, func )
与NOTIFY_HANDLER类似,它通过控件ID映射一系列窗口消息到一个单一的消息处理函数中。 |
|