为啥我不能在 CALLBACK 函数中使用此代码?

Posted

技术标签:

【中文标题】为啥我不能在 CALLBACK 函数中使用此代码?【英文标题】:why i can't using this code in CALLBACK Function?为什么我不能在 CALLBACK 函数中使用此代码? 【发布时间】:2017-04-28 17:37:39 【问题描述】:

我希望更改静态文本,但我不能,

LRESULT CALLBACK KeybdProc(int nCode, WPARAM wParam, LPARAM lParam)

    if ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))
    
        KBDLLHOOKSTRUCT *pKey = (KBDLLHOOKSTRUCT*)lParam;
        int key = pKey->vkCode;
        cout << key << " ";
        if (key == VK_INSERT)
        
        SetDlgItemText(IDC_STATUSTEXT, "On")
        
        if (key == VK_DELETE)
        
            SetDlgItemText(IDC_STATUSTEXT, "Off")
        
    
CallNextHookEx(KbHook, nCode, wParam, lParam);
return 0;



HHOOK KbHook;

BOOL CUSBDlg::OnInitDialog()

    CDialog::OnInitDialog();

SetDlgItemText(IDC_STATUSTEXT, "Successfully Loaded!!!");

cout << "Successfully Loaded !!!" << endl;
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);

HMODULE hInstance = GetModuleHandle(NULL);
KbHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeybdProc, hInstance, 0);

return TRUE;


错误“函数不接受2个参数”

我可以解决它吗?

我可以使用这个功能吗

void CUSBDlg::Pray(byte t, int i)

在 KeybdProc 中?

如果我尝试像这样使用这个功能

LRESULT CALLBACK KeybdProc(int nCode, WPARAM wParam, LPARAM lParam)

    if ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))
    
        KBDLLHOOKSTRUCT *pKey = (KBDLLHOOKSTRUCT*)lParam;
        int key = pKey->vkCode;
        cout << key << " ";
        if (key == VK_INSERT)
        
            SetDlgItemText(IDC_STATUSTEXT, "On")
            Pray(0x04, 6)
        
        if (key == VK_DELETE)
        
            SetDlgItemText(IDC_STATUSTEXT, "Off")
        
    
CallNextHookEx(KbHook, nCode, wParam, lParam);
return 0;


错误“未声明的标识符”

有人帮我解决这个问题 X(

【问题讨论】:

没有理由将KbHook 设为全局 - 根据文档,CallNextHookEx 的第一个参数被忽略。但是,您的问题看起来像您不知道如何在 C++ 中调用成员函数,这与 Windows API 无关,尽管第一个代码示例没有指出问题发生在哪里,而且很难测试自己因为这不是minimal reproducible example。 你能帮帮我吗:) ?? CUSBDlg::Pray()?读一两本书,那些文物就会消失。更严肃的一点是:无论您多么祈祷,除非您牢牢掌握 C++ 和 Windows API,否则您的 MFC 努力不会有好的结果。 【参考方案1】:

您的回调不是对话框类的非静态方法,因此它没有用于调用CWnd::SetDlgItemText()CUSBDlg::Prey() 方法的this 指针。您在Prey() 上收到“未声明的标识符”错误,因为范围内没有具有该名称的函数。并且您收到“函数不接受 2 个参数”错误,因为回调正在尝试调用 Win32 API SetDlgItemText() 函数,该函数在范围内但需要 3 个参数作为输入。

要解决这两个问题,您需要存储一个指向对话框的全局指针,以便回调可以在需要时访问它,例如:

CUSBDlg *Dlg;
HHOOK KbHook;

LRESULT CALLBACK KeybdProc(int nCode, WPARAM wParam, LPARAM lParam)

    if ((nCode == HC_ACTION) && (wParam == WM_KEYDOWN))
    
        KBDLLHOOKSTRUCT *pKey = (KBDLLHOOKSTRUCT*)lParam;
        int key = pKey->vkCode;
        cout << key << " ";
        if (key == VK_INSERT)
        
            Dlg->SetDlgItemText(IDC_STATUSTEXT, "On")
            Dlg->Pray(0x04, 6)
        
        if (key == VK_DELETE)
        
            Dlg->SetDlgItemText(IDC_STATUSTEXT, "Off")
        
    

    CallNextHookEx(KbHook, nCode, wParam, lParam);
    return 0;


BOOL CUSBDlg::OnInitDialog()

    CDialog::OnInitDialog();

    ...

    Dlg = this;

    GetModuleHandle(NULL);
    KbHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeybdProc, hInstance, 0);

    ...

【讨论】:

以上是关于为啥我不能在 CALLBACK 函数中使用此代码?的主要内容,如果未能解决你的问题,请参考以下文章

nodejs的回调函数里为啥需要return

为啥我不能在其他类或函数中使用我的 Propel ORM 类?

为啥要在ajax里面的请求地址加上callback=

为啥我不能删除 _mm_empty()?

为啥 Go Back 不能使用此源代码在 webview android 应用程序中工作?

为啥我不能继承这个变量?