您的位置:首页 > 其它

关于在COM组件中 ATL/WTL使用webbroswer控件无法响应Ctrl+A Ctrl+V Ctrl+C及回车键的处理

2010-03-18 11:20 986 查看
如果在COM组件中ATL/WTL窗口中使用了webbroswer控件,这时默认情况下是无法响应Ctrl+A Ctrl+V Ctrl+C等快捷键的

so我以CDialogImpl类为例子说明

首先创建webbroswer控件使用一个包装类

class CHTMLWin  : public CWindowImpl< CHTMLWin, CAxWindow>
{

::ATL::CComPtr<IWebBrowser2> m_pBrowserApp;

// Message map and handlers
BEGIN_MSG_MAP(CHTMLWin)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()

virtual void OnFinalMessage(HWND /*hWnd*/)
{
delete this;
}

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;
// give HTML page a chance to translate this message
if(pMsg->hwnd == m_hWnd || IsChild(pMsg->hwnd))
bRet = (BOOL)SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg);

return bRet;
}

LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

// Connect events
HRESULT hRet = QueryControl(IID_IWebBrowser2, (void**)&m_pBrowserApp);
if(SUCCEEDED(hRet))
{
if(FAILED(DispEventAdvise(m_pBrowserApp, &DIID_DWebBrowserEvents2)))
ATLASSERT(FALSE);
}

// Set host flag to indicate that we handle themes
CComPtr<IAxWinAmbientDispatch> spHost;
hRet = QueryHost(IID_IAxWinAmbientDispatch, (void**)&spHost);
if(SUCCEEDED(hRet))
{
hRet = spHost->put_DocHostFlags(DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME);
ATLASSERT(SUCCEEDED(hRet));
}

//lRet = LoadSourceHtm() ? 0 : -1;
return lRet;
}

virtual void OnFinalMessage(HWND /*hWnd*/)
{
delete this;
}

}


在对话框中

HHOOK hHook = NULL;

class CHTMLDlg :
public CDialogImpl<CHTMLDlg >,
public CMessageFilter, public CIdleHandler
{

......

CString m_strResourceURL;

CHTMLWin  *m_pHTML ;

static  CHTMLDlg* m_pThis;

// 使用钩子来处理转发消息
static LRESULT FAR PASCAL MsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMSG lpMsg = (LPMSG) lParam;
if ( nCode >= 0 && PM_REMOVE == wParam )
{
if ( (lpMsg->message != WM_CHAR && lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) )
{
if (m_pThis->PreTranslateMessage(lpMsg)) // 调用CDialogImpl中的PreTranslateMessage,很重要以实现快捷键响应
{
lpMsg->hwnd = NULL;
lpMsg->message = WM_NULL;
lpMsg->lParam  = 0;
lpMsg->wParam  = 0;
}
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}

virtual BOOL PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message==WM_KEYDOWN && pMsg->wParam == 0x0D)
pMsg->message = WM_CHAR; // 将回车转为此种消息以使webbrowser处理

if (m_pHTML  && m_pHTML->PreTranslateMessage(pMsg) )
return TRUE;

return CWindow::IsDialogMessage(pMsg);
}

virtual BOOL OnIdle()
{
return FALSE;
}

LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = TRUE;

m_pThis = this;

CString szModule;
if (GetModuleFileName(_AtlBaseModule.m_hInst, szModule.GetBuffer(_MAX_PATH), _MAX_PATH))
{
m_strResourceURL.Format(_T("res://%s/%d"), szModule, IDR_HTML1); // 资源中的网页
}
szModule.ReleaseBuffer();

// 创建网页控件
m_pHTML = new CHTMLWin;

m_pHTML->Create(m_hWnd, 0, m_strResourceURL); // m_strResourceURL可以替换为其它URL地址,但必须是URL以确保创建网页控件

hHook = SetWindowsHookEx( WH_GETMESSAGE, MsgProc,
NULL, GetCurrentThreadId() );

return 1;  // Let the system set the focus
}

.....

}


其他钩子的释放不再列出....

其实主要是需要在消息循环中筛选消息向webbroswer窗口发送消息

处理方式为::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg);

以便使webbroswer控件有机会转换处理;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐