让VC中的非模式属性表PropertySheet出现OK按钮 - 技术文章 - 张宏

(这条文章已经被阅读了 33 次) 时间:2001-06-03 22:57:22 来源:张宏 (茶馆主人) 原创-IT

让VC中的非模式属性表PropertySheet出现OK/Cancel/Apply按钮

北京商即通数码科技有限公司 张宏

很多VC程序员都遇到过这个问题,当建立一个非模式的属性表(不是向导模式)时,此时正常用DoModal()调用时可以出现的OK/Cancel/Apply等按钮全都不见了,真让人郁闷!笔者查找了很多资料,均没有正确的答案,最后,笔者自己分析,在CPropertySheet调用初始化对话框CPropertySheet::OnInitDialog()时由于m_psh中自动设置了PSH_MODELESS属性,导致自动调整对话框大小,隐藏了对话框中的OK按钮部分,因此,笔者考虑以下解决办法:
1.从CPropertySheet派生一个自己的属性表类,将要加入的页面作为其成员变量:
class CMySheet : public CPropertySheet
{
DECLARE_DYNAMIC(CMySheet)

// Construction
public:
CMySheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
CMySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMySheet)
public:
virtual BOOL OnInitDialog();
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CMySheet();

// Generated message map functions
protected:
//{{AFX_MSG(CMySheet)
// NOTE – the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
void AddPages(); //添加属性页
CPage2 page2; //定义属性页变量
CPage1 page1;
};

2.添加属性页:
void CMySheet::AddPages()
{
AddPage(&page1);
AddPage(&page2);
}
CMySheet::CMySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
AddPages();
}

CMySheet::CMySheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
AddPages();
}

3.在属性页的初始化对话框中拉大对话框高度,并且将OK/Cancel/Apply按钮显示、激活。
BOOL CMySheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();

RECT rc;

// 调整属性页对话框的大小
GetWindowRect (&rc);
rc.bottom += 30; //窗口向下拉30点,让OK按扭可以显示出来
MoveWindow (&rc); //调整窗口
GetDlgItem(IDOK)->ShowWindow(SW_SHOW); //显示隐藏的OK按钮
GetDlgItem(IDOK)->EnableWindow(); //激活OK按钮
GetDlgItem(IDCANCEL)->ShowWindow(SW_SHOW); //显示隐藏的Cancel按钮
GetDlgItem(IDCANCEL)->EnableWindow(); //激活Cancel按钮
GetDlgItem(ID_APPLY_NOW)->ShowWindow(SW_SHOW); //显示Apply按钮
GetDlgItem(ID_APPLY_NOW)->EnableWindow(); //激活Apply按钮

return bResult;
}
好了,在主对话框中加入一个测试按钮,加入一个CmySheet *sh指针成员变量,并且加入以下代码:
CTestPropertySheetDlg::CTestPropertySheetDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTestPropertySheetDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
sh=NULL;
}
void CTestPropertySheetDlg::OnButton1()
{
sh=new CMySheet(“测试对话框”);
sh->Create(this);
}

void CTestPropertySheetDlg::OnDestroy()
{
CDialog::OnDestroy();

if (sh) delete sh;
}

编译工程并运行,你看到了什么?OK/Cancel/Apply全都出来了!
可是,点击OK按钮看看?怎么?不会关闭对话框!!! >:-(((
怎么办?是非模式对话框没有响应OK按钮吗?不是,当前的各属性页已经得到了OK按钮事件,但是属性表没有对OK按钮响应,加上对事件的处理以后就可以了:
BOOL CMySheet::OnCommand(WPARAM wParam, LPARAM lParam)
{
if (HIWORD (wParam) == BN_CLICKED)
{
switch (LOWORD (wParam))
{
case IDOK:
PressButton (PSBTN_OK);
DestroyWindow ();
return (TRUE);
case ID_APPLY_NOW: // Apply
PressButton (PSBTN_APPLYNOW);
return (TRUE);
case IDCANCEL:
PressButton (PSBTN_CANCEL);
DestroyWindow ();
return (TRUE);
case IDHELP:
PressButton (PSBTN_HELP);
return (TRUE);
}
}
return CPropertySheet::OnCommand(wParam, lParam);
}

现在再编译试试看,一切OK了。