我想调用函数弹出一个ACTIVEX控件的对话框
Active X Test Container可以,不知它是如何做的?

解决方案 »

  1.   

    http://www.codeguru.com/Cpp/COM-Tech/activex/controls/article.php/c2649/Case 1: Your container wants to display property sheet of your control in runtime mode.Actually, as I said before, this is documented in "Inside OLE" of Brockschmidt (pp795+.) Unfortunately, Brockschmidt assumes that you create your OLE control from scratch without COleControl class. If you have already derived your control from COleControl class (as you normally do), you already have a train of interfaces which you can see in OLE Object Viewer. In this case the following steps demonstrate how to display the property pages in runtime mode in your container.Add GetPages() method to the implementation file of your control this way:
    // This method returns array of property pages used then by
    // OLE container to bring property pages to the user
    STDMETHODIMP CDoSomethingCtrl::"#630000">XSpecifyPropertyPages::GetPages(CAUUID *pPages)
    {
        GUID *pGUID;
        const unsigned CPROPPAGES = 4;
            
        pPages->cElems = 0;
        pPages->pElems = NULL;
     
        pGUID = (GUID*) CoTaskMemAlloc( CPROPPAGES * sizeof(GUID) );    if( NULL == pGUID )
        {
            return ResultFromScode(E_OUTOFMEMORY);
        }    // Fill the array of property pages now
        pGUID[0] = COptionsPropPage::guid;
        pGUID[2] = CLSID_CFontPropPage;
        pGUID[3] = CLSID_CColorPropPage;
        pGUID[4] = CLSID_CPicturePropPage;    //Fill the structure and return
        pPages->cElems = CPROPPAGES;
        pPages->pElems = pGUID;
        return NOERROR;
    }
    Pay attention to this strange class XSpecifyPropertyPages: there is no place to declare this. Where does it come from? From COleControl, of course. Declaration of COleControl class includes the following lines:// ISpecifyPropertyPages
    BEGIN_INTERFACE_PART(SpecifyPropertyPages, ISpecifyPropertyPages)
        INIT_INTERFACE_PART(COleControl, SpecifyPropertyPages)
        STDMETHOD(GetPages)(CAUUID*);
    END_INTERFACE_PART(SpecifyPropertyPages)
            where BEGIN_INTERFACE_PART is further decoded to
            #define BEGIN_INTERFACE_PART(localClass, baseClass) \
        class X##localClass : public baseClass \
        { \
        public: \
            STDMETHOD_(ULONG, AddRef)(); \ and so on
    This is where XSpecifyPropertyPages comes from.Add OnShowProperties method to the implementation file of your container (this is taken as is from the Inside OLE of BrockSchmidt with a note below):
    void CApp::OnShowProperties(void)
    {
        ISpecifyPropertyPages  *pISPP;
        CAUUID                  caGUID;
        HRESULT                 hr;
        LCID lcid = AmbientLocaleID();    if (FAILED(m_pIDispatch->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pISPP)))
        {
            AfxMessageBox("Object has no property pages.");
            return;
        }    hr=pISPP->GetPages(&caGUID);
        pISPP->Release();    if (FAILED(hr))
        {
            AfxMessageBox("Failed to retrieve property page GUIDs.");
            return;
        }    hr=OleCreatePropertyFrame(m_hWnd, 10, 10, OLETEXT("Beeper")
            , 1, (IUnknown **)&m_pIDispatch, caGUID.cElems
            , caGUID.pElems, lcid, 0L, NULL);    if (FAILED(hr))
            AfxMessageBox("OleCreatePropertyFrame failed.");    //Free GUIDs.
        CoTaskMemFree((void *)caGUID.pElems);
        return;
    }
    Notes: I changed a few minor things to get this code compiled imeediately without any further changes. I changed Message method of BrockSchmidt to the standard AfxMessageBox(). Then, I replaced the 9th parameter from m_lcid to 0L because I am not interested in locale information (of course you have to take care of it if you support multiple languages!!!)The theory of property pages, property pages browsing and notifications is slightly more difficult than that. I sincerely encourage you to read the sixteenth chapter of "Inside OLE" of BrockSchmidt to get the full picture of OLE property pages.