I am using settimer to start the timer. I want to change the timer value everytime the timer lapses.
The code is as below:
#include<iostream>
#include <windows.h>
#include <stdio.h>
#include<WinUser.h>
#pragma comment( lib, "user32.lib" )
void main()
{
int id = 1;
static bool isStart = false;
static long l = 10000;
while(1)
{
int n;
MSG msg = {0};
{
SetTimer(NULL, id,l,NULL);
while(GetMessage(&msg,NULL, 0,0))
{
// Post WM_TIMER messages to the hwndTimer procedure.
if (msg.message == WM_TIMER)
{
std::cout << "Timer expired";
KillTimer(NULL, id);
msg.message = 0x0;
l = 20000;
break;
}
}
}
}
}
Even though I change the value to 20000 its not taking, the timer is set only once.
Need help on this.
Thanks
You need to use the return value of SetTimer to kill the timer
int main(int argc, char **argv)
{
static bool isStart = false;
static long l = 5000;
while(1)
{
int n;
MSG msg = {0};
UINT_PTR p = SetTimer(NULL, 0,l,NULL);
while(GetMessage(&msg,NULL, 0,0))
{
// Post WM_TIMER messages to the hwndTimer procedure.
if (msg.message == WM_TIMER)
{
std::cout << "Timer expired" << std::endl;
KillTimer(NULL, p);
msg.message = 0x0;
l = 20000;
break;
}
}
}
}
SetTimer From MSDN
Return value
Type: Type: UINT_PTR If the function succeeds and the hWnd parameter
is NULL, the return value is an integer identifying the new timer. An
application can pass this value to the KillTimer function to destroy
the timer.
Related
I have the following problem with retrieving the window handle from a specific window (title and class name are known):
There are two identical windows with different handles under two different processes, but FindWindow() can find the handle only from the newest window spawned, never from the first one.
What can be used instead? Can EnumWindows() be used to retrieve a list of windows with the same characteristics?
Use the Win32 API EnumWindows , and then check which process each window belongs to by using the Win32 API GetWindowThreadProcessId.
Here is a sample:
#include <iostream>
#include <Windows.h>
using namespace std;
BOOL CALLBACK enumProc(HWND hwnd, LPARAM) {
TCHAR buf[1024]{};
GetClassName(hwnd, buf, 100);
if (!lstrcmp(buf, L"Notepad"))
{
GetWindowText(hwnd, buf, 100);
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
wcout << buf << " " << pid << endl;
}
return TRUE;
}
int main() {
EnumWindows(&enumProc, 0);
}
If you need to check the window of each process, you can refer to this answer.
typedef struct
{
const char *name;
const char *class;
HWND handles[10];
int handlesFound;
} SearchWindowInfo;
SearchWindowInfo wi;
wi.handlesFound = 0;
wi.title = "WindowName";
wi.class = "ClassName";
BOOL CALLBACK searchWindowCallback(HWND hwnd, LPARAM lParam)
{
SearchWindoInfo *wi = (SearchWindoInfo *)lParam;
char buffer[256];
if (wi->handlesFound == 10)
return FALSE;
buffer[255] = 0;
if (wi->name)
{
int rc = GetWindowText(hwnd, buffer, sizeof(buffer)-1);
if(rc)
{
if (strcmp(wi->name, buffer) == 0)
{
wi->handles[wi->handlesFound++] = hwnd;
return TRUE;
}
}
}
if (wi->class)
{
int rc = GetClassName (hwnd, buffer, sizeof(buffer)-1);
if(rc)
{
if (strcmp(wi->class, buffer) == 0)
{
wi->handles[wi->handlesFound++] = hwnd;
return TRUE;
}
}
}
return TRUE;
}
EnumWindows(searchWindowCallback, (LPARAM)&wi);
for(int i = 0; i < wi.handlesFound; i++)
{
// yeah...
}
I am trying to detect how many instances of a application person is running. Did he open my application once? Twice? Thrice?
I tried to detect it by checking it's instances by process names, but in windows it is pointles - people might change .exe name and it won't count towards final number.
How would I proceed then? I thought about searching it by className (HWND?) rather by processName, but how would I do it?
This is the code I am using for detecting by process name:
int Platform::getMulticlientCount(const std::string& ProcessName)
{
PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
const char *cstr = ProcessName.c_str();
int counter = 0;
if (Process32First(hSnapshot, &pe32))
{
do
{
if (_tcsicmp(pe32.szExeFile, cstr) == 0)
{
counter++;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return counter;
}
The instance of the Remy:
static int counter;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char classname[MAX_PATH] = { 0 };
GetClassNameA(hwnd,classname, MAX_PATH);
if (_tcsicmp(classname, (char*)lParam) == 0)
counter++;
return true;
}
int Platform::getMulticlientCount(const std::string& ClassName)
{
counter = 0;
const char *cstr = ClassName.c_str();
EnumWindows(EnumWindowsProc, (LPARAM)cstr);
return counter;
}
If you also need to get the instance, in EnumWindowsProc:
HINSTANCE instance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
If you also need to get the processId, in EnumWindowsProc:
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
Here is an example code that counts the instances that are running. While the application count the instances it self it does not matter if the binary is renamed. I used a file to keep the example simple but registry would work too. The only thing that is missing is a global mutex to protect the file against concurrent access. HTH
#include <iostream>
#include <thread>
#include <fstream>
#include <Windows.h>
class GlobalCounter
{
public:
GlobalCounter(const std::string& id)
: _id(id)
{
const auto filename = "C:\\users\\twollgam\\" + id + ".counter";
if (GlobalFindAtomA(id.c_str()) == 0)
{
std::ofstream(filename) << 1;
std::cout << "I am the first instance." << std::endl;
}
else
{
auto counter = 0;
std::ifstream(filename) >> counter;
++counter;
std::ofstream(filename) << counter;
std::cout << "I am the " << counter << " instance." << std::endl;
}
_atom = GlobalAddAtomA(id.c_str());
}
~GlobalCounter()
{
const auto filename = "C:\\users\\twollgam\\" + _id + ".counter";
auto counter = 0;
std::ifstream(filename) >> counter;
--counter;
std::ofstream(filename) << counter;
GlobalDeleteAtom(_atom);
}
private:
const std::string _id;
ATOM _atom;
};
int main()
{
const auto globalCounter = GlobalCounter("test");
std::cout << "Hello World!\n";
std::this_thread::sleep_for(std::chrono::seconds(30));
return 0;
}
This question already has an answer here:
C++ Hotkey to run function
(1 answer)
Closed 5 years ago.
I'm trying to code a little "virus" (just a fun joke program which messes around with the cursor and makes some beep sounds). However, I want to close this process with my F9 key.
Here's what I have so far:
void executeApp()
{
while (true)
{
if (GetAsyncKeyState(VK_F9) & 0x8000)
{
exit(0);
}
Sleep(200);
}
}
I made a thread that runs this function. However, when I run my entire code and press F9, the process still runs. Only when I press it 2-3 times, it comes up with an Error: "Debug Error! abort() has been called."
It would be nice if someone knows how I can kill my process via a hotkey.
Here is the whole code of the program:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <thread>
#include <random>
using namespace std;
//random number gen for while loops in cursor/beep functions.
random_device rd;
mt19937 eng(rd());
uniform_int_distribution<> distr(1, 100);
//variables used for this program.
int random, Dur, X, Y, Freq;
HWND mywindow, Steam, CMD, TaskMngr;
char Notepad[MAX_PATH] = "notepad.exe";
char Website[MAX_PATH] = "http:\\www.google.de";
//functions
void RandomCursor(), Beeper(), OpenStuff(), executeApp();
//threads
thread cursor(RandomCursor);
thread beeps(Beeper);
thread openstuff(OpenStuff);
thread appexecute(executeApp);
int main()
{
srand(time(0));
random = rand() % 3;
system("title 1337app");
cursor.join();
beeps.join();
appexecute.join();
return 0;
}
//void SetUp()
//{
// mywindow = FindWindow(NULL, "1337app");
// cout << "oh whats that? let me see.\n";
// Sleep(1000);
// ShowWindow(mywindow, false);
//}
void Beeper()
{
while (true)
{
if (distr(eng) > 75)
{
Dur = rand() % 206;
Freq = rand() % 2124;
Beep(Dur, Freq);
}
Sleep(1500);
}
}
//void OpenStuff()
//{
// ShellExecute(NULL, "open", Notepad, NULL, NULL, SW_MAXIMIZE);
// ShellExecute(NULL, "open", Website, NULL, NULL, SW_MAXIMIZE);
//}
void RandomCursor()
{
while (true)
{
if (distr(eng) < 50)
{
X = rand() % 302;
Y = rand() % 202;
SetCursorPos(X, Y);
}
Sleep(500);
}
}
void executeApp()
{
while (true)
{
if (GetAsyncKeyState(VK_F9) & 0x8000)
{
exit(0);
}
Sleep(200);
}
}
GetAsyncKeyState() returns two pieces of information, but you are looking at only one of them and it is the one that is not very useful to your code.
Per the documentation:
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
When you AND the return value with 0x8000, you are testing only the most significant bit, which means you are testing only if the key is currently down at the exact moment that GetAsyncKeyState() is called. Which is why it usually takes several presses, or holding down the key for awhile, for your code to detect the key press. You have a race condition in your code.
You should also AND the return value with 0x0001 to check if the key has been pressed and released in between the times that you call GetAsyncKeyState():
if (GetAsyncKeyState(VK_F9) & 0x8001)
Or simply:
if (GetAsyncKeyState(VK_F9) != 0)
That being said, what you really should do instead is actually monitor the keyboard and let it tell you when the key is pressed. Either:
use RegisterHotKey(), handling WM_HOTKEY window messages.
use RegisterRawInputDevices(), handling WM_INPUT window messages.
use SetWindowsHookEx() to monitor key presses using a callback function instead of a window (but you still need a message loop).
Update: Since your code does not have an HWND of its own, try SetWindowsHookEx(), eg:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <ctime>
#include <thread>
#include <random>
using namespace std;
//random number gen for while loops in cursor/beep functions.
random_device rd;
mt19937 eng(rd());
uniform_int_distribution<> distr(1, 100);
//variables used for this program.
int random, Dur, X, Y, Freq;
HWND mywindow, Steam, CMD, TaskMngr;
char Notepad[MAX_PATH] = "notepad.exe";
char Website[MAX_PATH] = "http://www.google.de";
HANDLE hExitApp = NULL;
//functions
//void SetUp()
//{
// mywindow = FindWindow(NULL, "1337app");
// cout << "oh whats that? let me see.\n";
// Sleep(1000);
// ShowWindow(mywindow, false);
//}
void Beeper()
{
if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT)
{
do
{
if (distr(eng) > 75)
{
Dur = rand() % 206;
Freq = rand() % 2124;
Beep(Dur, Freq);
}
}
while (WaitForSingleObject(hExitApp, 1500) == WAIT_TIMEOUT);
}
}
//void OpenStuff()
//{
// ShellExecute(NULL, NULL, Notepad, NULL, NULL, SW_MAXIMIZE);
// ShellExecute(NULL, NULL, Website, NULL, NULL, SW_MAXIMIZE);
//}
void RandomCursor()
{
if (WaitForSingleObject(hExitApp, 0) == WAIT_TIMEOUT)
{
do
{
if (distr(eng) < 50)
{
X = rand() % 302;
Y = rand() % 202;
SetCursorPos(X, Y);
}
}
while (WaitForSingleObject(hExitApp, 500) == WAIT_TIMEOUT);
}
}
LRESULT CALLBACK MyLowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
switch (wParam)
{
case WM_KEYDOWN:
case WM_KEYUP:
if (reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam)->vkCode == VK_F9)
SetEvent(hExitApp);
break;
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
void executeApp()
{
PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &MyLowLevelKeyboardProc, NULL, 0);
if (hook)
{
MSG msg;
do
{
if (MsgWaitForMultipleObjects(1, &hExitApp, FALSE, INFINITE, QS_ALLINPUT) != (WAIT_OBJECT_0+1))
break;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
while (true);
UnhookWindowsHookEx(hook);
}
SetEvent(hExitApp);
}
int main()
{
hExitApp = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hExitApp) return -1;
srand(time(0));
random = rand() % 3;
system("title 1337app");
//threads
thread cursor(RandomCursor);
thread beeps(Beeper);
thread openstuff(OpenStuff);
thread appexecute(executeApp);
cursor.join();
beeps.join();
openstuff.join();
appexecute.join();
CloseHandle(hExitApp);
return 0;
}
i have an HID usb rfid reader that act like a keyboard,
i don't want to put a textbox on my form (WPF) to recieve the text from it because i have other requirements .
instead i am trying to capture the key pressed events and process them . for that i have tried three differents methods :
Windows Hook (c++)
this is the most simple testcase example that illustrate the issue
#include <iostream>
#include <fstream>
#include <Windows.h>
#pragma comment(lib, "user32.lib")
HHOOK keyboardHook{ NULL };
DWORD lastkey = 0;
LRESULT CALLBACK MyLowLevelKeyBoardProc(const int nCode, const WPARAM wParam, const LPARAM lParam)
{
KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT *)lParam;
switch (wParam)
{
case WM_KEYUP:
if (lastkey == 13)
system("cls");
std::cout << "KeyUp event : " << kb->vkCode << std::endl;
lastkey = kb->vkCode;
break;
}
return CallNextHookEx(keyboardHook, nCode, wParam, lParam);
}
int main(int argc, char* argv[])
{
keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);
if (keyboardHook == NULL) {
std::cout << "Keyboard hook failed!" << std::endl;
}
while (GetMessage(NULL, NULL, 0, 0));
return 0;
}
Raw input API
by handling the WM_INPUT message (too many code to show)
oblita interception library
the most interesting solution that i will use if i fix the problem
#include "stdafx.h"
#include "C:\Dev\WPF\Interception\library\interception.h"
#include "C:\Dev\WPF\Interception\Interception-1.0.0\samples\utils.h"
#include <string>
#include <iostream>
enum ScanCode
{
SCANCODE_X = 0x2D,
SCANCODE_Y = 0x15,
SCANCODE_ESC = 0x01
};
int main()
{
using namespace std;
InterceptionContext context;
InterceptionDevice device;
InterceptionStroke stroke;
wchar_t hardware_id[500];
string buffer = "";
//raise_process_priority();
context = interception_create_context();
interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_UP | INTERCEPTION_FILTER_KEY_UP);
while (interception_receive(context, device = interception_wait(context), &stroke, 1) > 0)
{
if (interception_is_keyboard(device))
{
InterceptionKeyStroke &keystroke = *(InterceptionKeyStroke *)&stroke;
if (keystroke.code == SCANCODE_ESC) break;
size_t length = interception_get_hardware_id(context, device, hardware_id, sizeof(hardware_id));
if (wcsstr(hardware_id, L"04F3&PID_0009") == 0)
interception_send(context, device, &stroke, 1); // Real Keyboard
else
{
// RFID reader
if (keystroke.code == 28)
{
std::cout << buffer << endl;
buffer = "";
}
else
buffer = buffer + std::to_string(keystroke.code);
}
}
}
interception_destroy_context(context);
return 0;
}
all the three methods gave me the same problem :
some keys are randomly lost during the read, instead of having the 10 characters i my have 8/9 only .
if i use the rfid reader on blocnote no character is lost so there is no problem with the reader .
so my question is : how to ensure that no message/key is lost by windows on the hooks , even if the read operation may take 10 seconds .
thanks and good day .
I'm having a problem when trying to run the following code:
#include "header.h"
int main()
{
id = GetCurrentProcessId();
EnumWindows(hEnumWindows, NULL);
Sleep(5000);
//MoveWindow(hThis, 450, 450, 100, 100, TRUE);
system("pause");
return 0;
}
//header.h
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>
using namespace std;
DWORD id = 0;
HWND hThis = NULL;
BOOL CALLBACK hEnumWindows(HWND hwnd, LPARAM lParam)
{
DWORD pid = 0;
pid = GetWindowThreadProcessId(hwnd, NULL);
if (pid == id)
{
hThis = GetWindow(hwnd, GW_OWNER);
if (!hThis)
{
cout << "Error getting window!" << endl;
}
else
{
char *buffer = nullptr;
int size = GetWindowTextLength(hThis);
buffer = (char*)malloc(size+1);
if (buffer != nullptr)
{
GetWindowText(hThis, buffer, size);
cout << pid << ":" << buffer << endl;
free(buffer);
}
}
}
return TRUE;
}
When I run this code nothing is output to the screen almost as if the program is not attached. I tried running it under a console and windows subsystem in VS2013.
According to the GetCurrentProcessId docs, the API
Retrieves the process identifier of the calling process.
GetWindowThreadProcessId, on the other hand,
Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.
The return value is the identifier of the thread that created the window.
So looking at your call:
pid = GetWindowThreadProcessId(hwnd, NULL);
You're actually getting back a thread ID, not a process ID. So when you compare pid to id, you're comparing a process ID and a thread ID, and that's just not going to work. Try this instead:
GetWindowThreadProcessId(hwnd, &pid);
(Note: I can't actually test whether this works, since EnumWindows requires a top-level window to enumerate and I ran this as a console app. Let me know if this answer doesn't work for you and I'll delete it.)
(As a second note, you don't need to use NULL anymore, even for WinAPI stuff like HWND. nullptr will work perfectly fine.)
I assume you're trying to find the "Main" window from the ProcessID.. In that case, this MAY help:
#include "stdafx.h"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>
struct WindowHandleStructure
{
unsigned long PID;
HWND WindowHandle;
};
BOOL CALLBACK EnumWindowsProc(HWND WindowHandle, LPARAM lParam)
{
unsigned long PID = 0;
WindowHandleStructure* data = reinterpret_cast<WindowHandleStructure*>(lParam);
GetWindowThreadProcessId(WindowHandle, &PID);
if (data->PID != PID || (GetWindow(WindowHandle, GW_OWNER) && !IsWindowVisible(WindowHandle)))
{
return TRUE;
}
data->WindowHandle = WindowHandle;
return FALSE;
}
HWND FindMainWindow(unsigned long PID)
{
WindowHandleStructure data = { PID, nullptr };
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&data));
return data.WindowHandle;
}
int main()
{
HWND Window = FindMainWindow(GetCurrentProcessId());
std::wstring Buffer(GetWindowTextLength(Window) + 1, L'\0');
GetWindowText(Window, &Buffer[0], Buffer.size());
std::wcout << Buffer.c_str() << L"\n";
system("pause");
return 0;
}