![]()
前回までの作業で「Googleツールバー」を複数表示できるようになった。今回は「Googleツールバー」だけでなく、ほかのInternet Explorer用ツールバーも表示できるようにする。
//■追加
class CAvailableIEToolbar
{
public:
CAtlString strName;
IID clsidToolbar;
CAvailableIEToolbar()
{
clsidToolbar = GUID_NULL;
}
CAvailableIEToolbar(const IID& clsid,LPCTSTR pszName)
{
clsidToolbar = clsid;
strName = pszName;
}
};
CAtlArray<CAvailableIEToolbar> _acAvailableIEToolbar; //■追加
//■追加
//指定したHKEY内のレジストリキー名を列挙
bool RegEnumKeyName(HKEY hKey,CAtlArray<CAtlString>& astrClsid)
{
int i;
LONG nRet;
i = 0;
while(1)
{
TCHAR pszName[2048];
DWORD dwLen;
DWORD dwType;
//レジストリ内を列挙
dwLen = 2048;
*pszName = NULL;
nRet = ::RegEnumValue(hKey,i++,pszName,&dwLen,NULL,&dwType,NULL,NULL);
if(nRet != ERROR_SUCCESS)
break;
if(pszName == NULL || *pszName == NULL)
continue;
astrClsid.Add(pszName);
}
return true;
}
//■追加
//レジストリに登録されているIEツールバーを見つけ
//_acAvailableIEToolbarに格納する
bool EnumAvailableIEToolbar(void)
{
LONG nRet;
CRegKey cRegistry;
CAtlArray<CAtlString> astrClsid;
_acAvailableIEToolbar.RemoveAll();
//最初にレジストリからIEツールバーかもしれないレジストリキーをすべて列挙して
//astrClsidへ格納
//ユーザー専用のIEツールバーかもしれないレジストリキーを列挙
nRet = cRegistry.Open(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Internet Explorer\\Toolbar\\WebBrowser"));
if(nRet == ERROR_SUCCESS)
{
RegEnumKeyName(cRegistry.m_hKey,astrClsid);
cRegistry.Close();
}
//ユーザー共通のIEツールバーかもしれないレジストリキーを列挙
nRet = cRegistry.Open(HKEY_LOCAL_MACHINE,_T("Software\\Microsoft\\Internet Explorer\\Toolbar"));
if(nRet == ERROR_SUCCESS)
{
bool bFind;
size_t i;
size_t j;
size_t nSize;
CAtlArray<CAtlString> astrClsid2;
RegEnumKeyName(cRegistry.m_hKey,astrClsid2);
cRegistry.Close();
//重複チェックして重複していないものだけastrClsid2からastrClsidへコピー
nSize = astrClsid.GetCount();
for(i = 0; i < astrClsid2.GetCount(); i++)
{
bFind = false;
for(j = 0; j < nSize; j++)
{
if(astrClsid[j].CompareNoCase(astrClsid2[i]))
continue;
bFind = true; //重複が見つかった
break;
}
if(bFind)
continue;
//重複はなかった
astrClsid.Add(astrClsid2[i]);
}
}
//astrClsidに格納されているIEツールバーかもしれないレジストリキーが
//IEツールバーかどうかをチェックして_acAvailableIEToolbarへ追加
size_t i;
size_t nSize;
nSize = astrClsid.GetCount();
for(i = 0; i < nSize; i++)
{
HRESULT hr;
GUID rclsid;
CAtlStringW ustrName;
CAtlString strName;
CComPtr<IDeskBand> pIDeskBand;
//文字列からIIDへ変換
ustrName = astrClsid[i];
hr = ::CLSIDFromString(ustrName.GetBuffer(0),&rclsid);
if(FAILED(hr))
continue;
//ためしにCoCreateしてIDeskBandかをチェック
hr = ::CoCreateInstance(rclsid,NULL,CLSCTX_INPROC_SERVER,IID_IDeskBand,(void**)&pIDeskBand);
if(pIDeskBand == NULL)
continue;
pIDeskBand = NULL;
/////////////////////////
//IEツールバーが見つかった
CLSIDtoUIString(rclsid,strName);
_acAvailableIEToolbar.Add(CAvailableIEToolbar(rclsid,strName));
}
return true;
}
//■追加
//CLSIDをUI用の文字列に変換する
bool CLSIDtoUIString(const IID& rclsid,CAtlString& strText)
{
HRESULT hr;
LONG nRet;
ULONG nChars;
TCHAR pszName[2048];
WCHAR* pwszString;
CRegKey cReg2;
CAtlString strKey;
strText = _T("");
/////////////////////////////////////
// HKEY_CLASSES_ROOT\\CLSID\\{xxxxxxxx}
//からUI名の取得を試みる
//
pwszString = NULL;
hr = ::StringFromCLSID(rclsid,&pwszString);
if(FAILED(hr))
return false;
strKey = _T("CLSID\\") + (CAtlString)pwszString;
::CoTaskMemFree(pwszString);
nRet = cReg2.Open(HKEY_CLASSES_ROOT,strKey);
if(nRet == ERROR_SUCCESS)
{
nChars = 2048;
nRet = cReg2.QueryStringValue(NULL,pszName,&nChars);
cReg2.Close();
if(nRet == ERROR_SUCCESS)
{
strText = pszName;
if(strText != _T(""))
return true;
}
}
/////////////////////////////////////
// HKEY_CLASSES_ROOT\\xxxx.xxxx.xxxx
//(プログラムID)からUI名の取得を試みる
//
pwszString = NULL;
hr = ::ProgIDFromCLSID(rclsid,&pwszString);
strKey = pwszString;
::CoTaskMemFree(pwszString);
nRet = cReg2.Open(HKEY_CLASSES_ROOT,strKey);
if(nRet == ERROR_SUCCESS)
{
nChars = 2048;
nRet = cReg2.QueryStringValue(NULL,pszName,&nChars);
cReg2.Close();
if(nRet == ERROR_SUCCESS)
{
strText = pszName;
if(strText != _T(""))
return true;
}
}
strText = strKey;
return false;
}
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// コマンドバー ウィンドウの作成
HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
// メニューのアタッチ
m_CmdBar.AttachMenu(GetMenu());
// コマンドバー画像の読み込み
m_CmdBar.LoadImages(IDR_MAINFRAME);
// 以前のメニューの削除
SetMenu(NULL);
HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);
CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
AddSimpleReBarBand(hWndCmdBar);
AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
_wndAddressBar.Create(m_hWnd,CRect(0,0,200,200),0,WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_CLIPCHILDREN,WS_EX_CLIENTEDGE);
AddSimpleReBarBand(_wndAddressBar,0,TRUE); //アドレスバーを1列で表示
//■変更
{
size_t i;
size_t nSize;
EnumAvailableIEToolbar();
nSize = _acAvailableIEToolbar.GetCount();
for(i = 0; i < nSize; i++)
{
AddIEToolbar(_acAvailableIEToolbar[i].clsidToolbar);
}
}
CreateSimpleStatusBar();
m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
UIAddToolBar(hWndToolBar);
UISetCheck(ID_VIEW_TOOLBAR, 1);
UISetCheck(ID_VIEW_STATUS_BAR, 1);
// メッセージ フィルターおよび画面更新用のオブジェクト登録
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
CMenuHandle menuMain = m_CmdBar.GetMenu();
m_view.SetWindowMenu(menuMain.GetSubMenu(WINDOW_MENU_POSITION));
_cTabImageList.Create(16,16,ILC_COLOR | ILC_MASK,1,10);
m_view.SetImageList(_cTabImageList);
return 0;
}
![]()
これで実行すると、インストールされているIE用ツールバーの分だけリバーが作られ、複数のIE用ツールバーが表示されるようになった。
一番上の「DinopSearchBar」は内部処理がIEに直接アクセスする形で実装されているためきちんと表示されず、2つ目の「Adobe PDF」はリバーサイズがきちんと設定されず、4番目の「Gooスティック」はウインドウサイズ変更時の再描画処理がきちんとされていないなど、まだきちんと動かない部分も多いが、とりあえずはいろいろなIE用のツールバーが利用可能になった。
次回はメニューからIE用ツールバーを選択して表示できるようにする。
