首页 > 编程语言 >很实用(极少使用的词)的键盘消息转发(热键间接设置程序) [有代码]

很实用(极少使用的词)的键盘消息转发(热键间接设置程序) [有代码]

时间:2023-04-28 23:13:02浏览次数:50  
标签:VK return HWND hwnd 热键 键盘 ini 转发


有些重复的点击是需要做的.但是有时这些点击是不需要看着操作.所以把该窗口切换到前台再去点击让我te不爽.于是写了这么个东西来方便方便.

比如我自己写的试听清风网站的dj音乐这种东西.是需要发现这个歌曲不好听就换下首的,直到找到我喜欢的歌曲才去看它一下,那么这个程序可以帮我设定一个热键,我按一下它就换下首,因为这个程序把这个热键转发到我那个听音乐程序上了,我只需要处理一下这个按钮事件就可以了.而也因为html+js是无法设置全局热键的.所以它们俩配合起来特别好用.

 

很实用(极少使用的词)的键盘消息转发(热键间接设置程序) [有代码]_配置文件

 

很实用(极少使用的词)的键盘消息转发(热键间接设置程序) [有代码]_热键_02

 

应用.在js代码中编写处理ctrl+q的代码是后首,然后指定接受的窗口到这个页面(必须指向到文档的窗口,指向ie框架的窗口是无效的),把所有的窗口最小化,在进行其它操作时都可以按一下CTRL+q来换到下首了.非常方便.

很实用(极少使用的词)的键盘消息转发(热键间接设置程序) [有代码]_Windows_03

代码/程序下载    https://skydrive.live.com/?cid=0c051e9a0a1fd5a3&sc=documents&id=C051E9A0A1FD5A3%21536#

 

更新:

1. 增加允许设置alt做为控制键,因为ctrl键应用上比较多,转发此键将触发其它操作,二个控制键一只手按不了,不考虑使用

--------c语言代码,就一个文件,ide是dev c++-----------------------------

#include <windows.h>

/*
 * ini解析模块
 * 下载地址:http://ndevilla.free.fr/iniparser/
 * 使用方式:解压后把src中的所有文件复制到本工程中的iniparser目录中
 * 接着把里面的c后缀文件添加到工程中,否则会出现链接不了的问题 
 * 可以把这些c加入工程中的一个目录下面也行 
 */ 
#include "./iniparser/iniparser.h"
    
#define INI_NAME "keys.ini" /* 写死配置文件名 */ 
#define KEYTABLELEN sizeof keyTable / sizeof keyTable[0]


/*
 * 函数声明部分
 */

void create_default_ini_file(char *ini_name);
void  parse_ini_file(char * ini_name,HWND hwnd);
void regHotKey(HWND hwnd, char *ini, int ctrlKey);
void delHotKey(HWND hwnd);
UINT findVkey(char *temp, int len);
void sendKeys(HWND rhwnd, LPARAM lParam, HWND hwnd);

struct{
    char *name; /* 用于配置中的按键自定义命名*/ 
    UINT VKCode; /* 实际按键的虚拟码 ,查看msdn的虚拟码表即可得到 */ 
}keyTable[] = {/* 有些使用少的不需要做为热键 */ 
    "space", VK_SPACE,
    "pageup", VK_PRIOR,
    "pagedown", VK_NEXT,
    "end", VK_END,
    "home", VK_HOME,
    "left", VK_LEFT,
    "up", VK_UP,
    "right", VK_RIGHT,
    "down", VK_DOWN,
    "insert", VK_INSERT,
    "delete", VK_DELETE,
    "0", 0x30,
    "1", 0x31,
    "2", 0x32,
    "3", 0x33,
    "4", 0x34,
    "5", 0x35,
    "6", 0x36,
    "7", 0x37,
    "8", 0x38,
    "9", 0x39,
    "a", 0x41,
    "b", 0x42,
    "c", 0x43,
    "d", 0x44,
    "e", 0x45,
    "f", 0x46,
    "g", 0x47,
    "h", 0x48,
    "i", 0x49,
    "j", 0x4A,
    "k", 0x4B,
    "l", 0x4C,
    "m", 0x4D,
    "n", 0x4E,
    "o", 0x4F,
    "p", 0x50,
    "q", 0x51,
    "r", 0x52,
    "s", 0x53,
    "t", 0x54,
    "u", 0x55,
    "v", 0x56,
    "w", 0x57,
    "x", 0x58,
    "y", 0x59,
    "z", 0x5A,
    "+", VK_ADD,
    "-", VK_SUBTRACT,
    ".", VK_DECIMAL,
    "/", VK_DIVIDE
};/* 按键对应表 */ 

/*
 * 声明结束
 */
 
  
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "keysWindow";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "通用全局快捷键发送程序",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);
    UpdateWindow (hwnd) ;
     
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    
    return messages.wParam;
}

/* 消息处理 */ 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{        
            HDC                   hdc ;
            PAINTSTRUCT           ps ;
            static HWND mHwnd, bingHwnd;
            static int cxChar, cyChar, isDrog = 0;
            POINT mmPoint;
            int helpWin = 1;  

           switch (message) {       
               case   WM_CREATE :   
                    cxChar = LOWORD (GetDialogBaseUnits ()) ;        
                     cyChar = HIWORD (GetDialogBaseUnits ()) ;
                    parse_ini_file(INI_NAME, hwnd);/* 启动时载入配置 */ 
                    /* 帮助按钮 */ 
                    CreateWindow ( TEXT("button"),"使用帮助",        
                                      WS_CHILD | WS_VISIBLE |  BS_PUSHBUTTON,        
                                     0, 0,        
                                    20 * cxChar,  1 * cyChar,        
                                    hwnd, (HMENU) helpWin,        
                                      ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
                      /* 绑定窗口标题指示条 */ 
                      bingHwnd = CreateWindow ( TEXT("static"),NULL,        
                                      WS_CHILD | WS_VISIBLE |  SS_LEFT,        
                                     0, 2 * cyChar,        
                                    0, 0,        
                                    hwnd, (HMENU) 999,        
                                      NULL, NULL) ;
                    return 0 ; 
                case WM_SIZE:               
                    /* 改变绑定指示条区域大小 */ 
                    MoveWindow (bingHwnd, 0, 2 * cyChar, LOWORD (lParam), cyChar, TRUE) ;
                    return 0; 
                case WM_PAINT:
                    hdc = BeginPaint(hwnd, &ps);
                    char gTip[] = "本窗按左键后移到接按键的窗口后松开完成绑定,选定的窗口如下:";
                    TextOut (hdc, 0, cyChar, gTip, lstrlen(gTip)) ;
                    char keyTitle[] = TEXT("已生效且会转发的热键如下:");
                    TextOut (hdc, 0, cyChar * 3, keyTitle, lstrlen(keyTitle)) ;
                    EndPaint(hwnd, &ps);
                    return 0; 
                case WM_COMMAND :
                    if (helpWin == LOWORD(wParam)){/* 如果是帮助按钮消息显示帮助窗口 */ 
                        MessageBox(NULL,"本程序是用来为一些没有全局热键程序设置热键,如给ie设置热键.\n\n" 
                                "使用步骤:\n"
                                "1. 在本窗口任意一个位置按住鼠标左键不放,并移动到一个你准备用来接受按键的窗口\n"
                                "   注意,有些窗口并不接受按键的,也就是相当你在该程序的这个位置按相同键时没有效果的话\n"
                                "   那么你应该移动到此程序的另一个位置试试,直到发现这个按键对它有作用为此.\n"
                                "   一个更加好的方法是,点一下这个位置,按下你设置的键,看它是不是如预想作用.\n"
                                "2. 在本程序的目录下的keys.ini中按说明输入你要转发的按键.设置会在下回启动时生效.\n"
                                "3. 配置文件设定,窗口绑定,把本程序最小化,你会发现在按下设定的键时,它在绑定程序上出现作用了.\n\n"
                                
                                "为方便自己写的小程序.所以bug很明显\n"
                                "代码在百度qidizi空间有." 
                                ,"使用帮助"
                                , MB_OK);
                    } 
                     return 0; 
                case WM_LBUTTONDOWN :
                    isDrog = 1; /*取消前面设置的窗口*/
                    SetCapture (hwnd) ;/* 绑定鼠标到本程序,当鼠标移出本程序窗口区域后还能监控移动消息 */ 
                    return 0;
                case WM_MOUSEMOVE:
                    if (! isDrog) return 0; 
                    GetCursorPos (&mmPoint);/* 获取鼠标坐标点 */ 
                    mHwnd = WindowFromPoint (mmPoint);/* 坐标点得到窗口句柄 */ 
                    char wTitle[256]; 
                    SetWindowText(bingHwnd, mHwnd ? 
                                (GetWindowText (mHwnd, wTitle, 100) ? wTitle : "窗口无标题") 
                                    : "绑定失败" ); /* 显示当前鼠标指向窗口标题 */ 
                    return 0;
                case WM_LBUTTONUP:
                    isDrog = 0;
                    ReleaseCapture();/* 释放鼠标绑定 */ 
                    return 0;
                case WM_HOTKEY:
                    sendKeys(mHwnd, lParam, hwnd);/* 热键消息 */ 
                    return 0;
                case WM_DESTROY:
                    delHotKey(hwnd); /* 退出程序需要移除热键,防止占用 */ 
                    PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                    break;
                default:                      /* for messages that we don't deal with */
                    return DefWindowProc (hwnd, message, wParam, lParam);    
        }
}

void delHotKey(HWND hwnd){
    int i = 0, len  = KEYTABLELEN;
    
    for (; i < len; i++){
        UnregisterHotKey(hwnd, (int)keyTable[i].VKCode);
    }
}

/* 创建初始配置文件 */ 
void create_default_ini_file(char * ini_name)
{
    FILE    *    ini ;
    
    if (_access(ini_name, 0) == 0) {
        return; /* 配置文件已存在不需要创建样本 */ 
    }
    
    ini = fopen(INI_NAME, "w");
    fprintf(ini,
    "#\n"
    "# 本文件是全局热键设定(或叫转发键)配置文件\n" 
    "# 文件名必须是:keys.ini 请不要重命名本文件\n"
    "# 如果修改错误,可以删除本文件,让程序重新生成样本后再修改.\n"
    "# 配置只有在程序启动时才进行应用,在启动后的配置变动只有重启程序才有效果\n" 
    "#\n\n"
    "# 配置语法:\n" 
    "# 每个设置占用一行\n"
    "# 每行设置如下格式:\n" 
    "# 控制键名=可配置使用的非控制键名系列[多个键名之间用空格(英文状态下的空格键)隔开,键名英文字母全部小写)].\n"
    "# 如下一行表示设置CTRL+a, CTRL+b为热键,将把相同的键转发到指定程序上,也就是当你按下这些键时,指定程序也同时相当在该程序上按下相同的组合键\n"
    "# ctrl=a b;这里写本行注释" 
    "# 可用的控制键名有: ctrl, alt;\n"
    "# 可用的组合键如下:\n" 
    "#\n# ");    
    
    int i = 0, len  = KEYTABLELEN;
    
    for (; i < len; i++){
        fprintf(ini,"%s ", keyTable[i].name);/* 列举可用的组合键到配置说明中 */ 
    }
    
    fprintf(ini,"\n"
            "[hotkey]\n"
            "alt=;键名之间使用空格(注意不能使用tab)隔开\n"
            "ctrl=a b;键名之间使用空格(注意不能使用TAB)隔开\n\n");
    fclose(ini);
}

void parse_ini_file(char * ini_name, HWND hwnd){
    dictionary    *    ini;    
    create_default_ini_file(ini_name); 
    ini = iniparser_load(ini_name);
    
    if (ini==NULL) {
        MessageBox(NULL,ini_name, "打开以下配置文件失败, 无法注册热键,请关闭程序", MB_OK);
        return;
    }
        
    regHotKey(hwnd, iniparser_getstring(ini, "hotkey:alt", ""), MOD_ALT);
    regHotKey(hwnd, iniparser_getstring(ini, "hotkey:ctrl", ""), MOD_CONTROL);
    iniparser_freedict(ini);/* 必须用完才能释放,否则上面的keys将也被清空 */ 
}

void regHotKey(HWND hwnd, char *keys, int ctrlKey){
    int keyVk, maxName = 20, copy, tlen  = KEYTABLELEN;
    static keyI = 0;
    int cyChar = HIWORD (GetDialogBaseUnits ()), cxChar = LOWORD(GetDialogBaseUnits()); 
    char temp[maxName + 1], msg[maxName + 500];
    
    while(*(keys) != '\0'){/* 未结束 */ 
        copy = 0;
                
        while(*(keys) != '\0'){                        
            if (*(keys) == ' '){
                if (copy == 0){/* 名前空格跳过 */ 
                    keys++; 
                    continue;
                }else if (copy + 1 >= maxName){/* 过长忽略 */
                    keys++;
                    copy = 0;/* 丢弃上个名,取下个名 */ 
                    continue; 
                }else{/* 取完整名 */ 
                    break; 
                } 
            }else if (copy + 1 >= maxName){/* key name 超过长度,直接忽略,注意保留最后一位做\0 */ 
                keys++;/* 忽略 */ 
                continue; 
            }
            
            temp[copy++] = *(keys), keys++;
        }
        
        temp[copy] = '\0';/* 必须正确结束字符串 */ 
        keyVk = findVkey(temp, tlen);
        if (0 == keyVk) continue;/* 键码是非0的 */
        /* 提示热键注册信息 */ 
        CreateWindow ( TEXT("static"),msg,        
                                      WS_CHILD | WS_VISIBLE |  SS_LEFT,        
                                     0, (keyI + 4) * cyChar,        
                                    cxChar * wsprintf(msg, "注册热键[%s + %s]%s;"
                                    , ctrlKey == MOD_ALT ? "ALT" : (ctrlKey == MOD_CONTROL ? "ctrl" : "未知控制键")
                                    , temp, 
                                    
        /* 参数3固定以后值之一:MOD_ALT,MOD_CONTROL,MOD_SHIFT,MOD_WIN*/
        /* 参数4必须使用虚拟键码 */ 
                                    RegisterHotKey(hwnd, (int)keyVk, ctrlKey, keyVk)
                                     ? "成功" : "失败:可能是其它程序已经注册了此热键")
                                    ,  cyChar,        
                                    hwnd, (HMENU) keyI,        
                                      NULL, NULL) ;
        keyI++; 
    }
}

/* 查找是否允许此自定键名,并返回虚拟码 */ 
UINT findVkey(char *temp, int len){
    int i = 0;
    
    for (; i < len; i++){
        if (strcmp(temp, keyTable[i].name) == 0){
            return keyTable[i].VKCode;
        }
    }

    return 0;
}

/* 向指定窗口发送按键 */ 
void sendKeys(HWND rhwnd, LPARAM lParam, HWND hwnd){
    if (! rhwnd){
        SetWindowText(hwnd, "错误:接收窗口未指定");
        return; 
    }
     /*
         sizeof   CHAR   =   1
        sizeof   BYTE   =   1
        sizeof   WORD   =   2
        sizeof   DWORD   =   4
        sizeof   INT       =   4
        sizeof   LONG     =   4 
     */
    char keyMsg[256];
    int sendCtrl, hotCtrl = LOWORD(lParam), hotVKey = HIWORD(lParam);
    
    switch (hotCtrl){
        /* 只允许使用ctrl控制键 */ 
        case MOD_CONTROL:
            sendCtrl = VK_CONTROL;/* 转化成发送码 */ 
            break;
        case MOD_ALT:
            sendCtrl = VK_MENU;/* 转化成发送码 */ 
            break;
            
        default:
            wsprintf(keyMsg, "转发失败,不允许的控制键码:%d", hotCtrl); 
            return; 
    }
    

    WPARAM wCtrl = MAKEWPARAM(sendCtrl, 0), wKey = MAKEWPARAM(hotVKey, 0); 
    PostMessage(rhwnd, WM_KEYDOWN, wCtrl, 0); /* 模拟按下控制键 */ 
    PostMessage(rhwnd, WM_KEYDOWN, wKey, 0); /* 模拟按下,这里直接转发,不需要转键码*/
    Sleep(100); /* 暂停让接收程序足够反应 */ 
    PostMessage(rhwnd, WM_KEYUP, wKey, 0);   /* 模拟抬起*/
    PostMessage(rhwnd, WM_KEYUP, wCtrl, 0);   /* 模拟抬起 控制 键 */
    wsprintf(keyMsg, "热键[%d(控制键码), %d(组合键码)],转发[%d(控制键码)+ %d(组合键码)]", hotCtrl, hotVKey, sendCtrl, hotVKey);    
    SetWindowText(hwnd, keyMsg);
    
    /* 参数3是虚拟键码,4是附加信息,一般是0 */ 
    /*
    BOOL WINAPI PostMessage(
      __in_opt  HWND hWnd,
      __in      UINT Msg,
      __in      WPARAM wParam,
      __in      LPARAM lParam
    );
    */ 
}

标签:VK,return,HWND,hwnd,热键,键盘,ini,转发
From: https://blog.51cto.com/u_252283/6235708

相关文章

  • 全部虚拟键盘键码
    Thefollowingtableshowsthesymbolicconstantnames,hexadecimalvalues,andmouseorkeyboardequivalentsforthevirtual-keycodesusedbythesystem.Thecodesarelistedinnumericorder.Constant/valueDescriptionVK_LBUTTON0x01Le......
  • Python很多时候要从键盘连续输入一个数组,并用空格隔开;Python爬取一些数据;python pip安
    Python要从键盘连续输入一个数组,并用空格隔开,Python中的实现方法如下:str=input(‘以空格为间隔连续输入一个数组:’)然后在键盘中输入,会·得到的str为一个字符串,要将其转为一个列表有两种方法方法一:a=[int(n)forninstr_in.split()]方法二:a=list(map(int,str.strip().sp......
  • 【远程连接工具】xshell上用vi/vim小键盘无法使用的修改办法
    转至:https://blog.csdn.net/qq_44676946/article/details/117257410问题:后台开发人员经常使用Xshell来访问远程服务器,在用vim(或vi)编辑文件的时,使用小键盘数字键的时候,可能会输入一堆字母和换行,并不是数字。修改:1.修改会话属性2.选择类别“终端”-VT模式3.选择“初始数字键盘......
  • 4.4 网际协议:因特网中的转发和编址
    一、IPv4数据报格式 1.版本号:4bit 2.首部长度:4bit,用于确定IP数据报中载荷实际开始的地方。一般IP数据报首部长度为20字节。 3.服务类型 4.数据报长度:16bit,IP数据报的总长度(首部+数据),单位为字节。 5.16比特标识,3比特标志,13比特片偏移:与分片有关 6.寿命:每过一台......
  • sql.SQLException: 对只转发结果集的无效操作: absolute,可滚动结果集
    获得ResultSet的长度可以使用getRow,但是首先要设置ResultSet为可滚动结果集,否则会报java.sql.SQLException:对只转发结果集的无效操作:absolute设置方法为Statement 的设置方法:Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_O......
  • [AHK]双击托盘区某可见程序图标以激活之(为读取微信新消息定义热键)
    检索TrayIcon对应的程序,并激活为QQ激活,自定义热键win+q,实现代码如下:(注意win10下面"QQ.exe"区分大小写才可以)#q::o:=TrayIcon_GetInfo("QQ.exe")Loop,%o.MaxIndex(){WinShow%"QQahk_classTXGuiFoundationahk_pid"o[A_Index].pidWinActivate%"QQahk_cla......
  • 用热键win+字母激活任务栏上的按钮[ahk]
    ;bug:热键请自行修改,发现按win+dwin+l等和系统热键冲突,可以改成空格键或Capslock键+字母;Fileencoding:UTF-8AutoHotkey版本:1.0.9.1操作系统:WindowsXP脚本说明:QuicktaskswitchingwithWin+[a,b,...,z]脚本版本:v1.0Timestamp:2012-12-2014:12:56*......
  • [AHK]热键获取TC当前的路径
    原创部分:热键alt+shif+c复制当前tc窗口中的路径。#IfWinActiveahk_classTTOTAL_CMD!+c::PostMessage1075,2029,0,,ahk_classTTOTAL_CMD;复制完整路径return#IfWinActive2010年04月11日星期日17:07一故事的开始,寻找TotalCommander(以下简称TC)的快捷键--“在下已经严重鼠......
  • 【ahk】为QQ增加激活主面板的热键
    本脚本只是实现了热键激活不在前台的QQ主面板,并不是热键打开主面板。使用方法:先手动打开QQ主面板,并且不要最小化,然后运行本脚本,此脚本会探测到主面板的id,然后绑定热键win+z来用于激活动作。/*为QQ增加热键这个脚本前提是,你要激活的窗口需要事先打开的(且主面板不能最小化)。然后......
  • [AHK]为通达信增加打开关闭交易窗口的功能热键
    用文华财经习惯用空格呼叫出交易界面,通达信软件(招商证券)没有相应热键,便用AutoHotkey来帮它定义一个。#Persistent#SingleInstanceForceControl:="AfxWnd424"#IfWinActiveahk_classTdxW_MainFrame_ClassSpace::ControlClick,%Control%,,,,,NA#If华泰是426......