繁体   English   中英

在 c++ 中使用指针

[英]Use pointers in c++

我需要使用“CreateTimerQueueTimer”来创建一个计时器。

参数必须作为指针传递。

这是我的代码:

void sendKey(int vk, ) {

    KEYBDINPUT  kb = { 0 };
    INPUT       Input = { 0 };
    int scan = MapVirtualKey(vk, 0);

    /* Generate a "key down" */
    kb.dwFlags = KEYEVENTF_EXTENDEDKEY;
    kb.wVk = vk;
    Input.type = INPUT_KEYBOARD;
    Input.ki = kb;
    Input.ki.wScan = scan;
    SendInput(1, &Input, sizeof(Input));

    /* Generate a "key up" */
    ZeroMemory(&kb, sizeof(KEYBDINPUT));
    ZeroMemory(&Input, sizeof(INPUT));
    kb.dwFlags = KEYEVENTF_KEYUP;
    KEYEVENTF_EXTENDEDKEY;
    kb.wVk = vk;
    Input.type = INPUT_KEYBOARD;
    Input.ki = kb;
    Input.ki.wScan = scan;
    SendInput(1, &Input, sizeof(Input));

    return;
}


void CALLBACK ProcessRequests(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    sendKey((int)lpParameter, true);

}


void myfunc()
{
    int VirtualKey=50;

    CreateTimerQueueTimer(&m_hTimer, nullptr, &ProcessRequests, &VirtualKey, 100, 0, WT_EXECUTEONLYONCE);
}

在“ProcessRequests”中有 function“sendKey”接受 integer 作为参数,但 lpParameter 是一个指针。 如何传递“lpParameter”的值并将其转换为 integer?

谢谢 !

这有两个问题:

  1. lpParameter指向一个int ,但您将视为一个int
  2. lpParameterintmyfunc的本地变量,因此在您的计时器触发并且您的回调被调用时不再存在

第一个问题很容易解决,只需改变你解释lpParameter的方式:

void CALLBACK ProcessRequests(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    int* param = static_cast<int*>(lpParameter);
    sendKey(*param, true);
}

后一个问题有点棘手,您如何解决它取决于您的需求。 由于看起来这些函数都是某些 class 的成员(基于m_hTimer的名称),您可能希望将密钥代码存储为 class 数据成员而不是myfunc中的局部变量:

class MyClass
{
    int VirtualKey;

    // ...

    void myfunc()
    {
        VirtualKey = 50;  // set the class member instead of
                          // creating a local variable

        CreateTimerQueueTimer(
            &m_hTimer,
            nullptr,
            &ProcessRequests,
            &VirtualKey,
            100,
            0,
            WT_EXECUTEONLYONCE
        );
    }

    // ...
};

如果这些函数不是 class 的一部分,或者您不想保留任何类型的全局 state 多次调用myfunc可能会干扰,那么另一种方法是动态分配参数。 请记住在ProcessRequests完成后释放它:

void CALLBACK ProcessRequests(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    int* param = static_cast<int*>(lpParameter);
    sendKey(*param, true);
    delete param;
}

void myfunc()
{
    int* VirtualKey = new int(50);

    CreateTimerQueueTimer(
        &m_hTimer,
        nullptr,
        &ProcessRequests,
        VirtualKey,  // NOTE: no &, VirtualKey is already a pointer
        100,
        0,
        WT_EXECUTEONLYONCE
    );
}

如果可能的话,我会推荐前一种方法。 如果您忘记释放某些代码路径中的关键代码(即,如果您稍后添加代码以在计时器运行之前取消计时器),则很容易创建 memory 泄漏。

您正在向CreateTimerQueueTimer()传递一个指向本地int变量的int*指针,但随后您将ProcessRequests()中的lpParameter视为它是int值而不是它实际上是的int*指针。

int传递到回调中很好,但您需要将类型转换的值传递给指针,例如:

void CALLBACK ProcessRequests(PVOID lpParameter, BOOLEAN /*TimerOrWaitFired*/)
{
    sendKey(static_cast<int>(reinterpret_cast<intptr_t>(lpParameter)), ...);
}

void myfunc()
{
    int VirtualKey = 50;

    CreateTimerQueueTimer(..., reinterpret_cast<void*>(static_cast<intptr_t>(VirtualKey)), ...);
}

此外,一次使用 1 个INPUT调用SendInput() 2 次而在调用之间没有任何延迟是代码中的逻辑错误,可能会导致输入队列出现问题。 由于您的代码没有延迟,因此您应该使用 2 个INPUT调用SendInput() 1 次,例如:

void sendKey(int vk, ... ) {

    INPUT Inputs[2] = { };
    ...

    /* Generate a "key down" */
    Inputs[0].type = INPUT_KEYBOARD;
    Inputs[0].ki.dwFlags = ...;
    Inputs[0].ki.wVk = ...;
    Inputs[0].ki.wScan = ...;

    /* Generate a "key up" */
    Inputs[1] = Inputs[0];
    Inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;

    SendInput(2, Inputs, sizeof(INPUT));
}

您可以尝试从 void* 转换为 int* ,然后再转换为 int ,如下所示:

void CALLBACK ProcessRequests(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    sendKey(*(int*)lpParameter, true);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM