How To Implementing a Custom Property Showing a FileOpen Dialog (166768)



The information in this article applies to:

  • Microsoft Visual C++, 32-bit Editions 4.2, when used with:
    • the hardware: Intel x86
  • Microsoft Visual C++, 32-bit Editions 4.2b, when used with:
    • the hardware: Intel x86
  • Microsoft Visual C++, 32-bit Editions 5.0, when used with:
    • the hardware: Intel x86

This article was previously published under Q166768

SUMMARY

This article demonstrates a way to show the FileOpen dialog box for a custom property in an ActiveX control. The custom property is implemented by using per-property browsing in an ActiveX control. For information on implementing such a custom property, please see the following article in the Microsoft Knowledge Base:

140592 How To Implementing Per-Property Browsing for a Custom Property

When the custom property is selected for editing in a design environment such as Microsoft Visual Basic, an ellipsis button (or three-dots button) will be shown on the Properties window for the property. Clicking the ellipsis button in the Properties window displays a FileOpen dialog box associated with the property.

MORE INFORMATION

Because the Windows FileOpen common dialog box is not a COM object, it doesn't have a CLSID associated with it. However, if you follow the instructions in Knowledge Base article Q140592 to add a custom property to an ActiveX control, the MFC framework calls OnMapPropertyToPage() to obtain the CLSID of a property page that implements editing of the specified property. To achieve the goal of showing the FileOpen dialog box, create a "dummy" property page and return its CLSID in the OnMapPropertyToPage() function. Then, using ClassWizard, add an OnInitDialog() function to the "dummy" property page class and add the following code:
   // CTestPropPage is the classname for the "dummy" property page.
   BOOL CTestPropPage::OnInitDialog()
   {
     COlePropertyPage::OnInitDialog();

     // Display the FileOpen dialog box because the property page is not
     // visible yet.
     CFileDialog dlg(TRUE);
     int nRet = dlg.DoModal();

     if(nRet == IDOK)
     {
       // Do something with the selected filename. For illustration
       // purposes assume that the control associated with this property
       // page has a property named FileName which is of type BSTR. The
       // following code will set the FileName property in the associated
       // control(s) to the filename selected by the user via the FileOpen
       // dialog box.

       DISPID dwFileNameDispID;
       COleDispatchDriver PropDispDriver;
       ULONG nObjects;

       // Get the array of control IDispatch's stored in the property page.
       LPDISPATCH FAR * lpObjectArray = GetObjectArray(&nObjects);

       // Get the name of the selected file.
       CString strFileName = dlg.GetFileName();

       // Set the filename property for all the control objects currently
       // associated with this property page.
       for (ULONG i = 0; i < nObjects; i++)
       {
         // Get the Dispatch ID for the property and if successful set the
         // value of the property.
         LPCOLESTR lpOleStr = L"FileName";

         if (SUCCEEDED(lpObjectArray[i]->GetIDsOfNames(IID_NULL,
           (LPOLESTR*)&lpOleStr, 1, 0, &dwFileNameDispID)))
         {
           // Set the property.
           PropDispDriver.AttachDispatch(lpObjectArray[i], FALSE);
           PropDispDriver.SetProperty(dwFileNameDispID, VT_BSTR,
             (LPCTSTR)strFileName);
           PropDispDriver.DetachDispatch();
         }
       }
     }

     // We are done with the FileOpen dialog box. Now you need to kill
     // the property page so the user won't see it.
     EndDialog(-1);

     return TRUE;  // return TRUE unless you set the focus to a control
                   // EXCEPTION: OCX Property Pages should return FALSE}
   }
				
The following steps summarize how to show a custom dialog for a custom property:

  1. Insert a new dialog into the control project. Use ClassWizard to generate a new class for this dialog and specify COlePropertyPage as the base class to be used. This new class will be the "dummy" property page referenced above (CTestPropPage as shown in article 140592).
  2. Follow the steps in Knowledge Base article 140592 to implement per-property browsing for a custom property and specify the CLSID of the "dummy" property page created above (i.e. CTestPropPage::guid) in the OnMapPropertyToPage() method in the control.
  3. Use ClassWizard to add an OnInitDialog() method to the "dummy" property page class and add the appropriate dialog creation and handling code as shown above.
NOTE: The technique presented in this article can be used to display any dialog box.

Modification Type:MinorLast Reviewed:7/1/2004
Keywords:kbCmnDlgFileO kbCtrl kbhowto kbInprocSvr KbUIDesign KB166768