📄 webctrl.c
字号:
#define WEBPAGE_SEARCH 3
#define WEBPAGE_REFRESH 4
#define WEBPAGE_STOP 5
void DoPageAction(HWND hwnd, DWORD action)
{
IWebBrowser2 *webBrowser2;
IOleObject *browserObject;
// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
// we initially attached the browser object to this window.
browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA));
// We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
// object, so we can call some of the functions in the former's table.
if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
{
// Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is
// webBrowser2->lpVtbl.
// Call the desired function
switch (action)
{
case WEBPAGE_GOBACK:
{
// Call the IWebBrowser2 object's GoBack function.
webBrowser2->lpVtbl->GoBack(webBrowser2);
break;
}
case WEBPAGE_GOFORWARD:
{
// Call the IWebBrowser2 object's GoForward function.
webBrowser2->lpVtbl->GoForward(webBrowser2);
break;
}
case WEBPAGE_GOHOME:
{
// Call the IWebBrowser2 object's GoHome function.
webBrowser2->lpVtbl->GoHome(webBrowser2);
break;
}
case WEBPAGE_SEARCH:
{
// Call the IWebBrowser2 object's GoSearch function.
webBrowser2->lpVtbl->GoSearch(webBrowser2);
break;
}
case WEBPAGE_REFRESH:
{
// Call the IWebBrowser2 object's Refresh function.
webBrowser2->lpVtbl->Refresh(webBrowser2);
}
case WEBPAGE_STOP:
{
// Call the IWebBrowser2 object's Stop function.
webBrowser2->lpVtbl->Stop(webBrowser2);
}
}
// Release the IWebBrowser2 object.
webBrowser2->lpVtbl->Release(webBrowser2);
}
}
long DisplayHTMLStr(HWND hwnd, LPCTSTR string)
{
IWebBrowser2 *webBrowser2;
LPDISPATCH lpDispatch;
IHTMLDocument2 *htmlDoc2;
IOleObject *browserObject;
SAFEARRAY *sfArray;
VARIANT myURL;
VARIANT *pVar;
BSTR bstr;
// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
// we initially attached the browser object to this window.
browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA));
// Assume an error.
bstr = 0;
// We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
// object, so we can call some of the functions in the former's table.
if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
{
VariantInit(&myURL);
myURL.vt = VT_BSTR;
myURL.bstrVal = SysAllocString(L"about:blank");
// Call the Navigate2() function to actually display the page.
webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0);
// Free any resources (including the BSTR).
VariantClear(&myURL);
// Call the IWebBrowser2 object's get_Document so we can get its DISPATCH object. I don't know why you
// don't get the DISPATCH object via the browser object's QueryInterface(), but you don't.
if (!webBrowser2->lpVtbl->get_Document(webBrowser2, &lpDispatch))
{
// We want to get a pointer to the IHTMLDocument2 object embedded within the DISPATCH
// object, so we can call some of the functions in the former's table.
if (!lpDispatch->lpVtbl->QueryInterface(lpDispatch, &IID_IHTMLDocument2, (void**)&htmlDoc2))
{
if ((sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *)&ArrayBound)))
{
if (!SafeArrayAccessData(sfArray, (void**)&pVar))
{
pVar->vt = VT_BSTR;
#ifndef UNICODE
{
wchar_t *buffer;
DWORD size;
size = MultiByteToWideChar(CP_ACP, 0, string, -1, 0, 0);
if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto bad;
MultiByteToWideChar(CP_ACP, 0, string, -1, buffer, size);
bstr = SysAllocString(buffer);
GlobalFree(buffer);
}
#else
bstr = SysAllocString(string);
#endif
SafeArrayUnaccessData(sfArray);
// Store our BSTR pointer in the VARIENT.
if ((pVar->bstrVal = bstr))
{
// Pass the VARIENT with its BSTR to write() in order to shove our desired HTML string
// into the body of that empty page we created above.
htmlDoc2->lpVtbl->write(htmlDoc2, sfArray);
// Close the document. If we don't do this, subsequent calls to DisplayHTMLStr
// would append to the current contents of the page
htmlDoc2->lpVtbl->close(htmlDoc2);
//webBrowser2->lpVtbl->Navigate2(webBrowser2, pVar, 0, 0, 0, 0);
// Normally, we'd need to free our BSTR, but SafeArrayDestroy() does it for us
// SysFreeString(bstr);
}
}
// Free the array. This also frees the VARIENT that SafeArrayAccessData created for us,
// and even frees the BSTR we allocated with SysAllocString
SafeArrayDestroy(sfArray);
}
// Release the IHTMLDocument2 object.
bad: htmlDoc2->lpVtbl->Release(htmlDoc2);
}
// Release the DISPATCH object.
lpDispatch->lpVtbl->Release(lpDispatch);
}
// Release the IWebBrowser2 object.
webBrowser2->lpVtbl->Release(webBrowser2);
}
// No error?
if (bstr) return(0);
// An error
return(-1);
}
long DisplayHTMLPage(HWND hwnd, LPTSTR webPageName)
{
IWebBrowser2 *webBrowser2;
VARIANT myURL;
IOleObject *browserObject;
// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
// we initially attached the browser object to this window.
browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA));
// We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
// object, so we can call some of the functions in the former's table.
if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
{
VariantInit(&myURL);
myURL.vt = VT_BSTR;
#ifndef UNICODE
{
wchar_t *buffer;
DWORD size;
size = MultiByteToWideChar(CP_ACP, 0, webPageName, -1, 0, 0);
if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto badalloc;
MultiByteToWideChar(CP_ACP, 0, webPageName, -1, buffer, size);
myURL.bstrVal = SysAllocString(buffer);
GlobalFree(buffer);
}
#else
myURL.bstrVal = SysAllocString(webPageName);
#endif
if (!myURL.bstrVal)
{
badalloc: webBrowser2->lpVtbl->Release(webBrowser2);
return(-6);
}
// Call the Navigate2() function to actually display the page.
webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0);
// Free any resources (including the BSTR we allocated above).
VariantClear(&myURL);
// We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it,
// so we can release our hold on it). Note that we'll still maintain our hold on the browser
// object.
webBrowser2->lpVtbl->Release(webBrowser2);
// Success
return(0);
}
return(-5);
}
void ResizeBrowser(HWND hwnd, DWORD width, DWORD height)
{
IWebBrowser2 *webBrowser2;
IOleObject *browserObject;
// Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
// we initially attached the browser object to this window.
browserObject = *((IOleObject **)GetWindowLong(hwnd, GWL_USERDATA));
// We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
// object, so we can call some of the functions in the former's table.
if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
{
// Call are put_Width() and put_Height() to set the new width/height.
webBrowser2->lpVtbl->put_Width(webBrowser2, width);
webBrowser2->lpVtbl->put_Height(webBrowser2, height);
webBrowser2->lpVtbl->Release(webBrowser2);
}
}
long EmbedBrowserObject(HWND hwnd)
{
IOleObject *browserObject;
IWebBrowser2 *webBrowser2;
RECT rect;
char *ptr;
_IOleClientSiteEx *_iOleClientSiteEx;
if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *))))
return(-1);
// Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable.
_iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *));
_iOleClientSiteEx->client.lpVtbl = &MyIOleClientSiteTable;
// Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable.
_iOleClientSiteEx->inplace.inplace.lpVtbl = &MyIOleInPlaceSiteTable;
// Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable.
_iOleClientSiteEx->inplace.frame.frame.lpVtbl = &MyIOleInPlaceFrameTable;
// Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it.
_iOleClientSiteEx->inplace.frame.window = hwnd;
// Initialize our IDocHostUIHandler object with a pointer to our IDocHostUIHandler VTable.
_iOleClientSiteEx->ui.ui.lpVtbl = &MyIDocHostUIHandlerTable;
if (!OleCreate(&CLSID_WebBrowser, &IID_IOleObject, OLERENDER_DRAW, 0, (IOleClientSite *)_iOleClientSiteEx, &MyIStorage, (void**)&browserObject))
{
*((IOleObject **)ptr) = browserObject;
SetWindowLong(hwnd, GWL_USERDATA, (LONG)ptr);
browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0);
GetClientRect(hwnd, &rect);
// Let browser object know that it is embedded in an OLE container.
if (!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) &&
!browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) &&
!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
{
webBrowser2->lpVtbl->put_Left(webBrowser2, 0);
webBrowser2->lpVtbl->put_Top(webBrowser2, 0);
webBrowser2->lpVtbl->put_Width(webBrowser2, rect.right);
webBrowser2->lpVtbl->put_Height(webBrowser2, rect.bottom);
webBrowser2->lpVtbl->Release(webBrowser2);
// Success
return(0);
}
// Something went wrong!
UnEmbedBrowserObject(hwnd);
return(-3);
}
GlobalFree(ptr);
return(-2);
}
/*
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
// Initialize the OLE interface. We do this once-only.
if (OleInitialize(NULL) == S_OK)
{
WNDCLASSEX wc;
// Register the class of our window to host the browser. 'WindowProc' is our message handler
// and 'ClassName' is the class name. You can choose any class name you want.
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = &ClassName[0];
RegisterClassEx(&wc);
// Create a window. NOTE: We embed the browser object duing our WM_CREATE handling for
// this window.
if ((msg.hwnd = CreateWindowEx(0, &ClassName[0], "An HTML string", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
HWND_DESKTOP, NULL, hInstance, 0)))
{
// For this window, display a string in the BODY of a web page.
DisplayHTMLStr(msg.hwnd, "<H2><CENTER>HTML string test</CENTER></H2><P><FONT COLOR=RED>This is a <U>HTML string</U> in memory.</FONT>");
// Show the window.
ShowWindow(msg.hwnd, nCmdShow);
UpdateWindow(msg.hwnd);
}
// Create another window with another browser object embedded in it.
if ((msg.hwnd = CreateWindowEx(0, &ClassName[0], "Microsoft's web site", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
HWND_DESKTOP, NULL, hInstance, 0)))
{
// For this window, display a URL. This could also be a HTML file on disk such as "c:\\myfile.htm".
DisplayHTMLPage(msg.hwnd, "http://www.microsoft.com");
// Show the window.
ShowWindow(msg.hwnd, nCmdShow);
UpdateWindow(msg.hwnd);
}
// Do a message loop until WM_QUIT.
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Free the OLE library.
OleUninitialize();
return(0);
}
MessageBox(0, "Can't open OLE!", "ERROR", MB_OK);
return(-1);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -