// // DHTML駆動クラス // DHTMLで記述された UI からクラスの機能を呼び出して実行させることができる // #include #include CComModule _Module; #include #include #include /** * DHTMLの外部呼出しを受理するクラス * クラスをまぜてつくる (CMyWindow で直接 public IDispatch) * とおちるので分離。原因は不明 */ class CHtmlExt : public IDispatch { public: //---------------------------------------------------------------------------- // IUnknown 実装 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) { if (riid == IID_IUnknown || riid == IID_IDispatch) { if (ppvObject == NULL) return E_POINTER; *ppvObject = this; AddRef(); return S_OK; } else { *ppvObject = 0; return E_NOINTERFACE; } } ULONG STDMETHODCALLTYPE AddRef() { return 1; } ULONG STDMETHODCALLTYPE Release() { return 1; } //---------------------------------------------------------------------------- // IDispatch 実装 STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { return E_NOTIMPL; } STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { return E_NOTIMPL; } enum { NONE = 0, SETBGCOLOR = 1, }; /** * メソッド名とIDの対応をとるメソッド * regszNames にメソッド名の配列がくるので、 * rgdispid に対応する dispid を返してやる */ STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { UINT i; for (i=0; i spBody(pdispparams->rgvarg[1].pdispVal); if (spBody != NULL) { spBody->put_bgColor(pdispparams->rgvarg[0]); } } break; default: return E_NOTIMPL; } return S_OK; } }; /** * HTMLコンポーネントを処理するウインドウクラスの実装例 * CAxWindow を使って、画面いっぱいの IEコンポーネントを作成している */ class CMyWindow : public CWindowImpl, public CHtmlExt { public: CComPtr browser; private: BEGIN_MSG_MAP(CMyWindow) MESSAGE_HANDLER(WM_CREATE, OnCreate) MESSAGE_HANDLER(WM_DESTROY, OnDestroy) END_MSG_MAP() LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&) { // コントロール用窓 CAxWindow wnd; RECT rect; // 自分のサイズと同じサイズに作成 GetClientRect(&rect); wnd.Create(m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 1); LPOLESTR pstrCLSID_WebBrowser = NULL; // コントロール作成 HRESULT hr = wnd.CreateControl(OLESTR("Shell.Explorer.2")); if (SUCCEEDED(hr)) { // 自分自身を external 処理用に登録 hr = wnd.SetExternalDispatch(static_cast(this)); } if (SUCCEEDED(hr)) { // インターフェース取得 hr = wnd.QueryControl(&browser); } return SUCCEEDED(hr) ? 0 : -1; } LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&){ if (browser) { // インターフェースがある場合は解放しておく browser.Release(); browser.Detach(); } // XXX アプリケーション終了 PostQuitMessage(0); return 0; } }; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int ret; _Module.Init(NULL, hInstance); AtlAxWinInit(); CMyWindow wnd; wnd.Create(NULL, CWindow::rcDefault, NULL, WS_OVERLAPPEDWINDOW|WS_VISIBLE); #if 0 { CComVariant vUrl("file://c:/htmlUI.htm"); CComVariant vempty; wnd.browser->Navigate2(&vUrl, &vempty, &vempty, &vempty, &vempty); } #else { // とりあえずドキュメント生成 CComVariant vUrl("about:blank"); CComVariant vempty; wnd.browser->Navigate2(&vUrl, &vempty, &vempty, &vempty, &vempty); // ドキュメントを取得して… CComPtr pDisp ; wnd.browser->get_Document(&pDisp) ; CComQIPtr pDoc = pDisp ; if (pDoc) { // テキストをながしこむ VARIANT *param; SAFEARRAY *sfArray = NULL; BSTR bstr = SysAllocString(OLESTR("")); sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1); if (sfArray) { SafeArrayAccessData(sfArray,(LPVOID*) ¶m); param->vt = VT_BSTR; param->bstrVal = bstr; SafeArrayUnaccessData(sfArray); pDoc->write(sfArray); SafeArrayDestroy(sfArray); } SysFreeString(bstr); } } #endif MSG msg; while (GetMessage(&msg, NULL, 0, 0)){ TranslateMessage(&msg); DispatchMessage(&msg); } ret = msg.wParam; _Module.Term(); return ret; }