![]()
前回はフォーカス関連のバグ修正のためビューウインドウをCAxWindowからCAxHostWindowに移行した。今回はIEコントロールがフォーカスを受け取ったことを検出して、正常に処理されるようにする。
virtual BOOL PreTranslateMessage(MSG* pMsg)
{
//■追加
{
CTabBrowser100View* pView;
pView = GetActivePageView();
if(pView && pView->PreTranslateMessage(pMsg))
return TRUE;
}
if(TranslatePopupMessage(pMsg->hwnd,pMsg->message,pMsg->wParam,pMsg->lParam,pMsg))
return TRUE;
if(_wndAddressBar.IsChild(::GetFocus()) == FALSE) //アドレスバーにフォーカスがあるときはPreTranslateMessageを回さない(アドレスバーでCtrl+Cなどを使えるようにするため)
{
if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
return TRUE;
}
return m_view.PreTranslateMessage(pMsg);
}
![]()
そしてビューウインドウ内にPreTranslateMessageを追加する。ビューに対してWM_FORWARDMSGを投げると、CAxHostWindow内で自動的にTranslateAcceleatorが呼び出される。
//■追加
//「Internet Explorer_Server」をサブクラス化
class CSubclassIEWnd : public CWindowImpl<CSubclassIEWnd>
{
CTabBrowser100View* _pView;
public:
CSubclassIEWnd(CTabBrowser100View* pView)
{
_pView = pView;
}
BEGIN_MSG_MAP(CSubclassIEWnd)
if(uMsg == WM_SETFOCUS || uMsg == WM_KILLFOCUS)// || uMsg == WM_MOUSEACTIVATE)
{
if(_pView)
_pView->SendMessage(uMsg,wParam,lParam);
}
if(uMsg == WM_DESTROY)
{
UnsubclassWindow();
}
END_MSG_MAP()
};
//■追加
CSubclassIEWnd _wndIEServer;
public:
DECLARE_WND_SUPERCLASS(NULL, CAxWindow::GetWndClassName()) //CAxHostWindow::ではなくCAxWindow::のままなことに注意
CTabBrowser100View(CTabView* pTabView)
: _wndReflect(this)
,_wndIEServer(this)
{
_pTabView = pTabView;
_bPageError = false;
}
//■追加
BOOL PreTranslateMessage(MSG* pMsg)
{
if((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
(pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
{
return FALSE;
}
BOOL bRet = FALSE;
//IOleInPlaceActiveObject::TranslateAccelerator(pMsg)の呼び出し
if(pMsg->hwnd == m_hWnd || IsChild(pMsg->hwnd))
bRet = (BOOL)SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);
return bRet;
}
//HTMLページが読み終わったときに呼ばれる処理
void _stdcall OnDocumentComplete(IDispatch* pDisp, VARIANT* vURL)
{
if(pDisp != _pIWebBrowser2)
return; //フレームなどの読み込み終了は無視
//■追加
//IEをサブクラス化
if(_wndIEServer.IsWindow() == FALSE && _pIWebBrowser2)
{
HWND hWnd;
HRESULT hr = E_FAIL;
CComPtr<IDispatch> pIDispatch;
CComPtr<IOleWindow> pIOleWindow;
_pIWebBrowser2->get_Document(&pIDispatch);
if(pIDispatch)
pIDispatch->QueryInterface(&pIOleWindow);
if(pIOleWindow)
hr = pIOleWindow->GetWindow(&hWnd);
if(SUCCEEDED(hr))
_wndIEServer.SubclassWindow(hWnd);
}
ChangeUIHandler(); //UIHandlerを変更する
HICON hIcon;
CAtlString strFile;
BEGIN_MSG_MAP(CTabBrowser100View)
MESSAGE_HANDLER(WM_DNP_SCRIPTERROR, OnDnpScriptError)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_DNP_SHOWSCRIPTERROR, OnShowScriptError)
MESSAGE_HANDLER(WM_DNP_SHOWPRIVACYREPORT, OnShowPrivacyReport)
MESSAGE_HANDLER(WM_DNP_SHOWPSECURITYREPORT, OnShowSecurityReport)
MESSAGE_HANDLER(WM_DNP_SHOWZONECONFIGURE, OnShowZoneConfigure)
MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) //■追加
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) //■追加
CHAIN_MSG_MAP(CAxHostWindow)
END_MSG_MAP()
private:
//■追加
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE("●OnSetFocus\n");
SetFocusChange(true);
bHandled = FALSE;
return 0;
}
//■追加
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLTRACE("●OnKillFocus\n");
SetFocusChange(false);
bHandled = FALSE;
return 0;
}
//アドレスバー用クラス
class CAddressBarCtrl : public CWindowImpl<CAddressBarCtrl,CComboBoxEx>
{
//■内部処理削除
class CInnerComboBox : public CWindowImpl<CInnerComboBox>
{
public:
BEGIN_MSG_MAP(CInnerComboBox)
//MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
//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;
//}
//LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
//{
// GetTopLevelParent().SendMessage(WM_DNP_CHANGEFOCUS,(WPARAM)FALSE); //メインウインドウへフォーカスを失ったことを通知
// bHandled = FALSE;
// return 0;
//}
};
//■変更
//IEコントロールがフォーカスを受け取ったときbGetFocus=true、
//IEコントロールがフォーカスを失ったときbGetFocus=falseとして呼び出す
bool SetFocusChange(bool bGetFocus)
{
if(_pIWebBrowser2 == NULL)
return false;
if(bGetFocus)
{
}
else
{
CComPtr<IOleInPlaceObject> pIOleInPlaceObject;
if(_pIWebBrowser2)
_pIWebBrowser2->QueryInterface(&pIOleInPlaceObject);
if(pIOleInPlaceObject)
pIOleInPlaceObject->UIDeactivate();
}
return true;
}
![]()
これでとりあえず、フォーカス関連のバグは修正された。しかし今回のバグ修正作業によりスクリプトの実行や画像の表示のON/OFF機能が使えなくなってしまっている。
次回はその部分を修正する。
