How to join a web browser in SDK (some original part translation)

zhaozj2021-02-16  80

Because of the work relationship, it is necessary to embed a web browser under SDK, but the program is developed by SDK, there are many articles on the Internet, but it is designed to design MFC, and later get two implementation methods under the help of netizens.

1. Yes based on ATL:

#include ccommodule _Module; #include

#pragma

Comment (Lib, "ATL")

int

WinApi WinMain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR LPCMDLINE,

int

nshowcmd)

...

{Msg msg; // Initialization COM and ATL Coinitialize (NULL); atlaxwininit (); hwnd hwnd = created, 0, maindlgproc); if (! Hwnd) ... {MessageBox (Null, Text) ... {MessageBox ("Fail to create the dialog!"), "Test", mb_iconerror); return 0;} showwindow; while (getMessage (& MSG, NULL, 0, 0)) ... {if (hwnd = = 0 ||! IsdialogMessage (HWND, & MSG)) ... {TranslateMessage (& MSG); DispatchMessage (& MSG);}} couninitialize (); return msg.wpaham;}

Bool Callback MAINDLGPROC (HWND HDLG, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)

...

{Rect rc; iWebBrowser2 * WebBrowser; Variant varmyurl; static caxwindow wincontainer; // This is the COM container Switch (Message) provided by ATL ... {Case WM_INITDIALOG: rc.top = 8; rc.beft = 8; rc.bottom = 250; rc.right = 180; WinContainer.Create (hDlg, rc, LPCTSTR ( "Microsoft.IExplorer.4"), WS_CHILD | WS_VISIBLE | WS_VSCROLL); // create a browser control WinContainer.QueryControl (__uuidof (IWebBrowser2), (void **) & webbrowser; variantinit (& varmyurl); var aturl.vt = vt_bs; #ifndef unicode ... {wchar_t * buffer; dword size; size = multibytetowidechar (cp_acp, 0, "www.xxx.com", - 1, 0, 0); IF (! (Buffer = (wchar_t *) Globalalloc (gmem_fixed, sizeof (wchar_t) * size)) Return False; multibytetowidechar (CP_ACP, 0, "www.xxx.com", -1, buffer, size); varMyURL.bstrVal = SysAllocString (buffer); GlobalFree (buffer);} #else varMyURL.bstrVal = SysAllocString ( "www.xxx.com"); # endif WebBrowser-> Navigate2 (& varMyURL, 0, 0, 0, 0); VariantClear (& VarmyURL); WebBrowser-> Release (); B Reak;} // end switch (message) returnaf;} 2. Below is a translation of an English article, where is http://www.codeguru.com/cpp/in/ieprogram/Article.php/c4379/ How to The following pure Win32 C to display a web page author: Jeff Glatt time: December 12, 2002 environment: Win32, VC6 (recommended but not required), IE 4.0 (or some other support OLE automation online editing

Other browsers). Introduction: There are many articles on the Internet to introduce how to embed an IE browser in their own programs. But examples of these articles are generally based on MFC, .NET, C # or at least WTL, because these frameworks themselves make a lot of work makes it easy to embed a browser. But if you only use pure C and Win32 (or even C ), then these examples don't use it. This article is to teach you how to embed a browser under pure C and Win32 environments, more generally, teach you how to interact with Ole / COM object below pure C and Win32 environments and create your own OLE / COM Object. I even gave a DLL that I have compiled, as long as you are willing to deal with any Ole / COM, you just need to call its extraction function, you can display a web page unless you want to modify the source code. Using Static, Edit, ListBox, ComboBox, etc. Windows standard control, you can get the handle of these controls, such as HWnd, can control them via SendMessage, and you can control them, and you want to pass some information or some data It will also give you a message (they will put the message in the window of the window, you can get these messages via getMessage). But for the OLE / COM object is not the case. You and there are no news exchanges between them. OLE / COM object gives you some function pointers, you can control these objects through these function pointers. For example, IWebBrowser2 object gives a function pointer to make you read and display a page in your program. In turn, if the OLE / COM object wants to give you some data or notifications, you need to write some functions and provide these function pointers to the OLE / COM object, so that OLE / COM object can complete data transfer by calling these functions or Event notification. In other words, you customize an OLE / COM object in your own program. Therefore, the most troublesome in pure C is how to make the embedded OLE / COM object fully interact with your program. In general, you call the functions in the OLE / COM object, the OLE / COM object calls you the function you provide in your program. It is like calling the DLL export function, but this DLL can also call a function of the rule in your C program (a bit similar to the callback function). However, the DLL is different, you don't need to use loadLibrary () and getProcAddress () to get a function of a COM object, but through the system function to get a pointer of an object, then through this object to get its function pointer . OLE / COM objects and its VTable simple, a COM object is indeed a C structure that contains some function pointers that can be called by external calls. These pointers must be the first member variable of the structure, which can be some other data, but the function pointer must be the first member variable. This must pay attention (because we will create your own OLE / COM object in our C program, so you have to know how to declare and create a COM "structure"). In fact, this first member variable is a pointer to another structure, and the function pointer is actually stored in this structure. In essence, this secondary structure is actually an array stored in these different function pointers. We call this array as VTable. In addition, the top three function pointers in vtable must be these three specific function pointers: queryinterface (), addRef (), and release () (when you create your own object, what you can start, as long as you This function is in line with the rules mentioned later). Here is the definition of these three functions:

HRESULT STDMETHODCALLTYPE QUERYINTERFACE (IUNKNOWN FAR *

This, Refiid Riid, LPvoid ​​Far

*

PPVOBJ); HRESULT STDMETHODCALLTYPE ADDREF (IUNKNOWN FAR

*

THIS); HRESULT STDMETHODCALLTYPE RELEASE (IUNKNOWN FAR

*

THIS);

Let's take a look at what these parameters and HRESULT do mean. The first member variable of the OLE / COM object must be pointed to the vTable, at least queryinterface (), addRef (), addRef (), and Release () interface in vtable () three functions pointers (they are related to the IUnknown interface), and the three You must define the same as the prototype given above. Here I have the easiest example of the OLE / COM object I called "MyObject", I first defined a VTable structure called "MyObject_vtbl" and then define "MyObject" objects.

/ ** /

/ * This is the vtable for myObject. It must start out with at * least the folload three point point point

Struct

MyObject_vtbl

...

{(HRESULT STDMETHODCALLTYPE *) QueryInterface (IUnknown FAR * This, REFIID riid, LPVOID FAR * ppvObj); (HRESULT STDMETHODCALLTYPE *) AddRef (IUnknown FAR * This); (HRESULT STDMETHODCALLTYPE *) Release (IUnknown FAR * This); / * * // * There Would Be Other Pointers Here if this Object Had More * functions. * /}

/ ** /

/ * This is the myObject structure * /

Struct

MyObject

...

{/ ** // * The first thing in the object must be a pointer * to its VTable * / struct MYOBJECT_VTBL * lpVtbl;! / ** // * The Object may have other embedded objects here, or some * private data. * But all this must be after the Above vTable Pointer. * /}

As can be seen from the example, a COM object is always pointing to its vTable pointer, and the first three pointers of VTABLE are generally named QueryInterface, addRef, and Release, which function pointers depend on this object. For example, a browser object's function pointer absolutely and some of the function pointers of the object of playing music, but all the first member variables of all OLE / COM objects always point to its vTable pointer, and the top three of Vtable The pointer is always queryinterface, addref, and relayse, which is rule, you can only follow. When you create your own COM object, you have to implement these three "iUnknown" functions in your function. For example, you may have a named myqueryinterface (), myaddref (), and myrelease () as follows: HRESULT stdmethodcalltype myqueryinterface (IUNKNOWN FAR)

*

This, Refiid Riid, LPvoid ​​Far

*

PPVOBJ)

...

{RETURN (S_OK);

HRESULT stdmethodcalltype myaddref (iunknown far

*

This)

...

{RETURN (S_OK);

HRESULT stdmethodcalltype myrelease (IUNKNOWN FAR

*

This)

...

{RETURN (S_OK);

At the same time, you have to initialize your COM object with these three function pointers. Here is an example in which Vtabel named "MyObject" COM object is initialized with the MyObject_vtbl structure named "exampletable":

int

Main ()

...

{Struct MYOBJECT Example; struct MYOBJECT_VTBL ExampleTable; ExampleTable.QueryInterface = MyQueryInterface; ExampleTable.AddRef = MyAddRef; ExampleTable.Release = MyRelease; Example.lpVtbl = & ExampleTable;}

Now we have created a VTabel's correctly initialized OLE / COM object (which is an example in the example). Now we have to pass the pointer of this structure to the related system function, so other objects (such as browser objects) ) You can call myQueryInterface (), myaddref (), and myrelease () functions in our C-compiled executable, and sound is not bad?

QueryInterface (), addRef (), and release () We need to know in addition to the above. Let's take a look at the definition of these three functions, you will find that the first parameters of these three functions are pointers of the iUnknown structure. Here we need to modify these definitions according to our MyObject objects:

HRESULT stdmethodCallType QueryInterface (MyObject Far

*

This, Refiid Riid, LPvoid ​​Far

*

PPVOBJ); HRESULT STDMETHODCALLTYPE ADDREF (MyObject Far

*

THIS); HRESULT STDMETHODCALLTYPE RELEASE (MyObject Far

*

THIS);

Our MyObject_vtbl should be like this: Struct

MyObject_vtbl

...

{(HRESULT STDMETHODCALLTYPE * QueryInterface) (MYOBJECT FAR * This, REFIID riid, LPVOID FAR * ppvObj); (HRESULT STDMETHODCALLTYPE *) AddRef (MYOBJECT FAR * This); (HRESULT STDMETHODCALLTYPE *) Release (MYOBJECT FAR * This);}

You may have questions "Is it that it means that the first parameter of these three functions should be the pointer to the MyObject structure?" It is true, I mean this. For example, when we pass the MyObject object Example to the browser object, and this browser object is to call MyQueryInterface () through Example, so the first parameter is the pointer of the Example. This way we can know which example is called myQueryInterface (). In addition, we can add some member variables of the instance independent behind this structure. This way we don't need to use any global variables, guarantee the reusability of the structure - we can generate an example of any of this structure. You may be called: "Wait! It looks a bit like C . This adult pointer seems to be a 'this' pointer in the object of C ." You are a genius, everything Be said by you. This is the foundation of COM. This way you can use C code to effectively implement C classes without carrying additional burden on C . In summary, (in COM) When your function is called, the first parameter always contains the structure of the VTABLE or the pointer to the object. This is an simulation of C class mechanisms to the simulation of the COM mechanism. After you get a pointer to a COM object, for example, a browser object, you can use the similar way to the object to call the object's member function. You can find the function you want through the object's vTable. When you call these functions, the first parameter is always the pointer of this COM object.

The basic type of COM (BSTR and VARIANT) you might think is a bit complicated. There is also a place where it is difficult to understand. Many OLE / COM objects are independent of language (they can be used in any language). For this COM object, you must try to abstract the data type. What do I mean? Take the ANSI C String, a C's String is a series of 8bit byte strings ending with 0, but String is not like this in Pascal. The start in the pascal has a BYTE stores the number of bytes followed. That is, PASCAL String is starting from a byte representing the length of the length, which is the actual character so that its end is not necessarily 0. So how do unicode saved? Each character of a Unicode is stored in two Bytes (or C). To support all languages ​​and extension types per language, COM objects always use COM basic types that can be used in each language. For example, if a COM wants to pass a String always uses the BSTR type. What is BSTR? It can be considered to be a PASCAL unicode string, each character is saved with two bytes, and starts with a String's start with a non-symbolic short to save the number of SHORTs. This allows the "string" type to apply in all languages. But this also means that when you pass C String to a COM object, you have to turn it into BSTR. Fortunately, the operating system itself provides SysallocString to help complete this conversion. Of course, there are other COM basic types, such as the basic types of values ​​that can be used in some way to use in various languages. Actually some COM objects need to operate a variety of data types, which uses another structure called Variant. For example, we assume that there is a Printer class with a Print () member function. And Print () can accept various data and print. If you pass a string to it, you can print the string, if you pass a DWORD to it, then convert DWORD to String and print this string. So print () needs to know that String or DWORD is delivered. So we can use Variant to package this string (or BSTR) and DWORD and a variety of types. We need to set this Variant's VT member variable according to the type of pass, and BSTR is set to vt_bstr, and DWORD is set to vt_decimal. This print () can determine what operations taken according to the VT member variables of the passed VARIANT. In summary, when you operate a COM object (such as our browser object), you may need to convert / populate the basic type to COM, and may even need to use a Variant type.

Your iStorage / IoleinplaceFrame / IoleClientSite / IoleInPlace Objects Now you already know some COM's background knowledge, let us continue to see what you need to make your browser COM objects. After you read the following article, you will be skilled in using the source code in cwebpage.c. First, you have to provide four objects to your browser object: iStorage, IoleinplaceFrame, IoleClientSite, and IoleinPlaceSite. This is four structures, each has its own vTable, these structures and their vTable is defined in the header file. Each of them has its own series of member functions. Let's take a look at the IStorage object first, it defines the VTable structure called iStorageVTBL. In this vTable, there are 18 function pointers (that is, IStorage itself has 18 specific functions, which is why everyone uses MFC, .NET, WTL to make work easier). Of course, the top three functions must also be queryinterface (), addRef (), and relation (). In CWEBPage.C, I named these three functions to Storage_Queryinterface (), Storage_Addref (), and Storage_Release (), after 15 equations, I started using Storage_OpenStream (), Storage_CopyTo () Wait, the role of iStorage function is to manage procedures and disk read and write, specific functions and parameters can refer to MSDN About ISTORAGE documents. So the easiest way to create iStorage is to declare it as a global variable, and use 18 function pointers to initialize it, my code is as follows: iStorageVTBL MyistOrageTable

=

...

{Storage_QueryInterface, Storage_AddRef, Storage_Release, Storage_CreateStream, Storage_OpenStream, Storage_CreateStorage, Storage_OpenStorage, Storage_CopyTo, Storage_MoveElementTo, Storage_Commit, Storage_Revert, Storage_EnumElements, Storage_DestroyElement, Storage_RenameElement, Storage_SetElementTimes, Storage_SetClass, Storage_SetStateBits, Storage_Stat}

;

Now I have a global initialization of IStorage ---- MyistORAGETABLE. The next step is to create my IStorage object. The easiest way to declare it as a global variable and initialize it, it only has a vTable:

IStorage Myistorage

=

...

{& Myistoragetable}

;

转载请注明原文地址:https://www.9cbs.com/read-14913.html

New Post(0)