WEB开发网
开发学院软件开发VC MFC程序员WTL指南(9)属性页与向导 阅读

MFC程序员WTL指南(9)属性页与向导

 2008-01-19 20:26:45 来源:WEB开发网   
核心提示:正如你看到的,我们遇到了棘手的问题,MFC程序员WTL指南(9)属性页与向导(8),PropSheetCallback()是一个静态方法,不能使用this指针访问属性表窗口,就需要添加一个标志并设置属性页的PROPSHEETPAGE结构中的几个成员:CBackgroundOptsPage::CBackgroundOpt

正如你看到的,我们遇到了棘手的问题。PropSheetCallback()是一个静态方法,不能使用this指针访问属性表窗口。那将这些代码从CPropertySheetImpl::PropSheetCallback()中拷贝出来,然后添加我们自己的方法行不行呢?撇开刚才将代码和特定版本的WTL联系在一起的方法(这已经被证明不是各好方法),现在代码应该是这样的:

class CAppPropertySheet : public CPropertySheetImpl<CAppPropertySheet>
{
//...
   static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM)
   {
     if(uMsg == PSCB_INITIALIZED)
     {
       // Code copied from WTL and tweaked to use CAppPropertySheet
       // instead of T:
       ATLASSERT(hWnd != NULL);
       CAppPropertySheet* pT = (CAppPropertySheet*)
                     _Module.ExtractCreateWndData();
       // subclass the sheet window
       pT->SubclassWindow(hWnd);
       // remove page handles array
       pT->_CleanUpPages();
       // Our own code follows:
       pT->CenterWindow ( pT->m_psh.hwndParent );
     }
     return 0;
   }
};

这从理论上讲很完美,但是我试过,属性表的位置并未改变。显然,通用控件的代码在我们调用CenterWindow()之后又改变了属性表窗口的位置。

必须放弃这个将代码封装到属性表类的方法,尽管它是个好的解决方案。我又回到原来的方案,即使用属性页窗口和属性表窗口相互协作是属性表窗口置中。我添加了一个用户定义消息UWM_CENTER_SHEET:

#define UWM_CENTER_SHEET WM_APP

CAppPropertySheet 在它的消息映射链中处理这个消息:

class CAppPropertySheet : public CPropertySheetImpl<CAppPropertySheet>
{
//...
   BEGIN_MSG_MAP(CAppPropertySheet)
     MESSAGE_HANDLER_EX(UWM_CENTER_SHEET, OnPageInit)
     CHAIN_MSG_MAP(CPropertySheetImpl<CAppPropertySheet>)
   END_MSG_MAP()
   // Message handlers
   LRESULT OnPageInit ( UINT, WPARAM, LPARAM );
protected:
   bool m_bCentered; // set to false in the ctor
};
LRESULT CAppPropertySheet::OnPageInit ( UINT, WPARAM, LPARAM )
{
   if ( !m_bCentered )
     {
     m_bCentered = true;
     CenterWindow ( m_psh.hwndParent );
     }
   return 0;
}

然后,每个属性页的OnInitDialog() 方法发送这个消息到属性表窗口:

BOOL CBackgroundOptsPage::OnInitDialog ( HWND hwndFocus, LPARAM lParam )
{
   GetPropertySheet().SendMessage ( UWM_CENTER_SHEET );
   DoDataExchange(false);
   return TRUE;
}

添加m_bCentered标志确保属性表窗口只响应收到的第一个UWM_CENTER_SHEET消息。

在属性页中添加图标

如果要使用属性表和属性页的未被成员函数封装的特性,就需要直接访问相关的数据结构:CPropertySheetImpl类中的PROPSHEETHEADER类型(结构)成员m_psh和CPropertyPageImpl类中的PROPSHEETPAGE类型(结构)成员m_psp。

例如:为例子中Option属性表中的Background页面添加一个图标,就需要添加一个标志并设置属性页的PROPSHEETPAGE结构中的几个成员:

CBackgroundOptsPage::CBackgroundOptsPage()
{
   m_psp.dwFlags |= PSP_USEICONID;
   m_psp.pszIcon = MAKEINTRESOURCE(IDI_TABICON);
   m_psp.hInstance = _Module.GetResourceInstance();
}

下面是这些代码的效果:

继续

我将在第九章介绍WTL的一些工具类,还有GDI对象和通用对话框的包装类。

修改记录

September 13, 2003: 文章第一次发布。

上一页  3 4 5 6 7 8 

Tags:MFC 程序员 WTL

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