返回首页

{A}{S0}谢谢
在这篇文章中提出的所有代码使用,所有的WTL的开发。
桌面样品使用,与他的权限,。感谢所有Bjarke。摘自的办公室97风格的颜色选择器控制
彩色菜单的颜色。演示
使用用户交互模式对话框,相当于向用户发出一个阻塞调用。 DoModal()调用一个简单的和唯一的出口点,并在返回时,携带所要求的资料,包括可能的用户取消。他们通常需要建立一个DIALOGTEMPLATE资源和联营CDialogImpl类派生类。
本文介绍类的不寻常的模态对话框的设置不要求所有。它使用了彗星的模板,而不是DIALOGTEMPLATE资源。
这是专为容易以最小的,如果有的话,具体的编码。它构成了一个灵活的工具集,允许容易编写,阅读和维护应用的代码和多个平台上的简单调整的具体要求。
基类派生或专业,如非标准菜单,仅仅是声明,并不会产生任何机器代码。
这篇文章是由三部分组成:显示了你可以从很少的代码行,并得到你认识 - 如果需要的话 - 模板专业代码。介绍了通用类和平台专门Vista和移动类。显示了一些应用性的使用,通过三个类似DialogX的应用程序,预Vista的一个支持Vista的桌面应用程序和同级目标平台的适应化修改,从2003年智能手机和PPC的2002年到WM6的所有移动设备的Windows Mobile应用程序。








随着WTL 8.0应用程序向导生成一个简单的SDI应用程序与CPP代码,并没有视图类。调用它DlgTou​​r。
打开资源编辑器,并添加字符串资源的"测试""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; D​​lgTou​​rgt;目录,包括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; D​​lgTou​​rgt;目录,其中包括在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;

}

编译,运行和右键单击在DlgTou​​r窗口:{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的兼容性,并没有视图类。调用它DlgTou​​r。
eVC4:下载,扩大和与EVC中打开它。
打开IDE资源视图
选择DlgTou​​rsp.rc
的res \ toolbar.bmp位图导入IDR_MAINFRAME ID
添加字符串资源ID_TEST ID"测试""
{A21提取} atldlgx.h LT; D​​lgTou​​rgt;目录,并包括在DlgTou​​rFrame.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}
粘贴或键入CDlgTou​​rFrame这些六线:的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的索引,如果没有,得到一个功能菜单我们必须使用返回值。 CDlgTou​​rFrame结束添加以下内容:的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}
粘贴或在CDlgTou​​rFrame此键入:的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()生成一个CC​​ellMenu定位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}相同。数据成员
// Control members



        TLeft m_Left;   // Left or top control member



        TRight m_Right; // Right or bottom control member
默认操作:Overrideable委员
消息处理程序,并调用这些成员可能会在衍生或专业类覆盖。如果不重写匹配的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分路实施。 定义和建设
/////////////////////////////////////////////////////////////////



// 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){}



};
{A90}
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下启用航空的。定义和建设
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){}





};
{A101}
航空: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模板参数。定义
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;

};
{A112}
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;是用来代替。
// 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]);

}
{S8}{A135}
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)如果选择发生。
// MainFrame.h



// ...  



void ColorMenu(POINT pt)

{

        int iSel = CMyColorMenu::TrackCellMenu(pt, TPM_TOPALIGN, m_icolor);

        if (iSel != -1)

        {

                m_icolor = iSel;

                Invalidate();

        }

}
{S9}{A136}
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和更新状态栏窗格中,如果出现一个选择的地址。
// 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);

        }

}
{A138}
#define STATUS_LENGTH 127 // Max length of pane text



// ...



typedef CInPlaceEditor<STATUS_LENGTH> CPaneEditor;
{A139}
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)。
void EditStatusPane(int iPane)

{

        CStatusPaneEditor(m_hWndStatusBar).EditPane(iPane);

}
{S11}{A140}
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通知。
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, &#960;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;

}
{A142}
CBjarkeShellDialog来自{A143},实现了右窗格中的上下文菜单。
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(), &#960;dl) 

                != FALSE) 

                      m_menu.TrackPopupMenu(pidl, GET_X_LPARAM(lParam), 

                        GET_Y_LPARAM(lParam), m_hWnd);

      }

  return 0;

}



};
{S12}
的CMainFrame::ShellDialog()分配一个CString的大小MAX_PATH,一个CBjarkeShellDialog实例,并调用DoModal字符串作为lParam的。返回时,更新状态栏窗格中选择的路径,如果选择发生。
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);

}
{S13}{A144}
当此示例Vista下运行,探索命令允许用户选择,支持Aero CBjarkeShellDialog或CMyVistaShellDialog使用Vista的IExplorerBrowser界面之间。在Vista以前的系统没有什么区别。 {A145}
CMyVistaShellDialog是一个{A146}通过Vista的IExplorerBrowser界面操作。
#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;

// ...
{S14}
更好的用户交互,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}
// 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);

        }
{S16}{A151}
此示例是一个相当于桌面DialogX的功能,2002年由PPC和Smartphone 2003 tagetting所有Windows Mobile设备的Windows Mobile 6。一些类略有不同,但主要区别是在框架窗口的代码。{A152}
CMyToolMenu实例的工具栏位图资源,与VS 2005编译时,使用DRA的命名空间功能,规模根据屏幕分辨率的细胞和位图。
#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
{S17}
CDialogXFrame:ToolMenu(角点)调用CMyToolMenu:TrackCellMenu(PT)使用TPM_BOTTOMALIGN定位点。
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]);

}
{S18}
看到桌面{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系统。
#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
{A159}
CDialogXFrame的PPC平台:EditStatusPane(INT iPane)调用CStatusPaneEditor(m_hWndStatusBar)之前提出的SIP EditPane(iPane)和事后的降低。
class 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

}

// ...
{A160} CFileTreeCtl和CFileListCtrl
这些实现子类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通知。
#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);

};   
{S22}{S23}
CDialogXFrame::ShellDialog()创建一个CString包含一个反斜杠,instanciates CMyFileDialog和DoModal调用的lParam扩大到MAX_PATH字符串缓冲区。返回时,状态栏更新所选路径,如果选择发生。{S24}结论
这是可能的,我们需要等待一些多年之前的MS编译器执行{A163}。
同时,与目前实施的C权力和WTL的库的帮助下,它可以访问许多不同的平台的Win32 API编写高效的可重用的代码。修订历史 2007年11月6日:发布2007年11月12日:第编辑和转移的主要CodeProject.com文章基地|阿兰里斯特

回答

评论会员:游客 时间:2011/12/15
你好阿兰,我将如何在CInPlaceEditor设置我自己的字体?我应该用哪个覆盖的函数?快乐编码,菲利普Kursawe
阿兰里斯特
评论会员:游客 时间:2011/12/15
喜菲利普,BOOLCInPlaceEditor::INIT(LPARAMlParam的)。在您的特殊版本改变任何你想要的字体,而不是AtlGetDefaultGuiFont结果()。欢呼声中,AR当聪明的(人)指出,在月球的傻瓜手指看起来(中国谚语)
菲利普Kursawe
评论会员:游客 时间:2011/12/15
您好再次,我比现在使用的对话框类,和喜欢他们的灵活性。现在我想创建一个cellmenu模拟移动电话号码块。codepretypedefWTL::CCellMenu<-1,spanclass="code-digit"3/span,spanclass="code-digit"4/span>DigitsPad; spanclass="code-keyword"void/spanDigitsPad::PaintCell(HDChdc,CELL&cell){ spanclass="code-keyword"static/spanPCWSTRchars=Lspanclass="code-string""/spanspanclass="code-string"123456789.0C"/span; WTL::CDCHandledc(hdc);RECTcellRect=cell.Rect(spanclass="code-keyword"true/span);dc.FillSolidRect(&cellRect,RGB(spanclass="code-digit"0/span,spanclass="code-digit"0/span,spanclass="code-digit"0/span));dc.SetTextColor(RGB(spanclass="code-digit"255/span,spanclass="code-digit"255/span,spanclass="code-digit"255/span));dc.SetBkMode(TRANSPARENT);dc.DrawText(chars+cell.Index(),spanclass="code-digit"1/span,&cellRect,DT_VCENTER|DT_CENTER);} spanclass="code-keyword"const/spanSIZEDigitsPad::CellSize(){spanclass="code-keyword"return/spanWTL::CSize(spanclass="code-digit"48/span+spanclass="code-digit"2/span*CELL::Cxy(),spanclass="code-digit"48/span+spanclass="code-digit"2/span*CELL::Cxy());} spanclass="code-keyword"void/spanDigitsPad::Close(INTiCmd){spanclass="code-keyword"if/span(iCmd==IDOK){spanclass="code-keyword"static/spanPCWSTRchars=Lspanclass="code-string""/spanspanclass="code-string"123456789.0C"/span;ATL::CStringtext;GetParent().GetWindowText(text);spanclass="code-keyword"if/span(chars[m_Data]==Lspanclass="code-string"'/spanspanclass="code-string"C'/span){}spanclass="code-keyword"else/span{text+=chars[m_Data];}GetParent().SetWindowText(text);}spanclass="code-keyword"else/span{EndDialog(-1);}}/pre/code这几乎与2小问题:1。菜单不再是封闭的,当用户在外面点击2。菜单GetParent返回主窗口,而不是使用这行代码创建CellMenu:codepreWTL::CWindowRectwinRect(wndCtl);DigitsPad::TrackCellMenu(WTL::CPoint(winRect.left,winRect.bottom),spanclass="code-digit"0/span,spanclass="code-digit"0/span,GetDlgItem(nID));/pre/code菜单家长应编辑领域的用户点击进入(GetDlgItem(NID))任何想法?PS:我的WindowsCE快乐编码,菲利普Kursawe
阿兰里斯特
评论会员:游客 时间:2011/12/15
喜菲利普,菲利普Kursawe写道:我比现在使用的对话框类,和喜欢的灵活性。感谢,在这里同样的{S25}菲利普Kursawe写道:"现在我想创建一个cellmenu模仿手机号码块。推CCellMenu其限制。你应该使用一个特定的CEmptyDialog派生类中,也许你的目标CCellMenu代码重用。祝你好运和欢呼声中,AR当明智的(人)点在月球的傻瓜看起来手指(中国谚语)
菲利普Kursawe
评论会员:游客 时间:2011/12/15
!优秀的文章我使用的一些简单的任务模板特殊化。然而,使用一个CControlDialog用ownerdrawn的ListBox,我想我会要创建我自己的子类CControlDialogImpl。codeprespanclass="code-keyword"class/spanCatalogItemsDialog:spanclass="code-keyword"public/spanWTL::CControlDialogImpl<CatalogItemsDialog,spanclass="code-digit"1000/span,WTL::CListBox,CatalogItemsCtrlTraits>{/pre/code虽然会产生错误:codepreerrorC2039:spanclass="code-string"'/spanspanclass="code-string"IsValid'/span:isnotamemberofspanclass="code-string"'/spanspanclass="code-string"ATL::CWinTraits<t_dwStyle,t_dwExStyle>'/spanwith[t_dwStyle=-spanclass="code-digit"1865938944/span,t_dwExStyle=1]C:\dev\projects\vendor\wtl\include\atldlgs.h(spanclass="code-digit"3543/span):spanclass="code-keyword"while/spancompilingspanclass="code-keyword"class/spanspanclass="code-keyword"template/spanmemberfunctionspanclass="code-string"'/spanspanclass="code-string"INT_PTRWTL::CIndirectDialogImpl<T,TDlgTemplate,TBase>::DoModal(HWND,LPARAM)'/spanwith[T=CatalogItemsDialog,TDlgTemplate=WTL::CControlDlgTraits,TBase=ATL::CDialogImpl<CatalogItemsDialog,ATL::CWindow>]/pre/code任何想法如何,我想实现自己的消息处理中的controldialog类?谢谢!快乐编码,菲利普Kursawe
阿兰里斯特
评论会员:游客 时间:2011/12/15
喜菲利普,恭喜,你发现了一个atldlgx.h{S25}错误更改行773:codepre spanclass="code-keyword"class/spanTDlgImpl spanclass="code-comment"///spanspanclass="code-comment"Emptydialogbaseclass/span =CEmptyDialogImpl<T,t_uIDD,CEmptyDlgTemplate<t_uIDD,CControlDlgTraits>>spanclass="code-comment"///spanspanclass="code-comment"defaultforTDlgImpl/span spanclass="code-comment"///spanspanclass="code-comment"!!BUG!!=CEmptyDialogImpl<T,t_uIDD,CControlDlgTraits>//defaultforTDlgImpl/span/pre/code应该是OK的。欢呼声中,AR当聪明的(人)指出,在月球的傻瓜手指看起来(中国谚语)
菲利普Kursawe
评论会员:游客 时间:2011/12/15
哇!谢谢您的快速反应!这是确实的错误,和我现在的工作所有者绘制ListBox控件"对话框。快乐编码,菲利普Kursawe
rajas
评论会员:游客 时间:2011/12/15
您好,我想你有趣的对话框。当我使用的单元格"菜单,从我调用对话框的窗口变成非活动状态-非客户区得到重绘显示无效状态。当细胞菜单关闭,它显示再次活跃起来-这是分心,有点混乱。欢呼声中,曼格拉的Sudhirhttp://DevelopersVoice.com(VC常见问题,MFC常见问题,C常见问题)http://Programmerworld.net(免费书籍和源代码)http://Faq.Programmerworld.net欢呼声中,AR