Skip to content

Instantly share code, notes, and snippets.

@shashwat001
Last active June 4, 2021 08:01
Show Gist options
  • Select an option

  • Save shashwat001/149e8845e79fa52e2b383c106f704385 to your computer and use it in GitHub Desktop.

Select an option

Save shashwat001/149e8845e79fa52e2b383c106f704385 to your computer and use it in GitHub Desktop.
// WindowEvents.cpp : Defines the entry point for the application.
//
#pragma once
// Windows Header Files
#include <windows.h>
#include <wtsapi32.h>
#pragma comment(lib,"wtsapi32.lib")
// C RunTime Header Files
#include <tchar.h>
#include "WindowEvents.h"
#include <iostream>
#include "json/json.h"
#include <string>
using namespace std;
#define MAX_LOADSTRING 100
#define LOG(msg , ...) Log(__LINE__, msg, __VA_ARGS__)
// Global Variables:msg
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HANDLE logFile;
char guidStr[100];
char logline[256];
char logtext[256];
void initializeLogFile();
ATOM MyRegisterClass();
void GetLastErrorAsString();
BOOL InitInstance();
void handlePowerBroadcast(WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void Log(int line, const char* msg, ...);
//void Log(int line, string);
void Log(int line, Json::Value);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
initializeLogFile();
LOG("Starting the process");
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINDOWEVENTS, szWindowClass, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINDOWEVENTS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass();
GetLastErrorAsString();
// Perform application initialization:
if (!InitInstance())
{
LOG("Could not instantiate instance");
GetLastErrorAsString();
return FALSE;
}
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass()
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
return RegisterClassExW(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance()
{
HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, GetModuleHandle(NULL), nullptr);
if (!hWnd)
{
return FALSE;
}
RegisterPowerSettingNotification(hWnd, &GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);
RegisterPowerSettingNotification(hWnd, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_WINDOW_HANDLE);
WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_ALL_SESSIONS);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
Json::Value data;
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
data["message"] = "Exit";
LOG(data);
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_POWERBROADCAST:
{
handlePowerBroadcast(wParam, lParam);
break;
}
case WM_WTSSESSION_CHANGE:
{
if (wParam == WTS_SESSION_LOCK) {
data["message"] = "WTS_SESSION_LOCK";
}
else if (wParam == WTS_SESSION_UNLOCK) {
data["message"] = "WTS_SESSION_UNLOCK";
}
else {
data["message"] = "Unhandled WM_WTSESSION_CHANGE";
data["wParam"] = to_string(wParam);
}
LOG(data);
break;
}
case WM_ENDSESSION:
{
if (wParam == TRUE) {
data["message"] = "WM_ENDSESSION";
data["lParam"] = to_string(lParam);
LOG(data);
}
break;
}
case WM_DESTROY:
data["message"] = "WM_DESTROY";
LOG(data);
PostQuitMessage(0);
break;
default:
data["message"] = to_string(message);
data["wParam"] = to_string(wParam);
LOG(data);
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void handlePowerBroadcast(WPARAM wParam, LPARAM lParam)
{
Json::Value data;
switch (wParam) {
case PBT_APMSUSPEND:
data["wParam"] = "PBT_APMSUSPEND";
LOG(data);
break;
case PBT_APMRESUMESUSPEND:
data["wParam"] = "PBT_APMRESUMESUSPEND";
LOG(data);
break;
case PBT_APMRESUMEAUTOMATIC:
data["wParam"] = "PBT_APMRESUMEAUTOMATIC";
LOG(data);
break;
case PBT_POWERSETTINGCHANGE:
{
POWERBROADCAST_SETTING* ps = (POWERBROADCAST_SETTING*)lParam;
GUID guid = ps->PowerSetting;
//data["guid"] = getGuid(guid);
if (guid == GUID_LIDSWITCH_STATE_CHANGE)
{
if (ps->Data[0] == 0) {
data["message"] = "Lid is closed";
}
else {
data["message"] = "Lid is opened";
}
LOG(data);
}
else if (guid == GUID_MONITOR_POWER_ON)
{
if (ps->Data[0] == 0) {
data["message"] = "Screen is off";
}
else {
data["message"] = "Screen is on";
}
LOG(data);
}
else
{
LOG("Unhandled power setting change");
}
break;
}
default:
data["wParam"] = to_string(wParam);
LOG(data);
}
}
char* getGuid(GUID guid) {
sprintf_s(guidStr, "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
return guidStr;
}
void initializeLogFile()
{
char buffer[100];
size_t size;
getenv_s(&size, buffer, 100, "TEMP");
string tempfolder(buffer);
string logpath = tempfolder + "\\lidaction.log";
OutputDebugString(wstring(logpath.begin(), logpath.end()).c_str());
logFile = CreateFileW(
wstring(logpath.begin(), logpath.end()).c_str(),
FILE_APPEND_DATA,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (logFile == INVALID_HANDLE_VALUE)
{
GetLastErrorAsString();
return;
}
}
void Log(int line, Json::Value log)
{
Json::StreamWriterBuilder builder;
builder["indentation"] = "";
Log(line, Json::writeString(builder, log).c_str());
}
//void Log(int line, string log)
//{
// Log(line, log.c_str());
//}
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
void GetLastErrorAsString()
{
DWORD dLastError = GetLastError();
LPCTSTR strErrorMessage = NULL;
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
dLastError,
0,
(LPWSTR)&strErrorMessage,
0,
NULL);
//Prints debug output to the console
OutputDebugString(strErrorMessage);
}
void Log(int line, const char* format, ...)
{
va_list valist;
va_start(valist, format);
DWORD dwBytesWritten;
SYSTEMTIME stime;
GetLocalTime(&stime);
sprintf_s(logline, "[%04d-%02d-%02d %02d:%02d:%02d] [%3d] ", stime.wYear, stime.wMonth, stime.wDay,
stime.wHour, stime.wMinute, stime.wSecond, line);
vsprintf_s(logtext, format, valist);
strcat_s(logline, logtext);
strcat_s(logline, "\n");
va_end(valist);
WriteFile(logFile,
logline,
strlen(logline),
&dwBytesWritten,
NULL);
}
//int main()
//{
// wWinMain(GetModuleHandle(NULL), NULL, NULL, 1);
// return 0;
//}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment