C++ C++;具有平台API的全局热键

C++ C++;具有平台API的全局热键,c++,qt,hotkeys,global-hotkey,C++,Qt,Hotkeys,Global Hotkey,我正在用C++/Qt开发一个在Windows、OSX和Linux上截图的应用程序。现在我需要设置全局热键,这样当应用程序在后台运行时,用户就可以截图了。我尝试使用Qxt和UGlobalHotkey,它们都是Qt库,但它们似乎都不起作用 我试图用Carbon为OSX实现它,但我需要调用一个类成员函数,这根本不起作用。有人能给我举个例子吗?你可以找到我的代码。我需要调用的函数是new_screenshot() 或者有没有其他方法可以实现这样的目标?我真的需要我的应用程序从后台截图,否则它是非常无用的

我正在用C++/Qt开发一个在Windows、OSX和Linux上截图的应用程序。现在我需要设置全局热键,这样当应用程序在后台运行时,用户就可以截图了。我尝试使用Qxt和UGlobalHotkey,它们都是Qt库,但它们似乎都不起作用

我试图用Carbon为OSX实现它,但我需要调用一个类成员函数,这根本不起作用。有人能给我举个例子吗?你可以找到我的代码。我需要调用的函数是new_screenshot()


或者有没有其他方法可以实现这样的目标?我真的需要我的应用程序从后台截图,否则它是非常无用的(是的,我应该在一开始就实现它,看看它是否工作)。每个平台都有一个单独的客户端(Cocoa Swift for OSX、GTK for Linux、C#client for Windows)会更好吗?在过去的几天里,我经常想到这一点。

我是否正确理解您想从热键事件处理程序调用
new\u屏幕截图
?如果是这样,
InstallApplicationEventHandler
允许您在第4个参数中传递指向用户数据的指针。将指针传递到
main窗口
实例(基于教程中的代码):

然后可以在事件处理程序中使用它

OSStatus MyHotKeyHandler(EventHandlerCallRef nextHandler,EventRef theEvent, void *userData)
{
//Do something once the key is pressed
static_cast<MainWindow*>(userData)->new_screenshot();
return noErr;
}
OSStatus MyHotKeyHandler(EventHandlerCallRef nextHandler、EventRef theEvent、void*用户数据)
{
//按键后做些什么
静态_cast(userData)->新_屏幕截图();
返回noErr;
}

我过去使用MFC和WIN32 API做了一些事情……因此它只在Windows上工作……但按
ALT+F10
可以隐藏/显示窗口

void CWinHideDlg::OnButtonActive() 
{
    CString tmp;
    GetDlgItemText(IDC_BUTTON_ACTIVE,tmp);
    if(0 == strcmp(tmp.GetBuffer(tmp.GetLength()),"Activate"))
    {
        m_myAtom=GlobalAddAtom("MY_GLOBAL_HOT_HIDE_KEY");
        int err=RegisterHotKey(this->GetSafeHwnd(),m_myAtom,MOD_ALT,VK_F10);
        SetDlgItemText(IDC_BUTTON_ACTIVE,"Stop");
        CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_UNHIDE);
        pBtn->EnableWindow(TRUE);
        SetDlgItemText(IDC_STATIC_INFO,"Set the mouse over the window \nand press ALT + F10 to hide it...");
    }
    else
    {
        UnregisterHotKey(this->GetSafeHwnd(),m_myAtom);
        GlobalDeleteAtom(m_myAtom);     
        CButton *pBtn = (CButton *)GetDlgItem(IDC_BUTTON_UNHIDE);
        pBtn->EnableWindow(FALSE);
        SetDlgItemText(IDC_BUTTON_ACTIVE,"Activate");

    }   
}
基本上,此代码激活/禁用热键
ALT+F10
,一旦激活,您可以通过将鼠标指针设置在窗口上并按下
ALT+F10
,隐藏/取消隐藏系统上正在运行的窗口

这是来自
WindowProc
功能:

if(message == WM_HOTKEY)
    {
        CString tmp;
        POINT pc;
        GetCursorPos(&pc);


        if(GetAsyncKeyState(VK_F10))
        {
            HWND hwnd=::WindowFromPoint(pc);            
            if(hwnd)
            {
                tmp.Format("%08Xh",hwnd);
                m_HideWins.InsertString(m_HideWins.GetCount(),tmp);
                ::ShowWindow(hwnd,SW_HIDE);
            }
        }
    } 
您可以使用该代码注册自己的热键,并使用它拍摄屏幕截图


希望对你有帮助

是的,这就是我要找的。我真的应该开始阅读文档了。不幸的是,它仍然不起作用。new_screenshot()永远不会被调用。是我当前拥有的。我发现您没有设置
EventTypeSpec
eventKind
成员。应该按下
KeventhotKeys
。这就成功了!非常感谢你。我可以问一下你是从哪里找到这个方法的吗?实际上,我只是想学习如何做一些更复杂的事情,根本找不到任何关于碳的文档,因为它似乎已被弃用。我正在我的应用程序中使用
JFHotkeyManager
。它在目标C中,但不应该太难理解:谢谢你的回答。我认为这将非常有用,因为我想在Windows、OSX和Linux上启用此功能。我已经读过windows API中的RegisterHotkey函数。但是->GetSafeHwnd()是如何工作的呢?我怎样才能让HWND通过?这可能会给你HWND:[链接]非常感谢!似乎正是我需要的Windows。太好了,祝你的项目好运。你能给我指出正确的方向吗?你似乎对此很了解,我认为我的现在可以工作了,因为每次我按组合键时,它都会打印0x16171fc0,但我的窗口从来没有出现过。我猜这是因为循环?我如何在不阻塞其余部分的情况下收听组合键?在单独的线程中运行它似乎不起作用,因为它不再检测热键组合。
if(message == WM_HOTKEY)
    {
        CString tmp;
        POINT pc;
        GetCursorPos(&pc);


        if(GetAsyncKeyState(VK_F10))
        {
            HWND hwnd=::WindowFromPoint(pc);            
            if(hwnd)
            {
                tmp.Format("%08Xh",hwnd);
                m_HideWins.InsertString(m_HideWins.GetCount(),tmp);
                ::ShowWindow(hwnd,SW_HIDE);
            }
        }
    }