使用非模態對話框的小技巧
作者:劉胤
工作上有用到非模態對話框,但是使用上有如下麻煩,
所有者擁有一個非模態對話框指針,非模態對話框在關閉的時候要設置這個指針為空,這樣一來,非模態對話框就必須"知道"所有者並且實現
了這樣的非模態對話框,就不能讓它在棧上創建(因為是 delete this),也不能一次創建多個非模態對話框(當然,這種情況很少)。如果把非
模態對話框聲明為 CNonModalDialg m_dlg;,那用戶點擊 OK 的時候,你就得 ShowWindow(SW_HIDE),這和對話框的本意還是有點不一致。
class CNonModalDialg;
class COwner
{
private:
CNonModalDialg *m_pDlg;
};
class CNonModalDialg
{
...
void OnOK()
{
...
delete this;
}
void OnCancel()
{
...
delete this;
}
void OnDestory()
{
m_pOwner->m_pDlg = NULL;
}
private:
COwner *m_pOwner;
};
通過 C++ 的模板,實現了一個 NonModal 類可以解決以上問題。代碼如下。
#ifndef NonModal_H
#define NonModal_H
template <typename DialogImpl, typename OwnerType>
class NonModal : public DialogImpl
{
public:
NonModal(OwnerType *pOwner)
: m_pOwner(pOwner)
{
}
void SetOwner(OwnerType *pOwner) { m_pOwner = pOwner; }
virtual BOOL DestroyWindow()
{
DialogImpl::DestroyWindow();
return DestroySelf();
}
protected:
virtual void OnOK()
{
DialogImpl::OnOK();
DestroySelf();
}
virtual void OnCancel()
{
DialogImpl::OnCancel();
DestroySelf();
}
private:
virtual ~NonModal() {}
BOOL DestroySelf()
{
BOOL bRet = FALSE;
if (m_pOwner) {
m_pOwner->OnDestroyNonModal(this);
}
bRet = DialogImpl::DestroyWindow();
delete this;
return bRet;
}
OwnerType *m_pOwner;
};
#define DECLARE_NonModalDialog(DialogImpl, OwnerImpl, VariableName) \
private:\
typedef NonModal<DialogImpl, OwnerImpl> DialogImpl##NonModal; \
frIEnd DialogImpl##NonModal; \