Win32HtmlViewRep( Win32HtmlView *view, HWND hw,int style ):hwnd(hw){ owner=view; site.rep=this; eventsink.rep=this; frame.rep=this; viewstyle=style; emitNavEvent=!!(viewstyle & BBHtmlView::NONAVIGATE); currenturl=new BBString(""); eventurl=new BBString(""); OleCreate( CLSID_WebBrowser,IID_IOleObject,OLERENDER_DRAW,0,&site,&storage,(void**)&oleObject ); OleSetContainedObject( oleObject,TRUE); oleObject->SetHostNames(L"Web Host",L"Web View"); oleObject->QueryInterface(IID_IWebBrowser2,(void**)&iBrowser); oleObject->QueryInterface(IID_IOleInPlaceObject,(void**)&inPlaceObject ); oleObject->QueryInterface(IID_IConnectionPointContainer,(void**)&iConnection); iConnection->FindConnectionPoint(DIID_DWebBrowserEvents, &iConnectionPoint); iConnectionPoint->Advise((LPUNKNOWN)&eventsink, &dwCookie); RECT rect; ::GetClientRect( hwnd,&rect ); oleObject->DoVerb(OLEIVERB_SHOW,NULL,&site,-1,hwnd,&rect); go( "about:blank" ); }
Webbrowser::Webbrowser(void): _refNum(0), //_rcWebWnd(0), _bInPlaced(false), _bExternalPlace(false), _bCalledCanInPlace(false), _bWebWndInited(false), _pOleObj(NULL), _pInPlaceObj(NULL), _pStorage(NULL), _pWB2(NULL), _pHtmlDoc2(NULL), _pHtmlDoc3(NULL), _pHtmlWnd2(NULL), _pHtmlEvent(NULL) { ::memset( (PVOID)&_rcWebWnd,0,sizeof(_rcWebWnd)); HRTEST_SE( OleInitialize(0),L"Failed in Initialize Ole"); HRTEST_SE( StgCreateDocfile(0,STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE,0,&_pStorage),L"ERROR:StgCreateDocfile"); HRTEST_SE( OleCreate(CLSID_WebBrowser,IID_IOleObject,OLERENDER_DRAW,0,this,_pStorage,(void**)&_pOleObj),L"Create Ole Failed"); HRTEST_SE( _pOleObj->QueryInterface(IID_IOleInPlaceObject,(LPVOID*)&_pInPlaceObj),L"Create OleInPlaceObject Failed"); GetWebBrowser2(); OleUninitialize(); RETURN: return; }
// create a new paint brush void TOleDocWindow::CMPBrush( RTMessage ) { BackupObject(); bObjectLoaded = FALSE; lstrcpy( lpszObjectName, GetNextObjectName() ); ret = OleCreate( "StdFileEditing", (LPOLECLIENT)pOwlClient, "PBRUSH", lhClientDoc, GetApplication()->Name, &lpObject, olerender_draw, 0 ); // Creating an Ole Object is a asynchronous operation. An // interesting experiment is to use TDW to step into // WaitOleNotBusy (which the following wait macro takes you // to) and look at the user screen between message // dispatching. You should see pbrush gradually paint // itself as it processes the messages which which Ole // generates for it. In general, if a Ole Server does not // behave properly when creating an object, a likely cause is a // problem with the message dispatch loop. wait( ret , lpObject ); // OleSetHostNames sets the name in the server app. If this // was not called, pbrush would display a string with a bunch // of % sings in it. ret = OleSetHostNames( lpObject, GetApplication()->Name, lpszObjectName ); wait( ret , lpObject ); }
BOOL EmbedBrowserObject(PWBOBJ pwbo) { HWND hwnd; IOleObject *browserObject; IWebBrowser2 *webBrowser2; RECT rect; char *ptr; _IOleClientSiteEx *_iOleClientSiteEx; if(!pwbo) return FALSE; hwnd = pwbo->hwnd; if(!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *)))) return FALSE; _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *)); _iOleClientSiteEx->client.lpVtbl = &MyIOleClientSiteTable; _iOleClientSiteEx->inplace.inplace.lpVtbl = &MyIOleInPlaceSiteTable; _iOleClientSiteEx->inplace.frame.frame.lpVtbl = &MyIOleInPlaceFrameTable; _iOleClientSiteEx->inplace.frame.window = hwnd; _iOleClientSiteEx->ui.ui.lpVtbl = &MyIDocHostUIHandlerTable; if(!OleCreate((REFCLSID)&CLSID_WebBrowser, (IID *)&IID_IOleObject, OLERENDER_DRAW, 0, (IOleClientSite *)_iOleClientSiteEx, &MyIStorage, (void**)&browserObject)) { *((IOleObject **)ptr) = browserObject; // The original code uses SetWindowLong/GetWindowLong with GWL_USERDATA to store the // browser object pointer. we use pwbo->lparams[0] because the former is already used // to store the WinBinder object. pwbo->lparams[0] = (LONG)ptr; // SetWindowLong(hwnd, GWL_USERDATA, (LONG)ptr); browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0); GetClientRect(hwnd, &rect); if(!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) && !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) && !browserObject->lpVtbl->QueryInterface(browserObject, (IID *)&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); return TRUE; } UnEmbedBrowserObject(hwnd); return FALSE; } GlobalFree(ptr); return FALSE; }
bool ActiveXControlComponent::createControl (const void* controlIID) { deleteControl(); if (ComponentPeer* const peer = getPeer()) { const Rectangle<int> bounds (peer->getAreaCoveredBy (*this)); HWND hwnd = (HWND) peer->getNativeHandle(); ScopedPointer<Pimpl> newControl (new Pimpl (hwnd, *this)); HRESULT hr; if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, newControl->clientSite, newControl->storage, (void**) &(newControl->control))) == S_OK) { newControl->control->SetHostNames (L"JUCE", 0); if (OleSetContainedObject (newControl->control, TRUE) == S_OK) { RECT rect; rect.left = bounds.getX(); rect.top = bounds.getY(); rect.right = bounds.getRight(); rect.bottom = bounds.getBottom(); if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) { control = newControl; control->controlHWND = ActiveXHelpers::getHWND (this); if (control->controlHWND != 0) { control->setControlBounds (bounds); control->originalWndProc = (WNDPROC) GetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC); SetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC, (LONG_PTR) Pimpl::activeXHookWndProc); } return true; } } } } else { // the component must have already been added to a real window when you call this! jassertfalse; } return false; }
bool ActiveXControlComponent::createControl (const void* controlIID) { deleteControl(); ComponentPeer* const peer = getPeer(); // the component must have already been added to a real window when you call this! jassert (dynamic_cast <Win32ComponentPeer*> (peer) != nullptr); if (dynamic_cast <Win32ComponentPeer*> (peer) != nullptr) { const Point<int> pos (getTopLevelComponent()->getLocalPoint (this, Point<int>())); HWND hwnd = (HWND) peer->getNativeHandle(); ScopedPointer<Pimpl> newControl (new Pimpl (hwnd, *this)); HRESULT hr; if ((hr = OleCreate (*(const IID*) controlIID, IID_IOleObject, 1 /*OLERENDER_DRAW*/, 0, newControl->clientSite, newControl->storage, (void**) &(newControl->control))) == S_OK) { newControl->control->SetHostNames (L"Juce", 0); if (OleSetContainedObject (newControl->control, TRUE) == S_OK) { RECT rect; rect.left = pos.getX(); rect.top = pos.getY(); rect.right = pos.getX() + getWidth(); rect.bottom = pos.getY() + getHeight(); if (newControl->control->DoVerb (OLEIVERB_SHOW, 0, newControl->clientSite, 0, hwnd, &rect) == S_OK) { control = newControl; setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); control->controlHWND = ActiveXHelpers::getHWND (this); if (control->controlHWND != 0) { originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC); SetWindowLongPtr ((HWND) control->controlHWND, GWLP_WNDPROC, (LONG_PTR) Pimpl::activeXHookWndProc); } return true; } } } } return false; }
BOOL InitWebBrowser(HHInfo *info, HWND hwndParent) { WebBrowserContainer *container; IOleInPlaceObject *inplace; HRESULT hr; RECT rc; container = heap_alloc_zero(sizeof(*container)); if (!container) return FALSE; container->IOleClientSite_iface.lpVtbl = &OleClientSiteVtbl; container->IOleInPlaceSite_iface.lpVtbl = &OleInPlaceSiteVtbl; container->IOleInPlaceFrame_iface.lpVtbl = &OleInPlaceFrameVtbl; container->IDocHostUIHandler_iface.lpVtbl = &DocHostUIHandlerVtbl; container->ref = 1; container->hwndWindow = hwndParent; info->web_browser = container; hr = OleCreate(&CLSID_WebBrowser, &IID_IOleObject, OLERENDER_DRAW, 0, &container->IOleClientSite_iface, &MyIStorage, (void **)&container->ole_obj); if (FAILED(hr)) goto error; GetClientRect(hwndParent, &rc); hr = OleSetContainedObject((struct IUnknown *)container->ole_obj, TRUE); if (FAILED(hr)) goto error; hr = IOleObject_DoVerb(container->ole_obj, OLEIVERB_SHOW, NULL, &container->IOleClientSite_iface, -1, hwndParent, &rc); if (FAILED(hr)) goto error; hr = IOleObject_QueryInterface(container->ole_obj, &IID_IOleInPlaceObject, (void**)&inplace); if (FAILED(hr)) goto error; IOleInPlaceObject_SetObjectRects(inplace, &rc, &rc); IOleInPlaceObject_Release(inplace); hr = IOleObject_QueryInterface(container->ole_obj, &IID_IWebBrowser2, (void **)&container->web_browser); if (SUCCEEDED(hr)) return TRUE; error: ReleaseWebBrowser(info); return FALSE; }
//创建函数 OLECONTAINER_FUNCTION(BOOL)::Create(GUID clsid, DWORD dwExStyle, DWORD dwStyle, HWND hWndParent, HINSTANCE hInstance) { m_bTransparent=dwExStyle&WS_EX_LAYERED; //变量定义 WNDCLASSEX WndClassEx; ZeroMemory(&WndClassEx,sizeof(WndClassEx)); //设置变量 WndClassEx.cbSize=sizeof(WNDCLASSEX); WndClassEx.hInstance=hInstance; WndClassEx.lpszClassName=WND_FLASH_CLASS; WndClassEx.lpfnWndProc=COleContainerWnd<TControl>::WndProcStatic; //注册窗口 RegisterClassEx(&WndClassEx); CRect rcRect; if (dwStyle&WS_CHILD) ::GetClientRect(hWndParent, &rcRect); else ::GetWindowRect(hWndParent, &rcRect); m_hWnd=CreateWindowEx(dwExStyle,WND_FLASH_CLASS,NULL,dwStyle,rcRect.left,rcRect.top,rcRect.Width(),rcRect.Height(),hWndParent,NULL,hInstance,(VOID *)this); ::SetWindowPos(m_hWnd,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE); HRESULT hResult; hResult=OleCreate(clsid, IID_IOleObject, OLERENDER_DRAW,0,(IOleClientSite *)this,(IStorage *)this,(VOID **)&m_pIOleObject); if (FAILED(hResult)) { static bool bShow=true; if (hResult==REGDB_E_CLASSNOTREG && bShow) { bShow=false; //提示消息 CInformation Information; if (IDOK==Information.ShowMessageBox(TEXT("系统提示"),TEXT("您的FLASH播放器版本过低,为了正常使用功能,请您下载最新的Flash插件。点击确定最新的Flash插件 "),MB_OKCANCEL,30)) { //打开页面 ShellExecute(NULL,TEXT("OPEN"),TEXT("http://www.adobe.com/go/getflashplayer"),NULL,NULL,SW_NORMAL); } OnErrorClassNotReg(); } return FALSE; } if (FAILED(OleSetContainedObject(m_pIOleObject, TRUE))) return FALSE; if (FAILED(m_pIOleObject->QueryInterface(__uuidof(TControl), (VOID **)&m_pIControl))) return FALSE; if (FAILED(m_pIOleObject->QueryInterface(IID_IViewObjectEx, (VOID **)&m_pIViewObjectEx))) { m_pIViewObjectEx=NULL; if (FAILED(m_pIOleObject->QueryInterface(IID_IViewObject, (VOID **)&m_pIViewObject))) return FALSE; } if (m_bTransparent) { if (FAILED(m_pIOleObject->QueryInterface(IID_IOleInPlaceObjectWindowless, (VOID **)&m_pIOleInPlaceObjectWindowless))) { if (FAILED(m_pIOleObject->QueryInterface(IID_IOleInPlaceObject, (VOID **)&m_pIOleInPlaceObject))) return FALSE; m_bTransparent=FALSE; } } else { if (FAILED(m_pIOleObject->QueryInterface(IID_IOleInPlaceObject, (VOID **)&m_pIOleInPlaceObject))) return FALSE; } if (!OnBeforeShowingContent()) return FALSE; if (FAILED(m_pIOleObject->DoVerb(OLEIVERB_SHOW, NULL, (IOleClientSite *)this, 0, NULL, NULL))) return FALSE; if (!OnAfterShowingContent()) return FALSE; INT nScreenW=GetSystemMetrics(SM_CXSCREEN); INT nScreenH=GetSystemMetrics(SM_CYSCREEN); ::SetWindowPos(m_hWnd,HWND_TOPMOST,(nScreenW-rcRect.Width())/2, (nScreenH-rcRect.Height())/2, 0, 0, SWP_NOSIZE); return TRUE; }
OLECONTAINER(BOOL)::Create(GUID clsid, DWORD dwExStyle, DWORD dwStyle, HWND hWndParent, HINSTANCE hInst) { m_hWndParent = hWndParent; m_hInst = hInst; m_CLSID = clsid; m_bTransparent = (dwExStyle & WS_EX_LAYERED) ? TRUE : FALSE; m_bChild = (dwStyle & WS_CHILD) ? TRUE : FALSE; WNDCLASSEX wcs = {0}; wcs.cbSize = sizeof(WNDCLASSEX); wcs.lpfnWndProc = COleContainerWnd<TObj>::WndProcStatic; wcs.hInstance = hInst; wcs.lpszClassName = W2X_FLASH_WND_CLASS; RegisterClassEx(&wcs); RECT rt = {0}; if (NULL != hWndParent) { if (m_bChild) { ::GetClientRect(hWndParent, &rt); } else { ::GetWindowRect(hWndParent, &rt); } } else { rt.right = rt.left + 32; rt.bottom = rt.top + 32; } m_hWnd = CreateWindowEx(dwExStyle, W2X_FLASH_WND_CLASS, m_wnd_name_ptr, dwStyle, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, hWndParent, NULL, hInst, (void *)this); HRESULT hr; hr = OleCreate(m_CLSID, IID_IOleObject, OLERENDER_DRAW, 0, (IOleClientSite *)this, (IStorage *)this, (void **)&m_lpO); if (FAILED(hr)) { if (hr == REGDB_E_CLASSNOTREG) { OnErrorClassNotReg(); } return FALSE; } hr = OleSetContainedObject(m_lpO, TRUE); if (FAILED(hr)) return FALSE; hr = m_lpO->QueryInterface(__uuidof(TObj), (void **)&m_lpControl); if (FAILED(hr)) return FALSE; hr = m_lpO->QueryInterface(IID_IViewObjectEx, (void **)&m_lpViewObjectEx); if (FAILED(hr)) { m_lpViewObjectEx = NULL; hr = m_lpO->QueryInterface(IID_IViewObject, (void **)&m_lpViewObject); if (FAILED(hr)) return FALSE; } if (m_bTransparent) { hr = m_lpO->QueryInterface(IID_IOleInPlaceObjectWindowless, (void **)&m_lpInPlaceObjWindowless); if (FAILED(hr)) { hr = m_lpO->QueryInterface(IID_IOleInPlaceObject, (void **)&m_lpInPlaceObj); if (FAILED(hr)) return FALSE; m_bTransparent = FALSE; } } else { hr = m_lpO->QueryInterface(IID_IOleInPlaceObject, (void **)&m_lpInPlaceObj); if (FAILED(hr)) return FALSE; } if (!OnBeforeShowingContent()) return FALSE; hr = m_lpO->DoVerb(OLEIVERB_SHOW, NULL, (IOleClientSite *)this, 0, NULL, NULL); if (FAILED(hr)) return FALSE; if (!OnAfterShowingContent()) return FALSE; return TRUE; }
MYEXPORT long MYWINAPI EmbedBrowserObject(HWND hwnd) { IOleObject *browserObject; IWebBrowser2 *webBrowser2; RECT rect; char *ptr; IOleInPlaceFrameEx *iOleInPlaceFrameEx; _IOleClientSiteEx *_iOleClientSiteEx; // Our IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame functions need to get our window handle. We // could store that in some global. But then, that would mean that our functions would work with only that // one window. If we want to create multiple windows, each hosting its own browser object (to display its // own web page), then we need to create a unique IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame // structs for each window. (Actually, the IOleClientSite and IOleInPlaceSite must be allocated as a // single struct, with the IOleClientSite embedded first). And we'll put an extra field at the end of those // structs to store our extra data such as a window handle. Remember that a pointer to our IOleClientSite we // create here will be passed as the first arg to every one of our IOleClientSite functions. Ditto with the // IOleInPlaceFrame object we create here, and the IOleInPlaceFrame functions. So, our functions are able to // retrieve the window handle we'll store here, and then, they'll work with all such windows containing a // browser control. Of course, that means we need to GlobalAlloc the structs now. We'll just get all 3 with // a single call to GlobalAlloc, but you could do them separately if desired. // // Um, we're not actually allocating a IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame structs. Because // we're appending our own fields to them, we're getting an IOleInPlaceFrameEx and an _IOleClientSiteEx (which // contains both the IOleClientSite and IOleInPlaceSite. But as far as the browser is concerned, it thinks that // we're giving it the plain old IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame. // // One final thing. We're going to allocate extra room to store the pointer to the browser object. if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(IOleInPlaceFrameEx) + sizeof(_IOleClientSiteEx) + sizeof(IOleObject *)))) return(-1); // Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable. iOleInPlaceFrameEx = (IOleInPlaceFrameEx *)(ptr + sizeof(IOleObject *)); iOleInPlaceFrameEx->frame.lpVtbl = (IOleInPlaceFrameVtbl *)&MyIOleInPlaceFrameTable; // Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it. iOleInPlaceFrameEx->window = hwnd; // Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable. _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleInPlaceFrameEx) + sizeof(IOleObject *)); _iOleClientSiteEx->client.lpVtbl = (IOleClientSiteVtbl *)&MyIOleClientSiteTable; // Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable. _iOleClientSiteEx->inplace.inplace.lpVtbl = (IOleInPlaceSiteVtbl *)&MyIOleInPlaceSiteTable; // Save a pointer to our IOleInPlaceFrameEx object so that our IOleInPlaceSite functions can retrieve it. _iOleClientSiteEx->inplace.frame = iOleInPlaceFrameEx; // Get a pointer to the browser object and lock it down (so it doesn't "disappear" while we're using // it in this program). We do this by calling the OS function OleCreate(). // // NOTE: We need this pointer to interact with and control the browser. With normal WIN32 controls such as a // Static, Edit, Combobox, etc, you obtain an HWND and send messages to it with SendMessage(). Not so with // the browser object. You need to get a pointer to its "base structure" (as returned by OleCreate()). This // structure contains an array of pointers to functions you can call within the browser object. Actually, the // base structure contains a 'lpVtbl' field that is a pointer to that array. We'll call the array a 'VTable'. // // For example, the browser object happens to have a SetHostNames() function we want to call. So, after we // retrieve the pointer to the browser object (in a local we'll name 'browserObject'), then we can call that // function, and pass it args, as so: // // browserObject->lpVtbl->SetHostNames(browserObject, SomeString, SomeString); // // There's our pointer to the browser object in 'browserObject'. And there's the pointer to the browser object's // VTable in 'browserObject->lpVtbl'. And the pointer to the SetHostNames function happens to be stored in an // field named 'SetHostNames' within the VTable. So we are actually indirectly calling SetHostNames by using // a pointer to it. That's how you use a VTable. // // NOTE: We pass our _IOleClientSiteEx struct and lie -- saying that it's a IOleClientSite. It's ok. A // _IOleClientSiteEx struct starts with an embedded IOleClientSite. So the browser won't care, and we want // this extended struct passed to our IOleClientSite functions. if (!OleCreate(&CLSID_WebBrowser, &IID_IOleObject, OLERENDER_DRAW, 0, (IOleClientSite *)_iOleClientSiteEx, (IStorage *)&MyIStorage, (void**)&browserObject)) { // Ok, we now have the pointer to the browser object in 'browserObject'. Let's save this in the // memory block we allocated above, and then save the pointer to that whole thing in our window's // USERDATA field. That way, if we need multiple windows each hosting its own browser object, we can // call EmbedBrowserObject() for each one, and easily associate the appropriate browser object with // its matching window and its own objects containing per-window data. *((IOleObject **)ptr) = browserObject; SetWindowLong(hwnd, GWLP_USERDATA, (LONG_PTR)ptr); // We can now call the browser object's SetHostNames function. SetHostNames lets the browser object know our // application's name and the name of the document in which we're embedding the browser. (Since we have no // document name, we'll pass a 0 for the latter). When the browser object is opened for editing, it displays // these names in its titlebar. // // We are passing 3 args to SetHostNames. You'll note that the first arg to SetHostNames is the base // address of our browser control. This is something that you always have to remember when working in C // (as opposed to C++). When calling a VTable function, the first arg to that function must always be the // structure which contains the VTable. (In this case, that's the browser control itself). Why? That's // because that function is always assumed to be written in C++. And the first argument to any C++ function // must be its 'this' pointer (ie, the base address of its class, which in this case is our browser object // pointer). In C++, you don't have to pass this first arg, because the C++ compiler is smart enough to // produce an executable that always adds this first arg. In fact, the C++ compiler is smart enough to // know to fetch the function pointer from the VTable, so you don't even need to reference that. In other // words, the C++ equivalent code would be: // // browserObject->SetHostNames(L"My Host Name", 0); // // So, when you're trying to convert C++ code to C, always remember to add this first arg whenever you're // dealing with a VTable (ie, the field is usually named 'lpVtbl') in the standard objects, and also add // the reference to the VTable itself. // // Oh yeah, the L is because we need UNICODE strings. And BTW, the host and document names can be anything // you want. 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) && // Set the display area of our browser control the same as our window's size // and actually put the browser object into our window. !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) && // Ok, now things may seem to get even trickier, One of those function pointers in the browser's VTable is // to the QueryInterface() function. What does this function do? It lets us grab the base address of any // other object that may be embedded within the browser object. And this other object has its own VTable // containing pointers to more functions we can call for that object. // // 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. For example, one IWebBrowser2 function // we intend to call below will be Navigate2(). So we call the browser object's QueryInterface to get our // pointer to the IWebBrowser2 object. !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. // Let's call several functions in the IWebBrowser2 object to position the browser display area // in our window. The functions we call are put_Left(), put_Top(), put_Width(), and put_Height(). // Note that we reference the IWebBrowser2 object's VTable to get pointers to those functions. And // also note that the first arg we pass to each is the pointer to the IWebBrowser2 object. 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); // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it // right now, so we can release our hold on it). Note that we'll still maintain our hold on the // browser object until we're done with that object. webBrowser2->lpVtbl->Release(webBrowser2); // Success return(0); } // Something went wrong! UnEmbedBrowserObject(hwnd); return(-3); } GlobalFree(ptr); return(-2); }
OLECONTAINER(BOOL)::Create(GUID clsid, DWORD dwExStyle, DWORD dwStyle, HWND hWndParent, HINSTANCE hInst) { m_hWndParent = hWndParent; m_hInst = hInst; m_CLSID = clsid; m_bTransparent = dwExStyle & WS_EX_LAYERED; m_bChild = dwStyle & WS_CHILD; WNDCLASSEX wcs = {0}; wcs.cbSize = sizeof(WNDCLASSEX); wcs.lpfnWndProc = COleContainerWnd<TObj>::WndProcStatic; wcs.hInstance = hInst; wcs.lpszClassName = "MyOleControl"; RegisterClassEx(&wcs); RECT r; if (m_bChild) ::GetClientRect(hWndParent, &r); else ::GetWindowRect(hWndParent, &r); m_hWnd = CreateWindowEx(dwExStyle, "MyOleControl", "MyOleControlWindow", dwStyle, r.left, r.top, r.right-r.left, r.bottom-r.top, hWndParent, NULL, hInst, (void *)this); ::SetWindowPos(GetHWND(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); HRESULT hr; hr = OleCreate(m_CLSID, IID_IOleObject, OLERENDER_DRAW, 0, (IOleClientSite *)this, (IStorage *)this, (void **)&m_lpO); if (FAILED(hr)) { if (hr == REGDB_E_CLASSNOTREG) { OnErrorClassNotReg(); } return FALSE; } hr = OleSetContainedObject(m_lpO, TRUE); if (FAILED(hr)) return FALSE; hr = m_lpO->QueryInterface(__uuidof(TObj), (void **)&m_lpControl); if (FAILED(hr)) return FALSE; hr = m_lpO->QueryInterface(IID_IViewObjectEx, (void **)&m_lpViewObjectEx); if (FAILED(hr)) { m_lpViewObjectEx = NULL; hr = m_lpO->QueryInterface(IID_IViewObject, (void **)&m_lpViewObject); if (FAILED(hr)) return FALSE; } if (m_bTransparent) { hr = m_lpO->QueryInterface(IID_IOleInPlaceObjectWindowless, (void **)&m_lpInPlaceObjWindowless); if (FAILED(hr)) { hr = m_lpO->QueryInterface(IID_IOleInPlaceObject, (void **)&m_lpInPlaceObj); if (FAILED(hr)) return FALSE; m_bTransparent = FALSE; } } else { hr = m_lpO->QueryInterface(IID_IOleInPlaceObject, (void **)&m_lpInPlaceObj); if (FAILED(hr)) return FALSE; } if (!OnBeforeShowingContent()) return FALSE; hr = m_lpO->DoVerb(OLEIVERB_UIACTIVATE, NULL, (IOleClientSite *)this, 0, NULL, NULL); //hr = m_lpO->DoVerb(OLEIVERB_UIACTIVATE, NULL, (IOleClientSite *)this, 0, NULL, NULL); if (FAILED(hr)) return FALSE; if (!OnAfterShowingContent()) return FALSE; return TRUE; }
//创建函数 BOOL CFlashActiveX::CreateControl(DWORD dwStyle, CWnd * pParentWnd, CRect rcCreate, HINSTANCE hInstance, IUnknownEx * pIUnknownEx) { //状态效验 ASSERT(m_hWnd==NULL); if (m_hWnd!=NULL) return FALSE; //变量定义 WNDCLASSEX WndClassEx; ZeroMemory(&WndClassEx,sizeof(WndClassEx)); //设置变量 WndClassEx.cbSize=sizeof(WNDCLASSEX); WndClassEx.hInstance=hInstance; WndClassEx.lpszClassName=WND_FLASH_CLASS; WndClassEx.lpfnWndProc=::DefWindowProc; //注册窗口 RegisterClassEx(&WndClassEx); //查询接口 m_pIFlashControlSink=QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx,IFlashControlSink); //创建窗口 m_hWnd=CreateWindowEx(WS_EX_LAYERED,WND_FLASH_CLASS,NULL,dwStyle,rcCreate.left,rcCreate.top,rcCreate.Width(),rcCreate.Height(), pParentWnd->m_hWnd,NULL,hInstance,(VOID *)this); //创建控件 GUID ClsID=ShockwaveFlashObjects::CLSID_ShockwaveFlash; HRESULT hResult=OleCreate(ClsID,IID_IOleObject,OLERENDER_DRAW,0,(IOleClientSite *)this,(IStorage *)this,(VOID **)&m_pIOleObject); //结果判断 if (FAILED(hResult)) { static bool bShow=true; if ((hResult==REGDB_E_CLASSNOTREG)&&(bShow==false)) { bShow=false; //提示消息 CInformation Information; if (IDOK==Information.ShowMessageBox(TEXT("系统提示"),TEXT("您的FLASH播放器版本过低,为了正常使用功能,请您下载最新的Flash插件。点击确定最新的Flash插件 "),MB_OKCANCEL,30)) { //打开页面 ShellExecute(NULL,TEXT("OPEN"),TEXT("http://www.adobe.com/go/getflashplayer"),NULL,NULL,SW_NORMAL); } } return FALSE; } //容器模式 OleSetContainedObject(m_pIOleObject,TRUE); //查询接口 if (FAILED(m_pIOleObject->QueryInterface(__uuidof(IFalshControl),(VOID * *)&m_pIFalshControl))) { ASSERT(FALSE); return FALSE; } //查询接口 if (FAILED(m_pIOleObject->QueryInterface(IID_IViewObjectEx,(VOID * *)&m_pIViewObjectEx))) { if (FAILED(m_pIOleObject->QueryInterface(IID_IViewObject,(VOID **)&m_pIViewObject))) { ASSERT(FALSE); return FALSE; } } //设置组件 m_pIFalshControl->PutWMode(TEXT("transparent")); //显示控件 if (FAILED(m_pIOleObject->DoVerb(OLEIVERB_UIACTIVATE,NULL,(IOleClientSite *)this,0L,NULL,NULL))) { ASSERT(FALSE); return FALSE; } return TRUE; }