第52回 Googleツールバーの表示サイズを自動調整する (タブブラウザーを作る)

tabbrowser224.gif
前回はタブがあるときだけ「Googleツールバー」用のリバーが表示されるようにした。今回はリバーの大きさが「Googleツールバー」に合わせて変わるようにする。

「Googleツールバー」の生成はCMainFrame::OnCreate内で行っていた。それを関数に切り出して呼び出すようにした。生成処理内では前回実装したリバーのIDを取得する処理を使ってDESKBANDINFOの情報をリバーにセットする。
	//Create関数のオーバーライド。内部でIEの取得、接続などを行う
	HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		HWND	hWnd;

		hWnd = __super::Create(hWndParent,rect,szWindowName,dwStyle,dwExStyle,MenuOrID,lpCreateParam);
		if(hWnd == NULL)
			return	NULL;			//Create失敗

		QueryControl(&_pIWebBrowser2);		//_pIWebBrowser2にこのビューに関連づいているIEをセットする
		if(_pIWebBrowser2 == NULL)
			return	hWnd;			//WebBrowser取得失敗

		Advise(_pIWebBrowser2);		//IEとの接続


		//jacascriptや画像ダウンロードのコントロール設定
		{
			CComPtr<IOleObject>		pIOleObject;
			CComObject<CAmbientControl>*		pCAmbientControl;
			CComPtr<IAxWinAmbientDispatchEx>	pIAxWinAmbientDispatchEx;

			//ダウンロードコントロールの準備
			CComObject<CAmbientControl>::CreateInstance(&pCAmbientControl);
			if(pCAmbientControl)
				pCAmbientControl->QueryInterface(&_pIAmbientControl);

			//IEコントロールへのセット
			_pIWebBrowser2->QueryInterface(&pIOleObject);
			if(pIOleObject && pCAmbientControl)
				pIOleObject->SetClientSite(pCAmbientControl);

			//デフォルトのダウンロードコントロールを設定
			//本来ならゾーン変化をチェックしてゾーンに応じて決定すべき?
			SetAmbientDownloadControl(DLCTL_DLIMAGES | DLCTL_VIDEOS | DLCTL_BGSOUNDS);
		}

		//■変更
		//Googleツールバーを生成する
		{
			GUID	rclsid;
			WCHAR	pszGUID[] = {L"{2318C2B1-4965-11d4-9B18-009027A5CD4F}"};		//GoogleツールバーのGUID

			::CLSIDFromString(pszGUID,&rclsid);

			CreateIEToolbar(_hWndRebarIE,&_pIDeskBand,rclsid);
		}

		return	hWnd;
	}




	//■追加
	//hWndParentはCDummyWnd(Googleツールバーの親となるウインドウハンドル)
	//clsidIDeskBandはGoogleツールバーのCLSIDを指定する
	bool	CreateIEToolbar(HWND hWndParent,IDeskBand** ppIDeskBand,const IID& clsidIDeskBand)
	{
		HRESULT	hr;

		if(ppIDeskBand == NULL)
			return	false;
		if(*ppIDeskBand)
		{
			ATLASSERT(0);
			(*ppIDeskBand)->Release();
			*ppIDeskBand = NULL;
		}

		hr = ::CoCreateInstance(clsidIDeskBand,NULL,CLSCTX_INPROC_SERVER,IID_IDeskBand,(void**)ppIDeskBand);
		if(FAILED(hr) || *ppIDeskBand == NULL)
			return	false;

		CComPtr<IObjectWithSite>	pIObjectWithSite;

		(*ppIDeskBand)->QueryInterface(IID_IObjectWithSite,(void**)&pIObjectWithSite);

		//デスクバンドをホスト用クラスに割り当てる
		{
			CComPtr<IIEToolbar>	pIIEToolbar;

			pIIEToolbar = new CComObject<CIEToolbar>;

			pIIEToolbar->put_hwnd(hWndParent);
			if(_pIWebBrowser2)
				pIIEToolbar->put_IWebBrowser2(_pIWebBrowser2);
			if(pIObjectWithSite)
				hr = pIObjectWithSite->SetSite(pIIEToolbar);

			if(SUCCEEDED(hr))
				hr = (*ppIDeskBand)->ShowDW(TRUE);		//表示
		}

		DESKBANDINFO	sDeskBandInfo;

		//別に必要ないが情報をたくさん取得
		::ZeroMemory(&sDeskBandInfo,sizeof(DESKBANDINFO));
		sDeskBandInfo.dwMask = DBIM_MINSIZE | DBIM_MAXSIZE | DBIM_INTEGRAL | DBIM_ACTUAL | DBIM_TITLE | DBIM_MODEFLAGS | DBIM_BKCOLOR;
		hr = (*ppIDeskBand)->GetBandInfo(0,DBIF_VIEWMODE_NORMAL,&sDeskBandInfo);

		CRect	rect(0,0,1500,sDeskBandInfo.ptMinSize.y);		//サイズの一時設定(後で自動調整)

		//rebar情報の設定
		{
			HWND	hWndRebar;
			UINT	nIndex;

			hWndRebar = ::GetParent(hWndParent);
			nIndex = -1;
			::SendMessage(hWndParent,WM_DNP_GETRBINDEX,(WPARAM)&nIndex,NULL);
			if(nIndex != -1 && hWndRebar)
			{
				REBARBANDINFO	info;

				//MinSizeのみをリバーへ設定。本来ならもっと情報を設定すべき
				::ZeroMemory(&info,sizeof(REBARBANDINFO));
				info.cbSize	= sizeof(REBARBANDINFO);
				info.fMask	= RBBIM_CHILDSIZE;
				::SendMessage(hWndRebar,RB_GETBANDINFO,nIndex,(LPARAM)&info);
				info.cyMinChild	= sDeskBandInfo.ptMinSize.y;
				info.cyChild	= sDeskBandInfo.ptMinSize.y;
				info.cxMinChild	= sDeskBandInfo.ptMinSize.x;
				::SendMessage(hWndRebar,RB_SETBANDINFO,nIndex,(LPARAM)&info);

				//位置調整
				::SendMessage(hWndRebar,RB_GETRECT,nIndex,(LPARAM)&rect);
				::SendMessage(hWndParent,WM_SIZE,SIZE_RESTORED,MAKELPARAM(rect.Width(),rect.Height()));
			}
		}

		return	true;
	}

tabbrowser225.gif 次に「Googleツールバー」で(トップレベルHTMLとして作られている?)ドロップダウンメニューを開くとビューウインドウにきちんとフォーカスが当たらない問題を修正する。CIEUtilityのSetFocusChange内を変更する。今まではUIDeactivateを呼ぶのみだったが、InPlaceDeactivateも呼ぶようにした。
	//■処理内容追加
	//IEコントロールがフォーカスを受け取ったときbGetFocus=true、
	//IEコントロールがフォーカスを失ったときbGetFocus=falseとして呼び出す
	bool	SetFocusChange(bool bGetFocus)
	{
		if(_pIWebBrowser2 == NULL)
			return	false;

		HRESULT	hr = E_FAIL;
		CComPtr<IOleInPlaceObject> pIOleInPlaceObject;

		if(_pIWebBrowser2)
			_pIWebBrowser2->QueryInterface(&pIOleInPlaceObject);
		if(pIOleInPlaceObject == NULL)
			return	S_OK;

		if(bGetFocus)
		{
			hr = pIOleInPlaceObject->UIDeactivate();
			pIOleInPlaceObject->InPlaceDeactivate();
		}
		else
		{
			HWND hWnd;

			hr = pIOleInPlaceObject->GetWindow(&hWnd);
			if(SUCCEEDED(hr) && ::IsWindow(hWnd))
				::ShowWindow(hWnd,SW_NORMAL);
		}

		return	true;
	}

tabbrowser226.gif 同様にCIEToolbar内も変更しておく。
	//■処理内容追加
	//IInputObjectSite
	STDMETHOD(OnFocusChangeIS)(IUnknown *punkObj,BOOL fSetFocus)
	{
		HRESULT	hr = E_FAIL;
		CComPtr<IOleInPlaceObject> pIOleInPlaceObject;

		if(_pIDispatch)
			_pIDispatch->QueryInterface(&pIOleInPlaceObject);
		if(pIOleInPlaceObject == NULL)
			return	S_OK;

		if(fSetFocus)
		{
			hr = pIOleInPlaceObject->UIDeactivate();
			pIOleInPlaceObject->InPlaceDeactivate();
		}
		else
		{
			HWND hWnd;
			hr = pIOleInPlaceObject->GetWindow(&hWnd);
			if(SUCCEEDED(hr) && ::IsWindow(hWnd))
				::ShowWindow(hWnd,SW_NORMAL);
		}

		return	S_OK;
	}

tabbrowser227.gif
これでビルド/実行すると、これまで下端が切れて表示されていた「Googleツールバー」がきちんと表示されるようになった。

次回複数のInternet Explorer用ツールバーが表示できるようにするための準備をする。

プロジェクトファイルをダウンロード


カテゴリー「タブブラウザーを作る」 のエントリー