吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 518|回复: 6
上一主题 下一主题
收起左侧

[C&C++ 原创] 简易热键启动器

  [复制链接]
跳转到指定楼层
楼主
ashi876 发表于 2026-9-26 12:51 回帖奖励
本帖最后由 ashi876 于 2026-9-26 13:07 编辑

一直想要一个只简单工作又不会BB的热键工具。

[C] 纯文本查看 复制代码
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ Compatible
// This file is automatically generated by RisohEditor 6.2.1.
// resource.rc

#define IDC_LIST_HOTKEY                     101
#define IDC_STATIC_STATUS                   102
#define IDC_BTN_ADD                         103
#define IDC_BTN_DEL                         104
#define IDC_BTN_DOWN                        106
#define IDC_BTN_CLOSE                       108
#define IDC_BTN_TRAY                        109

#define IDD_MAIN                            1000

#ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
        #define _APS_NO_MFC                 1
        #define _APS_NEXT_RESOURCE_VALUE    100
        #define _APS_NEXT_COMMAND_VALUE     100
        #define _APS_NEXT_CONTROL_VALUE     1000
        #define _APS_NEXT_SYMED_VALUE       300
    #endif
#endif


[C] 纯文本查看 复制代码
//main.c
#include <windows.h>
#include <commctrl.h>
#include <shellapi.h>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "resource.h"#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "shell32.lib")

#define MAX_ITEMS   64
#define HOTKEY_BASE 1000
#define WM_TRAYICON (WM_USER + 1)

typedef struct {
    char name[64];
    char cmd[512];
    UINT mods;
    UINT vk;
    char hotkey_text[64];
    int  checked;
    int  hk_id;
    int  uid;
} HotkeyItem;

HotkeyItem items[MAX_ITEMS];
int item_count = 0;
int next_uid = 0;

HWND win;
HWND hList;

int  edit_row = -1;
int  edit_col = -1;
HWND hEdit = NULL;

int  capturing = 0;
int  cap_row = -1;

char ini_path[MAX_PATH];

NOTIFYICONDATAA nid = {0};
int tray_added = 0;

void set_status(const char *text)
{
    SetDlgItemText(win, IDC_STATIC_STATUS, text);
}

void strip_newlines(char *s)
{
    for (; *s; s++) {
        if (*s == '\r' || *s == '\n') *s = ' ';
    }
}

void format_hotkey(UINT mods, UINT vk, char *out, int out_size)
{
    out[0] = 0;
    if (vk == 0) return;

    if (mods & MOD_CONTROL) strcat_s(out, out_size, "Ctrl+");
    if (mods & MOD_ALT)     strcat_s(out, out_size, "Alt+");
    if (mods & MOD_SHIFT)   strcat_s(out, out_size, "Shift+");
    if (mods & MOD_WIN)     strcat_s(out, out_size, "Win+");

    char key[16] = {0};

    if (vk >= 'A' && vk <= 'Z') {
        key[0] = (char)vk;
    } else if (vk >= '0' && vk <= '9') {
        key[0] = (char)vk;
    } else if (vk >= VK_F1 && vk <= VK_F12) {
        sprintf_s(key, sizeof(key), "F%d", vk - VK_F1 + 1);
    } else {
        switch (vk) {
        case VK_SPACE:   strcpy_s(key, sizeof(key), "Space");   break;
        case VK_RETURN:  strcpy_s(key, sizeof(key), "Enter");   break;
        case VK_ESCAPE:  strcpy_s(key, sizeof(key), "Esc");     break;
        case VK_TAB:     strcpy_s(key, sizeof(key), "Tab");     break;
        case VK_BACK:    strcpy_s(key, sizeof(key), "Back");    break;
        case VK_DELETE:  strcpy_s(key, sizeof(key), "Del");     break;
        case VK_INSERT:  strcpy_s(key, sizeof(key), "Ins");     break;
        case VK_HOME:    strcpy_s(key, sizeof(key), "Home");    break;
        case VK_END:     strcpy_s(key, sizeof(key), "End");     break;
        case VK_PRIOR:   strcpy_s(key, sizeof(key), "PgUp");    break;
        case VK_NEXT:    strcpy_s(key, sizeof(key), "PgDn");    break;
        case VK_LEFT:    strcpy_s(key, sizeof(key), "Left");    break;
        case VK_RIGHT:   strcpy_s(key, sizeof(key), "Right");   break;
        case VK_UP:      strcpy_s(key, sizeof(key), "Up");      break;
        case VK_DOWN:    strcpy_s(key, sizeof(key), "Down");    break;
        default:
            sprintf_s(key, sizeof(key), "0x%02X", vk);
            break;
        }
    }
    strcat_s(out, out_size, key);
}

int parse_hotkey(const char *text, UINT *mods, UINT *vk)
{
    *mods = 0;
    *vk = 0;
    if (!text || !*text) return 0;

    char buf[128];
    strncpy_s(buf, sizeof(buf), text, _TRUNCATE);

    char *token = strtok(buf, "+");
    char *last = NULL;
    while (token) {
        while (*token == ' ') token++;
        char *end = token + strlen(token) - 1;
        while (end > token && *end == ' ') *end-- = 0;

        if (_stricmp(token, "Ctrl") == 0 || _stricmp(token, "Control") == 0)
            *mods |= MOD_CONTROL;
        else if (_stricmp(token, "Alt") == 0)
            *mods |= MOD_ALT;
        else if (_stricmp(token, "Shift") == 0)
            *mods |= MOD_SHIFT;
        else if (_stricmp(token, "Win") == 0)
            *mods |= MOD_WIN;
        else
            last = token;

        token = strtok(NULL, "+");
    }

    if (!last) return 0;

    if (strlen(last) == 1) {
        char c = last[0];
        if (c >= 'a' && c <= 'z') c -= 32;
        if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
            *vk = (UINT)c;
            return 1;
        }
    }

    if ((last[0] == 'F' || last[0] == 'f') && strlen(last) <= 3) {
        int n = atoi(last + 1);
        if (n >= 1 && n <= 12) {
            *vk = VK_F1 + (n - 1);
            return 1;
        }
    }

    if (_stricmp(last, "Space") == 0)  { *vk = VK_SPACE;  return 1; }
    if (_stricmp(last, "Enter") == 0)  { *vk = VK_RETURN; return 1; }
    if (_stricmp(last, "Esc") == 0)    { *vk = VK_ESCAPE; return 1; }
    if (_stricmp(last, "Tab") == 0)    { *vk = VK_TAB;    return 1; }
    if (_stricmp(last, "Back") == 0)   { *vk = VK_BACK;   return 1; }
    if (_stricmp(last, "Del") == 0)    { *vk = VK_DELETE; return 1; }
    if (_stricmp(last, "Ins") == 0)    { *vk = VK_INSERT; return 1; }
    if (_stricmp(last, "Home") == 0)   { *vk = VK_HOME;   return 1; }
    if (_stricmp(last, "End") == 0)    { *vk = VK_END;    return 1; }
    if (_stricmp(last, "PgUp") == 0)   { *vk = VK_PRIOR;  return 1; }
    if (_stricmp(last, "PgDn") == 0)   { *vk = VK_NEXT;   return 1; }
    if (_stricmp(last, "Left") == 0)   { *vk = VK_LEFT;   return 1; }
    if (_stricmp(last, "Right") == 0)  { *vk = VK_RIGHT;  return 1; }
    if (_stricmp(last, "Up") == 0)     { *vk = VK_UP;     return 1; }
    if (_stricmp(last, "Down") == 0)   { *vk = VK_DOWN;   return 1; }

    return 0;
}

void get_ext(const char *cmd, char *ext, int ext_size)
{
    ext[0] = 0;
    if (!cmd || !*cmd) return;
    while (*cmd == ' ') cmd++;

    char path[512];
    if (*cmd == '"') {
        cmd++;
        const char *p = strchr(cmd, '"');
        if (p) {
            int len = (int)(p - cmd);
            if (len >= (int)sizeof(path)) len = sizeof(path) - 1;
            memcpy(path, cmd, len);
            path[len] = 0;
        } else {
            strncpy_s(path, sizeof(path), cmd, _TRUNCATE);
        }
    } else {
        const char *p = strchr(cmd, ' ');
        int len = p ? (int)(p - cmd) : (int)strlen(cmd);
        if (len >= (int)sizeof(path)) len = sizeof(path) - 1;
        memcpy(path, cmd, len);
        path[len] = 0;
    }

    char *dot = strrchr(path, '.');
    if (!dot) return;
    dot++;

    int i = 0;
    while (dot[i] && i < ext_size - 1) {
        ext[i] = (char)tolower((unsigned char)dot[i]);
        i++;
    }
    ext[i] = 0;
}

void unregister_item(int idx)
{
    if (idx < 0 || idx >= item_count) return;
    if (items[idx].hk_id != 0) {
        UnregisterHotKey(win, items[idx].hk_id);
        items[idx].hk_id = 0;
    }
}

void unregister_all(void)
{
    for (int i = 0; i < item_count; i++) unregister_item(i);
}

void run_item(int idx)
{
    if (idx < 0 || idx >= item_count) return;
    if (items[idx].cmd[0] == 0) return;

    char exe[512] = {0};
    char args[1024] = {0};

    const char *cmd = items[idx].cmd;
    while (*cmd == ' ') cmd++;

    if (*cmd == '"') {
        cmd++;
        const char *p = strchr(cmd, '"');
        if (p) {
            int len = (int)(p - cmd);
            if (len >= (int)sizeof(exe)) len = sizeof(exe) - 1;
            memcpy(exe, cmd, len);
            exe[len] = 0;
            p++;
            while (*p == ' ') p++;
            strncpy_s(args, sizeof(args), p, _TRUNCATE);
        } else {
            strncpy_s(exe, sizeof(exe), cmd, _TRUNCATE);
        }
    } else {
        const char *p = strchr(cmd, ' ');
        if (p) {
            int len = (int)(p - cmd);
            if (len >= (int)sizeof(exe)) len = sizeof(exe) - 1;
            memcpy(exe, cmd, len);
            exe[len] = 0;
            p++;
            while (*p == ' ') p++;
            strncpy_s(args, sizeof(args), p, _TRUNCATE);
        } else {
            strncpy_s(exe, sizeof(exe), cmd, _TRUNCATE);
        }
    }

    char ext[16];
    get_ext(exe, ext, sizeof(ext));

    char dir[512];
    strncpy_s(dir, sizeof(dir), exe, _TRUNCATE);
    char *slash = strrchr(dir, '\\');
    if (slash) *slash = 0;
    else dir[0] = 0;

    char full[1600];

    if (strcmp(ext, "bat") == 0 || strcmp(ext, "cmd") == 0) {
        sprintf_s(full, sizeof(full), "cmd.exe /c \"%s\" %s", exe, args);
    } else {
        if (args[0])
            sprintf_s(full, sizeof(full), "\"%s\" %s", exe, args);
        else
            sprintf_s(full, sizeof(full), "\"%s\"", exe);
    }

    STARTUPINFOA si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));

    if (CreateProcessA(NULL, full, NULL, NULL, FALSE, 0, NULL,
                       dir[0] ? dir : NULL, &si, &pi)) {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        set_status("已启动。");
    } else {
        char msg[128];
        sprintf_s(msg, sizeof(msg), "启动失败,错误码 %lu", GetLastError());
        set_status(msg);
    }
}

void set_row(int row, const HotkeyItem *it)
{
    LVITEM lvi;
    ZeroMemory(&lvi, sizeof(lvi));

    lvi.mask = LVIF_TEXT;
    lvi.iItem = row;
    lvi.iSubItem = 0;
    lvi.pszText = (LPSTR)it->name;
    if (row >= ListView_GetItemCount(hList))
        ListView_InsertItem(hList, &lvi);
    else
        ListView_SetItem(hList, &lvi);

    ListView_SetItemText(hList, row, 1, (LPSTR)it->cmd);
    ListView_SetItemText(hList, row, 2, (LPSTR)it->hotkey_text);
    ListView_SetCheckState(hList, row, it->checked);
}

int register_item(int idx)
{
    if (idx < 0 || idx >= item_count) return 0;
    if (items[idx].vk == 0) return 0;

    int id = HOTKEY_BASE + items[idx].uid;
    if (RegisterHotKey(win, id, items[idx].mods, items[idx].vk)) {
        items[idx].hk_id = id;
        return 1;
    }
    return 0;
}

void end_edit(int save)
{
    if (!hEdit || edit_row < 0 || edit_col < 0) {
        if (hEdit) { DestroyWindow(hEdit); hEdit = NULL; }
        edit_row = edit_col = -1;
        capturing = 0;
        return;
    }

    if (save) {
        if (edit_col == 0) {
            char buf[512];
            GetWindowTextA(hEdit, buf, sizeof(buf));
            strip_newlines(buf);
            strncpy_s(items[edit_row].name, sizeof(items[edit_row].name), buf, _TRUNCATE);
            ListView_SetItemText(hList, edit_row, 0, (LPSTR)items[edit_row].name);
        } else if (edit_col == 1) {
            char buf[512];
            GetWindowTextA(hEdit, buf, sizeof(buf));
            strip_newlines(buf);
            strncpy_s(items[edit_row].cmd, sizeof(items[edit_row].cmd), buf, _TRUNCATE);
            ListView_SetItemText(hList, edit_row, 1, (LPSTR)items[edit_row].cmd);
        } else if (edit_col == 2) {
            ListView_SetItemText(hList, edit_row, 2, (LPSTR)items[edit_row].hotkey_text);
        }
    }

    DestroyWindow(hEdit);
    hEdit = NULL;
    edit_row = edit_col = -1;
    capturing = 0;
}

void begin_edit(int row, int col)
{
    if (row < 0 || row >= item_count) return;
    if (col < 0 || col > 2) return;

    end_edit(1);

    RECT rc;
    if (!ListView_GetSubItemRect(hList, row, col, LVIR_BOUNDS, &rc)) return;

    int col_width = 0;
    if (col == 0) col_width = 80;
    else if (col == 1) col_width = 300;
    else if (col == 2) col_width = 100;
    rc.right = rc.left + col_width;

    edit_row = row;
    edit_col = col;

    DWORD style = WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL;
    if (col == 2) style |= ES_READONLY;

    hEdit = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
                           style,
                           rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
                           hList, NULL, GetModuleHandle(NULL), NULL);

    if (col == 0) SetWindowTextA(hEdit, items[row].name);
    else if (col == 1) SetWindowTextA(hEdit, items[row].cmd);
    else if (col == 2) {
        SetWindowTextA(hEdit, items[row].hotkey_text);
        capturing = 1;
        cap_row = row;
    }

    SetFocus(hEdit);
    SendMessage(hEdit, EM_SETSEL, 0, -1);
}

void add_item(void)
{
    if (item_count >= MAX_ITEMS) { set_status("列表已满。"); return; }

    HotkeyItem *it = &items[item_count];
    memset(it, 0, sizeof(*it));
    strcpy_s(it->name, sizeof(it->name), "新项目");
    it->uid = next_uid++;

    set_row(item_count, it);
    item_count++;

    ListView_SetItemState(hList, item_count - 1,
                          LVIS_SELECTED | LVIS_FOCUSED,
                          LVIS_SELECTED | LVIS_FOCUSED);
    ListView_EnsureVisible(hList, item_count - 1, FALSE);
    set_status("已添加。");
}

void del_item(void)
{
    int sel = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
    if (sel < 0) { set_status("未选中任何行。"); return; }

    end_edit(1);

    unregister_item(sel);

    memmove(&items[sel], &items[sel + 1], (item_count - sel - 1) * sizeof(HotkeyItem));
    item_count--;
    ListView_DeleteItem(hList, sel);

    set_status("已删除。");
}

void save_ini(void)
{
    char buf[64];

    end_edit(1);

    WritePrivateProfileStringA(NULL, NULL, NULL, ini_path);

    sprintf_s(buf, sizeof(buf), "%d", item_count);
    WritePrivateProfileStringA("General", "count", buf, ini_path);

    for (int i = 0; i < item_count; i++) {
        char sec[32];
        sprintf_s(sec, sizeof(sec), "Item%d", i);

        strip_newlines(items[i].name);
        strip_newlines(items[i].cmd);
        strip_newlines(items[i].hotkey_text);

        WritePrivateProfileStringA(sec, "name",    items[i].name,        ini_path);
        WritePrivateProfileStringA(sec, "cmd",     items[i].cmd,         ini_path);
        WritePrivateProfileStringA(sec, "hotkey",  items[i].hotkey_text, ini_path);

        sprintf_s(buf, sizeof(buf), "%d", items[i].checked ? 1 : 0);
        WritePrivateProfileStringA(sec, "checked", buf, ini_path);
    }

    set_status("已保存到 hotkey.ini。");
}

void load_ini(void)
{
    char buf[64];

    GetPrivateProfileStringA("General", "count", "0", buf, sizeof(buf), ini_path);
    int n = atoi(buf);
    if (n <= 0) return;
    if (n > MAX_ITEMS) n = MAX_ITEMS;

    item_count = 0;
    next_uid = 0;

    for (int i = 0; i < n; i++) {
        char sec[32];
        sprintf_s(sec, sizeof(sec), "Item%d", i);

        HotkeyItem *it = &items[item_count];
        memset(it, 0, sizeof(*it));
        it->uid = next_uid++;

        GetPrivateProfileStringA(sec, "name", "",
            it->name, sizeof(it->name), ini_path);

        GetPrivateProfileStringA(sec, "cmd", "",
            it->cmd, sizeof(it->cmd), ini_path);

        GetPrivateProfileStringA(sec, "hotkey", "",
            it->hotkey_text, sizeof(it->hotkey_text), ini_path);

        GetPrivateProfileStringA(sec, "checked", "0", buf, sizeof(buf), ini_path);
        it->checked = (atoi(buf) != 0) ? 1 : 0;

        parse_hotkey(it->hotkey_text, &it->mods, &it->vk);

        set_row(item_count, it);
        item_count++;
    }

    for (int i = 0; i < item_count; i++) {
        if (items[i].checked && items[i].vk != 0) {
            if (!register_item(i)) {
                items[i].checked = 0;
                ListView_SetCheckState(hList, i, 0);
            }
        }
    }
}

void show_tray(void)
{
    if (!tray_added) {
        Shell_NotifyIconA(NIM_ADD, &nid);
        tray_added = 1;
    }
}

void hide_tray(void)
{
    if (tray_added) {
        Shell_NotifyIconA(NIM_DELETE, &nid);
        tray_added = 0;
    }
}

LRESULT CALLBACK HotkeyEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
                                UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    switch (msg)
    {
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
        {
            UINT vk = (UINT)wParam;
            UINT mods = 0;

            if (GetKeyState(VK_CONTROL) & 0x8000) mods |= MOD_CONTROL;
            if (GetKeyState(VK_MENU)    & 0x8000) mods |= MOD_ALT;
            if (GetKeyState(VK_SHIFT)   & 0x8000) mods |= MOD_SHIFT;
            if ((GetKeyState(VK_LWIN) & 0x8000) || (GetKeyState(VK_RWIN) & 0x8000))
                mods |= MOD_WIN;

            if (vk == VK_CONTROL || vk == VK_SHIFT || vk == VK_MENU ||
                vk == VK_LWIN || vk == VK_RWIN || vk == VK_TAB)
                return 0;

            if (vk == VK_ESCAPE) {
                end_edit(0);
                SetFocus(hList);
                return 0;
            }

            if (vk == VK_RETURN) {
                end_edit(1);
                SetFocus(hList);
                return 0;
            }

            if (cap_row >= 0 && cap_row < item_count) {
                items[cap_row].mods = mods;
                items[cap_row].vk = vk;
                format_hotkey(mods, vk, items[cap_row].hotkey_text,
                              sizeof(items[cap_row].hotkey_text));

                SetWindowTextA(hwnd, items[cap_row].hotkey_text);
                ListView_SetItemText(hList, cap_row, 2, (LPSTR)items[cap_row].hotkey_text);

                if (items[cap_row].checked) {
                    unregister_item(cap_row);
                    if (register_item(cap_row)) {
                        set_status("已注册热键。");
                    } else {
                        items[cap_row].checked = 0;
                        ListView_SetCheckState(hList, cap_row, 0);
                        set_status("快捷键冲突或格式无效,注册失败。");
                    }
                }
            }
            return 0;
        }
        break;

    case WM_CHAR:
    case WM_SYSCHAR:
        return 0;
    }

    return DefSubclassProc(hwnd, msg, wParam, lParam);
}

INT_PTR CALLBACK DialogProc(HWND h, UINT m, WPARAM w, LPARAM l)
{
    switch (m) {
    case WM_INITDIALOG:
        {
            win = h;
            hList = GetDlgItem(h, IDC_LIST_HOTKEY);

            GetModuleFileNameA(NULL, ini_path, MAX_PATH);
            char *p = strrchr(ini_path, '\\');
            if (p) *(p + 1) = 0;
            strcat_s(ini_path, sizeof(ini_path), "hotkey.ini");

            SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
                LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES);

            LVCOLUMN lvc;
            ZeroMemory(&lvc, sizeof(lvc));
            lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

            lvc.iSubItem = 0;
            lvc.pszText = "名称";
            lvc.cx = 80;
            lvc.fmt = LVCFMT_LEFT;
            ListView_InsertColumn(hList, 0, &lvc);

            lvc.iSubItem = 1;
            lvc.pszText = "路径";
            lvc.cx = 280;
            ListView_InsertColumn(hList, 1, &lvc);

            lvc.iSubItem = 2;
            lvc.pszText = "快捷键";
            lvc.cx = 100;
            ListView_InsertColumn(hList, 2, &lvc);

            nid.cbSize = sizeof(nid);
            nid.hWnd = h;
            nid.uID = 1;
            nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
            nid.uCallbackMessage = WM_TRAYICON;
            nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
            strcpy_s(nid.szTip, sizeof(nid.szTip), "快捷键管理");

            load_ini();
            set_status("就绪。");
            return TRUE;
        }

    case WM_COMMAND:
        switch (LOWORD(w)) {
        case IDC_BTN_ADD:  add_item();     break;
        case IDC_BTN_DEL:  del_item();     break;
        case IDC_BTN_DOWN: save_ini();     break;
        case IDC_BTN_TRAY:
            show_tray();
            ShowWindow(h, SW_HIDE);
            break;
        case IDC_BTN_CLOSE:
        case IDCANCEL:
            hide_tray();
            unregister_all();
            EndDialog(h, 0);
            break;
        }
        return TRUE;

    case WM_TRAYICON:
        {
            if (l == WM_LBUTTONDBLCLK) {
                ShowWindow(h, SW_SHOW);
                SetForegroundWindow(h);
                hide_tray();
            } else if (l == WM_RBUTTONUP) {
                POINT pt;
                GetCursorPos(&pt);
                HMENU menu = CreatePopupMenu();
                AppendMenuA(menu, MF_STRING, 1, "显示");
                AppendMenuA(menu, MF_STRING, 2, "退出");
                SetForegroundWindow(h);
                int cmd = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_NONOTIFY,
                                         pt.x, pt.y, 0, h, NULL);
                DestroyMenu(menu);
                if (cmd == 1) {
                    ShowWindow(h, SW_SHOW);
                    SetForegroundWindow(h);
                    hide_tray();
                } else if (cmd == 2) {
                    hide_tray();
                    unregister_all();
                    EndDialog(h, 0);
                }
            }
        }
        return TRUE;

    case WM_NOTIFY:
        {
            NMHDR *nh = (NMHDR*)l;
            if (nh->idFrom == IDC_LIST_HOTKEY) {

                if (nh->code == NM_CLICK) {
                    LPNMITEMACTIVATE nia = (LPNMITEMACTIVATE)l;
                    if (nia->iItem >= 0) {

                        LVHITTESTINFO hti;
                        ZeroMemory(&hti, sizeof(hti));
                        hti.pt = nia->ptAction;
                        hti.iItem = nia->iItem;
                        hti.iSubItem = nia->iSubItem;
                        ListView_SubItemHitTest(hList, &hti);

                        if (hti.flags & LVHT_ONITEMSTATEICON) {
                            break;
                        }

                        int col = nia->iSubItem;
                        if (col >= 0 && col <= 2) {
                            begin_edit(nia->iItem, col);
                            if (col == 2 && hEdit) {
                                SetWindowSubclass(hEdit, HotkeyEditProc, 1, 0);
                            }
                        }
                    }
                    return TRUE;
                }

                if (nh->code == LVN_ITEMCHANGED) {
                    LPNMLISTVIEW nlv = (LPNMLISTVIEW)l;
                    if ((nlv->uChanged & LVIF_STATE) &&
                        ((nlv->uNewState ^ nlv->uOldState) & LVIS_STATEIMAGEMASK)) {

                        int row = nlv->iItem;
                        if (row < 0 || row >= item_count) return TRUE;

                        BOOL now_checked = ListView_GetCheckState(hList, row);

                        if (now_checked && !items[row].checked) {
                            if (register_item(row)) {
                                items[row].checked = 1;
                                set_status("已注册热键。");
                            } else {
                                items[row].checked = 0;
                                ListView_SetCheckState(hList, row, FALSE);
                                set_status("快捷键冲突或格式无效,注册失败。");
                            }
                        } else if (!now_checked && items[row].checked) {
                            unregister_item(row);
                            items[row].checked = 0;
                            set_status("已注销热键。");
                        }
                    }
                    return TRUE;
                }
            }
        }
        break;

    case WM_HOTKEY:
        {
            int id = (int)w;
            for (int i = 0; i < item_count; i++) {
                if (items[i].hk_id == id && items[i].checked) {
                    run_item(i);
                    break;
                }
            }
        }
        return TRUE;

    case WM_DESTROY:
        hide_tray();
        unregister_all();
        break;
    }
    return FALSE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
    INITCOMMONCONTROLSEX cc;
    cc.dwSize = sizeof(cc);
    cc.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES;
    InitCommonControlsEx(&cc);

    DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DialogProc);
    return 0;
}


[C] 纯文本查看 复制代码
// resource.rc
// 此文件由 RisohEditor 6.2.1 自动生成。
// &#8224; <-- 这个匕首符号有助于 UTF-8 检测。
#include "resource.h"
#define APSTUDIO_HIDDEN_SYMBOLS
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#undef APSTUDIO_HIDDEN_SYMBOLS
#pragma code_page(65001) // UTF-8

LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT

IDD_MAIN DIALOGEX 0, 0, 269, 214
CAPTION "快捷键管理"
STYLE DS_MODALFRAME | DS_SHELLFONT | WS_POPUPWINDOW | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX
FONT 9, "Microsoft YaHei", 400, 0, 0
{
    CONTROL "", IDC_LIST_HOTKEY, "SysListView32", LVS_SHOWSELALWAYS | LVS_SINGLESEL | LVS_REPORT | WS_BORDER | WS_TABSTOP, 5, 3, 261, 187
    LTEXT "就绪。", IDC_STATIC_STATUS, 7, 192, 254, 12
    PUSHBUTTON "添加", IDC_BTN_ADD, 6, 204, 20, 10
    PUSHBUTTON "删除", IDC_BTN_DEL, 30, 204, 20, 10
    PUSHBUTTON "保存", IDC_BTN_DOWN, 55, 204, 20, 10
    PUSHBUTTON "托盘", IDC_BTN_TRAY, 80, 204, 20, 10
    PUSHBUTTON "关闭", IDC_BTN_CLOSE, 203, 204, 60, 10
}

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

#ifdef APSTUDIO_INVOKED

1 TEXTINCLUDE
{
    "resource.h\0"
}

2 TEXTINCLUDE
{
    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include <windows.h>\r\n"
    "#include <commctrl.h>\r\n"
    "#include <richedit.h>\r\n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "\0"
}

3 TEXTINCLUDE
{
    "\r\n"
    "\0"
}

#endif // def APSTUDIO_INVOKED
#ifndef APSTUDIO_INVOKED

#endif // ndef APSTUDIO_INVOKED

001.png (26.62 KB, 下载次数: 0)

001.png

hotkey.7z

18.15 KB, 下载次数: 28, 下载积分: 吾爱币 -1 CB

已编译含源码

免费评分

参与人数 3吾爱币 +9 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
laozhang4201 + 1 + 1 热心回复!
Good11 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
 楼主| ashi876 发表于 2026-9-26 13:04 |楼主
本帖最后由 ashi876 于 2026-9-26 13:07 编辑

msys2 ucrt gcc编译命令
windres resource.rc -O coff -o resource.o
gcc -O2 -s -fexec-charset=GBK main.c resource.o -o HotkeyManager.exe -mwindows -lcomctl32 -lshell32
如果用vc2022
rc resource.rc
cl /nologo /W3 /D_CRT_SECURE_NO_WARNINGS /UUNICODE /U_UNICODE main.c resource.res /Fe:hotkey.exe /link user32.lib gdi32.lib comctl32.lib shell32.lib /subsystem:windows

3#
esclong 发表于 2026-9-26 13:24
4#
esclong 发表于 2026-9-26 13:26
5#
xiong070820 发表于 2026-9-26 14:34
唉!搞得好麻烦
6#
lxhwan100 发表于 2026-9-26 19:44
hotkeyp挺好用
7#
Huanxiang2 发表于 2026-9-28 09:12
ashi876 发表于 2026-9-26 13:04
msys2 ucrt gcc编译命令
windres resource.rc -O coff -o resource.o
gcc -O2 -s -fexec-charset=GBK mai ...

你的代码非常好,赞
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-9-29 10:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表