![]()
前回までにWTLのタブビューをひな形にアドレスバーや「戻る」「進む」ボタンなどを実装してきた。タブブラウザーとしてそれなりに動くようになってきたが、アドレスバーに致命的な不具合があった。[BackSpace]や[←]キーなどが使えない点だ。今回はその点を修正する。
前回までに作成したプロジェクトのソリューションウインドウにある「MainFrm.h」をダブルクリックして編集画面を開く。
今まではアドレスバーはCComboBoxExをそのまま利用していたが、新しくアドレスバー用のクラスを追加する。このクラスでは中にあるコントロールをサブクラス化することにより、マウスによるフォーカス取得(WM_MOUSEACTIVATE)を受け取って、メインフレームへWM_DNP_CHANGEFOCUSへ送るだけの処理をしている。
アドレスバーへのフォーカス取得はWM_COMMANDのEN_SETFOCUSやEN_KILLFOCUSでも行える。しかし今回はEN_SETFOCUSによるタイミングで処理するとキーカーソル(キャレット)が消えてしまうためWM_MOUSEACTIVATEとした。 本当はEN_SETFOCUSLタイミングで処理した方がいいのだが、、、何時間かテストをしたが結局解決方法が見つからず今回は諦めた。
#define WM_DNP_CHANGEFOCUS (WM_APP + 1) //■追加
//■追加
//アドレスバー用クラス
class CAddressBarCtrl : public CWindowImpl<CAddressBarCtrl,CComboBoxEx>
{
class CInnerComboBox : public CWindowImpl<CInnerComboBox>
{
public:
BEGIN_MSG_MAP(CInnerComboBox)
MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
END_MSG_MAP()
//マウスによるフォーカス取得時の処理
LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
GetTopLevelParent().SendMessage(WM_DNP_CHANGEFOCUS,(WPARAM)TRUE); //メインウインドウへフォーカスを受け取ったことを通知
bHandled = FALSE;
return 0;
}
};
CInnerComboBox _wndInnerComboBox;
public:
BEGIN_MSG_MAP(CAddressBarCtrl)
END_MSG_MAP()
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;
_wndInnerComboBox.SubclassWindow(GetComboCtrl()); //サブクラス化
return hWnd;
}
};
class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
CAddressBarCtrl _wndAddressBar; //■変更 アドレスバー用コンボボックス
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_DNP_CHANGEFOCUS, OnDnpChangeFocus) //■追加
NOTIFY_CODE_HANDLER(CBEN_ENDEDIT, OnAddressbarEnter)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
COMMAND_ID_HANDLER(ID_WINDOW_CLOSE, OnWindowClose)
COMMAND_ID_HANDLER(ID_WINDOW_CLOSE_ALL, OnWindowCloseAll)
COMMAND_RANGE_HANDLER(ID_WINDOW_TABFIRST, ID_WINDOW_TABLAST, OnWindowActivate)
COMMAND_ID_HANDLER(ID_IE_BACK, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_NEXT, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_STOP, OnIECommand)
COMMAND_ID_HANDLER(ID_IE_REFRESH, OnIECommand)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()
//■追加
//フォーカス変更時処理
LRESULT OnDnpChangeFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
BOOL bHasFocus = (BOOL)wParam; //アドレスバーなどがフォーカスを受け取っていたらTRUE
int nPage;
CTabBrowser100View* pView;
nPage = m_view.GetActivePage();
if(nPage < 0)
return 0; //アクティブなタブがない
pView = (CTabBrowser100View*)m_view.GetPageData(nPage);
if(pView == NULL)
return 0; //ビューが取得できなかった
if(pView->_pIWebBrowser2 == NULL)
return 0;
if(bHasFocus)
{
//アドレスバーなどIE以外がフォーカスを受け取った
CComPtr<IOleInPlaceObject> pIOleInPlaceObject;
pView->_pIWebBrowser2->QueryInterface(&pIOleInPlaceObject);
if(pIOleInPlaceObject)
pIOleInPlaceObject->UIDeactivate(); //IEのUIを無効化
}
return 0;
}

これでビルド/実行するとアドレスバー内で[BackSpace]キーが普通に使えるようになった。
計画性なくタブブラウザーを作っているのと、画像をキャプチャーするためにソースコードを撮りやすく配置しているためなどなどの要因でだんだんソースコードがごちゃごちゃしてきた。ちょっと整理したい気もするのだがとりあえず保留して、次回はタブの右クリックメニューを実装する。
