C ++ Win32防止窗口激活允许输入

时间:2014-08-05 18:37:19

标签: c++ windows winapi win32gui

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

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

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

因此我试图使用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

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

由于

詹姆斯

1 个答案:

答案 0 :(得分:1)

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

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

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

最后,请注意,由于Windows对屏幕虚拟键盘(TabTip)有额外支持,因此操作系统可能还有其他挑战。