You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Mac版MT5中如何用MQL5检测按键(含修饰键与ESC键)

在Mac版MT5中用MQL5检测按键输入的解决方案

原代码依赖Windows平台的user32.dll,Mac系统不支持该动态库,因此需要替换为Mac原生的CoreGraphics API实现按键状态检测,以下是具体方案:

核心实现思路

Mac平台通过导入系统CoreGraphics框架的CGEventSourceKeyState函数,直接获取系统级的按键按下状态,该函数支持检测所有标准键盘按键,包括修饰键与ESC键。

Mac专用按键检测代码

// 导入Mac CoreGraphics框架的按键状态检测函数
#import "/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics"
    bool CGEventSourceKeyState(uint sourceState, CGKeyCode key);
#import

// --- Mac 按键码定义 ---
#define VK_MAC_SHIFT    0x38    // SHIFT键
#define VK_MAC_CONTROL  0x3B    // CONTROL键
#define VK_MAC_OPTION   0x3A    // OPTION键(等效Windows的ALT)
#define VK_MAC_COMMAND  0x37    // COMMAND键(Mac核心修饰键)
#define VK_MAC_ESCAPE   0x35    // ESC键

// 通用按键检测函数
bool IsKeyDownMac(CGKeyCode key)
{
    // kCGEventSourceStateHIDSystemState 代表读取系统全局的按键状态
    return CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key);
}

// 封装常用修饰键检测
bool IsMacShift()          { return IsKeyDownMac(VK_MAC_SHIFT); }
bool IsMacControl()        { return IsKeyDownMac(VK_MAC_CONTROL); }
bool IsMacOption()         { return IsKeyDownMac(VK_MAC_OPTION); }
bool IsMacCommand()        { return IsKeyDownMac(VK_MAC_COMMAND); }
bool IsMacEscape()         { return IsKeyDownMac(VK_MAC_ESCAPE); }

// 测试用:遍历所有可能键码,输出当前按下的按键代码
void GetMacKeyCodePressed()
{
    // Mac键码范围为0x00-0xFF,遍历该范围即可覆盖所有按键
    for (CGKeyCode k = 0; k <= 0xFF; k++)
    {
        if (IsKeyDownMac(k))
        {
            Print("当前按下的Mac键码: ", k);
        }
    }
}

跨平台兼容代码(同时支持Windows/Mac)

通过预编译指令区分平台,一键适配两种环境:

#ifdef __MQL5__
    #ifdef _WIN32
        // Windows平台原有实现
        #import "user32.dll"
            int GetKeyState(int nVirtKey);
        #import

        #define VK_SHIFT    0x10
        #define VK_CONTROL  0x11
        #define VK_ALT      0x12
        #define VK_ESCAPE   0x1B

        bool IsKeyDown(int nVirtKey)
        {
            return(GetKeyState(nVirtKey) > 1000);
        }

        bool IsShift()   { return IsKeyDown(VK_SHIFT); }
        bool IsCtrl()    { return IsKeyDown(VK_CONTROL); }
        bool IsAlt()     { return IsKeyDown(VK_ALT); }
        bool IsEscape()  { return IsKeyDown(VK_ESCAPE); }

    #elif __APPLE__
        // Mac平台实现
        #import "/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics"
            bool CGEventSourceKeyState(uint sourceState, CGKeyCode key);
        #import

        #define VK_MAC_SHIFT    0x38
        #define VK_MAC_CONTROL  0x3B
        #define VK_MAC_OPTION   0x3A
        #define VK_MAC_COMMAND  0x37
        #define VK_MAC_ESCAPE   0x35

        bool IsKeyDownMac(CGKeyCode key)
        {
            return CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key);
        }

        bool IsShift()     { return IsKeyDownMac(VK_MAC_SHIFT); }
        bool IsCtrl()      { return IsKeyDownMac(VK_MAC_CONTROL); }
        bool IsAlt()       { return IsKeyDownMac(VK_MAC_OPTION); }
        bool IsCommand()   { return IsKeyDownMac(VK_MAC_COMMAND); }
        bool IsEscape()    { return IsKeyDownMac(VK_MAC_ESCAPE); }

    #endif
#endif

配合鼠标点击使用示例

在OnChartEvent函数中结合鼠标事件检测修饰键组合:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
    if(id == CHARTEVENT_CLICK)
    {
        // 检测Command+Shift+鼠标点击
        if(IsMacCommand() && IsMacShift())
        {
            Print("触发Command+Shift+左键点击操作");
            // 执行自定义业务逻辑
        }
        // 检测ESC键按下
        else if(IsMacEscape())
        {
            Print("ESC键按下,取消当前操作");
        }
    }
}

注意事项

  1. 系统权限设置:Mac系统需给MT5开启「输入监控」权限,路径为:系统设置 > 隐私与安全性 > 输入监控,勾选MT5。
  2. 键码差异:Mac与Windows的按键码完全不同,若需跨平台逻辑,需注意修饰键的业务等效性(比如Windows的Ctrl对应Mac的Command或Control,需根据需求调整)。
  3. 检测频率:避免高频循环检测按键,建议在OnTimer或OnChartEvent中按需调用检测函数。

内容的提问来源于stack exchange,提问作者Jeronymite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:43:19