簡體   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