Making a program using COM in windows

Pages: 123
You are doing really well FireCannon. This is particularly hard stuff. In fact, in my opinion, this is about as hard as it gets.

Before I read your post above, and realizing you were having linking difficulties related to IDEs, I compiled the IDispatch code from the command line. Believe it or not, that isn't hard to do at all, and a lot of us old timers are of the opinion that younger coders just starting out would benifit from this, as it shows how IDEs work more or less. Here is what the command line at the console looks like...

 
g++ Main.cpp -lKernel32 -lole32 -loleaut32 -luuid -oFireCannon01.exe -mconsole -m64 -s -Os


g++ is the mingw C++ compiler. I named my source code file Main.cpp, so that comes right after the g++. Then I listed the four Windows libraries which contain the binary code that the compiler and linker will need to create the executable. Then this line simply lists the name of the output file or executable I want created after a successful compile/link...

-oFireCannon01.exe

And...

-mconsole just states I want a console created. The -m64 says create a 64 bit binary. Finally, the last two are optional, but tell the compiler and linker to optimize for small code instead of speed.

But to get the above to work, when you type 'g++' in a console window the operating system needs to know where g++.exe is located, and it needs to have Main.cpp in the same directory which the command prompt console window is opened. In terms of g++, I believe the installation of mingw puts suitable entries in the Windows Environment Table to find g++. In terms of doing command line compiling work, whenever I intend to do that, here is what I do...

...I make myself a little batch file and put a shortcut to it on my Windows Desktop. Here is the one I made for this program...

1
2
3
CD\
cd C:\Code\CodeBlks\FireCannon\FC01
C:\Windows\system32\cmd.exe


The 1st line changes the directory back to C: root. The 2nd line changes the directory again to the project folder where I have the source code files for the project I'm working on. For this work for you I made a C:\Code\CodeBlks\FireCannon\FC01 directory. Finally, the last line opens a command prompt window to that directory, and we're ready for the compilation string posted above. Here is the program above where I've added a call to the Quit() method of the IWebBrowser Interface. Note you need to hit the [ENTER] key once for the Quit() to execute. After the Main.cpp source I have the contents of the command prompt window listed in #if 0 --- #endif conditional compilation statements. Check that particular usage of them out. You might like it...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// g++ Main.cpp -lKernel32 -lole32 -loleaut32 -luuid -oFireCannon01.exe -mconsole -m64 -s -Os
#include <windows.h>
#include <cstdio>

int main()
{
 const CLSID      CLSID_IE_Application = {0x0002DF01,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
 const IID        IID_IEApplication    = {0x0002DF05,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
 DISPPARAMS       NoArgs               = {NULL, NULL, 0, 0};
 IDispatch*       pApp                 = NULL;
 VARIANT          vArgArray[1];
 DISPPARAMS       DispParams;
 DISPID           dispidNamed;
 VARIANT          vResult;
 LCID             lcid;
 HRESULT          hr;

 hr=CoInitialize(NULL);
 if(SUCCEEDED(hr))
 {
    printf("CoInitialize() Succeeded!\n");
    hr = CoCreateInstance(CLSID_IE_Application, NULL, CLSCTX_LOCAL_SERVER, IID_IEApplication, (void **) &pApp);
    if(SUCCEEDED(hr))
    {
       printf("pApp = 0x%p\n",pApp);
       VariantInit(&vArgArray[0]);
       lcid                            = GetUserDefaultLCID();
       vArgArray[0].vt                 = VT_BOOL;
       vArgArray[0].boolVal            = TRUE;
       dispidNamed                     = DISPID_PROPERTYPUT;
       DispParams.rgvarg               = vArgArray;
       DispParams.rgdispidNamedArgs    = &dispidNamed;
       DispParams.cArgs                = 1;
       DispParams.cNamedArgs           = 1;
       VariantInit(&vResult);
       pApp->Invoke(0x00000192,IID_NULL,lcid,DISPATCH_PROPERTYPUT,&DispParams,&vResult,NULL,NULL);
       getchar();   // pApp->Quit() 0x12C
       pApp->Invoke(0x0000012c,IID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD,&NoArgs,NULL,NULL,NULL);
       pApp->Release();
    }
    else
       printf("CoCreateInstance() Failed!\n");
    CoUninitialize();
 }
 else
    printf("CoInitialize() Failed!\n");
 getchar();

 return 0;
}

#if 0
C:\Code\CodeBlks\FireCannon\FC01>g++ Main.cpp -lKernel32 -lole32 -loleaut32 -luu
id -oFireCannon01.exe -mconsole -m64 -s -Os

C:\Code\CodeBlks\FireCannon\FC01>dir
 Volume in drive C is OSDisk
 Volume Serial Number is 3E79-B713

 Directory of C:\Code\CodeBlks\FireCannon\FC01

08/08/2015  06:41 AM    <DIR>          .
08/08/2015  06:41 AM    <DIR>          ..
08/08/2015  06:33 AM                69 FC01.bat
08/08/2015  06:41 AM            39,424 FireCannon01.exe
08/08/2015  06:40 AM             1,866 Main.cpp
               3 File(s)         41,359 bytes
               2 Dir(s)  104,428,724,224 bytes free

C:\Code\CodeBlks\FireCannon\FC01>FireCannon01.exe
CoInitialize() Succeeded!
pApp = 0x0000000000327f50
#endif 

And the beauty of that is that to get a 32 bit executable all you need to change in the command line compilation string is the '-m64' where you substitute -m32. How's that for easy???

Note in my call to pApp->Invoke(...) above where I'm calling the Quit() method through IDispatch, the call is really easy because there aren't any parameters. With IDispatch work in C++ its the parameters that kill you. They all have to be passed into IDispatch::Invoke() through an array of VARIANTs.

I intend to post further about my Shell.Explorer example because, if I must say so myself, that is really cool. My intentions are to attempt a conversion to 64 bit. So don't attempt yet to use that compiled as a 64 bit executable because even if you somehow get it to compile, it'll instantly crash when it runs. I need to change all the pointer arithmetic and sizes of things to 64 bit. However, it will work fine compiled as x86 code. I worked on that code many years ago long before I was messing with 64 bit.

For anyone else who may be following this thread, that ActiveX Example is particularly complicated because of all the function pointer calls I'm making into Atl.dll. The reason I had to do that was because I wanted the example to work with mingw, and that was the only way I could manage it. I'll provide a bit easier code for anyone using Visual Studio. But later.

Not sure I'll have time for it this weekend though. I really need to get myself ready for a month long cross country expedition I'm making here shortly up to grizzly bear country.
Last edited on

I tried to reproduce the error by adding the invalid path to the library directory list, but it still compiled.


Not puzzling. Dlls loaded explicitely like that aren't loaded until the program actually runs. That's where the 'Dynamic' in Dynamic Link Libraries comes from.
freddie1 wrote:
Not puzzling. Dlls loaded explicitely like that aren't loaded until the program actually runs. That's where the 'Dynamic' in Dynamic Link Libraries comes from.
Sorry, I wasn't very clear. I was trying to see if I could get the compilation errors again by adding the fake folder path to the lib directory list in Dev-C++, not to make the program work at runtime by adding alt71.dll. I somehow wasn't able to reproduce compilation errors though.

freddie1 wrote:
Check that particular usage of them out. You might like it...
That is cool usage of them. Its looks like a good way to tag on extra non-code information.

thanks and have good weekend
Geez, I just sat down for a few minutes to see if I could get "Shell.Explorer" ActiveX Control (Internet Explorer) working with mingw in 64 bit and got it in about 10 minutes. That went too well! I'm posting this from that app. I want to test with VC++ yet, then I'll post it. Likely not till Sunday or Monday though.
I'm posting this code from a run of the code posted below. The command line compilation strings for 64 bit VC++ and 64 bit mingw are at top. Tomorrow I'll see if I can simplify the code somewhat by removing all the function pointer calls.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// MS VC++ -- cl Main.cpp /FeWebBrowser Kernel32.lib User32.lib Gdi32.lib ole32.lib oleaut32.lib uuid.lib  /O1 /Os /MT /GA
// Mingw   -- g++ Main.cpp -lKernel32 -luser32 -lgdi32 -lole32 -loleaut32 -luuid -oWebBrowser.exe -mwindows -m64 -s -Os
#define  UNICODE                 //Main.cpp - Web Browser Demo
#define  _UNICODE
#include <windows.h>
#include <cstdio>
#include "Main.h"
#include "IWebBrowser.h"
const IID IID_WebExplorer  = {0xEAB22AC1,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
HINSTANCE hAtlIns;


struct StartOLEProcess               // This galls me to no end to have to do this!
{                                    // Its requiring me to use a global variable
 StartOLEProcess()                   // for hAtlIns.  So far I haven't figurred a
 {                                   // way around it.
  CoInitialize(NULL);
  hAtlIns=LoadLibrary(L"Atl.dll");
 }

 ~StartOLEProcess()
 {
  CoUninitialize();
  if(hAtlIns)
     FreeLibrary(hAtlIns);
 }
}InitializeOLE;


long fnWndProc_OnCreate(lpWndEventArgs Wea)
{
 PFNATLAXCREATECONTROL pAtlCreateControl=NULL;
 PFNATLAXGETCONTROL pAtlAxGetControl=NULL;
 PFNATLAXWININIT pAtlAxWinInit=NULL;
 IUnknown* ppUnkContainer=NULL;
 IWebBrowser* pWebBrowser=NULL;
 IUnknown* pUnkIExplorer=NULL;
 HWND hCtl,hContainer;
 BSTR strProgId;
 HRESULT hr;

 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 if(hAtlIns)
 {
    hContainer=CreateWindowEx(0,L"static",L"",WS_CHILD|WS_VISIBLE,0,35,1180,750,Wea->hWnd,(HMENU)ID_CONTAINER,Wea->hIns,0);
    pAtlAxWinInit=(PFNATLAXWININIT)GetProcAddress(hAtlIns,"AtlAxWinInit");
    if(pAtlAxWinInit)
    {
       hr=pAtlAxWinInit();
       if(SUCCEEDED(hr))
       {
          pAtlCreateControl=(PFNATLAXCREATECONTROL)GetProcAddress(hAtlIns,"AtlAxCreateControl");
          if(pAtlCreateControl)
          {
             strProgId=SysAllocString(L"Shell.Explorer");
             hr=pAtlCreateControl(strProgId,hContainer,NULL,&ppUnkContainer);
             if(SUCCEEDED(hr))
             {
                SetWindowLongPtr(Wea->hWnd,0,(LONG_PTR)ppUnkContainer);
                pAtlAxGetControl=(PFNATLAXGETCONTROL)GetProcAddress(hAtlIns,"AtlAxGetControl");
                if(pAtlAxGetControl)
                {
                   hr=pAtlAxGetControl(hContainer,&pUnkIExplorer);
                   if(SUCCEEDED(hr))
                   {
                      SetWindowLongPtr(Wea->hWnd,1*sizeof(void*),(LONG_PTR)pUnkIExplorer);
                      hr=pUnkIExplorer->QueryInterface(IID_WebExplorer,(void**)&pWebBrowser);
                      if(SUCCEEDED(hr))
                         SetWindowLongPtr(Wea->hWnd,2*sizeof(void*),(LONG_PTR)pWebBrowser);
                      else
                         return 0;
                      hCtl=CreateWindowEx(WS_EX_CLIENTEDGE,L"edit",L"",WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,5,5,1000,25,Wea->hWnd,(HMENU)ID_URL,Wea->hIns,0);
                      SetWindowText(hCtl,L"www.cplusplus.com");
                      CreateWindow(L"button",L"Navigate",WS_CHILD|WS_VISIBLE,1050,5,80,25,Wea->hWnd,(HMENU)BTN_NAVIGATE,Wea->hIns,0);
                   }
                }
             }
          }
       }
    }
 }
 else
    MessageBox(Wea->hWnd,L"Couldn't Load Atl.dll",L"Failure",MB_ICONERROR);

 return 0;
}


long fnWndProc_OnCommand(lpWndEventArgs Wea)
{
 if(LOWORD(Wea->wParam)==BTN_NAVIGATE)
 {
    wchar_t szBuffer[256];
    HWND hEdit=GetDlgItem(Wea->hWnd,ID_URL);
    GetWindowText(hEdit,szBuffer,256);
    IWebBrowser* pWebBrowser=NULL;
    pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
    BSTR strUrl;
    strUrl=SysAllocString(szBuffer);
    if(pWebBrowser)
       pWebBrowser->Navigate(strUrl,NULL,NULL,NULL,NULL);
    SysFreeString(strUrl);
 }

 return 0;
}


long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 IUnknown* ppUnkContainer=NULL;
 IWebBrowser* pWebBrowser=NULL;
 IUnknown* pUnkIExplorer=NULL;

 pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
 if(pWebBrowser)
    pWebBrowser->Release();
 pUnkIExplorer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,1*sizeof(void*));
 if(pUnkIExplorer)
    pUnkIExplorer->Release();
 ppUnkContainer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,0);
 if(ppUnkContainer)
    ppUnkContainer->Release();
 PostQuitMessage(0);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{

 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 wchar_t szClassName[]=L"WebBrowser";
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=3*sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,100,15,1200,830,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


The IWebBrowser.h and Main.h files at top in the #includes are unchanged from my earlier posts of those files. This compiles to around 19 K with Mingw 4.8 x64 and 41 K with VC++ 9 (version 15) circa 2008 or so. Course, that isn't including Atl.dll which is a dependency. That file adds another 89 K. By the way, since Microsoft apparently redid that code for 64 bit (Atl.dll, that is), we can have a 64 bit version of this app. That file is simply found in C:\Windows\System32\Atl.dll.
Last edited on
I'm really going dowm memory lane trying to remember why I did this code the way I did. I think what happened is that I really hadn't spent much time on this IExplorer example. My main thrust at the time was trying to get all the various ActiveX Controls that shipped with Visual Studio 6 (circa 1998 or so) working in SDK style API C/C++ code. My main interest at the time was the MSFlexGrid OCX (MSFlxGrd.ocx). Windows doesn't really have a grid control among its standard concrols or 'Common Controls', but the widely used MSFlexGrid ActiveX Control that mostly Visual Basic used was very widely used. If one were a C++ coder and was using MFC that environment auto-generated typical wizard generated mystery code that everybody used but no one understands. If you were an SDK coder you were out of luck though unless you could figure out how to do it. So that was more or less my starting point.

And the deal was, as I now recall (its starting to come back to me), the MSFlexGrid was a 'licensed' ActiveX Control. What that means is that if you had a developer license for the Professional or Enterprise editions, you had a license for the ActiveX Control. So it would be included in the setup program you put together for users of your programs. But someone who got a program from you which included the MSFlexGrid.ocx file wouldn't have a license. The IClassFactoryEx Interface had a special member for instantiating licensed ActiveX Controls, and that had to be used. But something about the various versions of Atl.dll was going on and I had to resort to complicated function pointer calls to get the whole thing working for both mingw and MSVC.

And when I tested the whole thing as a lark kind of for IExplorer, I just used this function pointer laden code I think. But I think it can be redone without it.
Last edited on
I have just updated the above code so as to remove all the function pointer calls and to use implicit linking of the atl.dll through the atl.lib import library. I have tested this code with VC 9 (Visual Studio 2008) x86/x64 and MinGW 4.8 x64. The libs you need to link with are ole32.lib, oleaut32.lib, uuid.lib and atl.lib. Note that if messing around with different architectures (x86/x64) you need to be very, very careful to link asgainst the correct version of the libs. If you get link errors (unresolved externals), you are linking against the wrong architecture version. This code uses my previously posted IWebBrowser.h and Main.h files. The Shell.Explorer ActiveX Control has several 'outgoing interfaces'. Another name for these are Event Interfaces. I did not include that functionality, but I can if anyone is interested. File sizes on this are about 19 K x64 MinGW and 42 K VC9 \MT (staticaslly Linked) in x64...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef UNICODE           //Main.cpp - Web Browser Demo
   #define  UNICODE
#endif
#ifndef _UNICODE
   #define  _UNICODE
#endif
#include <windows.h>
#include <cstdio>
#include "Main.h"
#include "IWebBrowser.h"
EXTERN_C HRESULT __stdcall AtlAxWinInit();
EXTERN_C HRESULT __stdcall AtlAxGetControl(HWND hWnd, IUnknown** pp);
EXTERN_C HRESULT __stdcall AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer);
const IID IID_WebExplorer  = {0xEAB22AC1,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};


long fnWndProc_OnCreate(lpWndEventArgs Wea)
{
 IUnknown* ppUnkContainer = NULL;
 IWebBrowser* pWebBrowser = NULL;
 IUnknown* pUnkIExplorer  = NULL;
 HWND hContainer;
 BSTR strProgId;
 HRESULT hr;

 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 hContainer=CreateWindow((wchar_t*)L"static",(wchar_t*)L"",WS_CHILD|WS_VISIBLE,0,35,1180,750,Wea->hWnd,(HMENU)ID_CONTAINER,Wea->hIns,0);
 hr=AtlAxWinInit();
 if(SUCCEEDED(hr))
 {
    strProgId=SysAllocString((wchar_t*)L"Shell.Explorer");
    hr=AtlAxCreateControl(strProgId,hContainer,NULL,&ppUnkContainer);
    SysFreeString(strProgId);
    if(SUCCEEDED(hr))
    {
       SetWindowLongPtr(Wea->hWnd,0,(LONG_PTR)ppUnkContainer);
       hr=AtlAxGetControl(hContainer,&pUnkIExplorer);
       if(SUCCEEDED(hr))
       {
          SetWindowLongPtr(Wea->hWnd,1*sizeof(void*),(LONG_PTR)pUnkIExplorer);
          hr=pUnkIExplorer->QueryInterface(IID_WebExplorer,(void**)&pWebBrowser);
          if(SUCCEEDED(hr))
             SetWindowLongPtr(Wea->hWnd,2*sizeof(void*),(LONG_PTR)pWebBrowser);
          else
             return -1;
          CreateWindowEx(WS_EX_CLIENTEDGE,(wchar_t*)L"edit",(wchar_t*)L"www.cplusplus.com",WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,5,5,1000,25,Wea->hWnd,(HMENU)ID_URL,Wea->hIns,0);
          CreateWindow((wchar_t*)L"button",(wchar_t*)L"Navigate",WS_CHILD|WS_VISIBLE,1050,5,80,25,Wea->hWnd,(HMENU)BTN_NAVIGATE,Wea->hIns,0);
       }
    }
 }

 return 0;
}


long fnWndProc_OnCommand(lpWndEventArgs Wea)
{
 if(LOWORD(Wea->wParam)==BTN_NAVIGATE)
 {
    wchar_t szBuffer[256];
    HWND hEdit=GetDlgItem(Wea->hWnd,ID_URL);
    GetWindowText(hEdit,szBuffer,256);
    IWebBrowser* pWebBrowser=NULL;
    pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
    BSTR strUrl;
    strUrl=SysAllocString(szBuffer);
    if(pWebBrowser)
       pWebBrowser->Navigate(strUrl,NULL,NULL,NULL,NULL);
    SysFreeString(strUrl);
 }

 return 0;
}


long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 IUnknown* ppUnkContainer=NULL;
 IWebBrowser* pWebBrowser=NULL;
 IUnknown* pUnkIExplorer=NULL;

 pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
 if(pWebBrowser)
    pWebBrowser->Release();
 pUnkIExplorer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,1*sizeof(void*));
 if(pUnkIExplorer)
    pUnkIExplorer->Release();
 ppUnkContainer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,0);
 if(ppUnkContainer)
    ppUnkContainer->Release();
 PostQuitMessage(0);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{

 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 wchar_t szClassName[]=L"WebBrowser";
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 CoInitialize(NULL);
 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=4*sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,100,15,1200,830,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }
 CoUninitialize();

 return (int)messages.wParam;
}


By the way, I fixed the issue related to the StartOLEProcess() thingie. One simply needs to put CoUninitialize() in WinMain() after the message loop so termination works correctly.

I had been having some difficulties with atl.dll in that I was receiving a message about Atl90.dll missing. I downloaded that (its about a 170 K file) and put it in C:\Windows\system32 and then it worked. That would be for x64, that is.

Last edited on
I downloaded your code, moved the header files to the folder, set linking to the libraries, and changed compiler settings, and it worked!
In my C:\Windows\system32 folder I have atl.dll, atl100.dll and atl110.dll, so one of those must have made the program work.

Looks good!
Glad to hear that!

I forgot to mention that for the code immediately above you can remove the function pointer declarations which I believe are in Main.h.

That Atl.lib and atl71.dll, atl80.dll, atl90.dll, atl10.dll, atl11.dll stuff I've been dealing with for years and I really don't know much about it. Conceptually, I fully understand what its doing but there are all those different versions. What seems to be happening whem one links against Atl.lib is that there are functions in there which cause those various numbered versions of the dlls to be loaded.

I code a lot in another programming language called PowerBASIC, and I can also use all that atl stuff there. In fact, that's where I first encountered it with Atl71.dll.

The situation with ActiveX Controls is that they were designed to be used in what are termed RAD - Rapid Application Development - environment such as Visual Basic or C#. What happens there is that icons representing them show up in a 'toolbox' type entity, where one can drag a control onto a visual representation of the running form/program, and the IDE will take care of all the nasty programming details of this. In such environments the necessary 'glue' code becomes invisible to the programmer, or is auto-generated and stuck in ancillary files that become part of the project but which the coder seldom if ever looks at and almost certainly doesn't understand.

That Atl stuff is a way of performing the negotiations necessary between the ActiveX Control itself and the containing application. There are about a dozen fairly complex COM interfaces that need to be dealt with that Atl takes care of.

But all this does create dependency issues when one uses atl (which stands for Active Template Librarty, by the way) to host ActiveX Controls. Its basically a story of never ending grief, it sometimes seems. Or maybe I've just never handled it well. Personal problem I guess.

But in the PowerBASIC Community the problem was solved by someone who I can only describe as a genius. His name is Jose Roca and he coded a replacement for all the functionality contained within atl.lib and all the various dlls. He provided this solution to all of us in source code form as an include file named olecon.inc (Ole Container) which we can include in our PowerBASIC projects, thereby relieving us of the burden of dealing with this atl stuiff. The final resulting executables are even smaller than their C or C++ counterparts too, considering that if one were to make an application out of this in the setup program one would need to include both the C++ executable and the atlXX.dll dependencies.

I'm working on the event interface to the above code right now. In the COM model servers such as Shell.Explorer communicate with clients through an event interface. The Interfaces involved are IConnectionPointContainer and IConnectionPoint. In all the cases I've ever seen the the type of interface used is known as a 'dispinterface'. Coding it within the client to allow the client to respond to these events is quite complex in SDK style apps. As I mentioned above, if one is using RAD design environments such as old VB 6, Delphi, .NET, or even modern C++ where one is using Microsoft's Wizard generated code to handle this, its easy. A possible downside is that the coder doesn't really understand everything going on in his/her app. But I suppose there's a lot to be said too for leveraging other peoples knowledge who provided the functionality and understand the code.

Quite a while back I posted a tutorial on using ActiveX Controls in SDK Style apps here...

http://www.jose.it-berater.org/smfforum/index.php?topic=4451.0

...where I used the MSFlexGrid.ocx file as an example. The MSFlexGrid is an ActiveX Grid Control.
Last edited on
I've finished hooking up the events interface to the WebBrowser demo. I'll repost everything, as there were changes to several of the files. First Main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Main.cpp - Web Browser Demo
// g++ Main.cpp IWebBrowserEvents.cpp -lKernel32 -lgdi32 -luser32 -lole32 -loleaut32 -luuid -latl -oWebBrowser.exe -mwindows -m64 -s -Os
// cl Main.cpp IWebBrowserEvents.cpp Kernel32.lib User32.lib Gdi32.lib ole32.lib oleaut32.lib uuid.lib atl.lib /FeWebBrowser /O1 /Os /MT /GA
#ifndef UNICODE
    #define  UNICODE
#endif
#ifndef _UNICODE
    #define  _UNICODE
#endif
#include <windows.h>
#include <ocidl.h>
#include <cstdio>
#include "Main.h"
#include "IWebBrowser.h"
#include "IWebBrowserEvents.h"

EXTERN_C HRESULT __stdcall AtlAxWinInit();
EXTERN_C HRESULT __stdcall AtlAxGetControl(HWND hWnd, IUnknown** pp);
EXTERN_C HRESULT __stdcall AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer);

const IID LIBID_WebBrowser              = {0xEAB22AC0,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
const IID IID_IWebBrowser               = {0xEAB22AC1,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
const IID IID_IWebBrowserEvents         = {0x34A715A0,0x6587,0x11D0,{0x92,0x4A,0x00,0x20,0xAF,0xC7,0xAC,0x4D}};
const IID IID_IConnectionPointContainer = {0xB196B284,0xBAB4,0x101A,{0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07}};


long fnWndProc_OnCreate(lpWndEventArgs Wea)                      // What's Stored In NDCLASSEX::cbWndExtra Bytes (x64)
{                                                                //
 IConnectionPointContainer* pConnectionPointContainer = NULL;    // Offset   Bytes    What's Stored There
 IConnectionPoint*          pConnectionPoint          = NULL;    // ==================================================
 IUnknown*                  ppUnkContainer            = NULL;    //0        0  -  7  ppUnkContainer
 IWebBrowser*               pWebBrowser               = NULL;    //1        8  - 15  pUnkIExplorer
 IUnknown*                  pUnkIExplorer             = NULL;    //2        16 - 23  pWebBrowser
 CEventSink*                pEventSink                = NULL;    //3        24 - 31  pConnectionPoint
 HWND                       hContainer;                          //4        32 - 39  dwCookie
 DWORD                      dwCookie;
 BSTR                       strProgId;
 HRESULT                    hr;

 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 hContainer=CreateWindow((wchar_t*)L"static",(wchar_t*)L"",WS_CHILD|WS_VISIBLE,0,35,1180,750,Wea->hWnd,(HMENU)ID_CONTAINER,Wea->hIns,0);
 hr=AtlAxWinInit();
 if(SUCCEEDED(hr))
 {
    strProgId=SysAllocString((wchar_t*)L"Shell.Explorer");
    hr=AtlAxCreateControl(strProgId,hContainer,NULL,&ppUnkContainer);
    SysFreeString(strProgId);
    if(SUCCEEDED(hr))
    {
       SetWindowLongPtr(Wea->hWnd,0,(LONG_PTR)ppUnkContainer);
       hr=AtlAxGetControl(hContainer,&pUnkIExplorer);
       if(SUCCEEDED(hr))
       {
          SetWindowLongPtr(Wea->hWnd,1*sizeof(void*),(LONG_PTR)pUnkIExplorer);
          hr=pUnkIExplorer->QueryInterface(IID_IWebBrowser,(void**)&pWebBrowser);
          if(SUCCEEDED(hr))
             SetWindowLongPtr(Wea->hWnd,2*sizeof(void*),(LONG_PTR)pWebBrowser);
          else
             return -1;
          hr=pUnkIExplorer->QueryInterface(IID_IConnectionPointContainer,(void**)&pConnectionPointContainer);
          if(SUCCEEDED(hr))
          {
             hr=pConnectionPointContainer->FindConnectionPoint(IID_IWebBrowserEvents,&pConnectionPoint);
             if(SUCCEEDED(hr))
             {
                pConnectionPointContainer->Release();
                pConnectionPointContainer=NULL;
                SetWindowLongPtr(Wea->hWnd,3*sizeof(void*),(LONG_PTR)pConnectionPoint);
                pEventSink=new CEventSink;
                if(pEventSink)
                {
                   pEventSink->StoreGridPointer(pWebBrowser);
                   hr=pConnectionPoint->Advise((IUnknown*)pEventSink, &dwCookie);
                   if(SUCCEEDED(hr))
                      SetWindowLongPtr(Wea->hWnd,4*sizeof(void*),(LONG_PTR)dwCookie);
                   else
                      return -1;
                }
                else
                   return -1;
             }
             else
                return -1;
          }
          else
            return -1;
          CreateWindowEx(WS_EX_CLIENTEDGE,(wchar_t*)L"edit",(wchar_t*)L"www.cplusplus.com",WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,5,5,1000,25,Wea->hWnd,(HMENU)ID_URL,Wea->hIns,0);
          CreateWindow((wchar_t*)L"button",(wchar_t*)L"Navigate",WS_CHILD|WS_VISIBLE,1050,5,80,25,Wea->hWnd,(HMENU)BTN_NAVIGATE,Wea->hIns,0);
       }
       else
          return -1;
    }
    else
       return -1;
 }
 else
    return -1;

 return 0;
}


long fnWndProc_OnCommand(lpWndEventArgs Wea)
{
 if(LOWORD(Wea->wParam)==BTN_NAVIGATE)
 {
    wchar_t szBuffer[256];
    HWND hEdit=GetDlgItem(Wea->hWnd,ID_URL);
    GetWindowText(hEdit,szBuffer,256);
    IWebBrowser* pWebBrowser=NULL;
    pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
    BSTR strUrl;
    strUrl=SysAllocString(szBuffer);
    if(pWebBrowser)
       pWebBrowser->Navigate(strUrl,NULL,NULL,NULL,NULL);
    SysFreeString(strUrl);
 }

 return 0;
}


long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 IConnectionPoint* pConnectionPoint = NULL;
 IUnknown*         ppUnkContainer   = NULL;
 IWebBrowser*      pWebBrowser      = NULL;
 IUnknown*         pUnkIExplorer    = NULL;
 DWORD             dwCookie         = 0;

 pConnectionPoint=(IConnectionPoint*)GetWindowLongPtr(Wea->hWnd,3*sizeof(void*));
 dwCookie=(DWORD)GetWindowLongPtr(Wea->hWnd,4*sizeof(void*));
 if(pConnectionPoint)
 {
    pConnectionPoint->Unadvise(dwCookie);
    pConnectionPoint->Release();
 }
 pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
 if(pWebBrowser)
    pWebBrowser->Release();
 pUnkIExplorer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,1*sizeof(void*));
 if(pUnkIExplorer)
    pUnkIExplorer->Release();
 ppUnkContainer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,0);
 if(ppUnkContainer)
    ppUnkContainer->Release();
 PostQuitMessage(0);

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{

 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 wchar_t szClassName[]=L"WebBrowser";
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 CoInitialize(NULL);
 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=5*sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,100,15,1200,830,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }
 CoUninitialize();

 return messages.wParam;
}

Next, Main.h...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Main.h
#ifndef Main_h
#define Main_h

#define dim(x) (sizeof(x) / sizeof(x[0]))

typedef struct WindowsEventArguments
{
 HWND                         hWnd;
 WPARAM                       wParam;
 LPARAM                       lParam;
 HINSTANCE                    hIns;
}WndEventArgs, *lpWndEventArgs;

long fnWndProc_OnCreate       (lpWndEventArgs Wea);
long fnWndProc_OnCommand      (lpWndEventArgs Wea);
long fnWndProc_OnDestroy      (lpWndEventArgs Wea);

struct EVENTHANDLER
{
 unsigned int                 iMsg;
 long                         (*fnPtr)(lpWndEventArgs);
};

const EVENTHANDLER EventHandler[]=
{
 {WM_CREATE,                  fnWndProc_OnCreate},
 {WM_COMMAND,                 fnWndProc_OnCommand},
 {WM_DESTROY,                 fnWndProc_OnDestroy}
};

#define ID_CONTAINER          1250
#define BTN_NAVIGATE          1255
#define ID_URL                1265

#endif 

IWebBrowser.h first part ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// IWebBrowser.h
#ifndef SHDocVw_h
#define SHDocVw_h
#include <ocidl.h>

typedef interface IWebBrowser IWebBrowser;
typedef interface DWebBrowserEvents DWebBrowserEvents;
typedef interface IWebBrowserApp IWebBrowserApp;
typedef interface IWebBrowser2 IWebBrowser2;
typedef interface DWebBrowserEvents2 DWebBrowserEvents2;
typedef interface DShellWindowsEvents DShellWindowsEvents;
typedef interface IShellWindows IShellWindows;
typedef interface IShellUIHelper IShellUIHelper;
typedef interface IShellUIHelper2 IShellUIHelper2;
typedef interface IShellUIHelper3 IShellUIHelper3;
typedef interface DShellNameSpaceEvents DShellNameSpaceEvents;
typedef interface IShellFavoritesNameSpace IShellFavoritesNameSpace;
typedef interface IShellNameSpace IShellNameSpace;
typedef interface IScriptErrorList IScriptErrorList;


typedef enum CommandStateChangeConstants
{
 CSC_UPDATECOMMANDS              = -1,
 CSC_NAVIGATEFORWARD             = 1,
 CSC_NAVIGATEBACK                = 2
}CommandStateChangeConstants;


typedef enum OLECMDID
{
 OLECMDID_OPEN                   = 1,
 OLECMDID_NEW                    = 2,
 OLECMDID_SAVE                   = 3,
 OLECMDID_SAVEAS                 = 4,
 OLECMDID_SAVECOPYAS             = 5,
 OLECMDID_PRINT                  = 6,
 OLECMDID_PRINTPREVIEW           = 7,
 OLECMDID_PAGESETUP              = 8,
 OLECMDID_SPELL                  = 9,
 OLECMDID_PROPERTIES             = 10,
 OLECMDID_CUT                    = 11,
 OLECMDID_COPY                   = 12,
 OLECMDID_PASTE                  = 13,
 OLECMDID_PASTESPECIAL           = 14,
 OLECMDID_UNDO                   = 15,
 OLECMDID_REDO                   = 16,
 OLECMDID_SELECTALL              = 17,
 OLECMDID_CLEARSELECTION         = 18,
 OLECMDID_ZOOM                   = 19,
 OLECMDID_GETZOOMRANGE           = 20,
 OLECMDID_UPDATECOMMANDS         = 21,
 OLECMDID_REFRESH                = 22,
 OLECMDID_STOP                   = 23,
 OLECMDID_HIDETOOLBARS           = 24,
 OLECMDID_SETPROGRESSMAX         = 25,
 OLECMDID_SETPROGRESSPOS         = 26,
 OLECMDID_SETPROGRESSTEXT        = 27,
 OLECMDID_SETTITLE               = 28,
 OLECMDID_SETDOWNLOADSTATE       = 29,
 OLECMDID_STOPDOWNLOAD           = 30,
 OLECMDID_ONTOOLBARACTIVATED     = 31,
 OLECMDID_FIND                   = 32,
 OLECMDID_DELETE                 = 33,
 OLECMDID_HTTPEQUIV              = 34,
 OLECMDID_HTTPEQUIV_DONE         = 35,
 OLECMDID_ENABLE_INTERACTION     = 36,
 OLECMDID_ONUNLOAD               = 37,
 OLECMDID_PROPERTYBAG2           = 38,
 OLECMDID_PREREFRESH             = 39,
 OLECMDID_SHOWSCRIPTERROR        = 40,
 OLECMDID_SHOWMESSAGE            = 41,
 OLECMDID_SHOWFIND               = 42,
 OLECMDID_SHOWPAGESETUP          = 43,
 OLECMDID_SHOWPRINT              = 44,
 OLECMDID_CLOSE                  = 45,
 OLECMDID_ALLOWUILESSSAVEAS      = 46,
 OLECMDID_DONTDOWNLOADCSS        = 47,
 OLECMDID_UPDATEPAGESTATUS       = 48,
 OLECMDID_PRINT2                 = 49,
 OLECMDID_PRINTPREVIEW2          = 50,
 OLECMDID_SETPRINTTEMPLATE       = 51,
 OLECMDID_GETPRINTTEMPLATE       = 52,
 OLECMDID_PAGEACTIONBLOCKED      = 55,
 OLECMDID_PAGEACTIONUIQUERY      = 56,
 OLECMDID_FOCUSVIEWCONTROLS      = 57,
 OLECMDID_FOCUSVIEWCONTROLSQUERY = 58,
 OLECMDID_SHOWPAGEACTIONMENU     = 59,
 OLECMDID_ADDTRAVELENTRY         = 60,
 OLECMDID_UPDATETRAVELENTRY      = 61,
 OLECMDID_UPDATEBACKFORWARDSTATE = 62,
 OLECMDID_OPTICAL_ZOOM           = 63,
 OLECMDID_OPTICAL_GETZOOMRANGE   = 64,
 OLECMDID_WINDOWSTATECHANGED     = 65,
 OLECMDID_ACTIVEXINSTALLSCOPE    = 66,
 OLECMDID_UPDATETRAVELENTRY_DATARECOVERY= 67
}OLECMDID;


typedef enum OLECMDF
{
 OLECMDF_SUPPORTED               = 1,
 OLECMDF_ENABLED                 = 2,
 OLECMDF_LATCHED                 = 4,
 OLECMDF_NINCHED                 = 8,
 OLECMDF_INVISIBLE               = 16,
 OLECMDF_DEFHIDEONCTXTMENU       = 32
}OLECMDF;


typedef enum OLECMDEXECOPT
{
 OLECMDEXECOPT_DODEFAULT         = 0,
 OLECMDEXECOPT_PROMPTUSER        = 1,
 OLECMDEXECOPT_DONTPROMPTUSER    = 2,
 OLECMDEXECOPT_SHOWHELP          = 3
}OLECMDEXECOPT;


typedef enum SecureLockIconConstants
{
 secureLockIconUnsecure          = 0,
 secureLockIconMixed             = 1,
 secureLockIconSecureUnknownBits = 2,
 secureLockIconSecure40Bit       = 3,
 secureLockIconSecure56Bit       = 4,
 secureLockIconSecureFortezza    = 5,
 secureLockIconSecure128Bit      = 6
}SecureLockIconConstants;


typedef enum NewProcessCauseConstants
{
 ProtectedModeRedirect           = 1
}NewProcessCauseConstants;


typedef enum ShellWindowTypeConstants
{
 SWC_EXPLORER                    = 0,
 SWC_BROWSER                     = 1,
 SWC_3RDPARTY                    = 2,
 SWC_CALLBACK                    = 4,
 SWC_DESKTOP                     = 8
}ShellWindowTypeConstants;


typedef enum ShellWindowFindWindowOptions
{
 SWFO_NEEDDISPATCH               = 1,
 SWFO_INCLUDEPENDING             = 2,
 SWFO_COOKIEPASSED               = 4
}ShellWindowFindWindowOptions;


interface IWebBrowser : IDispatch
{
 virtual HRESULT __stdcall GoBack(void)=0;
 virtual HRESULT __stdcall GoForward(void)=0;
 virtual HRESULT __stdcall GoHome(void)=0;
 virtual HRESULT __stdcall GoSearch(void)=0;
 virtual HRESULT __stdcall Navigate(BSTR URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers)=0;
 virtual HRESULT __stdcall Refresh(void)=0;
 virtual HRESULT __stdcall Refresh2(VARIANT* Level)=0;
 virtual HRESULT __stdcall Stop(void)=0;
 virtual HRESULT __stdcall GetApplication(IDispatch** ppDisp)=0;
 virtual HRESULT __stdcall GetParent(IDispatch** ppDisp)=0;
 virtual HRESULT __stdcall GetContainer(IDispatch** ppDisp)=0;
 virtual HRESULT __stdcall GetDocument(IDispatch** ppDisp)=0;
 virtual HRESULT __stdcall GetTopLevelContainer(VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall GetType(BSTR* Type)=0;
 virtual HRESULT __stdcall GetLeft(LONG* pl)=0;
 virtual HRESULT __stdcall SetLeft(LONG pl)=0;
 virtual HRESULT __stdcall GetTop(LONG* pl)=0;
 virtual HRESULT __stdcall SetTop(LONG pl)=0;
 virtual HRESULT __stdcall GetWidth(LONG* pl)=0;
 virtual HRESULT __stdcall SetWidth(LONG pl)=0;
 virtual HRESULT __stdcall GetHeight(LONG* pl)=0;
 virtual HRESULT __stdcall SetHeight(LONG pl)=0;
 virtual HRESULT __stdcall GetLocationName(BSTR* LocationName)=0;
 virtual HRESULT __stdcall GetLocationURL(BSTR* LocationURL)=0;
 virtual HRESULT __stdcall GetBusy(VARIANT_BOOL* pBool)=0;
};


interface IWebBrowserApp : IWebBrowser
{
 virtual HRESULT __stdcall Quit(void)=0;
 virtual HRESULT __stdcall ClientToWindow(int* pcx, int* pcy)=0;
 virtual HRESULT __stdcall PutProperty(BSTR Property, VARIANT vtValue)=0;
 virtual HRESULT __stdcall GetProperty(BSTR Property, VARIANT* pvtValue)=0;
 virtual HRESULT __stdcall GetName(BSTR* Name)=0;
 virtual HRESULT __stdcall GetHWND(LONG* pHWND)=0;
 virtual HRESULT __stdcall GetFullName(BSTR* FullName)=0;
 virtual HRESULT __stdcall GetPath(BSTR* Path)=0;
 virtual HRESULT __stdcall GetVisible(VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall SetVisible(VARIANT_BOOL pBool)=0;
 virtual HRESULT __stdcall GetStatusBar(VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall SetStatusBar(VARIANT_BOOL pBool)=0;
 virtual HRESULT __stdcall GetStatusText(BSTR* StatusText)=0;
 virtual HRESULT __stdcall SetStatusText(BSTR StatusText)=0;
 virtual HRESULT __stdcall GetToolBar(int* Value)=0;
 virtual HRESULT __stdcall SetToolBar(int Value)=0;
 virtual HRESULT __stdcall GetMenuBar(VARIANT_BOOL* Value)=0;
 virtual HRESULT __stdcall SetMenuBar(VARIANT_BOOL Value)=0;
 virtual HRESULT __stdcall GetFullScreen(VARIANT_BOOL* pbFullScreen)=0;
 virtual HRESULT __stdcall SetFullScreen(VARIANT_BOOL pbFullScreen)=0;
};


IWebBrowser.h Next Part...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
interface IWebBrowser2 : IWebBrowserApp
{
 virtual HRESULT __stdcall Navigate2(VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers)=0;
 virtual HRESULT __stdcall QueryStatusWB(OLECMDID cmdID, OLECMDF* pcmdf)=0;
 virtual HRESULT __stdcall ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt, VARIANT* pvaIn, VARIANT* pvaOut)=0;
 virtual HRESULT __stdcall ShowBrowserBar(VARIANT* pvaClsid, VARIANT* pvarShow, VARIANT* pvarSize)=0;
 virtual HRESULT __stdcall GetReadyState(tagREADYSTATE* plReadyState)=0;
 virtual HRESULT __stdcall GetOffline(VARIANT_BOOL* pbOffline)=0;
 virtual HRESULT __stdcall SetOffline(VARIANT_BOOL pbOffline)=0;
 virtual HRESULT __stdcall GetSilent(VARIANT_BOOL* pbSilent)=0;
 virtual HRESULT __stdcall SetSilent(VARIANT_BOOL pbSilent)=0;
 virtual HRESULT __stdcall GetRegisterAsBrowser(VARIANT_BOOL* pbRegister)=0;
 virtual HRESULT __stdcall SetRegisterAsBrowser(VARIANT_BOOL pbRegister)=0;
 virtual HRESULT __stdcall GetRegisterAsDropTarget(VARIANT_BOOL* pbRegister)=0;
 virtual HRESULT __stdcall SetRegisterAsDropTarget(VARIANT_BOOL pbRegister)=0;
 virtual HRESULT __stdcall GetTheaterMode(VARIANT_BOOL* pbRegister)=0;
 virtual HRESULT __stdcall SetTheaterMode(VARIANT_BOOL pbRegister)=0;
 virtual HRESULT __stdcall GetAddressBar(VARIANT_BOOL* Value)=0;
 virtual HRESULT __stdcall SetAddressBar(VARIANT_BOOL Value)=0;
 virtual HRESULT __stdcall GetResizable(VARIANT_BOOL* Value)=0;
 virtual HRESULT __stdcall SetResizable(VARIANT_BOOL Value)=0;
};


interface IShellWindows : IDispatch
{
 virtual HRESULT __stdcall GetCount(LONG* Count)=0;
 virtual HRESULT __stdcall Item(VARIANT index, IDispatch** Folder)=0;
 virtual HRESULT __stdcall _NewEnum(IUnknown** ppunk)=0;
 virtual HRESULT __stdcall Register(IDispatch* pid, LONG HWND, int swClass, LONG* plCookie)=0;
 virtual HRESULT __stdcall RegisterPending(LONG lThreadId, VARIANT* pvarloc, VARIANT* pvarlocRoot, int swClass, LONG* plCookie)=0;
 virtual HRESULT __stdcall Revoke(LONG lCookie)=0;
 virtual HRESULT __stdcall OnNavigate(LONG lCookie, VARIANT* pvarloc)=0;
 virtual HRESULT __stdcall OnActivated(LONG lCookie, VARIANT_BOOL fActive)=0;
 virtual HRESULT __stdcall FindWindowSW(VARIANT* pvarloc, VARIANT* pvarlocRoot, int swClass, LONG* pHWND, int swfwOptions, IDispatch** ppdispOut)=0;
 virtual HRESULT __stdcall OnCreated(LONG lCookie, IUnknown* punk)=0;
 virtual HRESULT __stdcall ProcessAttachDetach(VARIANT_BOOL fAttach)=0;
};


interface IShellUIHelper : IDispatch
{
 virtual HRESULT __stdcall ResetFirstBootMode(void)=0;
 virtual HRESULT __stdcall ResetSafeMode(void)=0;
 virtual HRESULT __stdcall RefreshOfflineDesktop(void)=0;
 virtual HRESULT __stdcall AddFavorite(BSTR URL, VARIANT* Title)=0;
 virtual HRESULT __stdcall AddChannel(BSTR URL)=0;
 virtual HRESULT __stdcall AddDesktopComponent(BSTR URL, BSTR Type, VARIANT* Left, VARIANT* Top, VARIANT* Width, VARIANT* Height)=0;
 virtual HRESULT __stdcall IsSubscribed(BSTR URL, VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall NavigateAndFind(BSTR URL, BSTR strQuery, VARIANT* varTargetFrame)=0;
 virtual HRESULT __stdcall ImportExportFavorites(VARIANT_BOOL fImport, BSTR strImpExpPath)=0;
 virtual HRESULT __stdcall AutoCompleteSaveForm(VARIANT* Form)=0;
 virtual HRESULT __stdcall AutoScan(BSTR strSearch, BSTR strFailureUrl, VARIANT* pvarTargetFrame)=0;
 virtual HRESULT __stdcall AutoCompleteAttach(VARIANT* Reserved)=0;
 virtual HRESULT __stdcall ShowBrowserUI(BSTR bstrName, VARIANT* pvarIn, VARIANT* pvarOut)=0;
};


interface IShellUIHelper2 : IShellUIHelper
{
 virtual HRESULT __stdcall AddSearchProvider(BSTR URL)=0;
 virtual HRESULT __stdcall RunOnceShown(void)=0;
 virtual HRESULT __stdcall SkipRunOnce(void)=0;
 virtual HRESULT __stdcall CustomizeSettings(VARIANT_BOOL fSQM, VARIANT_BOOL fPhishing, BSTR bstrLocale)=0;
 virtual HRESULT __stdcall SqmEnabled(VARIANT_BOOL* pfEnabled)=0;
 virtual HRESULT __stdcall PhishingEnabled(VARIANT_BOOL* pfEnabled)=0;
 virtual HRESULT __stdcall BrandImageUri(BSTR* pbstrUri)=0;
 virtual HRESULT __stdcall SkipTabsWelcome(void)=0;
 virtual HRESULT __stdcall DiagnoseConnection(void)=0;
 virtual HRESULT __stdcall CustomizeClearType(VARIANT_BOOL fSet)=0;
 virtual HRESULT __stdcall IsSearchProviderInstalled(BSTR URL, unsigned int* pdwResult)=0;
 virtual HRESULT __stdcall IsSearchMigrated(VARIANT_BOOL* pfMigrated)=0;
 virtual HRESULT __stdcall DefaultSearchProvider(BSTR* pbstrName)=0;
 virtual HRESULT __stdcall RunOnceRequiredSettingsComplete(VARIANT_BOOL fComplete)=0;
 virtual HRESULT __stdcall RunOnceHasShown(VARIANT_BOOL* pfShown)=0;
 virtual HRESULT __stdcall SearchGuideUrl(BSTR* pbstrUrl)=0;
};


interface IShellUIHelper3 : IShellUIHelper2
{
 virtual HRESULT __stdcall AddService(BSTR URL)=0;
 virtual HRESULT __stdcall IsServiceInstalled(BSTR URL, BSTR Verb, unsigned int* pdwResult)=0;
 virtual HRESULT __stdcall InPrivateFilteringEnabled(VARIANT_BOOL* pfEnabled)=0;
 virtual HRESULT __stdcall AddToFavoritesBar(BSTR URL, BSTR Title, VARIANT* Type)=0;
 virtual HRESULT __stdcall BuildNewTabPage(void)=0;
 virtual HRESULT __stdcall SetRecentlyClosedVisible(VARIANT_BOOL fVisible)=0;
 virtual HRESULT __stdcall SetActivitiesVisible(VARIANT_BOOL fVisible)=0;
 virtual HRESULT __stdcall ContentDiscoveryReset(void)=0;
 virtual HRESULT __stdcall IsSuggestedSitesEnabled(VARIANT_BOOL* pfEnabled)=0;
 virtual HRESULT __stdcall EnableSuggestedSites(VARIANT_BOOL fEnable)=0;
 virtual HRESULT __stdcall NavigateToSuggestedSites(BSTR bstrRelativeUrl)=0;
 virtual HRESULT __stdcall ShowTabsHelp(void)=0;
 virtual HRESULT __stdcall ShowInPrivateHelp(void)=0;
};


interface IShellFavoritesNameSpace : IDispatch
{
 virtual HRESULT __stdcall MoveSelectionUp(void)=0;
 virtual HRESULT __stdcall MoveSelectionDown(void)=0;
 virtual HRESULT __stdcall ResetSort(void)=0;
 virtual HRESULT __stdcall NewFolder(void)=0;
 virtual HRESULT __stdcall Synchronize(void)=0;
 virtual HRESULT __stdcall Import(void)=0;
 virtual HRESULT __stdcall Export(void)=0;
 virtual HRESULT __stdcall InvokeContextMenuCommand(BSTR strCommand)=0;
 virtual HRESULT __stdcall MoveSelectionTo(void)=0;
 virtual HRESULT __stdcall GetSubscriptionsEnabled(VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall CreateSubscriptionForSelection(VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall DeleteSubscriptionForSelection(VARIANT_BOOL* pBool)=0;
 virtual HRESULT __stdcall SetRoot(BSTR bstrFullPath)=0;
};

IWebBrowser.h Last Part ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
interface IShellNameSpace : IShellFavoritesNameSpace
{
 virtual HRESULT __stdcall GetEnumOptions(LONG* pgrfEnumFlags)=0;
 virtual HRESULT __stdcall SetEnumOptions(LONG pgrfEnumFlags)=0;
 virtual HRESULT __stdcall GetSelectedItem(IDispatch** pItem)=0;
 virtual HRESULT __stdcall SetSelectedItem(IDispatch* pItem)=0;
 virtual HRESULT __stdcall GetRoot(VARIANT* pvar)=0;
 virtual HRESULT __stdcall SetRoot(VARIANT pvar)=0;
 virtual HRESULT __stdcall GetDepth(int* piDepth)=0;
 virtual HRESULT __stdcall SetDepth(int piDepth)=0;
 virtual HRESULT __stdcall GetMode(unsigned int* puMode)=0;
 virtual HRESULT __stdcall SetMode(unsigned int puMode)=0;
 virtual HRESULT __stdcall GetFlags(unsigned int* pdwFlags)=0;
 virtual HRESULT __stdcall SetFlags(unsigned int pdwFlags)=0;
 virtual HRESULT __stdcall SetTVFlags(unsigned int dwFlags)=0;
 virtual HRESULT __stdcall GetTVFlags(unsigned int* dwFlags)=0;
 virtual HRESULT __stdcall GetColumns(BSTR* bstrColumns)=0;
 virtual HRESULT __stdcall SetColumns(BSTR bstrColumns)=0;
 virtual HRESULT __stdcall GetCountViewTypes(int* piTypes)=0;
 virtual HRESULT __stdcall SetViewType(int iType)=0;
 virtual HRESULT __stdcall SelectedItems(IDispatch** ppid)=0;
 virtual HRESULT __stdcall Expand(VARIANT var, int iDepth)=0;
 virtual HRESULT __stdcall UnselectAll(void)=0;
};


interface IScriptErrorList : IDispatch
{
 virtual HRESULT __stdcall advanceError(void)=0;
 virtual HRESULT __stdcall retreatError(void)=0;
 virtual HRESULT __stdcall canAdvanceError(LONG* pfCanAdvance)=0;
 virtual HRESULT __stdcall canRetreatError(LONG* pfCanRetreat)=0;
 virtual HRESULT __stdcall getErrorLine(LONG* plLine)=0;
 virtual HRESULT __stdcall getErrorChar(LONG* plChar)=0;
 virtual HRESULT __stdcall getErrorCode(LONG* plCode)=0;
 virtual HRESULT __stdcall getErrorMsg(BSTR* pstr)=0;
 virtual HRESULT __stdcall getErrorUrl(BSTR* pstr)=0;
 virtual HRESULT __stdcall getAlwaysShowLockState(LONG* pfAlwaysShowLocked)=0;
 virtual HRESULT __stdcall getDetailsPaneOpen(LONG* pfDetailsPaneOpen)=0;
 virtual HRESULT __stdcall setDetailsPaneOpen(LONG fDetailsPaneOpen)=0;
 virtual HRESULT __stdcall getPerErrorDisplay(LONG* pfPerErrorDisplay)=0;
 virtual HRESULT __stdcall setPerErrorDisplay(LONG fPerErrorDisplay)=0;
};

#endif // SHDocVw_h 
IWebBrowserEvents.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// IWebBrowserEvents.h
#ifndef IWebBrowserEvents_h
#define IWebBrowserEvents_h
#include "IWebBrowser.h"


interface DWebBrowserEvents2 : IDispatch
{
 void __stdcall StatusTextChange(BSTR Text);
 void __stdcall ProgressChange(LONG Progress, LONG ProgressMax);
 void __stdcall CommandStateChange(LONG Command, VARIANT_BOOL Enable);
 void __stdcall DownloadBegin(void);
 void __stdcall DownloadComplete(void);
 void __stdcall TitleChange(BSTR Text);
 void __stdcall PropertyChange(BSTR szProperty);
 void __stdcall BeforeNavigate2(IDispatch* pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, VARIANT_BOOL* Cancel);
 void __stdcall NewWindow2(IDispatch** ppDisp, VARIANT_BOOL* Cancel);
 void __stdcall NavigateComplete2(IDispatch* pDisp, VARIANT* URL);
 void __stdcall DocumentComplete(IDispatch* pDisp, VARIANT* URL);
 void __stdcall OnQuit(void);
 void __stdcall OnVisible(VARIANT_BOOL Visible);
 void __stdcall OnToolBar(VARIANT_BOOL ToolBar);
 void __stdcall OnMenuBar(VARIANT_BOOL MenuBar);
 void __stdcall OnStatusBar(VARIANT_BOOL StatusBar);
 void __stdcall OnFullScreen(VARIANT_BOOL FullScreen);
 void __stdcall OnTheaterMode(VARIANT_BOOL TheaterMode);
 void __stdcall WindowSetResizable(VARIANT_BOOL Resizable);
 void __stdcall WindowSetLeft(LONG Left);
 void __stdcall WindowSetTop(LONG Top);
 void __stdcall WindowSetWidth(LONG Width);
 void __stdcall WindowSetHeight(LONG Height);
 void __stdcall WindowClosing(VARIANT_BOOL IsChildWindow, VARIANT_BOOL* Cancel);
 void __stdcall ClientToHostWindow(LONG* CX, LONG* CY);
 void __stdcall SetSecureLockIcon(LONG SecureLockIcon);
 void __stdcall FileDownload(VARIANT_BOOL ActiveDocument, VARIANT_BOOL* Cancel);
 void __stdcall NavigateError(IDispatch* pDisp, VARIANT* URL, VARIANT* Frame, VARIANT* StatusCode, VARIANT_BOOL* Cancel);
 void __stdcall PrintTemplateInstantiation(IDispatch* pDisp);
 void __stdcall PrintTemplateTeardown(IDispatch* pDisp);
 void __stdcall UpdatePageStatus(IDispatch* pDisp, VARIANT* nPage, VARIANT* fDone);
 void __stdcall PrivacyImpactedStateChange(VARIANT_BOOL bImpacted);
 void __stdcall NewWindow3(IDispatch** ppDisp, VARIANT_BOOL* Cancel, unsigned int dwFlags, BSTR bstrUrlContext, BSTR bstrUrl);
 void __stdcall SetPhishingFilterStatus(LONG PhishingFilterStatus);
 void __stdcall WindowStateChanged(unsigned int dwWindowStateFlags, unsigned int dwValidFlagsMask);
 void __stdcall NewProcess(LONG lCauseFlag, IDispatch* pWB2, VARIANT_BOOL* Cancel);
 void __stdcall ThirdPartyUrlBlocked(VARIANT* URL, unsigned int dwCount);
 void __stdcall RedirectXDomainBlocked(IDispatch* pDisp, VARIANT* StartURL, VARIANT* RedirectURL, VARIANT* Frame, VARIANT* StatusCode);
};


class CEventSink : public DWebBrowserEvents2     //CEventSink
{
 public:
 CEventSink();
 virtual ~CEventSink();
 HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
 ULONG   __stdcall AddRef();
 ULONG   __stdcall Release();
 HRESULT __stdcall GetTypeInfoCount(UINT* pCountTypeInfo);
 HRESULT __stdcall GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo);
 HRESULT __stdcall GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId);
 HRESULT __stdcall Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr);
 
 void    __stdcall StoreGridPointer(IWebBrowser* pIWebBrowser);                 // <<< Implemented In IWebBrowserEvents.cpp 
 
 void    __stdcall StatusTextChange(BSTR Text){}
 void    __stdcall ProgressChange(LONG Progress, LONG ProgressMax){}
 void    __stdcall CommandStateChange(LONG Command, VARIANT_BOOL Enable){}
 void    __stdcall DownloadBegin(void){}
 void    __stdcall DownloadComplete(void){}
 void    __stdcall TitleChange(BSTR Text){}
 void    __stdcall PropertyChange(BSTR szProperty){}
 void    __stdcall BeforeNavigate2(IDispatch* pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, VARIANT_BOOL* Cancel){}
 void    __stdcall NewWindow2(IDispatch** ppDisp, VARIANT_BOOL* Cancel){}
 
 void    __stdcall NavigateComplete2(IDispatch* pDisp, VARIANT* URL);           // <<< Implemented In IWebBrowserEvents.cpp
 
 void    __stdcall DocumentComplete(IDispatch* pDisp, VARIANT* URL){}
 void    __stdcall OnQuit(void){}
 void    __stdcall OnVisible(VARIANT_BOOL Visible){}
 void    __stdcall OnToolBar(VARIANT_BOOL ToolBar){}
 void    __stdcall OnMenuBar(VARIANT_BOOL MenuBar){}
 void    __stdcall OnStatusBar(VARIANT_BOOL StatusBar){}
 void    __stdcall OnFullScreen(VARIANT_BOOL FullScreen){}
 void    __stdcall OnTheaterMode(VARIANT_BOOL TheaterMode){}
 void    __stdcall WindowSetResizable(VARIANT_BOOL Resizable){}
 void    __stdcall WindowSetLeft(LONG Left){}
 void    __stdcall WindowSetTop(LONG Top){}
 void    __stdcall WindowSetWidth(LONG Width){}
 void    __stdcall WindowSetHeight(LONG Height){}
 void    __stdcall WindowClosing(VARIANT_BOOL IsChildWindow, VARIANT_BOOL* Cancel){}
 void    __stdcall ClientToHostWindow(LONG* CX, LONG* CY){}
 void    __stdcall SetSecureLockIcon(LONG SecureLockIcon){}
 void    __stdcall FileDownload(VARIANT_BOOL ActiveDocument, VARIANT_BOOL* Cancel){}
 void    __stdcall NavigateError(IDispatch* pDisp, VARIANT* URL, VARIANT* Frame, VARIANT* StatusCode, VARIANT_BOOL* Cancel){}
 void    __stdcall PrintTemplateInstantiation(IDispatch* pDisp){}
 void    __stdcall PrintTemplateTeardown(IDispatch* pDisp){}
 void    __stdcall UpdatePageStatus(IDispatch* pDisp, VARIANT* nPage, VARIANT* fDone){}
 void    __stdcall PrivacyImpactedStateChange(VARIANT_BOOL bImpacted){}
 void    __stdcall NewWindow3(IDispatch** ppDisp, VARIANT_BOOL* Cancel, unsigned int dwFlags, BSTR bstrUrlContext, BSTR bstrUrl){}
 void    __stdcall SetPhishingFilterStatus(LONG PhishingFilterStatus){}
 void    __stdcall WindowStateChanged(unsigned int dwWindowStateFlags, unsigned int dwValidFlagsMask){}
 void    __stdcall NewProcess(LONG lCauseFlag, IDispatch* pWB2, VARIANT_BOOL* Cancel){}
 void    __stdcall ThirdPartyUrlBlocked(VARIANT* URL, unsigned int dwCount){}
 void    __stdcall RedirectXDomainBlocked(IDispatch* pDisp, VARIANT* StartURL, VARIANT* RedirectURL, VARIANT* Frame, VARIANT* StatusCode){}

 private:
 long         m_cRef;
 ITypeInfo*   m_pTypeInfo;
 IWebBrowser* pWebBrowser;
};

#endif 
IWebBrowserEvents.cpp...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// IWebBrowserEvents.cpp
#ifndef UNICODE
   #define  UNICODE
#endif
#ifndef _UNICODE
   #define  _UNICODE
#endif
#include <windows.h>
#include <cstdio>
#include <string>
#include "Main.h"
#include "IWebBrowserEvents.h"
#include "IWebBrowser.h"
extern "C" const IID LIBID_WebBrowser      = {0xEAB22AC0,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
extern "C" const IID IID_IWebBrowserEvents = {0x34A715A0,0x6587,0x11D0,{0x92,0x4A,0x00,0x20,0xAF,0xC7,0xAC,0x4D}};
extern FILE* fp;


CEventSink::CEventSink() : m_cRef(0)       //CEventSink Constructor
{
 ITypeLib* pTypeLib=NULL;
 HRESULT hr;

 this->m_pTypeInfo=NULL;
 hr=LoadRegTypeLib(LIBID_WebBrowser,1,0,LANG_NEUTRAL,&pTypeLib);
 if(SUCCEEDED(hr))
 {
    hr = pTypeLib->GetTypeInfoOfGuid(IID_IWebBrowserEvents, &m_pTypeInfo);
    pTypeLib->Release();
 }
}


CEventSink::~CEventSink()
{
 if(this->m_pTypeInfo)
    this->m_pTypeInfo->Release();
}


HRESULT CEventSink::QueryInterface(REFIID riid, void** ppv)
{
 if(riid == IID_IUnknown)
    *ppv = (IUnknown*)this;
 else if(riid == IID_IDispatch)
    *ppv = (IDispatch*)this;
 else if(riid == IID_IWebBrowserEvents)
    *ppv = (DWebBrowserEvents2*)this;
 else
 {
    *ppv = NULL;
    return E_NOINTERFACE;
 }
 AddRef();

 return S_OK;
}


ULONG CEventSink::AddRef()
{
 this->m_cRef++;
 return this->m_cRef;
}


ULONG CEventSink::Release()
{
 if(--m_cRef != 0)
    return m_cRef;
 else
    delete this;

 return 0;
}


HRESULT CEventSink::GetTypeInfoCount(UINT* pCountTypeInfo)
{
 *pCountTypeInfo = 1;
 return S_OK;
}


HRESULT CEventSink::GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo)
{
 *ppITypeInfo = NULL;
 if(iTypeInfo != 0)
    return DISP_E_BADINDEX;
 m_pTypeInfo->AddRef();
 *ppITypeInfo = m_pTypeInfo;
 return S_OK;
}


HRESULT CEventSink::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
{
 if(riid != IID_NULL)
    return DISP_E_UNKNOWNINTERFACE;
 return DispGetIDsOfNames(m_pTypeInfo, rgszNames, cNames, rgDispId);
}


HRESULT CEventSink::Invoke(DISPID dispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDParms, VARIANT* pVarResult, EXCEPINFO* pErInfo, UINT* pErr)
{
 if(riid != IID_NULL)
    return DISP_E_UNKNOWNINTERFACE;
 else
 {
    switch(dispId)
    {
      case 0xfc:  // NavigateComplete2
        {
           this->NavigateComplete2(pDParms->rgvarg[1].pdispVal, pDParms->rgvarg[0].pvarVal);
           break;
        }
    }
 }

 return S_OK;
}


void CEventSink::NavigateComplete2(IDispatch* pDisp, VARIANT* pVariantURL)
{
 MessageBox(NULL,pVariantURL->bstrVal,L"Received Event CEventSink::NavigateComplete2()",MB_ICONINFORMATION);
}


void CEventSink::StoreGridPointer(IWebBrowser* pIWebBrowser)
{
 this->pWebBrowser=pIWebBrowser;
}

Worked on first try. Great job!
I had stripped all the debug code out of that, but here is the original Main.cpp where debug output is controlled by #define MyDebug. Need two posts for this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Main.cpp - Web Browser Demo
// g++ Main.cpp IWebBrowserEvents.cpp -lKernel32 -lgdi32 -luser32 -lole32 -loleaut32 -luuid -latl -oWebBrowser.exe -mwindows -m64 -s -Os
// cl Main.cpp IWebBrowserEvents.cpp Kernel32.lib User32.lib Gdi32.lib ole32.lib oleaut32.lib uuid.lib atl.lib /FeWebBrowser /O1 /Os /MT /GA
#ifndef UNICODE
    #define  UNICODE
#endif
#ifndef _UNICODE
    #define  _UNICODE
#endif
#define MyDebug
#include <windows.h>
#include <ocidl.h>
#include <cstdio>
#include "Main.h"
#include "IWebBrowser.h"
#include "IWebBrowserEvents.h"

#ifdef MyDebug
   FILE* fp  = NULL;
#endif

EXTERN_C HRESULT __stdcall AtlAxWinInit();
EXTERN_C HRESULT __stdcall AtlAxGetControl(HWND hWnd, IUnknown** pp);
EXTERN_C HRESULT __stdcall AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer);

const IID LIBID_WebBrowser              = {0xEAB22AC0,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
const IID IID_IWebBrowser               = {0xEAB22AC1,0x30C1,0x11CF,{0xA7,0xEB,0x00,0x00,0xC0,0x5B,0xAE,0x0B}};
const IID IID_IWebBrowserEvents         = {0x34A715A0,0x6587,0x11D0,{0x92,0x4A,0x00,0x20,0xAF,0xC7,0xAC,0x4D}};
const IID IID_IConnectionPointContainer = {0xB196B284,0xBAB4,0x101A,{0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07}};


long fnWndProc_OnCreate(lpWndEventArgs Wea)                      // What's Stored In NDCLASSEX::cbWndExtra Bytes (x64)
{                                                                //
 IConnectionPointContainer* pConnectionPointContainer = NULL;    // Offset   Bytes    What's Stored There
 IConnectionPoint*          pConnectionPoint          = NULL;    // ==================================================
 IUnknown*                  ppUnkContainer            = NULL;    //0        0  -  7  ppUnkContainer
 IWebBrowser*               pWebBrowser               = NULL;    //1        8  - 15  pUnkIExplorer
 IUnknown*                  pUnkIExplorer             = NULL;    //2        16 - 23  pWebBrowser
 CEventSink*                pEventSink                = NULL;    //3        24 - 31  pConnectionPoint
 HWND                       hContainer;                          //4        32 - 39  dwCookie
 DWORD                      dwCookie;
 BSTR                       strProgId;
 HRESULT                    hr;

 #ifdef MyDebug
    fprintf(fp,"  Entering fnWndProc_OnCreate()\n");
 #endif
 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
 hContainer=CreateWindow((wchar_t*)L"static",(wchar_t*)L"",WS_CHILD|WS_VISIBLE,0,35,1180,750,Wea->hWnd,(HMENU)ID_CONTAINER,Wea->hIns,0);
 #ifdef MyDebug
    fprintf(fp,"    Wea->hIns                 = 0x%p\n",Wea->hIns);
    fprintf(fp,"    Wea->hWnd                 = 0x%p\n",Wea->hWnd);
    fprintf(fp,"    hContainer                = 0x%p\n",hContainer);
    fprintf(fp,"    S_OK                      = %ld\n",S_OK);
 #endif
 hr=AtlAxWinInit();
 #ifdef MyDebug
    fprintf(fp,"    hr(AtlAxWinInit)          = %ld\n",hr);
 #endif
 if(SUCCEEDED(hr))
 {
    #ifdef MyDebug
       fprintf(fp,"    AtlAxWinInit() Succeeded!\n");
    #endif
    strProgId=SysAllocString((wchar_t*)L"Shell.Explorer");
    hr=AtlAxCreateControl(strProgId,hContainer,NULL,&ppUnkContainer);
    SysFreeString(strProgId);
    if(SUCCEEDED(hr))
    {
       #ifdef MyDebug
          fprintf(fp,"    hr(AtlAxCreateControl)    = %ld\n",hr);
          fprintf(fp,"    ppUnkContainer            = 0x%p\n",ppUnkContainer);
       #endif
       SetWindowLongPtr(Wea->hWnd,0,(LONG_PTR)ppUnkContainer);
       hr=AtlAxGetControl(hContainer,&pUnkIExplorer);
       if(SUCCEEDED(hr))
       {
          #ifdef MyDebug
             fprintf(fp,"    hr(AtlAxGetControl)       = %ld\n",hr);
          #endif
          SetWindowLongPtr(Wea->hWnd,1*sizeof(void*),(LONG_PTR)pUnkIExplorer);
          #ifdef MyDebug
             fprintf(fp,"    pUnkIExplorer             = 0x%p\n",pUnkIExplorer);
          #endif
          hr=pUnkIExplorer->QueryInterface(IID_IWebBrowser,(void**)&pWebBrowser);
          #ifdef MyDebug
             fprintf(fp,"    pWebBrowser               = 0x%p\n",pWebBrowser);
          #endif
          if(SUCCEEDED(hr))
             SetWindowLongPtr(Wea->hWnd,2*sizeof(void*),(LONG_PTR)pWebBrowser);
          else
             return -1;
          hr=pUnkIExplorer->QueryInterface(IID_IConnectionPointContainer,(void**)&pConnectionPointContainer);
          if(SUCCEEDED(hr))
          {
             #ifdef MyDebug
                fprintf(fp,"    pConnectionPointContainer = 0x%p\n",pConnectionPointContainer);
             #endif
             hr=pConnectionPointContainer->FindConnectionPoint(IID_IWebBrowserEvents,&pConnectionPoint);
             if(SUCCEEDED(hr))
             {
                #ifdef MyDebug
                   fprintf(fp,"    pConnectionPoint          = 0x%p\n",pConnectionPoint);
                #endif
                pConnectionPointContainer->Release();
                pConnectionPointContainer=NULL;
                SetWindowLongPtr(Wea->hWnd,3*sizeof(void*),(LONG_PTR)pConnectionPoint);
                pEventSink=new CEventSink;
                #ifdef MyDebug
                fprintf(fp,"    pEventSink                = 0x%p\n",pEventSink);
                #endif
                if(pEventSink)
                {
                   pEventSink->StoreGridPointer(pWebBrowser);
                   hr=pConnectionPoint->Advise((IUnknown*)pEventSink, &dwCookie);
                   if(SUCCEEDED(hr))
                      SetWindowLongPtr(Wea->hWnd,4*sizeof(void*),(LONG_PTR)dwCookie);
                   else
                      return -1;
                }
                else
                   return -1;
             }
             else
                return -1;
          }
          else
            return -1;
          CreateWindowEx(WS_EX_CLIENTEDGE,(wchar_t*)L"edit",(wchar_t*)L"www.cplusplus.com",WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL,5,5,1000,25,Wea->hWnd,(HMENU)ID_URL,Wea->hIns,0);
          CreateWindow((wchar_t*)L"button",(wchar_t*)L"Navigate",WS_CHILD|WS_VISIBLE,1050,5,80,25,Wea->hWnd,(HMENU)BTN_NAVIGATE,Wea->hIns,0);
       }
       else
          return -1;
    }
    else
       return -1;
 }
 else
    return -1;
 #ifdef MyDebug
 fprintf(fp,"  Leaving fnWndProc_OnCreate()\n\n");
 #endif

 return 0;
}


long fnWndProc_OnCommand(lpWndEventArgs Wea)
{
 if(LOWORD(Wea->wParam)==BTN_NAVIGATE)
 {
    #ifdef MyDebug
    fprintf(fp,"  Entering fnWndProc_OnCommand : Case BTN_NAVIGATE\n");
    #endif
    wchar_t szBuffer[256];
    HWND hEdit=GetDlgItem(Wea->hWnd,ID_URL);
    GetWindowText(hEdit,szBuffer,256);
    IWebBrowser* pWebBrowser=NULL;
    pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
    BSTR strUrl;
    strUrl=SysAllocString(szBuffer);
    if(pWebBrowser)
       pWebBrowser->Navigate(strUrl,NULL,NULL,NULL,NULL);
    SysFreeString(strUrl);
    #ifdef MyDebug
    fprintf(fp,"    pWebBrowser = 0x%p\n",pWebBrowser);
    fprintf(fp,"  Leaving fnWndProc_OnCommand : Case BTN_NAVIGATE\n\n");
    #endif
 }

 return 0;
}
2nd part...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
long fnWndProc_OnDestroy(lpWndEventArgs Wea)
{
 IConnectionPoint* pConnectionPoint = NULL;
 IUnknown*         ppUnkContainer   = NULL;
 IWebBrowser*      pWebBrowser      = NULL;
 IUnknown*         pUnkIExplorer    = NULL;
 DWORD             dwCookie         = 0;

 #ifdef MyDebug
 fprintf(fp,"  Entering fnWndProc_OnDestroy()\n");
 #endif
 pConnectionPoint=(IConnectionPoint*)GetWindowLongPtr(Wea->hWnd,3*sizeof(void*));
 dwCookie=(DWORD)GetWindowLongPtr(Wea->hWnd,4*sizeof(void*));
 if(pConnectionPoint)
 {
    #ifdef MyDebug
    fprintf(fp,"    pConnectionPoint = 0x%p\n",pConnectionPoint);
    fprintf(fp,"    dwCookie         = %lu\n",dwCookie);
    #endif
    pConnectionPoint->Unadvise(dwCookie);
    pConnectionPoint->Release();
 }
 pWebBrowser=(IWebBrowser*)GetWindowLongPtr(Wea->hWnd,2*sizeof(void*));
 #ifdef MyDebug
 fprintf(fp,"    pWebBrowser      = 0x%p\n",pWebBrowser);
 #endif
 if(pWebBrowser)
    pWebBrowser->Release();
 pUnkIExplorer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,1*sizeof(void*));
 if(pUnkIExplorer)
    pUnkIExplorer->Release();
 ppUnkContainer=(IUnknown*)GetWindowLongPtr(Wea->hWnd,0);
 if(ppUnkContainer)
    ppUnkContainer->Release();
 PostQuitMessage(0);
 #ifdef MyDebug
 fprintf(fp,"  Entering fnWndProc_OnDestroy()\n");
 #endif

 return 0;
}


LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{

 WndEventArgs Wea;

 for(unsigned int i=0; i<dim(EventHandler); i++)
 {
     if(EventHandler[i].iMsg==msg)
     {
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 wchar_t szClassName[]=L"WebBrowser";
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 #ifdef MyDebug
 fp=fopen("Output.txt","w");
 fprintf(fp,"Entering WinMain()\n");
 #endif
 CoInitialize(NULL);
 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=0;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=5*sizeof(void*);
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,100,15,1200,830,HWND_DESKTOP,0,hIns,0);
 #ifdef MyDebug
 fprintf(fp,"  hWnd = 0x%p\n\n",hWnd);
 #endif
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }
 CoUninitialize();
 #ifdef MyDebug
 fprintf(fp,"Leaving WinMain()\n");
 fclose(fp);
 #endif

 return messages.wParam;
}

Pages: 123