模拟全局热键

时间:2015-11-25 17:18:01

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

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

我用FindWindow尝试了keybd_event和SendInput,它与记事本一起工作正常,但截图程序运行最小化或隐藏,我知道SetForegroundWindow的问题。

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

2 个答案:

答案 0 :(得分:1)

也许键盘钩会解决问题吗?

不完美,但它们非常全球

答案 1 :(得分:0)

enter image description here

以下是全局热键的源代码。它已被设置为侦听 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);
}