在 MFC 应用中模拟应用内的键盘输入C++

Simulate keyboard input inside app in C++ MFC app

本文关键字:应用 键盘 输入 C++ 模拟 MFC      更新时间:2023-10-16

我创建了一个对话框MainDialog.cpp其中包含2 个编辑控件,其 ID 分别为IDC_EDITCONTROL_AIDC_EDITCONTROL_B,并将变量分别定义为m_editControlAm_editControlB

另外,我有2 个按钮,其 ID 分别为IDC_MFCBUTTON_KEY_XIDC_MFCBUTTON_KEY_Y,变量分别为m_buttonKeyXm_buttonKeyY

下面是源文件中的代码

#include "afxdialogex.h" 
IMPLEMENT_DYNAMIC(CMainDialog, CDialogEx)
CMainDialog::CMainDialog(CWnd* pParent): CDialogEx(IDD_MAIN_DIALOG, pParent)
{
}
CMainDialog::~CMainDialog()
{
}
void CMainDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDITCONTROL_A, m_editControlA);
DDX_Control(pDX, IDC_EDITCONTROL_B, m_editControlB);
DDX(Control(pDX, IDC_MFCBUTTON_KEY_X, m_buttonKeyX);
DDX(Control(pDX, IDC_MFCBUTTON_KEY_Y, m_buttonKeyY);
}
BEGIN_MESSAGE_MAP(CMainDialog, CDialogEx)
ON_EN_CHANGE(IDC_EDITCONTROL, &CMainDialog::OnEnChangeEditA)
ON_BN_CLICKED(IDC_MFCBUTTON_KEY_X, &CMainDialog::OnBnClickedButtonX)
ON_BN_CLICKED(IDC_MFCBUTTON_KEY_Y, &CMainDialog::OnBnClickedButtonY)
END_MESSAGE_MAP()
void CMainDialog::OnBnClickedButtonX()
{
m_editControlA.SetWindowTextW(_T("X"));  // test
}
void CMainDialog::OnBnClickedButtonX()
{
m_editControlA.SetWindowTextW(_T("Y"));  // test
}

我试图了解如何让每个按钮发送各自的字符(即XY在此示例中)到选定的编辑控件(如果已选中)。本质上,我想模拟键盘输入

我已经阅读了有关如何模拟键盘事件的文档以及sendMessage,但是由于我的C++知识非常基础,因此我不明白如何实现它。另外,根据我之前的问题,我发现GetFocus会很有用,但我目前的主要问题仍然是发送输入。

任何示例代码或有用的链接都可能对我学习如何模拟应用程序内的键盘输入非常有用。

字符使用WM_CHAR消息从操作系统发送到编辑控件。

实际上,它比这要复杂一些,但是您不需要模拟整个WM_KEYUP WM_KEYDOWN消息序列,因为它的最终结果是生成WM_CHAR消息。

您可以使用 CWnd::P ostMessage 将字符直接发送到编辑控件,即使它们没有焦点。

您可能已经在此处找到了WM_CHAR的文档:https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms646276(v=vs.85).aspx

哎呀.. 请原谅我的法语,英语文档在这里 https://msdn.microsoft.com/en-us/library/windows/desktop/ms646276(v=vs.85).aspx

(只需将 fr-fr 更改为 en-us 就可以解决问题,它可能适用于所有其他语言,整洁!

  • wParam保存您要发送的字符。 要么是普通的 ASCII 字符,要么是VK_常量之一......我建议你WM_CHARW使用unicode版本,因为现在大多数Windows软件都使用unicode。 宽字符的表示法为 L'X' 或 _T('X'),Unicode (UTF-16) 字符类型为 wchar_t。

  • lParam包含其他击键详细信息,0 应该适合您要做的事情。

要发送 X,只需调用

m_editControlA.PostMessage(WM_CHAR, _T('X'));  

使用 _T() 表示法时,括号之间的字符(或字符串)文本将自动转换为应用的 unicode 设置的正确字符宽度(应将其设置为 UNICODE,因为这是操作系统正在使用的,并且也是 Windows CE 的唯一有效编码,例如,你应该习惯于操作此类型。

几乎所有对字符串进行操作的 C 库函数的 _T() 宏和 _t* 覆盖都是在 tchar.h 中定义的,tchar.h 包含在 stdafx.h 中。 在 MFC 下,您将主要使用 CString,但最好知道这些东西在哪里。

[编辑] 当你开始运行它时,你应该开始玩WM_KEYDOWN。 您会发现直接到对话框的PostMessage(WM_CHAR,VK_ESCAPE)不会关闭它,而PostMessage(WM_KEYDOWN,VK_ESCAPE)会关闭它。并且m_editBox.PostMessage(WM_KEYDOWN,_T("X"))将向您的编辑框发送一个较低的键"x"。但这是另一个值得关注的话题。

享受MFC的乐趣!

对于您的最后一个问题:

当然,但它变得有点复杂,因为一旦你点击它,你的按钮就会获得焦点。 您必须为每个编辑框创建EN_SETFOCUS处理程序,并添加 CWnd* 数据成员以跟踪具有焦点的最后一个编辑框。

您的EN_SETFOCUS处理程序应如下所示

void CdlgDlg::OnEnSetfocusEdit1()
{ 
m_pWndLastFocus = &m_edit1;
}

不要忘记在构造函数中将指针设置为 NULL,并在调用m_pWndLastFocus->PostMessage()之前将其设置为有效。

在 MFC 中合成输入的方法是使用 SendInput 方法。