【问题标题】:C++ Win32 Prevent window Activation allow inputC++ Win32阻止窗口激活允许输入
【发布时间】:2014-08-05 18:37:18
【问题描述】:

我正在尝试为现有应用程序(我无法控制)制作自定义屏幕键盘

我打算使用它的程序只需要某些键(数字+一些字母)并且正在触摸屏环境中使用

但是,由于屏幕空间非常宝贵,因此使用内置屏幕键盘是不可能的。

因此,我正在尝试使用 Win32 制作一个基于 GUI 的简单 GUI,但是我似乎无法找到一种方法来阻止窗口被激活(作为正在使用的窗口)而不阻止我能够接收从所述窗口输入。

我已尝试使用标志创建窗口以防止激活 - WS_EX_NOACTIVATE 但是,当我这样做时,我似乎无法在另一个程序中接收我的模拟输入。

我知道我的输入代码有效(使用睡眠测试,然后单击其他窗口)

我也尝试使用 ShowWindow 在按下按钮后从窗口中删除激活,但无济于事。

我的代码简化为: main.cpp:

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winable.h>

#include "resource.h"

BOOL CALLBACK DialogProc(HWND H,UINT M,WPARAM W,LPARAM L)
{
    switch(M)
    {
        case WM_INITDIALOG:
        {
            return TRUE;
        }
        case WM_CLOSE:
        {
          EndDialog(H,0);
          return TRUE;
        }
        case WM_COMMAND:
        {
            ShowWindow(H, SW_SHOWNOACTIVATE);
            switch(LOWORD(W))
            {
                case A_KEY:
                    {
                        //Sleep(500);
                        INPUT ip;
                        // Set up a generic keyboard event.
                        ip.type = INPUT_KEYBOARD;
                        ip.ki.wScan = 0; // hardware scan code for key
                        ip.ki.time = 0;
                        ip.ki.dwExtraInfo = 0;
                        // Press the "A" key
                        ip.ki.wVk = 0x41; // virtual-key code for the "a" key
                        ip.ki.dwFlags = 0; // 0 for key press
                        SendInput(1, &ip, sizeof(INPUT));
                        // Release the "A" key
                        ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
                        SendInput(1, &ip, sizeof(INPUT));
                        return TRUE;
                    };
            }
        }
    }
    return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
}

resource.h:

#include <windows.h>
#define DLG_MAIN 1000
#define A_KEY 2000

resource.rc:

#include "resource.h"

DLG_MAIN DIALOG 0,0,300,111
CAPTION ""
STYLE WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_EX_TOPMOST|DS_SETFOREGROUND//WS_EX_NOACTIVATE
BEGIN
    CONTROL "A", A_KEY, "Button", WS_VISIBLE, 2, 2), 20, 20
END

关于我哪里出错/还有什么可以尝试的任何建议?

谢谢

詹姆斯

【问题讨论】:

  • 处理WM_MOUSEACTIVATE消息并返回MA_NOACTIVATE
  • 我尝试在 switch(M) 部分下添加一个额外的案例,这样做但它仍然不起作用,窗口仍然聚焦,我收到一个错误提示,告诉我我的类型不能,那是放那个箱子的正确地方吗?
  • 请记住,要从对话过程中返回一个值,您需要使用SetWindowLongPtr(hWnd, DWLP_MSGRESULT, &lt;value&gt;); 而不是简单地返回它。
  • 不知道 - 刚开始学习 C/C++,但现在我按一个按钮时整个对话框都消失了,并且没有输入任何文本?

标签: c++ windows winapi win32gui


【解决方案1】:

我不确定您可能有其他要求,但阅读您的帖子,我想您可以使用RegisterRawInputDevices 功能,它允许您从非活动窗口中检索输入信息。此外,您的消息循环可能不会“大量”延迟您发布的代码,因为您可以使用 WM_INPUT 消息来处理输入信息。

我将添加一个指向MSDN examples 的链接,而不是在此回复中放置一个代码 sn-p(它有一个代码 sn-p)。该示例可能会引导您使用 Win32 API 中可用的所有相关功能来检索原始输入数据。

关于窗口焦点,您可以在创建窗口时使用 WS_EX_NOACTIVATE 样式,因为在注册原始输入后您仍会收到 WM_INPUT 消息。

最后,请注意,由于 Windows 对屏幕虚拟键盘 (TabTip) 提供了额外支持,因此您在使用操作系统时可能会遇到其他挑战。

【讨论】:

  • 好的,我尝试按照您的建议进行操作,但是当我尝试编译时出现错误:'RegisterRawInputDevices' 未在此范围内声明,我尝试从MSDN 并且知道我必须添加以下内容:windows.h、winuser.h,并且我必须将 WM_INPUT 定义为 MSDN 上的值,我正在使用代码块和 gcc 编译器,不知道我要去哪里错了吗?
  • 嗨@JamesKent,RegisterRawInputDevices 函数是在Winuser.h 中定义的,但您只需要包含Windows.h,因为它还包含Winuser.h 头文件。 “未在此范围内声明”是您收到的唯一错误消息吗?
  • @james,您是否安装并正确设置了 Microsoft 的 Platform SDK(包括头文件和库)?我已经很久没有使用 CodeBlocks/GCC,但是这里有两个 codeblocks wiki 和论坛链接来设置 global compiler settings for the Platform SDKVC++ compiler
  • 我尝试安装 SDK,(7.0) 并按照该链接中的说明进行操作,但它仍然无法使用 GCC 或 VB2010 编译,如果我使用 GCC,我在其中一个标题中出现错误包括另一个不存在的标头-sal.h,如果我使用VB2010,我会收到更多警告,然后在到达RegisterRawInputDevices时失败,说找不到标识符。
  • @JamesKent,您能否删除“#define WIN32_LEAN_AND_MEAN”,以便 Windows.h 包含所有标题?此外,我会要求您分享您的源代码,以便我尝试编译它并提供任何进一步的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多