{A}{S0}谢谢
在这篇文章中提出的所有代码使用,所有的WTL的开发。
桌面样品使用,与他的权限,。感谢所有Bjarke。摘自的办公室97风格的颜色选择器控制
彩色菜单的颜色。演示
使用用户交互模式对话框,相当于向用户发出一个阻塞调用。 DoModal()调用一个简单的和唯一的出口点,并在返回时,携带所要求的资料,包括可能的用户取消。他们通常需要建立一个DIALOGTEMPLATE资源和联营CDialogImpl类派生类。
本文介绍类的不寻常的模态对话框的设置不要求所有。它使用了彗星的模板,而不是DIALOGTEMPLATE资源。
这是专为容易以最小的,如果有的话,具体的编码。它构成了一个灵活的工具集,允许容易编写,阅读和维护应用的代码和多个平台上的简单调整的具体要求。
基类派生或专业,如非标准菜单,仅仅是声明,并不会产生任何机器代码。
这篇文章是由三部分组成:显示了你可以从很少的代码行,并得到你认识 - 如果需要的话 - 模板专业代码。介绍了通用类和平台专门Vista和移动类。显示了一些应用性的使用,通过三个类似DialogX的应用程序,预Vista的一个支持Vista的桌面应用程序和同级目标平台的适应化修改,从2003年智能手机和PPC的2002年到WM6的所有移动设备的Windows Mobile应用程序。
随着WTL 8.0应用程序向导生成一个简单的SDI应用程序与CPP代码,并没有视图类。调用它DlgTour。
打开资源编辑器,并添加字符串资源的"测试""ID_TEST ID。
编辑的stdafx.h中包括atlmisc.h,我们将使用连接点和CString:// stdafx.h: include file for standard system include files,
// ...
#include <atlwin.h>
#include <atlmisc.h>
#include <atlframe.h>
// ... // 1
在CMainFrame声明的上下文菜单处理程序... ...{C}
{A21提取} atldlgx.h LT; DlgTourgt;目录,包括mainframe.cpp// MainFrm.cpp: implementation of the CMainFrame class
//
////////////////////////////////////////////////////////////////////////////
/
#include "stdafx.h"
#include "resource.h"
#include "atldlgx.h" // 3
#include "aboutdlg.h"
#include "MainFrm.h"
定义在MainFrm.cpp OnContextMenu// ...
LRESULT CMainFrame::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled) // 3
{
return 0;
}
// ...
:
编辑stdafx.h中的常量:// stdafx.h: include file for standard system include files,
// ...
// Change these values to use different versions
#define WINVER 0x0600 // 4
#define _WIN32_WINNT 0x0600 // 4
#define _WIN32_IE 0x0600 // 4
,提取WtlAero.h您的LT; DlgTourgt;目录,其中包括在mainframe.cpp atlctrlx.h和WtlAero.h前atldlgx.h:// MainFrm.cpp: implmentation of the CMainFrame class
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include <atlctrlx.h> // 5
#include "WtlAero.h" // 5
#include "atldlgx.h" // 3
现在我们可以开始游览本身。
粘贴或键入这两条线在CMainFrame::OnContextMenu代码:LRESULT CMainFrame::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
typedef CCellMenu<IDR_MAINFRAME, 4, 2> CToolMenu;
CToolMenu::TrackCellMenu(CPoint(lParam));
return 0;
}
编译,运行和右键单击在DlgTour窗口:{S2}
我们定义为 CToolMenu 4列2行显示IDR_MAINFRAME位图。我们称之为静态TrackCellMenu()成员的默认定位在口岸系统(LPARAM),鼠标坐标。
TrackCellMenu返回所选单元格或-1的索引,如果没有,得到一个功能菜单,我们必须采取行动后,返回值:LRESULT CMainFrame::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
typedef CCellMenu<IDR_MAINFRAME, 4, 2> CToolMenu;
int iSel = CToolMenu::TrackCellMenu(CPoint(lParam));
static const UINT commands[] =
{
ID_FILE_NEW, ID_FILE_OPEN, ID_FILE_SAVE, ID_EDIT_CUT,
ID_EDIT_COPY, ID_EDIT_PASTE, ID_FILE_PRINT, ID_APP_ABOUT
};
if(iSel != -1)
PostMessage(WM_COMMAND, commands[iSel]);
return 0;
}
命令处理程序唯一的功能是ID_APP_ABOUT。选择与键盘的问号,或按一下它带来"关于"对话框,执行任何其他的鼠标或键盘操作解雇菜单。
见在示例部分。
到CMainFrame中键入::OnContextMenu()成员:LRESULT CMainFrame::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
typedef CControlDialog<ID_TEST, CMonthCalendarCtrl> CDateDialog;
CPoint pt(lParam);
ScreenToClient(&pt);
CDateDialog dd(pt, CSize(300, 150));
dd.DoModal();
return 0;
}
编译,运行和右键单击。{S3}
我们定义为 CDateDialog主办一个CMonthCalendarCtrl,ID_TEST ID和默认样式。
我们实例化一个CDateDialog和鼠标的位置,任意大小的起源,呼吁DoModal()。
自动调整对话框MonthCalendar控制项左右,采取的CMainFrame的CDateDialog声明:OnContextMenu(),并为它添加一些模板专业化:typedef CControlDialog<ID_TEST, CMonthCalendarCtrl> CDateDialog;
bool CDateDialog::ControlDialog::Init(LPARAM lParam)
{
DefInit(lParam);
CRect rCtrl;
m_Ctrl.GetMinReqRect(rCtrl);
ResizeClient(rCtrl.Width(), rCtrl.Height());
return true;
}
LRESULT CMainFrame::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
//typedef CControlDialog<ID_TEST, CMonthCalendarCtrl> CDateDialog;
// ...
我们专门一个CDateDialog父类的成员,CControlDialogImpllt CDateDialog,ID_TEST,CMonthCalendarCtrlgt;:INIT()根据要求的CMonthCalendarCtrl尺寸(默认的初始化后)调整大小。
在桌面示例部分。
如果你没有跳过这一步执行额外的Vista的预赛。
在MainFrm.cpp键入:// MainFrm.cpp: implmentation of the CMainFrame class
// ...
class CTestDialog: public aero::CEmptyDialogImpl<CTestDialog, ID_TEST,
CEmptyDlgTemplate<ID_TEST, CSplitDlgTraits> >
{
typedef aero::CEmptyDialogImpl<CTestDialog, ID_TEST,
CEmptyDlgTemplate<ID_TEST,
CSplitDlgTraits> > AeroEmptyDialog;
public:
CTestDialog(SIZE size): AeroEmptyDialog(size)
{}
};
LRESULT CMainFrame::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
CTestDialog td(CSize(200, 200));
td.DoModal();
return 0;
}
编译,运行和右键单击。{五}
我们定义了一个CTestDialog类派生和行为像(调整大小边界)的风格与CSplitDialogTraits。我们实例化,并呼吁其DoModal()成员。
在Vista示例部分。
VS2005的:与WTL 8.0移动应用程序向导生成一个简单的SDI应用程序,针对PPC2003和Smartphone2003手机,CPP的代码,EVC的兼容性,并没有视图类。调用它DlgTour。
eVC4:下载,扩大和与EVC中打开它。
打开IDE资源视图
选择DlgToursp.rc
的res \ toolbar.bmp位图导入IDR_MAINFRAME ID
添加字符串资源ID_TEST ID"测试""
{A21提取} atldlgx.h LT; DlgTourgt;目录,并包括在DlgTourFrame.cpp后atldlgs.h// DlgTourFrame.cpp: implementation of the CDlgTourFrame class
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif
#include "atldlgs.h" // 1
#include "atldlgx.h" // 1
#include "aboutdlg.h"
#include "DlgTourFrame.h"
现在,我们可以采取参观。{A37}
粘贴或键入CDlgTourFrame这些六线:的OnAction代码:LRESULT CDlgTourFrame::OnAction(WORD /*wNotifyCode*/, WORD /*wID*/,
HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CRect rect;
GetClientRect(rect);
CPoint pt(rect.left, rect.bottom);
ClientToScreen(&pt);
typedef CCellMenu<IDR_MAINFRAME, 7, 1> CToolMenu;
CToolMenu::TrackCellMenu(pt, TPM_BOTTOMALIGN);
return 0;
}
选择智能手机2003平台上,编译,运行,推动"动作"按钮:{中六}我们定义了一个
IDR_MAINFRAME位图显示7列和1行。
我们称之为TrackCellMenu()底部(默认左)定位在底部左上角的帧的静态成员
TrackCellMenu返回所选单元格或-1的索引,如果没有,得到一个功能菜单我们必须使用返回值。 CDlgTourFrame结束添加以下内容:的OnAction:LRESULT CDlgTourFrame::OnAction(WORD /*wNotifyCode*/, WORD /*wID*/,
HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// ...
//CToolMenu::TrackCellMenu(pt, TPM_BOTTOMALIGN);
int iSel = CToolMenu::TrackCellMenu(pt, TPM_BOTTOMALIGN);
static const UINT commands[] =
{
ID_FILE_NEW, ID_FILE_OPEN, ID_FILE_SAVE, ID_EDIT_CUT,
ID_EDIT_COPY, ID_EDIT_PASTE, ID_APP_ABOUT
};
if(iSel != -1)
PostMessage(WM_COMMAND, commands[iSel]);
return 0;
};
唯一的工作处理程序OnAppAbout,如果我们选择使用键盘的问号,ID_APP_ABOUT命令将确实执行,并弹出关于对话框。
{A39}移动样品部分。{A40}
粘贴或在CDlgTourFrame此键入:的OnAction代码:LRESULT CDlgTourFrame::OnAction(WORD /*wNotifyCode*/, WORD /*wID*/,
HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
typedef CStdControlDialog<ID_TEST, CMonthCalendarCtrl> CDateDialog;
CDateDialog dd;
dd.DoModal();
return 0;
}
选择智能手机2003平台上,编译,运行,推动"动作"按钮:
{A41}托管ID_TEST编号CMonthCalendarCtrl,我们定义为CDateDialog。
我们实例化CDateDialog并呼吁DoModal()就可以了。
使用选定的日期,我们应该添加一些调用和一些专门的代码。与{A42}移动的示例部分。{A43}
平台独立的类:
{A44}
{A45}
{A47}
{A49}
{A51}
{A52}
{A53}
{A55}
{A56}
{A57}
{A58}
{A59}
{A60}
{A61}{A62}
CEmptyDlgTemplate是一个WTL::CMemDlgTemplate加载在其创建的资源字符串(点,大小尺寸)成员从对话框的标题。
要充分定义CEmptyDlgTemplate您需要指定一个字符串资源ID,并选择性的ATL:CWinTraits的风格的实例。
CEmptyDlgTraits,CControlDlgTraits,CSplitDlgTraits,各种CEmptyDlgTemplate专业对话框样式。
{A63}是一个MI类:将它添加到一个模态对话框继承列表和链接的消息映射,使父窗口和autocancels失去激活,它给出了一个简单menulike的行为时。
定义
由于我们还没有受益{A65}模板的typedef atldlgx.h CEmptyDialogImpl和其他类的定义不是很容易阅读。对于可读性每个模板参数是写在不同的线路和评论。template
< class T, // Actual dialog class: ie CMyEmptyDialog
UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
//menu (if matching resources exist)
class TDlgTemplate // In memory dialog template
= CEmptyDlgTemplate<t_uIDD, CEmptyDlgTraits>,
// default for TDlgTemplate
class TBase // CIndirectDialogImpl::TBase class
= ATL::CDialogImpl<T, ATL::CWindow> // default for TBase
>
class ATL_NO_VTABLE CEmptyDialogImpl: public CIndirectDialogImpl<
T,
TDlgTemplate,
TBase
> // CIndirectDialogImpl
{
typedef CEmptyDialogImpl<T, t_uIDD, TDlgTemplate, TBase> thisClass;
public:
typedef thisClass EmptyDialog;
// ...
明确扩大的模板定义最大的灵活性,允许类的用法。 TBASE到ATL的默认值::CDialogImpllt; GT,但移动设备CStdEmptyDialogImpl的TBASE的WTL::CStdDialogImpllt; GT;如果我们想要一个航空对话框{A66}所述,TBASE应的WTL::航空:CDialogImpllt; GT。{A67}
所有的构造函数有一个bool bDLU参数。如果属实,这是默认的,大小和定位参数转换为{A68}在生成的DLGTEMPLATE。
空的构造函数:派生类执行m_Template和M_DATA初始化
CEmptyDialogImpl()
浆纱构造函数:套原产地为{0,0}
CEmptyDialogImpl(尺寸大小,BOOL bDLU = TRUE)
定位的构造函数:套起源点和大小尺寸
CEmptyDialogImpl(点,规模的大小,BOOL bDLU = TRUE)
定位的构造方法:使用正确的起源和尺寸
CEmptyDialogImpl(RECT RECT,BOOL bDLU = TRUE)数据成员
枚举{IDD}是指从t_uIDD与其他对话框的兼容性。
LPARAM M_DATA保存用户数据,根据派生类。
HWND的m_hWndToolBar拥有工具栏上的控制手柄,如果任何(Win32平台)。
默认操作:Overrideable委员
消息处理程序,并调用这些成员可以在派生类中重写。如果不重写匹配的WM_xxx消息后,他们定义类的行为。 BOOL返回值是使用消息处理程序的返回bHandled值。
BOOL INIT(LPARAM lParam参数)调用DefInit(LPARAM)。
BOOL大小(WPARAM / * wParam参数* /,LPARAM / * lParam参数* /)重绘客户区。
BOOL涂料(HDC / * HDC * /)什么也不做。
关闭(ICMD)结束对话框返回ICMD。助手成员
DefInit(),默认的初始化成员副本DoModal()的lParam来M_DATA,试图创建一个工具栏,加载的菜单和设置对话框的图标从t_uIDD匹配的资源,并最终释放DLGTEMPLATE内存。设置在WM_INITDIALOG未处理叶在派生类的消息映射打开一个可能的后续。
MoveToTemplatePix()允许在初始化时,当模板位置的数据并没有被转换为creationtime DLUs的精确定位。
PixToDLU()成员内部使用的建设者。派生类
和{A58}使用一个特定的TBASE模板参数。
{A47公路},{A50}是从CEmptyDialogImpl派生的基类。
和是用户直接从CEmptyDialogImpl派生类。{A72}
CCellMenu目的是在一个矩形的单元布局是适当的情况下,以取代传统的菜单。它使用CMenuDialogTraits的样式:定义
CCellMenu来自{A45}和。
类定义使用三个模板参数,一个位图资源ID,列数和行数:
构造
typedef ATL::CWinTraits<WS_POPUP | WS_BORDER> CMenuDialogTraits;
class CMenuDlgTemplate: public CEmptyDlgTemplate<0, CMenuDialogTraits>
{};
template
< UINT t_uIDD, // Menu dialog IDD and bitmap
//(if matching resource exists)
INT t_nCol, // Number of columns
INT t_nRow // Number of rows
>
class CCellMenu: public CEmptyDialogImpl<
/*thisClass*/CCellMenu<t_uIDD, t_nCol, t_nRow>,
t_uIDD,
/*TDlgTemplate*/CMenuDlgTemplate
>, // CEmptyDialogImpl
public CMenuDialog<
/*thisClass*/CCellMenu<t_uIDD, t_nCol, t_nRow>
> // CMenuDialog
{
typedef CCellMenu<t_uIDD, t_nCol, t_nRow> thisClass;
public:
typedef CMenuDialog<thisClass> MenuDialog;
{
// ...
CCellMenu有一个构造函数使用overrideables静态常量SIZE CCellMenu一个点:CellSize()和静态的常量尺寸CCellMenu::MenuSize()计算从相关的位图的大小和行和列的数量各自的大小。如果没有t_uIDD ID的位图单元的大小是从系统指标SM_CXSMICON和SM_CYSMICON的计算。默认操作
CCellMenu使用选定的单元格和更新鼠标或键盘操作的指数M_DATA。
助手结构CCellMenu:Cell提供了不同的大小和位置计算。
CCellMenu::DoModal()返回选定的单元格指数,如果用户点击单元格或按回车键,或-1,如果对话框被取消或驳回。
CCellMenu的目的是要通过它的静态诠释CCellMenu运作:TrackCellMenu(点PT,UINT uFlags = 0,LPARAM lParam的= 0,HWND hWndParent = GetActiveWindow())
pt是定位基准点。
uFlags是一个TrackPopupMenu(TPM_xxxALIGN)标志的组合。
lParam是最初的选择指数。
CCellMenu:TrackCellMenu()生成一个CCellMenu定位uFlags表示,调用DoModal()成员,并返回用户选择指数。Overrideables
CCellMenu绘画和浆纱成员可能是专门的。
用法示例// Specializables
void PrePaint(HDC hdc)
{
SIZE s = MenuSize();
RECT rect = {0, 0, s.cx, s.cy};
CDCHandle(hdc).FillSolidRect(&rect,
GetSysColor(COLOR_MENU));
}
void PaintCells(HDC hdc)
{
for (int iRow = 0; iRow < t_nRow; iRow++)
for (int iCol = 0; iCol < t_nCol; iCol++)
PaintCell(hdc, CELL(iCol, iRow));
}
void PaintCell(HDC hdc, CELL &cell)
{
GetImageList().Draw(hdc, cell.Index(), cell.Left(true),
cell.Top(true),
cell.Index() == (INT)m_Data ?
ILD_SELECTED: ILD_NORMAL);
}
void FocusSelection(HDC hdc)
{
RECT rect = CELL((INT)m_Data).Rect();
CDCHandle(hdc).DrawFocusRect(&rect);
}
bool Paint(HDC hdc)
{
PrePaint(hdc);
PaintCells(hdc);
FocusSelection(hdc);
return true;
}
{A74}。{A75}
CControlDialogImpl实现一个单一的控制"对话框,从而使调用DoModal()上的任何控制。定义
构造函数typedef ATL::CWinTraits<WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU |
DS_CENTER, WS_EX_DLGMODALFRAME> CControlDlgTraits;
template
< class T, // Actual dialog class: ie CMyControlDialog
UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
// menu (if matching resources exist)
class TCtrl, // Control class
class TControlTraits // Control styles
= ATL::CControlWinTraits, // default control styles
class TDlgImpl // Empty dialog base class
= CEmptyDialogImpl<T, t_uIDD, CControlDlgTraits>
// default for TDlgImpl
>
class CControlDialogImpl: public TDlgImpl
{
typedef CControlDialogImpl<T, t_uIDD, TCtrl, TControlTraits,
TDlgImpl> thisClass;
public:
typedef thisClass ControlDialog;
// ...
{A76}相同。数据成员
CControlDialogImpl的类型TCtrl m_Ctrl成员。默认操作:Overrideable委员
这些成员被称为消息处理程序,并可能在衍生或专业类重写。如果不重写匹配的WM_xxx消息后,他们定义类的行为。 BOOL返回值是使用消息处理程序的返回bHandled值。
BOOL CControlDialogImpl:INIT(LPARAM lParam参数)返回CControlDialogImpl:DefInit(LPARAM)。
BOOL CControlDialogImpl:尺寸(WPARAM WPARAM,LPARAM lParam参数)返回CControlDialogImpl:DefSize(WPARAM,LPARAM)。
BOOL通知(INT idCtrl,LPNMHDR pnmhdr)被称为WM_NOTIFY消息,什么都不做,返回false。
BOOL的命令(WORD wNotifyCode,字WID,HWND的hWndCtl)WM_COMMAND消息调用,什么都不做,返回false。
BOOL键(UINT / * uMsg * /,WPARAM / * wParam参数* /,LPARAM / * lParam参数* /)被称为WM_KEYFIRST WM_KEYLAST消息,什么都不做,返回false。
HBRUSH CtlColor(HDC / * HDC * /)上呼吁WM_xxxCOLOR消息,什么都不做,返回NULL。助手成员
派生类bool DefInit(LPARAM lParam)
{
EmptyDialog::Init(lParam);
ControlInit();
return false;
}
void ControlInit()
{
RECT rCtrl;
GetClientRect(&rCtrl);
ATLVERIFY(m_Ctrl.Create(m_hWnd, rCtrl, NULL,
TControlTraits::GetWndStyle(0),
TControlTraits::GetWndExStyle(0), ATL_IDM_WINDOW_FIRST));
m_Ctrl.SetFocus();
}
bool DefSize(WPARAM wParam, LPARAM /*lParam*/)
{
if (m_Ctrl.IsWindow() && wParam != SIZE_MINIMIZED)
{
RECT rClient;
GetClientRect(&rClient);
m_Ctrl.MoveWindow(&rClient);
}
return false;
}
{A55}和移动{A59}实例化类派生直接从CControlDialogImpl。
{A49}派生的两个CControlDialogImpl。{A79}
CControlDialog是specializable CControlDialogImpl。定义
构造函数template
< UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
// menu (if matching resources exist)
class TCtrl, // Control class
class TControlTraits // Control styles
= ATL::CControlWinTraits,// default for TControlTraits
class TControlDlgTraits // Dialog styles
= CControlDlgTraits // default for TControlDlgTraits
>
class CControlDialog: public CControlDialogImpl<
/*thisClass*/CControlDialog<t_uIDD, TCtrl, TControlTraits,
TControlDlgTraits>,
t_uIDD,
TCtrl,
TControlTraits,
/*TDlgImpl*/CEmptyDialogImpl<
/*thisClass*/CControlDialog<t_uIDD, TCtrl,
TControlTraits, TControlDlgTraits>, t_uIDD,
/*TDlgTemplate*/CEmptyDlgTemplate<t_uIDD,
TControlDlgTraits>
> // CEmptyDialogImpl
> // CControlDialogImpl
{
typedef CControlDialog<t_uIDD, TCtrl, TControlTraits,
TControlDlgTraits> thisClass;
{A76}相同。用法示例
{A82}
CInPlaceEditor目的是为了让一些已知在一些知名的矩形文本编辑的地方。定义
CInPlaceEditor派生和从{A47}。
类定义使用三个模板参数,编辑的文本的最大长度,编辑控制类默认CEdit,编辑控件的样式默认为CInPlaceEditTraits。所以,默认是一个单行编辑与ES_AUTOHSCROLL。定义和建筑业
构造typedef CWinTraitsOR<ES_AUTOHSCROLL> CInPlaceEditTraits;
template <
UINT t_iLength,
// length of text buffer passed as lParam in DoModal() call
class TEditCtrl // edit control class
= CEdit, // default for TEditCtrl
class TEditTraits // edit control styles
= CInPlaceEditTraits // default for TEditTraits
>
class CInPlaceEditor: public CControlDialogImpl<
/*thisClass*/CInPlaceEditor<t_iLength, TEditCtrl, TEditTraits>,
/*t_uIDD*/t_iLength,
/*TCtrl*/TEditCtrl,
/*TCtrlTraits*/TEditTraits,
/*TDlgImpl*/CEmptyDialogImpl<
/*thisClass*/CInPlaceEditor<t_iLength, TEditCtrl,
TEditTraits>,
/*t_uIDD*/t_iLength,
/*TDlgTemplate*/CMenuDlgTemplate
> // CEmptyDialogImpl
>, // CControlDialogImpl
public CMenuDialog<CInPlaceEditor<t_iLength, TEditCtrl,
TEditTraits> >
{
typedef CInPlaceEditor<t_iLength, TEditCtrl, TEditTraits> thisClass;
public:
// Constructor
CInPlaceEditor(RECT rect): ControlDialog(rect)
{}
CInPlaceEditor有一个构造函数使用一个RECT。默认操作
CInPlaceEditor使用DoModal()lParam值作为t_iLength长度的文本缓冲区。 CInPlaceEditor:INIT(LPARAM lParam的)副本的lParam它的M_DATA成员,并设置有什么编辑控件的初始内容。
如果用户点击返回编辑控件的内容复制回M_DATA成员。
CInPlaceEditor的目的是要通过它的静态布尔CInPlaceEditor操作:编辑(RECTamp; rEdit,LPTSTR sText,HWND hwndParent = GetActiveWindow())
rEdit CInPlaceEditor的父坐标的定位矩形。
sText TCHAR缓冲区的大小,包含文字编辑t_iLength地址。Overrideables
用法示例bool Init(LPARAM lParam)
{
m_Data = lParam;
m_Template.Reset(); // free DLGTEMPLATE memory
ControlInit();
if (!m_Ctrl.GetFont())
m_Ctrl.SetFont(AtlGetDefaultGuiFont());
m_Ctrl.LimitText(t_iLength);
if(lParam)
{
ATLASSERT(!IsBadWritePtr((LPVOID)lParam,
t_iLength * sizeof(TCHAR)));
m_Ctrl.SetWindowText((LPCTSTR)lParam);
m_Ctrl.SetSel((INT)t_iLength, t_iLength);
}
return false;
}
HBRUSH CtlColor(HDC /*hdc*/)
{
return GetSysColorBrush(COLOR_HIGHLIGHT);
}
void Close(INT iCmd)
{
if((iCmd == IDOK) && m_Data)
m_Ctrl.GetWindowText((LPTSTR)m_Data, t_iLength);
EmptyDialog::Close(iCmd);
}
{A84}。{A85}
CSplitDialogImpl实现双控分裂对话框。定义typedef ATL::CWinTraitsOR<WS_THICKFRAME, 0,
CControlDlgTraits> CSplitDlgTraits;
typedef ATL::CWinTraitsOR<WS_TABSTOP> CSplitControlTraits;
template<UINT t_uIDD>
class CSplitDlgTemplate: public CEmptyDlgTemplate<t_uIDD,
CSplitDlgTraits>
{};
template
< class T, // Actual dialog class: ie CMySplitDialog
UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
// menu (if matching resources exist)
class TSplitImpl, // Splitter implementation class:
// ie WTL::CSplitterImpl<CMySplitDialog, true>
class TLeft, // Left (or top) control class
class TRight, // Right (or bottom) control class
class TLeftTraits // Left (or top) control styles
= CSplitControlTraits, // default for TLeftTraits
class TRightTraits // Right (or bottom) control styles
= CSplitControlTraits, // default for TRightTraits
class TDlgImpl // Empty dialog base class
= CEmptyDialogImpl<T, t_uIDD, CSplitDlgTemplate<t_uIDD> >
// default for TDlgImpl
>
class ATL_NO_VTABLE CSplitDialogImpl: public TDlgImpl,
public TSplitImpl
{
typedef CSplitDialogImpl<T, t_uIDD, TSplitImpl, TLeft, TRight,
TLeftTraits, TRightTraits, TDlgImpl> thisClass;
public:
typedef thisClass SplitDialog;
typedef TSplitImpl Splitter;
注意,TSplitImpl不仅限于WTL::CSplitterImpl。它可以从它派生{A86}构造函数
{A76}相同。数据成员
默认操作:Overrideable委员// Control members
TLeft m_Left; // Left or top control member
TRight m_Right; // Right or bottom control member
消息处理程序,并调用这些成员可能会在衍生或专业类覆盖。如果不重写匹配的WM_xxx消息后,他们定义类的行为。 BOOL返回值是复制到bHandled在返回的消息处理程序。
BOOL CSplitDialogImpl:INIT(LPARAM lParam参数)返回CSplitDialogImpl:DefInit(LPARAM)。
BOOL CSplitDialogImpl:尺寸(WPARAM WPARAM,LPARAM lParam的)呼叫分配器:SetSplitterRect()。
BOOL通知(INT idCtrl,LPNMHDR pnmhdr)被称为WM_NOTIFY消息,什么都不做,返回false。
HBRUSH CtlColor(HDC / * HDC * /)上呼吁WM_xxxCOLOR消息,什么都不做,返回NULL。
BOOL的命令(WORD wNotifyCode,字WID,HWND的hWndCtl)返回CSplitDialogImpl::PaneCommand(WID)。助手成员bool DefInit(LPARAM lParam)
{
EmptyDialog::Init(lParam);
Splitter::GetSystemSettings(false);
m_Left.Create(m_hWnd, rcDefault, NULL, TLeftTraits::GetWndStyle(0),
TLeftTraits::GetWndExStyle(0), ATL_IDM_WINDOW_FIRST);
m_Right.Create(m_hWnd, rcDefault,
NULL, TRightTraits::GetWndStyle(0),
TRightTraits::GetWndExStyle(0), ATL_IDM_WINDOW_LAST);
Splitter::SetSplitterPanes(m_Left, m_Right);
Splitter::SetSplitterRect();
Splitter::SetSinglePaneMode();
Splitter::SetSplitterPos();
return false;// WM_INITDIALOG not handled
}
// Pane related commands
bool PaneCommand(WORD wID)
{
switch(wID)
{
case ID_WINDOW_SPLIT:
Splitter::SetSinglePaneMode(
Splitter::GetSinglePaneMode() == SPLIT_PANE_NONE ?
Splitter::GetActivePane(): SPLIT_PANE_NONE);
break;
case ID_NEXT_PANE:
case ID_PREV_PANE:
if (Splitter::GetSinglePaneMode() != SPLIT_PANE_NONE)
Splitter::SetSinglePaneMode(!Splitter::GetActivePane());
else
Splitter::ActivateNextPane();
break;
default:
return false;
}
#if defined(__ATLWINCE_H__)
SetFocus();
#endif
return true;
}
BOOL PaneCommand(字WID)处理三个预定义的WTL的命令ID:
ID_WINDOW_SPLIT切换单/双窗格模式。
ID_NEXT_PANE和ID_PREV_PANE更改活动集中,可能是单一窗格。派生类
{A51},CStdHSplitDialog实例化的类派生直接从CSplitDialogImpl。{A89}
CSplitDialog是一个specializable CSplitDialogImpl类使用任何适当的TSplitImpl分路实施。
定义和建设
{A90}/////////////////////////////////////////////////////////////////
// CSplitDialog - Generic split dialog
//
template
< UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
// menu (if matching resources exist)
class TSplitImpl, // Splitter implementation class:
ie WTL::CSplitterImpl<CMySplitDialog, true>
class TLeft, // Left (or top) control class
class TRight, // Right (or bottom) control class
class TLeftTraits // Left (or top) control styles
= CSplitControlTraits, // default for TLeftTraits
class TRightTraits // Right (or bottom) control styles
= CSplitControlTraits, // default for TRightTraits
class TSplitDialogTraits // Dialog styles
= CSplitDlgTraits // default for TSplitDialogTraits
>
class CSplitDialog: public CSplitDialogImpl<
/*thisClass*/CSplitDialog<t_uIDD, TSplitImpl, TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits>,
t_uIDD,
TSplitImpl,
TLeft,
TRight,
TLeftTraits,
TRightTraits,
/*TDlgImpl*/CEmptyDialogImpl<
/*thisClass*/CSplitDialog<t_uIDD, TSplitImpl,
TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits>,
t_uIDD,
/*TDlgTemplate*/CEmptyDlgTemplate<t_uIDD,
TSplitDialogTraits>
> // CEmptyDialogImpl
> // CSplitDialogImpl
{
typedef CSplitDialog<t_uIDD, TSplitImpl, TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits> thisClass;
public:
// Constructors
CSplitDialog(){}
CSplitDialog(SIZE size, bool bDLU = true): SplitDialog(size, bDLU){}
CSplitDialog(POINT point, SIZE size,
bool bDLU = true): SplitDialog(point, size, bDLU){}
CSplitDialog(RECT rect, bool bDLU = true): SplitDialog(rect, bDLU){}
};
CVSplitDialog和CHSplitDialog specializable {A50} TSplitImpl是WTL的类:CSplitterImpllt,T,truegt;和WTL::CSplitterImpllt,T,falsegt。定义和建设/////////////////////////////////////////////////////////////////
// CVSplitDialog - Vertical WTL::CSplitterImpl based split dialog
//
template // see CSplitDialog template parameters description
< UINT t_uIDD,
class TLeft, class TRight,
class TLeftTraits = ATL::CControlWinTraits,
class TRightTraits = ATL::CControlWinTraits,
class TSplitDialogTraits = CSplitDlgTraits
>
class CVSplitDialog: public CSplitDialogImpl<
/*thisClass*/CVSplitDialog<t_uIDD, TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits>,
t_uIDD,
/*TSplitImpl*/CSplitterImpl<
/*thisClass*/CVSplitDialog<t_uIDD, TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits>,
true
>, // CSplitterImpl
TLeft, TRight, TLeftTraits, TRightTraits,
/*TDlgImpl*/CEmptyDialogImpl<
/*thisClass*/CVSplitDialog<t_uIDD, TLeft, TRight,
TLeftTraits, TRightTraits,TSplitDialogTraits>, t_uIDD,
/*TDlgTemplate*/CEmptyDlgTemplate<t_uIDD,
TSplitDialogTraits>
> // CEmptyDialogImpl
> // CSplitDialogImpl
{
typedef CVSplitDialog<t_uIDD, TLeft, TRight, TLeftTraits,
TRightTraits, TSplitDialogTraits> thisClass;
public:
// Constructors
CVSplitDialog(){}
CVSplitDialog(SIZE size, bool bDLU = true): SplitDialog(size, bDLU){}
CVSplitDialog(POINT point, SIZE size,
bool bDLU = true): SplitDialog(point, size, bDLU){}
CVSplitDialog(RECT rect, bool bDLU = true): SplitDialog(rect, bDLU){}
};
CHSplitDialog CSplitterImpl第二个模板参数的虚假相同。用法示例
{A92}。{A93}
编译这些类开发平台需要访问{A94}。
见{A66} WTL的描述:航空命名空间的类。{A96}
航空:CEmptyDialogImpl {A97} TBASE模板参数。
如果工具栏是连接到t_uIDD模板参数,它必须使用一个32位位图。请注意,这是不是Vista的要求,但如果它不是32位色WTL8.0代码将不加载工具栏位图与航空操作的正确标志。定义
构造函数template
< class T, // Actual dialog class: ie CMyAeroEmptyDialog
UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
//menu (if matching resources exist)
class TDlgTemplate // In memory dialog template
= CEmptyDlgTemplate<t_uIDD, CEmptyDlgTraits>
// default for TDlgTemplate
>
class ATL_NO_VTABLE CEmptyDialogImpl: public WTL::CEmptyDialogImpl<
T,
t_uIDD,
TDlgTemplate,
aero::CDialogImpl<T>
> // WTL::CEmptyDialogImpl
{
typedef aero::CEmptyDialogImpl<T, t_uIDD, TDlgTemplate> thisClass;
public:
typedef aero::CDialogImpl<T> AeroDialog;
typedef WTL::CEmptyDialogImpl<T, t_uIDD,
TDlgTemplate, AeroDialog> BaseEmptyDialog;
typedef thisClass EmptyDialog;
WTL的相同:{A76}。数据成员
航空:CToolBarCtrl m_ATB成员是子类的工具栏,在Vista下运行时使用。默认操作:Overrideable委员
BOOL航空:CEmptyDialogImpl:INIT(LPARAM lParam的)执行的WTL::CEmptyDialogImpl:INIT(LPARAM lParam的),如果工具栏是目前有条件的子类,它以一个航空:CToolBarCtrl。
航空::CEmptyDialogImpl:涂料(DC CDCHandle,RECTamp; rClient,RECTamp; rView,RECTamp; rDest)什么都不做。请注意,这是你应该重写或专门如果你要画的空对话框区域的成员。
航空:CControlDialog是支持Aero {A100}等价。
TCtrl类必须有一个正确的渲染Vista下启用航空的。定义和建设
{A101}template
< UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
menu (if matching resources exist)
class TCtrl, // Aero enabled Control class
class TControlTraits // Control styles
= ATL::CControlWinTraits, // default for TControlTraits
class TControlDlgTraits // Dialog styles
= CControlDlgTraits // default for TControlDlgTraits
>
class CControlDialog: public WTL::CControlDialogImpl<
/*thisClass*/aero::CControlDialog<t_uIDD, TCtrl, TControlTraits,
TControlDlgTraits>,
t_uIDD,
TCtrl,
TControlTraits,
/*TDlgImpl*/aero::CEmptyDialogImpl<
/*thisClass*/aero::CControlDialog<t_uIDD, TCtrl,
TControlTraits, TControlDlgTraits>, t_uIDD,
/*TDlgTemplate*/CEmptyDlgTemplate<t_uIDD,
TControlDlgTraits>
> // aero::CEmptyDialogImpl
> // WTL::CControlDialogImpl
{
typedef aero::CControlDialog<t_uIDD, TCtrl, TControlTraits,
TControlDlgTraits> thisClass;
public:
// Constructors
CControlDialog(){}
CControlDialog(SIZE size,
bool bDLU = true): ControlDialog(size, bDLU){}
CControlDialog(POINT point,
SIZE size, bool bDLU = true): ControlDialog(point, size, bDLU){}
CControlDialog(RECT rect,
bool bDLU = true): ControlDialog(rect, bDLU){}
};
航空:CSplitDialog支持Aero相当于和间接通过从 TDlgImpl模板参数。
两个TLeft TRight类必须有一个正确的渲染Vista下启用航空。定义和建设
示例代码
template
< UINT t_uIDD, // Dialog IDD, title, icon, toolbar,
// menu (if matching resources exist)
class TSplitImpl, // Aero enabled splitter implementation class:
// ie aero::CSplitterImpl<CMySplitDialog, true>
class TLeft, // Aero enabled reft (or top) control class
class TRight, // Aero enabled right (or bottom) control class
class TLeftTraits // Left (or top) control styles
= CSplitControlTraits, // default for TLeftTraits
class TRightTraits // Right (or bottom) control styles
= CSplitControlTraits, // default for TRightTraits
class TSplitDialogTraits // Dialog styles
= CSplitDlgTraits // default for TSplitDialogTraits
>
class CSplitDialog: public WTL::CSplitDialogImpl<
/*thisClass*/aero::CSplitDialog<t_uIDD, TSplitImpl, TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits>,
t_uIDD,
TSplitImpl,
TLeft,
TRight,
TLeftTraits,
TRightTraits,
/*TDlgImpl*/aero::CEmptyDialogImpl<
/*thisClass*/aero::CSplitDialog<t_uIDD, TSplitImpl,
TLeft, TRight,
TLeftTraits, TRightTraits,
TSplitDialogTraits>,
t_uIDD,
/*TDlgTemplate*/CEmptyDlgTemplate<t_uIDD,
TSplitDialogTraits>
> // aero::CEmptyDialogImpl
> // WTL::CSplitDialogImpl
{
typedef aero::CSplitDialog<t_uIDD, TSplitImpl, TLeft, TRight,
TLeftTraits, TRightTraits, TSplitDialogTraits> thisClass;
public:
// Constructors
CSplitDialog(){}
CSplitDialog(SIZE size, bool bDLU = true): SplitDialog(size, bDLU){}
CSplitDialog(POINT point,
SIZE size, bool bDLU = true): SplitDialog(point, size, bDLU){}
CSplitDialog(RECT rect, bool bDLU = true): SplitDialog(rect, bDLU){}
};
{A103}{A104}
这些类派生atlwince.h CStdDialogImpl,所以他们移动全屏相当于所有用途的类。
{A58}是与操作代码的唯一类。
CStdControlDialog,CStdSplitDialog,CStdHSplitDialog,CStdVSplitDialog只有定义代码。{A106}
CStdEmptyDialogImpl是一家专门{A45}使用CStdDialogImpl TBASE模板参数。定义
构造
CStdEmptyDialogImpl单一argumentless构造,所有的大小是处理t_shidiFlags模板参数。数据成员
没有。默认操作:Overrideable委员
CStdEmptyDialogImpl:INIT(LPARAM lParam参数)返回CStdEmptyDialogImpl:DefInit(LPARAM lParam的)。
所有其他的默认操作处理CEmptyDialogImpl BaseEmptyDialog访问:名称。助手成员
DefInit(),默认的初始化成员复制DoModal()的lParam来M_DATA,释放DLGTEMPLATE内存,创建一个菜单(从t_uIDD SHMENUBAR资源ATL_IDM_MENU_DONECANCEL否则,如果发现),最后执行CStdDialogBase初始化。 DefInit()返回false eVC/ATL3兼容性。
的MenuBar命令按钮佣工:
BOOL SetMenuBarCommand(INT IID,LPCTSTR psText,BOOL明亮= FALSE)
BOOL SetMenuBarCommand(INT IID,BOOL明亮= FALSE)
BOOL SetMenuBarCommand(UINT,UINT uNewId uOldId LPTSTR sText = NULL)派生类
CStdControlDialog,CStdSplitDialog,CStdVSplitDialog,CStdHSplitDialog间接来源于CStdEmptyDialogImpl。{A108}
CStdControlDialog是CControlDialog使用CStdEmptyDialogImpl作为TDlgImpl模板参数。定义
示例代码template
< UINT t_uIDD, // Dialog IDD, title, MenuBar (if matching resources exist)
class TCtrl, // Control class
class TControlTraits // Control styles
= ATL::CControlWinTraits, // default for TControlTraits
UINT t_shidiFlags // Position flags for ::SHInitDialog()
= WTL_STD_SHIDIF, // default for t_shidiFlags
class TDlgTemplate // In memory dialog template
= CStdEmptyDlgTemplate<t_uIDD> // default for TDlgTemplate
>
class CStdControlDialog: public CControlDialogImpl<
/*thisClass*/CStdControlDialog<t_uIDD, TCtrl, TControlTraits,
t_shidiFlags, TDlgTemplate>,
t_uIDD,
TCtrl,
TControlTraits,
/*TDlgImpl*/CStdEmptyDialogImpl<
/*thisClass*/CStdControlDialog<t_uIDD, TCtrl, TControlTraits,
t_shidiFlags, TDlgTemplate>, t_uIDD,
t_shidiFlags,
TDlgTemplate
> // CStdEmptyDialogImpl
> // CControlDialogImpl
{
typedef CStdControlDialog<t_uIDD, TCtrl, TControlTraits, t_shidiFlags,
TDlgTemplate> thisClass;
};
{A110}
CStdSplitDialog是一个专门{A51}使用{A58}作为TDlgImpl模板参数。定义
{A112}typedef ATL::CWinTraitsOR<0, WS_EX_CLIENTEDGE,
CStdEmptyDlgTraits> CStdSplitDlgTraits;
template <UINT t_uIDS>
class CStdSplitDlgTemplate: public CEmptyDlgTemplate<t_uIDS,
CStdSplitDlgTraits>
{};
template
< UINT t_uIDD, // Dialog IDD, title, MenuBar (
// if matching resources exist)
class TSplitImpl, // Splitter implementation class: ie
// WTL::CSplitterImpl<CMyStdSplitDialog, true>
class TLeft, // Left (or top) control class
class TRight, // Right (or bottom) control class
class TLeftTraits // Left (or top) control styles
= CSplitControlTraits, // default for TLeftTraits
class TRightTraits // Right (or bottom) control styles
= CSplitControlTraits, // default for TRightTraits
UINT t_shidiFlags // Position flags for ::SHInitDialog()
= WTL_STD_SHIDIF, // default for t_shidiFlags
class TDlgTemplate // In memory dialog template
= CStdSplitDlgTemplate<t_uIDD> // default for TDlgTemplate
>
class CStdSplitDialog: public CSplitDialogImpl<
/*thisClass*/CStdSplitDialog<t_uIDD,
TSplitImpl, TLeft, TRight,
TLeftTraits, TRightTraits, t_shidiFlags, TDlgTemplate>,
t_uIDD,
TSplitImpl,
TLeft,
TRight,
TLeftTraits,
TRightTraits,
/*TDlgImpl*/CStdEmptyDialogImpl <
/*thisClass*/CStdSplitDialog<t_uIDD,
TSplitImpl, TLeft,
TRight, TLeftTraits, TRightTraits, t_shidiFlags,
TDlgTemplate>,
t_uIDD,
t_shidiFlags,
TDlgTemplate
> // CStdEmptyDialogImpl
> // CSplitDialogImpl
{
typedef CStdSplitDialog<t_uIDD, TSplitImpl, TLeft,
TRight, TLeftTraits,
TRightTraits, t_shidiFlags, TDlgTemplate> thisClass;
};
CStdHSplitDialog和CStdVSplitDialog专门CHSplitDialog和使用作为TDlgImpl模板参数{A58}。定义
示例代码template // see CStdSplitDialog template parameters description
< UINT t_uIDD,
class TLeft, class TRight,
class TLeftTraits = CSplitControlTraits,
class TRightTraits = CSplitControlTraits,
UINT t_shidiFlags = WTL_STD_SHIDIF,
class TDlgTemplate = CStdSplitDlgTemplate<t_uIDD>
>
class CStdHSplitDialog: public CSplitDialogImpl<
/*thisClass*/CStdHSplitDialog<t_uIDD, TLeft, TRight,
TLeftTraits, TRightTraits, t_shidiFlags, TDlgTemplate>,
t_uIDD,
/*TSplitImpl*/CSplitterImpl<
/*thisClass*/CStdHSplitDialog<t_uIDD, TLeft, TRight,
TLeftTraits, TRightTraits,
t_shidiFlags, TDlgTemplate>,
false
>, // CSplitterImpl
TLeft,
TRight,
TLeftTraits,
TRightTraits,
/*TDlgImpl*/CStdEmptyDialogImpl <
/*thisClass*/CStdHSplitDialog<t_uIDD, TLeft, TRight,
TLeftTraits, TRightTraits,
t_shidiFlags, TDlgTemplate>,
t_uIDD,
t_shidiFlags,
TDlgTemplate
> // CEmptyDialogImpl
> // CSplitDialogImpl
{
typedef CStdHSplitDialog<t_uIDD, TLeft, TRight, TLeftTraits,
TRightTraits, t_shidiFlags, TDlgTemplate> thisClass;
};
CMyFileDialog{A114}
三个类似的DialogX应用程序显示引用的类,预Vista和一个支持Vista的桌面应用程序,和兄弟姐妹的Windows Mobile应用程序,目标与智能手机2003年至2002年和PPC平台的适应化修改,所有的移动设备到WM6的应用性用法。
要访问的样本,请下载并展开{A115} LT选择; locationgt;
VS2005和VCExpress:LT打开; locationgt; \ DialogX \ DialogX.sln工作与LT; locationgt; \ DialogX \桌面\ Desktop.vcproj(VS2005)LT; locationgt; \ DialogX \移动\ DialogX.vcproj 。
VC.NET 2003:打开LT; locationgt; \ DialogX \桌面\ DialogX.sln工作与LT; locationgt; \ DialogX \桌面\ DialogX.vcproj。
EVC 3 / 4:打开LT; locationgt; \ DialogX \移动\ DialogX.vcw工作与LT; locationgt; \ DialogX \移动\ DialogX.vcp。
VC6或VC.NET 2002年:创建与WTL AppWizard的一个简单的SDI DialogX项目没有CPP文件并没有视图类,复制生成的项目文件,以LT; locationgt; \ DialogX \桌面\并打开它。
三个样品的许多应用的代码是常见的,所以它是在LT分组; locationgt; \ DialogX \ DialogX.h。
DialogX:您将编译并运行此示例,如果您的开发环境已经无法访问到Vista SDK。
{A116}
{A117}
{A119}
{A120}
{A121}
{A122}
{的A123}
{A124}
{A125}
{A126}
{A127}
{A128}
{A129}
{A130}
{A131}
{A132}{A133}
CMyToolMenu实例的工具栏位图资源。typedef CCellMenu<IDR_MAINFRAME32, 6, 1> CMyToolMenu;
的CMainFrame::ToolMenu(角点)调用CMyToolMenu:使用默认TPM_LEFTALIGN提供点定位| TPM_TOPALIGN TrackCellMenu(PT)。当32位颜色不suported 8位颜色CCellMenult; IDR_MAINFRAME,6,1gt;是用来代替。
{S8}{A135}// MainFrame.h
// ...
void ToolMenu(POINT pt)
{
static const UINT commands[] = {ID_SHELLDIALOG, ID_DATEDIALOG,
ID_COLORMENU, ID_EDIT_STATUS, ID_TOOLMENU, ID_APP_ABOUT};
int iSel;
if (RunTimeHelper::IsCommCtrl6())
iSel = CMyToolMenu::TrackCellMenu(pt);
else
iSel = CCellMenu<IDR_MAINFRAME, 6, 1>::TrackCellMenu(pt);
if(iSel != -1)
PostMessage(WM_COMMAND, commands[iSel]);
}
CMyColorMenu专业CCellMenu:PaintCell画一个颜色表。////////////////////////////////////////////////////////////
// CMyColorMenu
#ifndef ID_COLORMENU
#define ID_COLORMENU 1001
#endif
typedef CCellMenu<ID_COLORMENU, 8, 5> CMyColorMenu;
// Color table
__declspec(selectany) COLORREF colors[] = /* from Chris Maunders */
{
// ...
};
void CMyColorMenu::PaintCell(HDC hdc, CELL& cell)
{
CBrush br = CreateSolidBrush(colors[cell.Index()]);
CDCHandle dc(hdc);
CBrushHandle brOld = dc.SelectBrush(br);
RECT rPaint = cell.Rect(true);
dc.Rectangle(&rPaint);
dc.SelectBrush(brOld);
}
的CMainFrame::ColorMenu(角点)调用CMyColorMenu:TrackCellMenu与当前的背景颜色和背景的索引(PT,TPM_TOPALIGN,m_icolor)如果选择发生。
{S9}{A136}// MainFrame.h
// ...
void ColorMenu(POINT pt)
{
int iSel = CMyColorMenu::TrackCellMenu(pt, TPM_TOPALIGN, m_icolor);
if (iSel != -1)
{
m_icolor = iSel;
Invalidate();
}
}
CMyDateDialog实例月历控件专业化。
专门BOOL CMyDateDialog:ControlDialog:通知(INT,LPNMHDR pnmh)作为验证处理月历控制的MCN_SELECT通知。
专门的BOOL CMyDateDialog:ControlDialog:命令(WORD / * wNotifyCode * /字WID,HWND / * hWndCtl * /)拷贝选定日期以M_DATA。////////////////////////////////////////////////////////////
// CMyDateDialog
#ifndef ID_DATEDIALOG
#define ID_DATEDIALOG 1000
#endif
typedef CWinTraitsOR<MCS_NOTODAY> CMyDateCtrlTraits;
#ifdef _WIN32_WCE
typedef CStdControlDialog<ID_DATEDIALOG,
CMonthCalendarCtrl, CMyDateCtrlTraits>
CMyDateDialog;
#else
typedef CControlDialog<ID_DATEDIALOG, CMonthCalendarCtrl, CMyDateCtrlTraits>
CMyDateDialog;
bool CMyDateDialog::ControlDialog::Init(LPARAM lParam)
{
ATLASSERT(!lParam || !IsBadWritePtr((LPVOID)lParam,
sizeof(SYSTEMTIME)));
DefInit(lParam);
CRect rCtrl;
m_Ctrl.GetMinReqRect(rCtrl);
ResizeClient(rCtrl.Width(), rCtrl.Height());
CenterWindow(GetParent());
return true;
};
#endif
bool CMyDateDialog::ControlDialog::Notify(int, LPNMHDR pnmh)
{
if(pnmh->code == MCN_SELECT)
PostMessage(WM_COMMAND, IDOK);
return false;
};
bool CMyDateDialog::ControlDialog::Command(WORD /*wNotifyCode*/, WORD wID,
HWND /*hWndCtl*/)
{
if((wID == IDOK) && m_Data)
m_Ctrl.GetCurSel((LPSYSTEMTIME)m_Data);
return false;
};
的CMainFrame::DateDialog()实例化一个CMyDateDialog和SYSTEMTIME结构,DoModal()调用的SYSTEMTIME和更新状态栏窗格中,如果出现一个选择的地址。
{A138}// MainFrame.h
// ...
void DateDialog()
{
CMyDateDialog dlg(CSize(150, 150));
SYSTEMTIME st = {0};
if(dlg.DoModal(m_hWnd, (LPARAM)&st) == IDOK)
{
TCHAR szDate[32] = {0};
::GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st,
NULL, szDate, 32);
CStatusBarCtrl(m_hWndStatusBar).SetText(1, szDate);
}
}
{A139}#define STATUS_LENGTH 127 // Max length of pane text
// ...
typedef CInPlaceEditor<STATUS_LENGTH> CPaneEditor;
CStatusPaneEditor是从一个状态栏控件的HWND构造一个简单的类,用一个单一的成员:BOOL EditPane(INT iPane)。
EditPane计算一个合适的矩形编辑窗格,窗格中的文字获取,调用CPaneEditor:编辑这些参数,并更新与编辑的文本窗格版发生。class CStatusPaneEditor
{
public:
CStatusPaneEditor(HWND hWndStatusBar): m_sb(hWndStatusBar)
{}
CStatusBarCtrl m_sb;
bool EditPane(int iPane)
{
ATLASSERT(m_sb.IsWindow());
CRect rPane;
ATLVERIFY(m_sb.GetRect(iPane, rPane));
rPane.InflateRect(-1,-1);
rPane.OffsetRect(0,-1);
m_sb.MapWindowPoints(m_sb.GetParent(), rPane);
CTempBuffer<TCHAR> sPane(STATUS_LENGTH);
m_sb.GetText(iPane, sPane);
bool bRes = CPaneEditor::Edit(rPane, sPane);
if (bRes)
m_sb.SetText(iPane, sPane);
return bRes;
}
};
的CMainFrame::EditStatusPane(INT iPane)与m_hWndStatusBar CStatusPaneEditor实例化和调用EditPane(iPane)。
{S11}{A140}void EditStatusPane(int iPane)
{
CStatusPaneEditor(m_hWndStatusBar).EditPane(iPane);
}
CMyShellDialog是{A141}。typedef CWinTraitsOR
<TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_BORDER |
WS_TABSTOP> CShellTreeTraits;
// Common controls V6 compatibility
#ifndef LVS_EX_DOUBLEBUFFER
#define LVS_EX_DOUBLEBUFFER 0
#endif
typedef CWinTraitsOR
<LVS_SINGLESEL | LVS_SHOWSELALWAYS |
LVS_AUTOARRANGE | LVS_NOCOLUMNHEADER | WS_BORDER |
WS_TABSTOP, LVS_EX_DOUBLEBUFFER> CShellListTraits;
//////////////////////////////////////////////////////////
// CMyShellDialog
#if !defined __WTL_AERO_H__
typedef CVSplitDialog<ID_SHELLDIALOG, CShellTreeCtrl, CShellListCtrl,
CShellTreeTraits, CShellListTraits> CMyShellDialog;
#else
// ...
ID_SHELLDIALOG工具栏资源实现CSplitDialogImpl处理命令。ID_SHELLDIALOG TOOLBAR 16, 16
BEGIN
BUTTON ID_WINDOW_SPLIT
BUTTON ID_NEXT_PANE
BUTTON ID_PREV_PANE
BUTTON IDOK
END
CMyShellDialog专业三个SplitDialog成员:(LPARAM的lParam)
BOOL CMyShellDialog:SplitDialog:初始化执行默认SplitDialog初始化,具体壳牌控制初始化,初始化工具栏,并返回true。
BOOL CMyShellDialog:SplitDialog:命令(字/ * wNotifyCode * / WORD WID的HWND / * hWndCtl * /)调整状态的ID_WINDOW_SPLIT按钮,选择的路径复制到M_DATA如果命令是IDOK。
BOOL CMyShellDialog:SplitDialog:通知(INT idCtrl,LPNMHDR pnmh)处理NM_SETFOCUS,NM_CLICK和TVN_SELCHANGED通知。
{A142}bool CMyShellDialog::SplitDialog::Init(LPARAM lParam)
{
ATLASSERT(!lParam ||
!IsBadWritePtr((LPVOID)lParam, MAX_PATH * sizeof(TCHAR)));
SplitDialog::DefInit(lParam);
#ifdef __ATLTHEME_H__
m_Left.SetWindowTheme(L"explorer", NULL);
m_Right.SetWindowTheme(L"explorer", NULL);
#endif
m_Right.SetExtendedListViewStyle(CShellListTraits::GetWndExStyle(0));
m_Left.Populate();
SetActivePane(SPLIT_PANE_LEFT);
SetSplitterPosPct(40);
CToolBarCtrl tb(m_hWndToolBar);
#if (_WIN32_WINNT >= 0x0501)
tb.SetWindowTheme(L"explorer");
#endif
tb.CheckButton(ID_WINDOW_SPLIT, TRUE);
tb.EnableButton(ID_NEXT_PANE, TRUE);
tb.EnableButton(ID_PREV_PANE, FALSE);
return true;
}
bool CMyShellDialog::SplitDialog::Command(WORD /*wNotifyCode*/, WORD wID,
HWND /*hWndCtl*/)
{
if (PaneCommand(wID))
{
if (wID == ID_WINDOW_SPLIT)
CToolBarCtrl(m_hWndToolBar).CheckButton(
ID_WINDOW_SPLIT,
GetSinglePaneMode() == SPLIT_PANE_NONE);
return true;
}
else if ((wID == IDOK) && m_Data)
{
int iItem = m_Right.GetSelectedIndex();
if (!m_Right.GetItemPath(iItem, (LPTSTR)m_Data))
m_Right.GetItemText(iItem, 0,
(LPTSTR)m_Data, MAX_PATH);
}
return false;
}
bool CMyShellDialog::SplitDialog::Notify(int idCtrl, LPNMHDR pnmh)
{
switch(pnmh->code)
{
case NM_SETFOCUS:
SetDefaultActivePane(pnmh->hwndFrom);
{
CToolBarCtrl tb(m_hWndToolBar);
tb.EnableButton(ID_NEXT_PANE,
GetDefaultActivePane() == SPLIT_PANE_RIGHT);
tb.EnableButton(ID_PREV_PANE,
GetDefaultActivePane() == SPLIT_PANE_LEFT);
}
break;
case NM_CLICK:
if (idCtrl != ATL_IDM_WINDOW_LAST)
return false;
else
{
LPNMLISTVIEW pnmlv = (LPNMLISTVIEW)pnmh;
CPidl pidl;
m_Right.GetItemPidl(pnmlv->iItem, πdl);
m_Left.SelectPidl(pidl);
break;
}
case TVN_SELCHANGED:
{
CWaitCursor cursor;
CPidl pidl;
m_Left.GetItemPidl((
(LPNMTREEVIEW)pnmh)->itemNew.hItem,
pidl);
m_Right.Populate(pidl);
m_Right.SelectItem(0);
}
break;
default:
return false;
}
return true;
}
CBjarkeShellDialog来自{A143},实现了右窗格中的上下文菜单。
{S12}class CBjarkeShellDialog: public CMyShellDialog
{
public:
CBjarkeShellDialog(SIZE sz): CMyShellDialog(sz)
{}
CExplorerMenu m_menu;
BEGIN_MSG_MAP(CBjarkeShellDialog)
MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
CHAIN_MSG_MAP_MEMBER(m_menu)
CHAIN_MSG_MAP(CMyShellDialog)
END_MSG_MAP()
LRESULT OnContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam,
BOOL& /*bHandled*/)
{
if (::GetFocus() == m_Right)
{
CPidl pidl;
if (m_Right.GetItemPidl(m_Right.GetSelectedIndex(), πdl)
!= FALSE)
m_menu.TrackPopupMenu(pidl, GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam), m_hWnd);
}
return 0;
}
};
的CMainFrame::ShellDialog()分配一个CString的大小MAX_PATH,一个CBjarkeShellDialog实例,并调用DoModal字符串作为lParam的。返回时,更新状态栏窗格中选择的路径,如果选择发生。
{S13}{A144}void ShellDialog()
{
int iRet = IDCANCEL;
CString sSelect;
LPTSTR sbuf = sSelect.GetBuffer(MAX_PATH);
#if (_WIN32_WINNT >= 0x0600) && defined(NTDDI_VERSION) && \
(NTDDI_VERSION >= NTDDI_LONGHORN)
// ...
endif // (_WIN32_WINNT >= 0x0600) && defined(NTDDI_VERSION) && \
(NTDDI_VERSION >= NTDDI_LONGHORN)
{
CBjarkeShellDialog dlg(CSize(600, 400));
iRet = dlg.DoModal(m_hWnd, (LPARAM)sbuf);
}
sSelect.ReleaseBuffer();
if (iRet == IDOK)
CStatusBarCtrl(m_hWndStatusBar).SetText(2, sSelect);
}
当此示例Vista下运行,探索命令允许用户选择,支持Aero CBjarkeShellDialog或CMyVistaShellDialog使用Vista的IExplorerBrowser界面之间。在Vista以前的系统没有什么区别。
{A145}
CMyVistaShellDialog是一个{A146}通过Vista的IExplorerBrowser界面操作。
{S14}#ifndef ID_VISTA_SHELLDIALOG
#ifndef ID_SHELLDIALOG
#define ID_VISTA_SHELLDIALOG 1000
#else
#define ID_VISTA_SHELLDIALOG ID_SHELLDIALOG
#endif
#endif
typedef CEmptyDlgTemplate<ID_VISTA_SHELLDIALOG, CSplitDlgTraits>
CVistaShellDlgTemplate;
class CMyVistaShellDialog: public CEmptyDialogImpl<CMyVistaShellDialog,
ID_VISTA_SHELLDIALOG, CVistaShellDlgTemplate>
{
public:
CMyVistaShellDialog(SIZE size): EmptyDialog(size, true)
{}
CComPtr<IExplorerBrowser> m_pIEB;
// ...
更好的用户交互,CMyVistaShellDialog应落实IExplorerBrowserEvents接口,这是这篇文章的范围,并留下你作为一门功课。{A147}和大气外壳控制
CAeroShellTreeCtrl和CAeroShellListCtrl {A148}的CShellTreeCtrl和CShellListCtrl。#if !defined __WTL_AERO_H__
// ...
#else
//////////////////////////////////////////////////////////
// AeroShell controls
class CAeroShellTreeCtrl: public aero::CCtrlImpl<CAeroShellTreeCtrl,
CShellTreeCtrl>
{
public:
CAeroShellTreeCtrl(): CCtrlImpl(VSCLASS_TREEVIEW)
{}
void DoPaint(HDC hdc, RECT& rect)
{
DefWindowProc(WM_PAINT, (WPARAM) hdc, NULL);
if (!m_BufferedPaint.IsNull())
m_BufferedPaint.MakeOpaque(&rect);
}
};
class CAeroShellListCtrl: public aero::CCtrlImpl<CAeroShellListCtrl,
CShellListCtrl>
{
public:
CAeroShellListCtrl(): CCtrlImpl(VSCLASS_LISTVIEW)
{}
void DoPaint(HDC hdc, RECT& rect)
{
DefWindowProc(WM_PAINT, (WPARAM) hdc, NULL);
if (!m_BufferedPaint.IsNull())
m_BufferedPaint.MakeOpaque(&rect);
}
};
CAeroShellDialog instanciates {A56}使用航空:CSplitterImpllt; CAeroShellDialog,truegt; TSplitImpl参数,TLeft参数,并作为TRight参数CAeroShellListCtrl CAeroShellTreeCtrl。//////////////////////////////////////////////////////////
// CAeroShellDialog
typedef class CAeroShellDialog: public aero::CSplitDialog<
/*t_uIDD*/ID_VISTASHELLDIALOG,
/*TSplitImpl*/aero::CSplitterImpl<
/*thisClass*/CAeroShellDialog,
true
>, // aero::CSplitterImpl
CAeroShellTreeCtrl, CAeroShellListCtrl,
CShellTreeTraits, CShellListTraits
> // CAeroEmptyDialogImpl
{
public:
// Constructor
CAeroShellDialog(SIZE size): CSplitDialog(size)
{}
} CMyShellDialog;
#endif // !defined __WTL_AERO_H__
当编译的Vista SDK,和Vista下运行,CMainFrame的:ShellDialog()调用INT的CMainFrame:SelectShellDialog()实例化一个WTL::CTaskDialog允许选择一个或。{S15}
{S16}{A151}
// MainFrm.h: interface of the CMainFrame class
// ...
#if (_WIN32_WINNT >= 0x0600) && defined(NTDDI_VERSION) && \
(NTDDI_VERSION >= NTDDI_LONGHORN)
int SelectShellDialog()
{
CTaskDialog td(m_hWnd);
td.ModifyFlags(0, TDF_POSITION_RELATIVE_TO_WINDOW |
TDF_USE_COMMAND_LINKS);
td.SetWindowTitle(ID_VISTA_SHELLDIALOG);
td.SetMainIcon(TD_INFORMATION_ICON);
td.SetMainInstructionText(L"Select shell browser dialog:");
TASKDIALOG_BUTTON tdb[2] =
{
{ID_SHELLDIALOG, L"CBjarkeShellDialog"},
{ID_SHELLDIALOG + 1, L"CMyVistaShellDialog"}
};
td.SetButtons(tdb,2);
td.SetCommonButtons(TDCBF_CANCEL_BUTTON);
int iRes = 0;
ATLVERIFY(td.DoModal(m_hWnd, &iRes) == S_OK);
return iRes == IDCANCEL ? -1: iRes - ID_SHELLDIALOG;
}
#endif // (_WIN32_WINNT >= 0x0600) && defined(NTDDI_VERSION) && \
(NTDDI_VERSION >= NTDDI_LONGHORN)
void ShellDialog()
{
int iRet = IDCANCEL;
CTempBuffer<TCHAR> sbuf(MAX_PATH);
#if (_WIN32_WINNT >= 0x0600) && defined(NTDDI_VERSION) && \
(NTDDI_VERSION >= NTDDI_LONGHORN)
int iSel =
RunTimeHelper::IsVista() ? SelectShellDialog(): 0;
if (iSel == -1)
return;
else if (iSel == 1)
{
CMyVistaShellDialog dlg(CSize(600, 400));
iRet = dlg.DoModal(m_hWnd, (LPARAM)(LPTSTR)sbuf);
}
else
#endif // (_WIN32_WINNT >= 0x0600) && defined(NTDDI_VERSION) && \
(NTDDI_VERSION >= NTDDI_LONGHORN)
{
CBjarkeShellDialog dlg(CSize(600, 400));
iRet = dlg.DoModal(m_hWnd, (LPARAM)(LPTSTR)sbuf);
}
if (iRet == IDOK)
CStatusBarCtrl(m_hWndStatusBar).SetText(2, sbuf);
}
此示例是一个相当于桌面DialogX的功能,2002年由PPC和Smartphone 2003 tagetting所有Windows Mobile设备的Windows Mobile 6。一些类略有不同,但主要区别是在框架窗口的代码。{A152}
CMyToolMenu实例的工具栏位图资源,与VS 2005编译时,使用DRA的命名空间功能,规模根据屏幕分辨率的细胞和位图。
{S17}#ifndef _WIN32_WCE
// ...
#else
typedef CCellMenu<IDR_MAINFRAME, 6, 1> CMyToolMenu;
#ifdef _WTL_CE_DRA // resolution awareness
const SIZE CMyToolMenu::CellSize()
{
SIZE size;
CBitmap bm = AtlLoadBitmap(IDR_MAINFRAME);
ATLASSERT(!bm.IsNull());
SIZE sbm;
bm.GetSize(sbm);
size.cx = DRA::SCALEX(sbm.cx / (t_nCol * t_nRow)) + 2 * CELL::Cxy();
size.cy = DRA::SCALEY(sbm.cy) + 2 * CELL::Cxy();
return size;
}
CImageList& CMyToolMenu::GetImageList()
{
static CImageList iml;
if (iml.IsNull())
iml = DRA::ImageList_LoadImage(
ModuleHelper::GetResourceInstance(),
MAKEINTRESOURCE(IDR_MAINFRAME),
DRA::UNSCALEX(CELL::Size().cx - 2 * CELL::Cxy()),
0, CLR_DEFAULT, IMAGE_BITMAP, 0);
ATLASSERT(!iml.IsNull());
return iml;
}
#endif // _WTL_CE_DRA
#endif // _WIN32_WCE
CDialogXFrame:ToolMenu(角点)调用CMyToolMenu:TrackCellMenu(PT)使用TPM_BOTTOMALIGN定位点。
{S18}void ToolMenu(POINT pt)
{
static const UINT commands[] =
{
ID_FILEDIALOG, ID_DATEDIALOG, ID_COLORMENU,
ID_EDIT_STATUS, ID_TOOLMENU, ID_APP_ABOUT
};
int iSel = CMyToolMenu::TrackCellMenu(pt, TPM_BOTTOMALIGN);
if(iSel != -1)
PostMessage(WM_COMMAND, commands[iSel]);
}
看到桌面{A155}说明。
CDialogXFrame:ColorMenu()计算底部的中心点,推ID_COLORMENU的按钮(只在PPC2003存在),调用CMyColorMenu::TrackCellMenu(PT TPM_CENTERALIGN | TPM_BOTTOMALIGN,m_icolor)与当前的背景颜色,释放指数按钮和更新的背景,如果选择的发生。{S19}{A156}
{A157}唯一的区别,用一个月的日历控制专业化。{S20}{A158}
移动CPaneEditor使用特定的CEditPaneCtrl处理一些WM5的编辑控制行为的差异,并允许一个上下键逃脱。
在PPC平台CPaneEditor要求SIP系统。
{A159}#define STATUS_LENGTH 127 // Max length of pane text
#ifdef _WIN32_WCE
// CEditPaneCtrl, a CEdit with vertical keys sending IDCANCEL to parent +
// PPC: 'usual' VK_RETURN handling for WM5
// SmartPhone: handling VK_TBACK as VK_BACK
//
class CEditPaneCtrl: public CWindowImpl<CEditPaneCtrl, CEdit>
{
public:
DECLARE_WND_SUPERCLASS(L"EditCtrl", CEdit::GetWndClassName())
BEGIN_MSG_MAP(CEditPaneCtrl)
MESSAGE_RANGE_HANDLER(WM_KEYFIRST, WM_KEYLAST, OnKey)
END_MSG_MAP()
LRESULT OnKey(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/,
BOOL& bHandled)
{
if (uMsg == WM_KEYUP)
switch (wParam)
{
case VK_TUP:
case VK_TDOWN:
::PostMessage(GetParent(), WM_COMMAND,
IDCANCEL, 0);
break;
#if defined WIN32_PLATFORM_PSPC
case VK_RETURN:
::PostMessage(GetParent(), WM_COMMAND,
IDOK, 0);
break;
#elif defined WIN32_PLATFORM_WFSP
case VK_TBACK:
SendMessage(WM_CHAR, VK_BACK);
#endif
}
bHandled = FALSE;
return 1;
}
};
typedef CInPlaceEditor<STATUS_LENGTH, CEditPaneCtrl> CPaneEditor;
#ifdef WIN32_PLATFORM_PSPC
bool CPaneEditor::Init(LPARAM lParam)
{
SHSipPreference(m_hWnd, SIP_UP);
return CInPlaceEditor::DefInit(lParam);
}
#endif // WIN32_PLATFORM_PSPC
CDialogXFrame的PPC平台:EditStatusPane(INT iPane)调用CStatusPaneEditor(m_hWndStatusBar)之前提出的SIP EditPane(iPane)和事后的降低。
{A160} CFileTreeCtl和CFileListCtrlclass CDialogXFrame: // ...
{
// ...
void EditStatusPane(int iPane)
{
#ifdef WIN32_PLATFORM_PSPC
SHSipPreference(m_hWnd, SIP_UP);
CStatusPaneEditor(m_hWndStatusBar).EditPane(iPane);
SHSipPreference(m_hWnd, SIP_DOWN);
#else
CStatusPaneEditor(m_hWndStatusBar).EditPane(iPane);
#endif
}
// ...
这些实现子类WTL::CTreeViewCtrlEx和WTL::CSortListViewCtrlImpl显示文件中的项目非常相似,许多其他除TFilter和TFinder模板参数,。这两个类需要:
一类的TFilter模板参数可以是任何类暴露布尔运算符()(TFinderamp FF)。这种设计使得它很容易选择在任何条件下的文件,包括运行时的条件下,外部的权限或文件内容。
一类TFinder模板参数,WTL的默认值:CFindFile,但可能是一个类似或派生类,通过不同的方式(如设备的远程API CeFindxxxFile())访问文件。template <class TFilter, class TFinder = WTL::CFindFile>
class CFileTreeCtrlF: public CWindowImpl<CFileTreeCtrlF<TFilter,
TFinder>, CTreeViewCtrlEx>
{
// ...
typedef CFileTreeCtrlF<CDirFilter> CDirTreeCtrl;
template <class TFilter, class TFinder = WTL::CFindFile>
class CFileListCtrlF: public CSortListViewCtrlImpl<
CFileListCtrlF< TFilter, TFinder> >
{
// ...
typedef CFileListCtrlF<CFileFilter> CFileListCtrl;
两个类都设在LT; locationgt; \ DialogX在\ Device \ FileControls.h实际上并非仅限于Windows Mobile平台。{A161}
CMyFileDialog是{A162}使用TLeft参数,并作为TRight参数CFileListCtrl CDirTreeCtrl。#if _WIN32_WCE < 0x500 && defined(WIN32_PLATFORM_WFSP)
// No WS_TABSTOP for SmartPhone 2003 controls
typedef CFileTreeTraits CFileDialogTreeTraits;
typedef CFileListTraits CFileDialogListTraits;
#else
typedef CWinTraitsOR<WS_TABSTOP, 0, CFileTreeTraits> CFileDialogTreeTraits;
typedef CWinTraitsOR<WS_TABSTOP, 0, CFileListTraits> CFileDialogListTraits;
#endif
typedef CStdHSplitDialog<ID_FILEDIALOG, CDirTreeCtrl, CFileListCtrl,
CFileDialogTreeTraits, CFileDialogListTraits> CMyFileDialog;
// ...
CMyFileDialog专门在PPC平台上,一个EmptyDialog成员,并始终三个SplitDialog成员:
对于PPC平台,BOOL CMyFileDialog:EmptyDialog:INIT(LPARAM lParam的)加载一个图形菜单栏,如果一个PPC 2002/2003平台上运行,在默认情况下,SplitDialog初始化..(LPARAM的lParam)
BOOL CMyFileDialog:SplitDialog:初始化执行的默认SplitDialog初始化,具体的文件控制初始化,并返回虚假eVC/ATL3兼容性。
BOOL CMyFileDialog:SplitDialog:命令(WORD / * wNotifyCode * /字WID,HWND / * hWndCtl * /)复制所选路径M_DATA如果命令是IDOK,返回SplitDialog:PaneCommand(WID),否则。
BOOL CMyFileDialog:SplitDialog:通知(INT idCtrl,LPNMHDR pnmh)使用NM_SETFOCUS调整PPC2003菜单栏按钮和其他平台左边的按钮文本,并处理NM_RETURN,NM_CLICK和FTCN_SELECT通知。
{S22}{S23}#ifdef WIN32_PLATFORM_PSPC
bool CMyFileDialog::EmptyDialog::Init(LPARAM lParam)
{
if (Device::Is2003())
return DefInit(lParam, ID_FILEDIALOG2003, 4);
else
return DefInit(lParam);
}
#endif
bool CMyFileDialog::SplitDialog::Init(LPARAM lParam)
{
ATLASSERT(!lParam ||
!IsBadWritePtr((LPVOID)lParam, MAX_PATH * sizeof(TCHAR)));
SplitDialog::DefInit(lParam);
m_Right.SetExtendedListViewStyle
(CFileDialogListTraits::GetWndExStyle(0));
m_Right.Init(Device::IsSmartPhone() ? LVS_SMALLICON: LVS_REPORT);
m_Left.Init((LPCTSTR)lParam);
SetActivePane(SPLIT_PANE_LEFT);
return false;
}
bool CMyFileDialog::SplitDialog::Notify(int idCtrl, LPNMHDR pnmhdr)
{
switch(pnmhdr->code)
{
case NM_SETFOCUS:
SetDefaultActivePane(pnmhdr->hwndFrom);
if (Device::Is2003() && !Device::IsSmartPhone())
{ // PPC2003 MenuBar
CMenuBarCtrl mb(::SHFindMenuBar(m_hWnd));
mb.HideButton(ID_NEXT_PANE,
GetDefaultActivePane() == SPLIT_PANE_RIGHT);
mb.HideButton(ID_PREV_PANE,
GetDefaultActivePane() == SPLIT_PANE_LEFT);
mb.PressButton(ID_WINDOW_SPLIT,
GetSinglePaneMode() == SPLIT_PANE_NONE);
}
else
SetMenuBarCommand(ID_NEXT_PANE, ID_NEXT_PANE,
GetDefaultActivePane() == SPLIT_PANE_RIGHT ?
L"Folders": L"Files");
break;
case NM_RETURN: // PPC2005 will do that
case NM_DBLCLK:
PostMessage(WM_COMMAND, IDOK);
break;
case FTCN_SELECT:
m_Right.SetFiles(m_Left.GetFileTreePath());
break;
default:
return false;
}
return true;
}
bool CMyFileDialog::SplitDialog::Command(WORD /*wNotifyCode*/,
WORD wID, HWND /*hWndCtl*/)
{
if(wID == IDOK)
{
if (m_Data)
{
CString sPath;
m_Right.GetFileListFullName(sPath);
SecureHelper::strcpyW_x((LPTSTR)m_Data,
MAX_PATH, sPath);
}
return false;
}
return SplitDialog::PaneCommand(wID);
};
CDialogXFrame::ShellDialog()创建一个CString包含一个反斜杠,instanciates CMyFileDialog和DoModal调用的lParam扩大到MAX_PATH字符串缓冲区。返回时,状态栏更新所选路径,如果选择发生。{S24}结论
这是可能的,我们需要等待一些多年之前的MS编译器执行{A163}。
同时,与目前实施的C权力和WTL的库的帮助下,它可以访问许多不同的平台的Win32 API编写高效的可重用的代码。修订历史
2007年11月6日:发布2007年11月12日:第编辑和转移的主要CodeProject.com文章基地|阿兰里斯特