我想扩展第三方应用程序的功能,该应用程序使用键盘快捷键在触摸屏显示器上使用。 我实现这一目标的计划是制作一个屏幕键盘,将键盘(虚拟)提供给应用程序,并更改窗口样式以将其嵌入键盘。
由于应用程序(Mach3)支持使用插件扩展功能,这就是我想要实现目标的方式。
对于嵌入我修改了here的代码,以便在加载mach3时,应用程序对话框会立即嵌入到我的对话框中。
对于键盘功能,我使用here中的代码为窗口提供WS_EX_NOACTIVATE
样式和正确移动的句柄。
我遇到的问题是,当我将焦点放在另一个窗口(例如记事本)并按下按钮以生成按键时,其他应用程序正确接收按键,但是当我将焦点放在嵌入式时窗口并按下按钮,焦点移动到按钮,子对话框没有收到按键。
如何防止焦点像这样改变? 这是一件我不知道的简单事情,还是我需要彻底改变我的做法?
我会发布一些代码,但相当多的代码,我不确定哪个位与解决这个问题最相关。
答案 0 :(得分:1)
我找出了问题的原因,现在我可以创建一个嵌入式对话框,其父对话框充当屏幕键盘。
首先如上所述,我需要对键盘代码进行一些更改,特别是文章所说的被覆盖的OnNcLButtonDown
:
void COnScreenKeyboardDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
if (!m_hForegroundWnd)
{
// store current foreground window
m_hForegroundWnd = ::GetForegroundWindow();
// temporarily make this dialog an activatable window
ModifyStyleEx(WS_EX_NOACTIVATE,0);
// make this dialog foreground
SetForegroundWindow();
}
CDialog::OnNcLButtonDown(nHitTest, point);
}
但实际应该是:
void CWrapperDialog::OnNcLButtonDown(UINT nHitTest, CPoint point) {
SetForegroundWindow();
CDialog::OnNcLButtonDown(nHitTest, point);
}
其次,文章说要用:
覆盖OnMouseMove
void COnScreenKeyboardDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_hForegroundWnd)
{
// make the previous foreground window active
::SetForegroundWindow(m_hForegroundWnd);
// make this dialog non-activating
ModifyStyleEx(0,WS_EX_NOACTIVATE);
// set it to NULL to mark that we do not need to do this again
m_hForegroundWnd = NULL;
}
CDialog::OnMouseMove(nFlags, point);
}
下面的评论“纠正”了这个:
void CWrapperDialog::OnMouseMove(UINT nFlags, CPoint point) {
::SetActiveWindow(0);
CDialog::OnMouseMove(nFlags, point);
}
然而我发现使用这段代码,每当我移动鼠标时,我都会从焦点变化中闪烁,所以我完全省略了它。
最后,键盘示例使用DoModal
创建对话框,而我使用Create
我创建了一个我可以使用AfxBeginThread
调用的包装函数:
UINT CWrapperDialog::ThreadDoModal(LPVOID pParam){
CWrapperDialog* dlg;
dlg = ((CWrapperDialog*)pParam);
dlg->DoModal();
return 0;
}
并称之为:
dlg = new CWrapperDialog;
AfxBeginThread(dlg->ThreadDoModal, dlg);
现在消息正在正确传递。
感谢o_weisman关于示例更改的提示,因为这产生了巨大的差异。