简体   繁体   English

在 c++ 中使用指针

[英]Use pointers in c++

I need to use "CreateTimerQueueTimer" to create a timer.我需要使用“CreateTimerQueueTimer”来创建一个计时器。

The parameter must be pass as pointer.参数必须作为指针传递。

Here my code:这是我的代码:

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);
}

Inside "ProcessRequests" there is the function "sendKey" that accept integer as parameter but lpParameter is a pointer.在“ProcessRequests”中有 function“sendKey”接受 integer 作为参数,但 lpParameter 是一个指针。 How I can pass the value of "lpParameter" and convert it in integer?如何传递“lpParameter”的值并将其转换为 integer?

Thanks !谢谢 !

There are two problems with this:这有两个问题:

  1. lpParameter points to an int , but you're treating it as if it is an int lpParameter指向一个int ,但您将视为一个int
  2. The int pointed to by lpParameter is local to myfunc and therefore no longer exists by the time your timer fires and your callback gets called lpParameterintmyfunc的本地变量,因此在您的计时器触发并且您的回调被调用时不再存在

The first issue is simple to solve, just change the way you interpret lpParameter :第一个问题很容易解决,只需改变你解释lpParameter的方式:

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

The latter issue is a bit tougher, and how you solve it will depend on your needs.后一个问题有点棘手,您如何解决它取决于您的需求。 Since it looks like these functions are all members of some class (based on the name of m_hTimer ), you may want to store the key code as a class data member instead of a local variable in myfunc :由于看起来这些函数都是某些 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
        );
    }

    // ...
};

If the functions aren't part of a class or you don't want to keep any sort of global state that multiple calls to myfunc could interfere with, then another approach would be to dynamically allocate the parameter.如果这些函数不是 class 的一部分,或者您不想保留任何类型的全局 state 多次调用myfunc可能会干扰,那么另一种方法是动态分配参数。 Just remember to free it when ProcessRequests is done with it:请记住在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
    );
}

I would recommend the former approach if possible.如果可能的话,我会推荐前一种方法。 It would be easy to create memory leaks if you forget to free the key code in some code path (ie if you later add code to cancel the timer before it runs).如果您忘记释放某些代码路径中的关键代码(即,如果您稍后添加代码以在计时器运行之前取消计时器),则很容易创建 memory 泄漏。

You are passing CreateTimerQueueTimer() an int* pointer that points to a local int variable, but then you are treating lpParameter in ProcessRequests() as-if it were the int value instead of the int* pointer that it really is.您正在向CreateTimerQueueTimer()传递一个指向本地int变量的int*指针,但随后您将ProcessRequests()中的lpParameter视为它是int值而不是它实际上是的int*指针。

Passing the int value into the callback is fine, but you need to pass th value type-casted to a pointer, eg: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)), ...);
}

Also, calling SendInput() 2 times with 1 INPUT at a time without any delay in between the calls is a logic bug in your code that will likely cause issues with the input queue.此外,一次使用 1 个INPUT调用SendInput() 2 次而在调用之间没有任何延迟是代码中的逻辑错误,可能会导致输入队列出现问题。 Since there is no delay in your code, you should instead call SendInput() 1 time with 2 INPUT s, eg:由于您的代码没有延迟,因此您应该使用 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));
}

You can try conversion from void* to int* and then to int like so:您可以尝试从 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