第65回 IE用ツールバーを再びきちんと表示する (タブブラウザーを作る)

tabbrowser295.gif
前回の作業で、「タブ」をバックグラウンドを開けるようになった。しかしその副作用で、タブの開き方によって「Googleツールバー」などのIE用ツールバーが表示されなかったり、下端が欠けるなどの不具合が生じた。今回はそれらを修正する。

まずCIEToolbarInfoの中でIEツールバーを生成する処理でbVisibleを利用した条件分岐を入れる。 IDeskBandからのGetBandInfoによる情報はShowDW(TRUE)を実行しないときちんと取得できない。そのためShowDWを実行しないときはGetBandInfoによる情報を利用せずに、既存のリバー情報のみを利用するようにした。
	//hWndParentはCDummyWnd(Googleツールバーの親となるウインドウハンドル)
	//clsidIDeskBandはGoogleツールバーのCLSIDを指定する
	bool	CreateIEToolbar(IWebBrowser2* pIWebBrowser2,HWND hWndParent,IDeskBand** ppIDeskBand,const IID& clsidIDeskBand,bool bVisible)
	{
		HRESULT	hr;

		if(ppIDeskBand == NULL || pIWebBrowser2 == 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) && bVisible)
				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;		//■変更 不要なサイズ指定が残っていたので変更

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

			hWndRebar = ::GetParent(hWndParent);
			nIndex = -1;
			::SendMessage(hWndParent,WM_DNP_GETRBINDEX,(WPARAM)&nIndex,NULL);
			if(nIndex != -1 && hWndRebar)
			{
				//ShowDW(TRUE)を実行していないとGetBandInfoでサイズが
				//取得できないので、bVisible=falseのときはリバーの大きさを
				//調整しない
				if(bVisible)		//■条件を追加
				{
					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;
	}

tabbrowser296.gif また、前回の実装でCMainFrame::CreateNewTab内にバグがあったのでそれを修正する。 pView->AddIEToolbarの呼び出し時に「!」が抜けていた。
	//タブの新規作成
	//nPosはタブを追加する場所。nPos<0(もしくはnPos=m_view.GetPageCount())で一番後ろ、
	//そのほかの数値はCTabView::InsertPageにそのまま渡す
	//
	//戻ったポインタは自動削除されるため、deleteの必要なし
	//
	//bOpenInBackground=trueならバックグラウンドでタブを開く
	//
	CTabBrowser100View*	CreateNewTab(LPCTSTR pszURL,LPCTSTR pszTitle,int nPos=-1,int nImage=-1,bool bOpenInBackground=false)
	{
		bool	ret;
		CTabBrowser100View*	pView;

		//bOpenInBackgroundが指定されていても現在タブが1つもない状態ならbOpenInBackgroundをfalseに強制設定する
		if(bOpenInBackground && m_view.GetPageCount() == 0)
			bOpenInBackground = false;

		pView = new CTabBrowser100View(&m_view);	//タブビューのポインタを渡す
		if(pView == NULL)
			return	NULL;

		//ビューウインドウ生成
		if(pszURL == NULL || *pszURL == NULL)
			pView->Create(m_view, rcDefault, _T("about:blank"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL, 0);
		else
			pView->Create(m_view, rcDefault, pszURL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL, 0);
		if(pView->IsWindow() == FALSE)
		{
			delete	pView;
			return	NULL;		//ビューウインドウ生成失敗
		}

		//タブにビューを割り当てる
		if(nPos < 0)
			nPos = m_view.GetPageCount();
		if(pszTitle)
			ret = m_view.InsertPage(nPos,pView->m_hWnd,pszTitle,nImage,pView,bOpenInBackground);
		else
			ret = m_view.InsertPage(nPos,pView->m_hWnd,_T(""),nImage,pView,bOpenInBackground);

		if(ret == false)
		{
			delete	pView;
			return	NULL;		//タブへの追加失敗
		}

		//IEツールバーの生成
		{
			size_t	i;
			size_t	nSize;

			nSize = _acAvailableIEToolbar.GetCount();
			for(i = 0; i < nSize; i++)
			{
				if(_acAvailableIEToolbar[i].pwndDummy)
					pView->AddIEToolbar(*_acAvailableIEToolbar[i].pwndDummy,! bOpenInBackground);		//■変更 IEツールバー生成
			}
		}

		return	pView;
	}

tabbrowser297.gif
これでビルド/実行するとIE用ツールバーが再びきちんと表示されるようになった。



これまでの作業で

・「お気に入り」メニューを開いているときにメニューバーの「お気に入り」がハイライトにならない
・「お気に入り」メニューでフォーカスが変わるため、メニューを開きながらメニューバーを順に開けない
・「お気に入り」メニューを開くとステータスバーのデザインが壊れる
・「お気に入り」メニュー内の項目選択でステータスバーへ解説表示ができない
・「お気に入り」メニュー内の項目の有効/無効を切りかえれない
・「編集」メニュー内の「コピー」などの各項目をアドレスバーなどIEコントロール以外で利用できない
・スクリプトエラーダイアログの抑制がNavigate直後に働かない
・Navigate直後のタブ名が「about:blank」になる
・アドレスバーの表示URLが長い場合、先頭から表示されずに後方が表示される
・「戻る」「進む」ボタンにIE履歴を選択するためのドロップメニューがない
・IEツールバーを利用するのに毎回手動で表示する必要がある(終了時の状態を保存していない)
・IEツールバーを新規表示するときに必ずリバーが1行表示される
・リンクの右クリックで「新しいタブで開く」でタブを開き、「新しいウインドウで開く」では新しくウインドウを生成するようにすべき
・ページ読み込み中を示す表示がない
・アドレスバーがオートコンプリートによるURL入力に対応していない
・メニュー項目で利用できないものが多い
・実装上のバグからUNICODEビルドしかできない

などなどざっと挙げただけどもまだ不具合や未実装な必要最低限の機能が多く残っている。

しかしだんだん疲れてきたのでしばらくタブブラウザーからは離れて保留にします。お疲れ様でした。また気が向くか要望があれば再開するかもしれませんが。。。

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


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