Limit occurrences of an event - c++

I have a function that controls a bulb. The bulb is programmed to flash whenever a key is pressed. However, I want to limit the minimum interval between flashes to prevent the bulb from burning out. The bulb is controlled by a relay switch connected to the serial port, and the code is as follows:
void WINAPI flash (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil)
{
//MATT: Define the serial port procedure
HANDLE hSerial;
//MATT: Fire the flash (by initialising and uninitialising the port)
hSerial = CreateFile("COM1",GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); CloseHandle(hSerial);
}
How do I limit the minimum flash interval in milliseconds (millisecond accuracy is very important)?

You could use a simple variable that keeps the time as reported by QueryPerformanceCounter. The accuracy of QPC is very, very high on most systems. On my system, the frequency is 2.8million- or one tick per ten processor clocks.
class bulb {
__int64 clocks;
__int64 frequency;
public:
static const int max_ms_between_flashes = 1;
bulb() {
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
frequency = li.QuadPart;
clocks = 0;
}
void flash(...) {
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
if (clocks == 0) {
// We are the first time, so set the clocks var
// and flash the bulb
clocks = li.QuadPart;
} else {
__int64 timepassed = clocks - li.QuadPart;
if (timepassed >= (((double)frequency) / (max_ms_between_flashes * 1000))) {
// It's been more than 1ms
clocks = li.QuadPart;
// flash the bulb
}
}
}
}

You could keep a static variable in that function storing the last time the switch was triggered.
Then all you need to do is check that the current time is at least x milliseconds after that time.
You could use GetSystemTimeAsFileTime or GetSystemTime to get the current timestamp, which is supposed to have millisecond resolution.

If you could store the millisecond interval between flashes in a global variable, say FLASH_INETRVAL:
void WINAPI flash (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HANDLE hSerial;
static long lastFlashMillis;
// currentTimeMillis() should be defined using a system
// call that returns current
// system time in milliseconds.
long interval = currentTimeMillis() - lastFlashMillis;
if (interval < FLASH_INTERVAL)
Sleep (interval);
lastFlashMillis = currentTimeMillis();
//MATT: Fire the flash (by initialising and uninitialising the port)
hSerial = CreateFile("COM1",GENERIC_WRITE, 0, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0); CloseHandle(hSerial);
}

Related

Why a hanging program increases its memory usage

A C++ background program developed in Visual Studio, called monitor, watches another program, called target, and restarts it each time it exits. A somewhat simplified version of the program is shown below.
#include <windows.h>
#include <tlhelp32.h>
#include <Process.h>
void BindToProcess();
const WCHAR PATH[] = L"C:\\Windows\\System32\\notepad.exe";
const WCHAR EXE[] = L"notepad.exe";
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd)
{
do
{
BindToProcess();
_wspawnl(_P_WAIT, PATH, PATH, NULL);
} while (TRUE);
return 0;
}
void BindToProcess()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return;
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return;
}
// Now walk the snapshot of processes, and search for target
do
{
const int len = (int) wcsnlen_s(EXE, 10);
if (CompareStringW(0, 0, pe32.szExeFile, len, EXE, len) == CSTR_EQUAL)
{
HANDLE handle[1];
handle[0] = OpenProcess(SYNCHRONIZE, FALSE, pe32.th32ProcessID);
WaitForMultipleObjects(1, handle, TRUE, INFINITE);
CloseHandle(handle[0]);
CloseHandle(hProcessSnap);
return;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return;
}
Monitor first checks to see if target is running and, if so, binds itself to it. It stays inactive until target exists. Then it restarts target and again stays inactive until target exists, just to restart it once more.
In the mockup program, I use notepad.exe as the target. In the real system, it is an application that searches the internet and displays the results in a graphical user interface. In practice, target never exits unless deliberately killed, so monitor does not loop; it stays hanging. Nevertheless, I observe that its memory grows.
Monitor never uses new() or malloc() to allocate memory. The only allocations occur in the calls to CreateToolhelp32Snapshot() and OpenProcess(), but the corresponding memory is released through calls to CloseHandle(). Therefore, no memory leaks should ever occur, even if the program was looping, but it doesn't, it hangs.
Why does a hanging program's memory grow? I observe both memory increases and memory decreases, but in the long run, memory grows.
This happens because the information accessed by your program is variable.
CreateToolhelp32Snapshot() does not always have the same memory usage because it is a snapshot of processes at any given time. Processes vary a lot, some can close and others can start.
And the snapshotted process information varies too. For example you are checking szExeFile which does not have a fixed size.
Also, memory allocation is sometimes done in blocks. So one run can reserve a block that is bigger or smaller, depending on what is available.
As long as the memory does not grow indefinitely this behavior is normal.

C Windows API determine if user inactive for certain period

So I've created a basic program with a blocking message event loop (to use little to no CPU while waiting) and waits for a user to change the foreground window, then executes some code:
#include <Windows.h>
VOID ExitFunction()
{
// Do Something
}
BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
{
switch (dwCtrlType)
{
case CTRL_SHUTDOWN_EVENT:
ExitFunction();
return TRUE;
case CTRL_LOGOFF_EVENT:
ExitFunction();
return TRUE;
//default:
//We don't care about this event
//Default handler is used
}
return FALSE;
}
VOID CALLBACK WinEventProcCallback(HWINEVENTHOOK hWinEventHook, DWORD dwEvent, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if (dwEvent == EVENT_SYSTEM_FOREGROUND)
{
// Do Stuff
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HWINEVENTHOOK WindowChangeEvent;
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
WindowChangeEvent = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL, WinEventProcCallback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
while (GetMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ExitFunction();
return 0;
}
I also want to incorporate checking if the user has been inactive for a certain amount of time (no mouse/keyboard input) but keep resource usage low. There are a couple of ways to approach this that I can think of:
Have the blocking event loop check if there has been mouse or keyboard input which resets some kind of timer back to zero and also checks within the same loop if the mouse input resulted in a foreground window change (which may cause issues if there is a delay between the mouse click event and the foreground window change (meaning the foreground window change won't be captured). Have an event triggered when the user input timer has completed the specified time.
Run the mouse & keyboard activity event timer on a separate thread or asynchronously to the foreground window change event. When the timer has completed fire off an event (run on separate thread or asynchronously to make sure a foreground window change event isn't missed).
On a separate thread or asynchronously, check every couple seconds the GetLastInputInfo() function to see if the inactivity threshold time has elapsed.
It can be called like so:
LASTINPUTINFO li;
li.cbSize = sizeof(LASTINPUTINFO);
GetLastInputInfo(&li);
Keeping in mind lowest resource usage, what way is best to implement the mouse/keyboard inactivity checking while also checking for foreground window changes.
You can set up a timer (see SetTimer) to have a user-defined callback called when an arbitrary timeout expires. This allows you to break out of the blocking GetMessage loop.
The callback can check the timestamp of the last input, and compare it to the current timestamp. If that time interval exceeds the desired inactivity timeout, it can perform the necessary steps. Otherwise it restarts the timer with the remainder of the timeout.
The following code illustrates this:
#include <Windows.h>
#include <iostream>
static const DWORD timeout_in_ms { 5 * 1000 };
void TimeoutExpired() { std::wcout << L"Timeout elapsed" << std::endl; }
void CALLBACK TimerProc(HWND, UINT, UINT_PTR id, DWORD current_time)
{
// Timers are periodic, but we want it to fire only once.
KillTimer(nullptr, id);
LASTINPUTINFO lii { sizeof(lii) };
GetLastInputInfo(&lii);
auto const time_since_input { current_time - lii.dwTime };
if (time_since_input < timeout_in_ms)
{
// User input was recorded inside the timeout interval -> restart timer.
auto const remaining_time { timeout_in_ms - time_since_input };
SetTimer(nullptr, 0, remaining_time, &TimerProc);
}
else
{
TimeoutExpired();
}
}
void StartInactivityTimer()
{
// Start a timer that expires immediately;
// the TimerProc will do the required adjustments and
// restart the timer if necessary.
SetTimer(nullptr, 0, 0, &TimerProc);
}
int wmain()
{
StartInactivityTimer();
MSG msg {};
while (GetMessageW(&msg, nullptr, 0, 0) > 0)
{
DispatchMessageW(&msg);
}
}
The entire logic is contained within TimerProc. To trigger the inactivity timer, StartInactivityTimer starts a timer that expires immediately. When TimerProc takes control it does the required calculations, and either restarts the timer, or calls the timeout procedure, TimeoutExpired.
This implementation has two advantages: For one, the entire timer restart logic is in a single place. More importantly, the inactivity condition is evaluated on first call. If StartInactivityTimer is called without any user input in the inactivity interval, it instantly executes TimeoutExpired.
Also note that the interval calculations use unsigned integer arithmetic, specifically subtraction. With unsigned integer 'underflow' being well defined in both C and C++, this solution is immune to GetTickCount's return value wrapping around to 0 after approximately 49.7 days.

C Windows API determine if user is inactive inclusive of playing media

I have written some code that makes use of a timer checking when the last user input was and prints it out to Visual Studio's debug console.
#include <Windows.h>
#include <stdio.h>
DWORD InactiveThreshold; // The allowable amount of inactive time milliseconds
BOOL Inactive;
SYSTEMTIME CurrentTime(char *ddmmyyyy, char *hhmmss)
{
SYSTEMTIME lt;
GetLocalTime(&lt);
snprintf(ddmmyyyy, 11, "%d/%d/%d", lt.wDay, lt.wMonth, lt.wYear);
snprintf(hhmmss, 9, "%d:%d:%d", lt.wHour, lt.wMinute, lt.wSecond);
return lt;
}
void DebugOutput(char *ddmmyyyy, char *hhmmss)
{
OutputDebugString(TEXT("\n\n"));
OutputDebugString(ddmmyyyy);
OutputDebugString(TEXT(" -- "));
OutputDebugString(hhmmss);
OutputDebugString(TEXT(" : "));
OutputDebugString(TEXT("Inactive"));
}
void CALLBACK TimerProc(HWND hwnd, UINT unt, UINT_PTR id, DWORD current_time)
{
LASTINPUTINFO li;
SYSTEMTIME lt;
DWORD TimeSinceInput, RemainingTime;
char ddmmyyyy[11], hhmmss[9];
// Timers continue to expire, so we need to stop it first.
KillTimer(NULL, id);
li.cbSize = sizeof(LASTINPUTINFO);
GetLastInputInfo(&li);
TimeSinceInput = current_time - li.dwTime;
if (TimeSinceInput > InactiveThreshold)
{
// [Also find a way to check if audio or video was playing during the user inactive period]
if (!(Inactive))
{
// Set flag so it only outputs that it is inactive once during an inactive period
Inactive = TRUE;
lt = CurrentTime(ddmmyyyy, hhmmss);
// [Find way to print the start of the inactive period as timestamp,
// subtracting InactiveThreshold from current time]
DebugOutput(ddmmyyyy, hhmmss);
}
// [Change below so once Inactive, stop timer and instead set event loop
// to check for user input(keyboard / mouse) to end the inactive period
// and output timestamp of the end of the inactive period]
SetTimer(NULL, 0, InactiveThreshold, &TimerProc);
}
else
{
Inactive = FALSE;
RemainingTime = InactiveThreshold - TimeSinceInput;
SetTimer(NULL, 0, RemainingTime, &TimerProc);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
Inactive = FALSE;
InactiveThreshold = 30000; // 30 seconds
SetTimer(NULL, 0, InactiveThreshold, &TimerProc);
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
DispatchMessage(&msg);
}
return 0;
}
Ideally it should print when the timestamp of the start of the inactive period was, then when the user is active again to print the timestamp of when the inactive period finished. However there's three main issues (also indicated in the code with square bracket comments //[] ):
GetLastInputInfo() doesn't take into account if the user is playing media (ex: watching a video or listening to audio in Google Chrome)
When determining the system is inactive, how would you subtract the InactiveThreshold time in ms from the current timestamp to determine the start of the inactive period as the data types used are different
How could you set an event callback to wait for user mouse/keyboard input again once it is decided that the user is inactive?
GetLastInputInfo() doesn't take into account if the user is playing
media (ex: watching a video or listening to audio in Google Chrome)
As I understand, system itself track activity only as whatever is available from GetLastInputInfo().
Cases like "user is watching video" are handled by sending WM_SYSCOMMAND with SC_SCREENSAVE or SC_MONITORPOWER, so that screen does not go blank if application swallows such message instead of passing to DefWindowProc. Or alternatively by SetThreadExecutionState with ES_DISPLAY_REQUIRED
Cases like background audio are handled by SetThreadExecutionState with ES_SYSTEM_REQUIRED.
This all means that user inactivity does happen, but some other conditions prevent from taking actions on this inactivity.
I'm afraid an application cannot reliably detect all such conditions.

Count number of mouse clicks C

I have a C code that checks if the left buttom of the mouse has been pressed. It works fine but I want to use it to count how many times the button has been clicked and call to a function when the button has been clicked a random number of times.
This is the code:
LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
int count = 0;
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
if (pMouseStruct != NULL){
if (wParam == WM_LBUTTONDOWN)
{
count++;
printf("%d",count);
if (count==finalNum){ // user clicked random times the mouse so we launch the final function
printf("\ndone!\n");
final();
}
printf("clicked");
}
printf("Mouse position X = %d Mouse Position Y = %d\n", pMouseStruct->pt.x, pMouseStruct->pt.y);
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
DWORD WINAPI MyMouseLogger(LPVOID lpParm)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
// here I put WH_MOUSE instead of WH_MOUSE_LL
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, NULL);
MSG message;
while (GetMessage(&message, NULL, 0, 0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(hMouseHook);
return 0;
}
void custom_delay(){
}
int main(int argc, char *argv[])
{
int count = 0;
HANDLE hThread;
DWORD dwThread;
//////Generate random number to call a function after rand() number of clicks
srand(time(NULL)); // Seed the time
int finalNum = rand() % (150 - 50) + 50; // Generate the number, assign to variable.
////////////////////////////////////////////////////////////////////////////
printf("%d", finalNum);
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MyMouseLogger, (LPVOID)argv[0], NULL, &dwThread);
if (hThread)
return WaitForSingleObject(hThread, INFINITE);
else
return 1;
}
}
The problem is that the count variable resets to 0 each time that a mouse event take place so I can't get a track of the times that the user clicks with the mouse.
The other problem is that I would like to generate a random number of times between 50 and 150 to call the final() function. How can I send that random number as an argument?
thank you for your help!
Since you declare count in a function it is allocated when the function is called and automatically deallocated as soon as the function returns, if you want count to last longer you could make it global (declare it outside the function).
Or you use the static key word in the delcaration of count, i.e. static int count = 0. When a variable is declared with static it's allocated for the length of the whole program. This way when the function returns count won't be unallocated.
Here's some more info about static -
What does static mean in ANSI-C
http://en.wikipedia.org/wiki/Static_variable
Now for the next part of your question, you can generate a pseudo random number in C by using the rand function. The function rand returns an integer from 0 to RAND_MAX which is a constant defined by the standard library. you can read more about rand here -
http://www.cplusplus.com/reference/cstdlib/rand/
Also if you want to store some random number and be able to access it from mouseProc you could give it global scope however be aware that it isn't always a good practice to make all your variables global.
http://en.wikipedia.org/wiki/Scope_(computer_science)

Game laggs after injecting my code

I made .dll which I am injecting into game. It runs pixel detection after I press alt + s but the game laggs. Is there any possibility to fix it?
It detects red color, presses mouse3 and in-game it shoots but too slow and game is lagging.
I tried to remove Sleep() but it lag more. Any suggestions?
#include <windows.h>
#include <gdiplus.h>
const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);
const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);
const COLORREF red=RGB(255, 0, 0);
const int Sound[]={SND_ALIAS_SYSTEMASTERISK,SND_ALIAS_SYSTEMEXCLAMATION};
const int State[]={MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP};
bool PixelCheck(HDC hdc)
{
time_t stop=GetTickCount()+50;
bool result=false;
while(GetTickCount()<stop) if(GetPixel(hdc,SCREEN_X,SCREEN_Y) == red) result=true;
Sleep(1);
return result;
}
DWORD WINAPI ThreadFunction(PVOID pvParam)
{
HDC hdc=GetDC(0);
bool shotbot=false,isdown=false;
INPUT ip;
ip.type=INPUT_MOUSE;
ip.mi.dx=0;
ip.mi.dy=0;
ip.mi.dwExtraInfo=0;
while(true)
{
if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
{
shotbot=!shotbot;
PlaySound((LPCSTR)Sound[shotbot],NULL,SND_ALIAS_ID);
}
Sleep(1);
if((shotbot&&PixelCheck(hdc))||isdown)
{
ip.mi.dwFlags=State[isdown];
SendInput(1,&ip,sizeof(INPUT));
isdown=!isdown;
}
}
ReleaseDC(0, hdc);
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if(fdwReason==DLL_PROCESS_ATTACH) SetThreadPriority(CreateThread(0,0,ThreadFunction,0,0,NULL),THREAD_PRIORITY_NORMAL);
return TRUE;
}
You're doing nothing but call GetPixel() for 50 milliseconds. That's a 50 millisecond lag right there. What did you expect?
Removing the Sleep call just means you lag more often, and each time still for 50 milliseconds. That too is expected.
Some points:
1) Your while loop is tight and CPU intensive. If you have a CPU that supports it, put the __mm_pause intrinsic in there (::YieldProcessor()) or try ::SwitchToThread()
2) GetPixel is tremendously slow IIRC,, there may be a quicker way to read the pixel value from an HBITMAP