[英]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.