我首先用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,谁能提供一些相关联接或例子啊。谢谢。

解决方案 »

  1.   

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/propsheet/functions/propertysheet.asp
      

  2.   


      属性页最重要的是Apply的实现.
      你可以参看MSDN ATL教程的示例
                     那很详细的..
      

  3.   

    arxing(阿行),在MSDN上,我也看到了你给的联接。但是不怎么懂Win SDK。
    我想问问,有没有像MFC那样,封装的比较好,能直接用的东东。
      

  4.   

    RedStar81(流刀T'ang),我要做的不是控件的Property sheet
    而是,在控件运行时,右键点击控件弹出一个Property Sheet来
    即在运行时,能与控件交互。
      

  5.   


      这个没做过,不过记得
      VSdotNET的MSDN中,有一个GL控件,实现了这个功能~~
      你自己找找吧~~
      那个控件是仿真火焰的~~
      

  6.   

    那个例子是AtlFire,但是只能对付一般的对话框,如果需要支持ActiveX控件,可以如下做:
    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;
    }
      

  7.   

    int WINAPI WinMain(...)
    {
    ...
      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);
    ...
    }
      

  8.   

    谢谢arxing(阿行)我会好好研究一下你给的代码的
      

  9.   

    arxing(阿行)
    你的代码里的AtlFindResource()是自己写的吗?
    编译时说'AtlFindResource' : undeclared identifier
    另外,我觉得我要实现的property sheet和AtlFire这个例子的很像
    但是它的property sheet只有一个page
    如果我要有好几个page应该怎么写呢?
      

  10.   

    AtlFindResource 可能是ATL7.0扩展的,你可以用::FindResource代替。
    属性页也是个数组,你可以照这样扩展的。
    因为AxtiveX资源不为一般对话框函数识别,所以当要创建支持ActiveX对话框的时候,必须把ActiveX的资源去掉,然后通过代码加上去,这你可以参考CAxDialog的实现。