【问题标题】:Simulate global hotkey模拟全局热键
【发布时间】:2016-02-28 14:32:39
【问题描述】:

您好,我正在使用 Visual c++ 我有一个工作程序,除了一件事我希望它能够使用单独的屏幕截图程序。我安装了单独的截图程序,它有一个注册的热键来截图,我希望我的程序来做。

我用 FindWindow 尝试了 keybd_event 和 SendInput,它在记事本上运行良好,但它的屏幕截图程序运行最小化或隐藏,我知道 SetForegroundWindow 的问题。

有没有办法让它像我刚刚在键盘上按下的所有窗口一样的 Windows 系统,就像真正的热键一样?它的屏幕截图程序可以使用真正的热键正常工作。

【问题讨论】:

    标签: c++ windows visual-c++ keypress hotkeys


    【解决方案1】:

    也许键盘挂钩可以解决问题?

    并不完美,但它们非常全球化

    【讨论】:

    • 好的,我可以了解钩子,但这可以按下按键还是只听?是其他程序有热键,我想我的程序按下它。
    • 看来我明白了。您想模拟击键,以便外部程序截取屏幕截图,对吗?好吧,那不是您遇到问题的热键。顺便说一句,请考虑以下几点: * 从您自己的代码中获取截图非常容易 * 您可以将自己的热键与对上述程序的某种管道调用结合起来 但是无论如何,您现在想要的解决方案是 SendInput() .是的,您已经尝试过了,但如果实施得当,应该可以工作。
    【解决方案2】:

    这是一个全局热键的源代码。它已设置为侦听 CTRL + y 组合键。一旦 CTRL + y 被触发,它就会抓取屏幕截图。

    要关闭全局热键,只需按 CTRL + q

    要隐藏控制台窗口并保持热键在后台运行,请按 CTRL + w

    #define _WIN32_WINNT 0x0400
    #pragma comment( lib, "user32.lib" )
    
    #include <iostream>
    #include <windows.h>
    #include <stdio.h>
    
    HHOOK hKeyboardHook;
    __declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam);
    void MessageLoop();
    DWORD WINAPI my_HotKey(LPVOID lpParm);
    int toggleVisibility = 1;
    
    int screenResolutionX = GetSystemMetrics(SM_CXSCREEN);
    int screenResolutionY = GetSystemMetrics(SM_CYSCREEN);
    POINT startCoord,endCoord;
    void grabScreenshot(POINT a, POINT b);
    
    /*********************************************
    ***                                        ***
    ***                                        ***
    **********************************************/
    
    
    int main(int argc, char** argv){
    
        /* uncomment to hide console window */
        //ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
    
        HANDLE hThread;
        DWORD dwThread;
    
        printf("\n  s c r e e n s h o t   H O T K E Y    \n\n");
        printf("press  CTRL-y  for  screenshot \n");
        printf("press  CTRL-w  to hide or make console window visible  \n");
        printf("press  CTRL-q  to quit  \n");
        printf("\n\n");
    
        hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)   my_HotKey, (LPVOID) argv[0], NULL, &dwThread);
    
        if (hThread) return WaitForSingleObject(hThread,INFINITE);
        else return 1;
    
    }
    
    /*********************************************
    ***                                        ***
    ***                                        ***
    **********************************************/
    
    
    __declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam){
        DWORD SHIFT_key=0;
        DWORD CTRL_key=0;
        DWORD ALT_key=0;
    
    
        if  ( (nCode == HC_ACTION) &&   ((wParam == WM_SYSKEYDOWN) ||  (wParam == WM_KEYDOWN) ) ) {
            KBDLLHOOKSTRUCT hooked_key =    *((KBDLLHOOKSTRUCT*)lParam);
            DWORD dwMsg = 1;
            dwMsg += hooked_key.scanCode << 16;
            dwMsg += hooked_key.flags << 24;
            char lpszKeyName[1024] = {0};
    
            int i = GetKeyNameText(dwMsg,   (lpszKeyName+1),0xFF) + 1;
    
            int key = hooked_key.vkCode;
    
            SHIFT_key = GetAsyncKeyState(VK_SHIFT);
            CTRL_key  = GetAsyncKeyState(VK_CONTROL);
            ALT_key   = GetAsyncKeyState(VK_MENU);
    
            //printf("%c",key);
    
            if ( (key >= 'A') && (key <= 'Z') || (key >= 'a') && (key <= 'z') || (key >= '0') && (key <= '9') ) {
    
                if  (GetAsyncKeyState(VK_SHIFT)>= 0) key +=32;
    
                /*********************************************
                ***   Hotkey scope                         ***
                ***   do stuff here                        ***
                **********************************************/
    
                if ( (CTRL_key !=0) && (key == 'y') || (key == 'Y') ) {
    
                   CTRL_key=0;
    
                   // grab a screenshot
    
                    startCoord.x=0;
                    startCoord.y=0;
    
                    endCoord.x=screenResolutionX;
                    endCoord.y=screenResolutionY;
    
                    ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
                    Sleep(1000);
                    grabScreenshot(startCoord,endCoord);
    
                    ShowWindow(FindWindowA("ConsoleWindowClass", NULL), true);
    
                    printf("\nThe Screenshot is in the Clipboard  \n\n");
                }
    
                //******************************************************
    
                if ( (CTRL_key !=0) && (key == 'q') ||  (key == 'Q') ) {
                    MessageBox(NULL, "\n\n\n\nShutting down\n\nPress  OK   to close\n\n", "                                     H O T K E Y                                            ", MB_OK);
                   PostQuitMessage(0);
                }
    
                //******************************************************
    
                if ( (CTRL_key !=0) && (key == 'w') ||  (key == 'W') ) {
    
                    toggleVisibility = - toggleVisibility;
    
                    if (toggleVisibility >0 ) {
                        ShowWindow(FindWindowA("ConsoleWindowClass", NULL), true);
                    }
                    else{
                        ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
                    }
                }
    
                SHIFT_key = 0;CTRL_key = 0; ALT_key = 0;
            }
        }
        return CallNextHookEx(hKeyboardHook,    nCode,wParam,lParam);
    }
    
    
    /*********************************************
    ***                                        ***
    ***                                        ***
    **********************************************/
    
    void MessageLoop(){
    
        MSG message;
        while (GetMessage(&message,NULL,0,0)){
            TranslateMessage( &message );
            DispatchMessage( &message );
        }
    }
    
    /*********************************************
    ***                                        ***
    ***                                        ***
    **********************************************/
    
    
    DWORD WINAPI my_HotKey(LPVOID lpParm){
        HINSTANCE hInstance = GetModuleHandle(NULL);
        if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm);
        if (!hInstance) return 1;
    
        hKeyboardHook = SetWindowsHookEx (  WH_KEYBOARD_LL, (HOOKPROC) KeyboardEvent,   hInstance,  NULL    );
        MessageLoop();
        UnhookWindowsHookEx(hKeyboardHook);
        return 0;
    }
    
    
    /*********************************************
    ***                                        ***
    ***                                        ***
    **********************************************/
    
    
    void grabScreenshot(POINT a, POINT b){
    
        // copy screen to bitmap
        HDC     hScreen = GetDC(NULL);
        HDC     hDC     = CreateCompatibleDC(hScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, abs(b.x-a.x), abs(b.y-a.y));
        HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
        BOOL    bRet    = BitBlt(hDC, 0, 0, abs(b.x-a.x), abs(b.y-a.y), hScreen, a.x, a.y, SRCCOPY);
    
        // save bitmap to clipboard
        OpenClipboard(NULL);
        EmptyClipboard();
        SetClipboardData(CF_BITMAP, hBitmap);
        CloseClipboard();
    
        // clean up
        SelectObject(hDC, old_obj);
        DeleteDC(hDC);
        ReleaseDC(NULL, hScreen);
        DeleteObject(hBitmap);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-12
      • 2019-12-07
      • 2016-02-22
      • 2018-05-01
      • 2011-03-15
      • 1970-01-01
      • 2021-12-14
      • 2011-05-28
      相关资源
      最近更新 更多