1.问题描述:MFC应用程序中,嵌入一个ocx控件,在控件中启动另一个进程,并作为子窗口;在子窗口中切换中英文模式,不起作用!
2.ocx控件中的Oncreate函数中,启动进程代码:
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
m_hWndMain = GetSafeHwnd();
// 启动进程
ZeroMemory(&m_sei, sizeof(SHELLEXECUTEINFO));//使用前最好清空
m_sei.cbSize = sizeof(SHELLEXECUTEINFO);//管理员权限执行cmd,最基本的使用与 ShellExecute 类似
m_sei.fMask = SEE_MASK_NOCLOSEPROCESS;
m_sei.lpVerb = TEXT("runas");
m_sei.lpFile = m_strAllPath;
m_sei.lpDirectory = m_strAllPath;
m_sei.lpParameters = GetVisitPara(); // 构造CEF需要访问的参数
m_sei.nShow = SW_HIDE;
if(!ShellExecuteEx(&m_sei))
{
AfxMessageBox(_T("初始化失败,启动MxvWebClient失败,请确认安装盘是否正确!"));
return FALSE;
}
m_nPid = GetProcessId(m_sei.hProcess);
GetWindowRect(&g_winRect);
通过进程的名称找到句柄m_hWndFind,并设置父子关系;相关代码:
::SetParent(m_hWndFind, m_hWndMain);
long nNewType = GetWindowLong(m_hWndFind, GWL_STYLE) &~WS_POPUP &~WS_BORDER & ~WS_CAPTION & ~WS_THICKFRAME /*| WS_CHILD*/ ;
::SetWindowLong(m_hWndFind, GWL_STYLE, nNewType);
//先改变大小,再发送消息
::MoveWindow(m_hWndFind, 0, 0, g_winRect.Width(), g_winRect.Height(), FALSE);
::ShowWindow(m_hWndFind, SW_SHOW);
3.在ocx控件中的进程的输入框中,切换中英文输入模式,按键CTRL+SPACE,不能切换
4.如果将设置父子关系的这段代码去掉,那么ocx控件中的进程是可以进行中英文输入模式的切换的(CTRL+SPACE)。
5.经测试,显示在ocx控件中的进程,其实能响应OnPreKeyEvent消息的,在这个消息响应函数中,增加了测试代码,按下CTRL+SPACE能弹出alter中的消息。
bool ClientHandler::OnPreKeyEvent(
CefRefPtr<CefBrowser> browser,
const CefKeyEvent& event,
CefEventHandle os_event,
bool* is_keyboard_shortcut )
{
CEF_REQUIRE_UI_THREAD();
if(event.focus_on_editable_field && event.windows_key_code == 0x20 && GetAsyncKeyState(VK_CONTROL)<0)
{
test_runner::Alert(browser, "You pressed the ctrl + space bar!");
}
return false;
}
6.再测试,发现在ocx控件中启动的进程,根本就没有接收到IME相关的消息