我首先用Class Wizard生成两个Property Page: COption1, COption2
然后向工程加入一个新类CSheet : public CPropertySheet,并在CSheet的构造函数里用AddPage()添加了上述的Property Page
最后我这样调用:
CSheet* MySheet = new CSheet("MySheet", NULL, 0);
CSheet->DoModal();这些代码在MFC ActiveX中能正常运行
但是,换到ATL ActiveX中就会出错。请大家告诉我这是怎么回事?是不是必须用Win SDK来写才行啊。
可是我不怎么会Win SDK,谁能提供一些相关联接或例子啊。谢谢。
然后向工程加入一个新类CSheet : public CPropertySheet,并在CSheet的构造函数里用AddPage()添加了上述的Property Page
最后我这样调用:
CSheet* MySheet = new CSheet("MySheet", NULL, 0);
CSheet->DoModal();这些代码在MFC ActiveX中能正常运行
但是,换到ATL ActiveX中就会出错。请大家告诉我这是怎么回事?是不是必须用Win SDK来写才行啊。
可是我不怎么会Win SDK,谁能提供一些相关联接或例子啊。谢谢。
属性页最重要的是Apply的实现.
你可以参看MSDN ATL教程的示例
那很详细的..
我想问问,有没有像MFC那样,封装的比较好,能直接用的东东。
而是,在控件运行时,右键点击控件弹出一个Property Sheet来
即在运行时,能与控件交互。
这个没做过,不过记得
VSdotNET的MSDN中,有一个GL控件,实现了这个功能~~
你自己找找吧~~
那个控件是仿真火焰的~~
class CPage1 :
public CAxDialogImpl<CPage1>
{
public:
enum { IDD = IDD_PAGE1 };
BEGIN_MSG_MAP(CPage1)
CHAIN_MSG_MAP(CAxDialogImpl<CPage1>)
END_MSG_MAP()
}template<class _T, class _Base = CWindow >
class CPropertyPageT
{
public:
static INT_PTR CALLBACK Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg != WM_INITDIALOG)
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
} PROPSHEETPAGE * pStruct = (PROPSHEETPAGE*)lParam; _T* pThis = (_T*)pStruct->lParam; ATLASSERT(pThis != NULL);
pThis->m_hWnd = hWnd;
pThis->m_thunk.Init((WNDPROC)pThis->GetDialogProc(), (CDialogImplBaseT<_Base>*)pThis);
DLGPROC pProc = (DLGPROC)pThis->m_thunk.GetWNDPROC();
DLGPROC pOldProc = (DLGPROC)::SetWindowLongPtr(hWnd, DWLP_DLGPROC, (LONG_PTR)pProc);
#ifdef _DEBUG
// check if somebody has subclassed us already since we discard it
if(pOldProc != Proc)
ATLTRACE(atlTraceWindowing, 0, _T("Subclassing through a hook discarded.\n"));
#else
pOldProc; // avoid unused warning
#endif
return pProc(hWnd, uMsg, wParam, lParam); }
};DLGTEMPLATE* GetDlgTemplate(HINSTANCE hInstance, LPCTSTR lpTemplateName)
{
AtlAxWinInit(); HRSRC hDlg = AtlFindResource(hInstance, lpTemplateName, (LPCTSTR)RT_DIALOG);
if (hDlg != NULL)
{
DWORD dwLastError = 0;
HGLOBAL hResource = LoadResource(hInstance, hDlg);
if (hResource != NULL)
{
DLGTEMPLATE* pDlg = (DLGTEMPLATE*) LockResource(hResource);
if (pDlg != NULL)
{
return _DialogSplitHelper::SplitDialogTemplate(pDlg, NULL);
}
}
} return NULL;
}
{
...
CPage1 page1; PROPSHEETPAGE psp[1];
PROPSHEETHEADER psh; LPCTSTR lpszTemplateName = MAKEINTRESOURCE(CPage1::IDD); psp[0].dwSize = sizeof(PROPSHEETPAGE);
psp[0].dwFlags = PSP_USETITLE | PSP_DLGINDIRECT ;
psp[0].hInstance = _AtlBaseModule.GetResourceInstance();
psp[0].pResource = GetDlgTemplate(psp[0].hInstance, lpszTemplateName);
//psp[0].pszTemplate = lpszTemplateName;
psp[0].pszIcon = NULL;
psp[0].pfnDlgProc = CPropertyPageT<CPage1>::Proc;
psp[0].lParam = (LPARAM)(&page1);
psp[0].pszTitle = _T("No.1");
psp[0].pfnCallback = NULL; psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE;
psh.hwndParent = NULL;
psh.hInstance = _AtlBaseModule.GetResourceInstance();
psh.pszIcon = NULL;
psh.pszCaption = (LPSTR) "Cell Properties";
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
psh.pfnCallback = NULL; PropertySheet(&psh);
...
}
你的代码里的AtlFindResource()是自己写的吗?
编译时说'AtlFindResource' : undeclared identifier
另外,我觉得我要实现的property sheet和AtlFire这个例子的很像
但是它的property sheet只有一个page
如果我要有好几个page应该怎么写呢?
属性页也是个数组,你可以照这样扩展的。
因为AxtiveX资源不为一般对话框函数识别,所以当要创建支持ActiveX对话框的时候,必须把ActiveX的资源去掉,然后通过代码加上去,这你可以参考CAxDialog的实现。