Добрый день уважаемые. Хотелось бы поделиться своей историей и маленьким лайфхаком.
Думаю у всех офисных работников бывает ситуация, когда после вкусненького обеда сильно разморило и хочется вздремнуть. На самом деле, дневной сон очень полезен как для организма, так и для работы, так как очень положительно влияет на продуктивность. Однако по моему опыту, более 20 минут — явный перебор. Этого достаточно чтобы организм привел себя в норму. И спустя буквально минуту, в течение которой очень хочется продолжить спать, организм просыпается, чувствуется бодрость и прилив сил.
С другой стороны, многие предпочитают выпить чашечку кофе. И хоть кажется, что это помогает, на самом деле организм не восстанавливает свои ресурсы, а только больше теряет. Да и вредно это.
В целом понятно, о чем идет речь, правда? однако вполне закономерно возникает вопрос, как это провернуть в офисе. И ведь все дело в том, что большинство начальников такое не одобряет. Да и диван есть далеко не везде. Да и вряд ли вы позволите себе на нем прикорнуть, если дорожите своим рабочим местом.
Однако мне повезло, у меня кресло может очень сильно откинуться назад, и я могу в целом выглядеть работающим, просто задумавшимся. И все бы ничего, если бы не одно но.
Абсолютно статичная картинка на мониторах выдает меня с потрохами!
Я как то поделился этой проблемой с другом, и он в шутку предложил сделать имитатор работы.
Идея мне очень понравилась, однако реализовать полноценный имитатор работы — это что вообще такое должно быть? оно что, и работать за меня смогло бы? В общем понятно, что создать такое было бы крайне затруднительно. Но можно было бы упростить задачу.
По роду деятельности я простой С++ программист, а посему очень часто ползаю по интернету и читаю различные статьи. Без этого никак, все это понимают.
Если понаблюдать за человеком, который читает длинную и сложную статью, можно заметить, что он периодически прокручивает статью то вверх, то вниз. И вот это то я и решил реализовать.
Спустя буквально час серфинга в интернете, путем объединения материала трех статей (статьи по скрытному приложению без окна, по перехвату событий клавиатуры и статьи по имитации событий от мышки) была реализована простецкая программа, которой я и хотел бы поделиться с людьми.
Идея простая в своей основе: случайные события прокрутки колесика мышки. То есть просто выбираешь статью подлиннее и посложнее по текущей задаче, включаешь имитатор, и засыпаешь себе спокойно. Программа не видна в диспетчере задач (или я просто слепой и не нашел ее там), с помощью комбинации клавиш Ctrl + пробел ставится на паузу, и возобновляет свое выполнение, а по нажатии стрелочки вниз она закрывается. Программу можно увидеть через консоль, с помощью команды tasklist, и при необходимости так можно выяснить ее PID, чтобы закрыть ее через taskkill.
Код программы я сам не до конца понимаю, поэтому комментариев его не будет.
Собственно, сам код:
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
HHOOK hKeyboardHook;
#define X 500
#define Y 500
#define SCREEN_WIDTH 1920
#define SCREEN_HEIGHT 1080
bool bQuit = false;
bool bPause = false;
__declspec(dllexport) LRESULT CALLBACK KeyboardEvent(int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD SHIFT_key = 0;
DWORD CTRL_key = 0;
DWORD ALT_key = 0;
if ((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))
{
KBDLLHOOKSTRUCT hooked_key = *((KBDLLHOOKSTRUCT*)lParam);
DWORD dwMsg = 1;
dwMsg += hooked_key.scanCode << 16;
dwMsg += hooked_key.flags << 24;
char lpszKeyName[1024] = { 0 };
int i = GetKeyNameText(dwMsg, (lpszKeyName + 1), 0xFF) + 1;
int key = hooked_key.vkCode;
SHIFT_key = GetAsyncKeyState(VK_SHIFT);
CTRL_key = GetAsyncKeyState(VK_CONTROL);
ALT_key = GetAsyncKeyState(VK_MENU);
//printf("Keycode = %c\n", key);
if (key == VK_DOWN)
{
bQuit = true;
PostQuitMessage(0);
}
if (CTRL_key != 0 && key == ' ')
{
bPause = !bPause;
}
//if (key >= 'A' && key <= 'Z')
//{
// if (GetAsyncKeyState(VK_SHIFT) >= 0) key += 32;
// /*********************************************
// *** Hotkey scope ***
// *** do stuff here ***
// **********************************************/
// if (CTRL_key != 0 && key == 'y')
// {
// MessageBox(NULL, "CTRL-y was pressed\nLaunch your app here", "H O T K E Y", MB_OK);
// CTRL_key = 0;
// //do stuff here
// }
// if (CTRL_key != 0 && key == 'q')
// {
// MessageBox(NULL, "Shutting down", "H O T K E Y", MB_OK);
// bQuit = true;
// PostQuitMessage(0);
// }
//
// SHIFT_key = 0;
// CTRL_key = 0;
// ALT_key = 0;
//}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
void MessageLoop()
{
MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
}
DWORD WINAPI my_HotKey(LPVOID lpParm)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
if (!hInstance) hInstance = LoadLibrary((LPCSTR)lpParm);
if (!hInstance) return 1;
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardEvent, hInstance, NULL);
MessageLoop();
UnhookWindowsHookEx(hKeyboardHook);
return 0;
}
void MouseSetup(INPUT *buffer)
{
buffer->type = INPUT_MOUSE;
buffer->mi.dx = (0 * (0xFFFF / SCREEN_WIDTH));
buffer->mi.dy = (0 * (0xFFFF / SCREEN_HEIGHT));
buffer->mi.mouseData = 0;
buffer->mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
buffer->mi.time = 0;
buffer->mi.dwExtraInfo = 0;
}
void MouseMoveAbsolute(INPUT *buffer, int x, int y)
{
buffer->mi.dx = (x * (0xFFFF / SCREEN_WIDTH));
buffer->mi.dy = (y * (0xFFFF / SCREEN_HEIGHT));
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
SendInput(1, buffer, sizeof(INPUT));
}
void MouseClick(INPUT *buffer)
{
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN);
SendInput(1, buffer, sizeof(INPUT));
Sleep(10);
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP);
SendInput(1, buffer, sizeof(INPUT));
}
void MouseWheel(INPUT *buffer, bool bUp)
{
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_WHEEL);
if(bUp)
buffer->mi.mouseData = 120;
else
buffer->mi.mouseData = -120;
SendInput(1, buffer, sizeof(INPUT));
}
/* declare window procedure for this application. */
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR szArgs, int nCmdShow)
{
HANDLE hThread;
DWORD dwThread;
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)my_HotKey, (LPVOID)szArgs[0], NULL, &dwThread);
INPUT buffer[1];
int probability = 3; // probability / 1000
int pr = probability;
int repeat = 0;
while (!bQuit)
{
if (bPause)
{
continue;
Sleep(100);
}
MouseSetup(buffer);
int p = rand() % 1000;
if (p < pr)
{
if(p >= (pr + 1) / 2)
MouseWheel(buffer, true);
else
MouseWheel(buffer, false);
pr-=100;
if (pr < probability)
pr = probability;
}
else
{
pr++;
}
Sleep(100);
}
if (hThread) return WaitForSingleObject(hThread, INFINITE);
return 0;
//MSG Msg; // save window messages here.
// /* Run the message pump. It will run until GetMessage() returns 0 */
//while (GetMessage(&Msg, NULL, 0, 0))
//{
// TranslateMessage(&Msg); // Translate virtual-key messages to character messages
// DispatchMessage(&Msg); // Send message to WindowProcedure
//}
//return Msg.wParam;
return 0;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WinProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case VK_ESCAPE:
{
MessageBox(NULL, "You hit escape, quitting now.", "Message", 0);
PostQuitMessage(0);
break;
}
// handle non-trapped messages.
default:return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0; // this indicates a message was trapped.
}
Код не очищен от лишних комментариев и прочего мусора по той простой причине, что кому то для понимания может пригодиться. К сожалению не могу приложить исполняемый файл для ленивых.
Хотелось бы отметить, что использовать эту программу я не рекомендую никому, да и сам ей пользоваться не рискну. Ведь если вы просто задремали на рабочем месте, это можно объяснить, сославшись на плохое самочувствие, или долгое отсутствие отпуска, или еще что — либо. А если кто — нибудь поймет, что вы пытаетесь его обмануть, это будет уже плохо, обидно и неприятно. И вряд ли положительно скажется на вашей карьере.