[英]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?
謝謝 !
這有兩個問題:
lpParameter
指向一個int
,但您將它視為一個int
lpParameter
的int
是myfunc
的本地變量,因此在您的計時器觸發並且您的回調被調用時不再存在第一個問題很容易解決,只需改變你解釋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.