SHDOCVW.DLL goodies with MSIE4

If you are someone who likes surprises, I am your friend. I got a pleasent surprise when I was looking thru the Microsoft Internet control (WebBrowser) as most people know it.. I opened the shdocvw.dll which comes along with the Internet explorer 4.0 and surprise, surprise, I found that It contains  Interfaces for the Shell, Shell Link and other stuff which the shell normally handles and which are painful to implement in C or C++.. See the implementation for the CDirDialog for a sample. This is not present in IE 3.x ..

Now, In order to use these Interfaces, You need to some work.:-( well, But this is mucho simpler than the ones we have seen till now.

What I am showing below is just a tip of an Iceberg, You have got a lot of stuff there. Check out the .H and .CPP files generated and the .ODL file which I am pasting here. You can do a lot of stuff with this..

Pay close attention to the description strings along with the funtions . They usually provide a neat pointer as to what the function is supposed to do..

You can generate the .ODL  file by Opening the shdocvw.dll (you can find it in windows\system directory) in the OLEVIEW.EXE which comes along with VC++ 5.0. I think its also downloadable from Microsoft site.

After generating the .ODL file, Create a new MFC  project in VC++ to your taste. .. Then, Add class from .tlb and select shdocvw.dll.. Select all the interfaces listed in the list box shown and ask it to create the wrapper class.

It will be created as shdocvw.h and shdocvw.cpp. These are also there in the ZIP file attached..

Since, these interfaces are undocumented, I must caution you about the fact that this might change.. But, then It might not..

Anyway, Add the following lines to your .CPP file where you want to call the interface functions..

#include "initguid.h"
//13709620-C279-11CE-A49E-444553540000
DEFINE_GUID(CLSID_Shell,0x13709620,0xc279,0x11ce,0xa4,0x9e,0x44,0x45,0x53,0x54,0x00,0x00);
//9BA05971-F6A8-11CF-A442-00A0C90A8F39
DEFINE_GUID(CLSID_ShellFolderViewOC ,0x9BA05971,0xF6A8,0x11CF,0xa4,0x43,0x00,0xa0,0xc9,0x0a,0x8f,0x39);
//9BA05972-F6A8-11CF-A442-00A0C90A8F39
DEFINE_GUID(CLSID_ShellWindows,0x9BA05972,0xF6A8,0x11CF,0xa4,0x43,0x00,0xa0,0xc9,0x0a,0x8f,0x39);
//11219420-1768-11D1-95BE-00609797EA4F
DEFINE_GUID(CLSID_ShellLinkObject,0x11219420,0x1768,0x11D1,0x95,0xbe,0x00,0x60,0x97,0x97,0xea,0x4f);
//62112AA1-EBE4-11CF-A5FB-0020AFE7292D
DEFINE_GUID(CLSID_ShellFolderView,0x62112AA1,0xEBE4,0x11CF,0xA5,0xfb,0x00,0x20,0xaf,0xe7,0x29,0x2d);
//64AB4BB7-111E-11D1-8F79-00C04FC2FBE1
DEFINE_GUID(CLSID_ShellUIHelper,0x64AB4BB7,0x111E,0x11D1,0x8f,0x79,0x00,0xc0,0x4f,0xc2,0xfb,0xe1);

Of course, before calling any functions, Make sure that the SHDOCVW.DLL is of the correct version..4.71.1712.5.

You can use the technique Eran Yariv has pointed out. You might want to do that in the beginning of your program so that you dont have to do that again until the execution is over.

Now, after this,, Its left to you to do what you want to do..

Following is a trivial example of invoking "Start-Run" dialog from your program.
 

{

    IShellDispatch disp; //Create a IShellDispatch variable

     WCHAR szValue[80] ;
     CLSID clsid;
     HRESULT sc;
        sc = ::CoCreateInstance( CLSID_Shell, NULL, CLSCTX_SERVER, IID_IDispatch, (void**)&disp ) ; //<== Create an instance of the shell
     if (FAILED (sc))
     {
            CString str;
      str.Format(_T("Failed to create Instance :-( "));
            TRACE( str) ;
      return;
     }

     disp.FileRun(); //<== Call FileRun

}
 

Another example for IShellDispatch ,,

The following example is to BrowseForFolder and get the Folder interface pointer.

{

    IShellDispatch disp;
     IDispatch * iDisp;

     WCHAR szValue[80] ;
     CLSID clsid;
     HRESULT sc;
        sc = ::CoCreateInstance( CLSID_Shell, NULL, CLSCTX_SERVER, IID_IDispatch, (void**)&disp ) ;
     if (FAILED (sc))
     {
            CString str;
      str.Format(_T("Failed to create Instance :-( "));
            TRACE( str) ;
      return;
     }
     VARIANT var;
     ZeroMemory (&var, sizeof (VARIANT));

      iDisp = disp.BrowseForFolder(NULL,"Whatever",BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS,var); 
     Folder ifolder(iDisp);
     CString str = ifolder.GetTitle ();

}

Of course, There is lot to be researched .. I will be doing it and put up an update as I get time.. Hope this will be good for the times to come..

Download File (31KB)