Skip to content

Commit

Permalink
Added feature; Bug fix
Browse files Browse the repository at this point in the history
Command-line can accept up to 4 virtual-key codes to override default Ctrl + Shift + F4.
System Tray icon will reappear if Explorer is reset.
  • Loading branch information
erickutcher committed Sep 18, 2024
1 parent f28cfbc commit d2d84eb
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 28 deletions.
10 changes: 5 additions & 5 deletions Monitor_Off/Monitor_Off.rc
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ IDI_ICON ICON "icon.ico"
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,2
PRODUCTVERSION 1,0,0,2
FILEVERSION 1,0,0,3
PRODUCTVERSION 1,0,0,3
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
Expand All @@ -80,12 +80,12 @@ BEGIN
BEGIN
VALUE "Comments", "Monitor Off is made free under the GPLv3 license."
VALUE "FileDescription", "Monitor Off will turn off the computer's monitor."
VALUE "FileVersion", "1, 0, 0, 2"
VALUE "FileVersion", "1, 0, 0, 3"
VALUE "InternalName", "Monitor Off"
VALUE "LegalCopyright", "Copyright � 2017-2020 Eric Kutcher"
VALUE "LegalCopyright", "Copyright � 2017-2024 Eric Kutcher"
VALUE "OriginalFilename", "Monitor_Off.exe"
VALUE "ProductName", "Monitor Off"
VALUE "ProductVersion", "1, 0, 0, 2"
VALUE "ProductVersion", "1, 0, 0, 3"
END
END
BLOCK "VarFileInfo"
Expand Down
2 changes: 1 addition & 1 deletion Monitor_Off/lite_dlls.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion Monitor_Off/lite_dlls.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
6 changes: 5 additions & 1 deletion Monitor_Off/lite_ntdll.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -33,6 +33,8 @@
pmemcpy _memcpy;
pmemset _memset;

pwcstoul _wcstoul;

HMODULE hModule_ntdll = NULL;

unsigned char ntdll_state = NTDLL_STATE_SHUTDOWN; // 0 = Not running, 1 = running.
Expand All @@ -54,6 +56,8 @@
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_memcpy, "memcpy" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_memset, "memset" ) )

VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_ntdll, ( void ** )&_wcstoul, "wcstoul" ) )

ntdll_state = NTDLL_STATE_RUNNING;

return true;
Expand Down
8 changes: 7 additions & 1 deletion Monitor_Off/lite_ntdll.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -34,6 +34,8 @@
#define _memcpy memcpy
#define _memset memset

#define _wcstoul wcstoul

#define _memcpy_s memcpy_s
#define _wmemcpy_s( dest, size, src, count ) memcpy_s( dest, sizeof( wchar_t ) * ( size ), src, sizeof( wchar_t ) * ( count ) )

Expand All @@ -45,9 +47,13 @@
typedef void * ( WINAPIV *pmemcpy )( void *dest, const void *src, size_t count );
typedef void * ( WINAPIV *pmemset )( void *dest, int c, size_t count );

typedef unsigned long ( WINAPIV *pwcstoul )( const wchar_t *nptr, wchar_t **endptr, int base );

extern pmemcpy _memcpy;
extern pmemset _memset;

extern pwcstoul _wcstoul;

extern unsigned char ntdll_state;

bool InitializeNTDLL();
Expand Down
4 changes: 3 additions & 1 deletion Monitor_Off/lite_shell32.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -21,6 +21,7 @@

#ifndef SHELL32_USE_STATIC_LIB

pCommandLineToArgvW _CommandLineToArgvW;
pShell_NotifyIconW _Shell_NotifyIconW;

HMODULE hModule_shell32 = NULL;
Expand All @@ -41,6 +42,7 @@
return false;
}

VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_CommandLineToArgvW, "CommandLineToArgvW" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_shell32, ( void ** )&_Shell_NotifyIconW, "Shell_NotifyIconW" ) )

shell32_state = SHELL32_STATE_RUNNING;
Expand Down
5 changes: 4 additions & 1 deletion Monitor_Off/lite_shell32.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,15 +35,18 @@

#include <shlwapi.h>

#define _CommandLineToArgvW CommandLineToArgvW
#define _Shell_NotifyIconW Shell_NotifyIconW

#else

#define SHELL32_STATE_SHUTDOWN 0
#define SHELL32_STATE_RUNNING 1

typedef LPWSTR * ( WINAPI *pCommandLineToArgvW )( LPCWSTR lpCmdLine, int *pNumArgs );
typedef BOOL ( WINAPI *pShell_NotifyIconW )( DWORD dwMessage, PNOTIFYICONDATA lpdata );

extern pCommandLineToArgvW _CommandLineToArgvW;
extern pShell_NotifyIconW _Shell_NotifyIconW;

extern unsigned char shell32_state;
Expand Down
4 changes: 3 additions & 1 deletion Monitor_Off/lite_user32.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -34,6 +34,7 @@
pLoadImageW _LoadImageW;
pPostQuitMessage _PostQuitMessage;
pRegisterClassExW _RegisterClassExW;
pRegisterWindowMessageW _RegisterWindowMessageW;
pSendMessageW _SendMessageW;
pSetForegroundWindow _SetForegroundWindow;
pSetWindowsHookExW _SetWindowsHookExW;
Expand Down Expand Up @@ -72,6 +73,7 @@
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_LoadImageW, "LoadImageW" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_PostQuitMessage, "PostQuitMessage" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_RegisterClassExW, "RegisterClassExW" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_RegisterWindowMessageW, "RegisterWindowMessageW" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_SendMessageW, "SendMessageW" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_SetForegroundWindow, "SetForegroundWindow" ) )
VALIDATE_FUNCTION_POINTER( SetFunctionPointer( hModule_user32, ( void ** )&_SetWindowsHookExW, "SetWindowsHookExW" ) )
Expand Down
5 changes: 4 additions & 1 deletion Monitor_Off/lite_user32.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -42,6 +42,7 @@
#define _LoadImageW LoadImageW
#define _PostQuitMessage PostQuitMessage
#define _RegisterClassExW RegisterClassExW
#define _RegisterWindowMessageW RegisterWindowMessageW
#define _SendMessageW SendMessageW
#define _SetForegroundWindow SetForegroundWindow
#define _SetWindowsHookExW SetWindowsHookExW
Expand Down Expand Up @@ -69,6 +70,7 @@
typedef HANDLE ( WINAPI *pLoadImageW )( HINSTANCE hinst, LPCTSTR lpszName, UINT uType, int cxDesired, int cyDesired, UINT fuLoad );
typedef VOID ( WINAPI *pPostQuitMessage )( int nExitCode );
typedef ATOM ( WINAPI *pRegisterClassExW )( const WNDCLASSEX *lpwcx );
typedef UINT ( WINAPI *pRegisterWindowMessageW )( LPCWSTR lpString );
typedef LRESULT ( WINAPI *pSendMessageW )( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
typedef BOOL ( WINAPI *pSetForegroundWindow )( HWND hWnd );
typedef HHOOK ( WINAPI *pSetWindowsHookExW )( int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId );
Expand All @@ -89,6 +91,7 @@
extern pLoadImageW _LoadImageW;
extern pPostQuitMessage _PostQuitMessage;
extern pRegisterClassExW _RegisterClassExW;
extern pRegisterWindowMessageW _RegisterWindowMessageW;
extern pSendMessageW _SendMessageW;
extern pSetForegroundWindow _SetForegroundWindow;
extern pSetWindowsHookExW _SetWindowsHookExW;
Expand Down
94 changes: 79 additions & 15 deletions Monitor_Off/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Monitor Off will turn off the computer's monitor.
Copyright (C) 2017-2020 Eric Kutcher
Copyright (C) 2017-2024 Eric Kutcher
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -37,10 +37,36 @@

HWND g_hWnd_main = NULL;

UINT WM_TASKBARCREATED = 0;

bool is_system_tray_initialized = false;
HMENU g_hMenuSub_tray = NULL;

NOTIFYICONDATA g_nid;

BYTE vk_list[ 4 ];
BYTE vk_list_count;

void InitializeSystemTray( HWND hWnd )
{
if ( !is_system_tray_initialized )
{
_memzero( &g_nid, sizeof( NOTIFYICONDATA ) );
g_nid.cbSize = NOTIFYICONDATA_V2_SIZE; // 5.0 (Windows 2000) and newer.
g_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
g_nid.hWnd = hWnd;
g_nid.uCallbackMessage = WM_TRAY_NOTIFY;
g_nid.uID = 1000;
g_nid.hIcon = ( HICON )_LoadImageW( GetModuleHandleW( NULL ), MAKEINTRESOURCE( IDI_ICON ), IMAGE_ICON, 16, 16, LR_SHARED );
_wmemcpy_s( g_nid.szTip, sizeof( g_nid.szTip ) / sizeof( g_nid.szTip[ 0 ] ), L"Middle click the system tray icon or press Ctrl + Shift + F4 to turn the monitor off.\0", 86 );
g_nid.szTip[ 85 ] = 0; // Sanity.

is_system_tray_initialized = true;
}

_Shell_NotifyIconW( NIM_ADD, &g_nid );
}

LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if ( nCode == HC_ACTION )
Expand All @@ -50,11 +76,35 @@ LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
// A key up might follow key down and prevent the monitor from turning off. Use key up instead.
if ( kbdllhs != NULL && wParam == WM_KEYUP )
{
if ( ( kbdllhs->vkCode == VK_F4 ) &&
( _GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) &&
( _GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) )
if ( vk_list_count > 0 )
{
bool modifiers_are_down = false;
for ( BYTE i = 0; i < ( vk_list_count - 1 ); ++i )
{
if ( _GetAsyncKeyState( vk_list[ i ] ) & 0x8000 )
{
modifiers_are_down = true;
}
else
{
modifiers_are_down = false;
break;
}
}

if ( ( kbdllhs->vkCode == vk_list[ vk_list_count - 1 ] ) && modifiers_are_down )
{
_SendMessageW( g_hWnd_main, WM_SYSCOMMAND, SC_MONITORPOWER, 2 );
}
}
else
{
_SendMessageW( g_hWnd_main, WM_SYSCOMMAND, SC_MONITORPOWER, 2 );
if ( ( kbdllhs->vkCode == VK_F4 ) &&
( _GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) &&
( _GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) )
{
_SendMessageW( g_hWnd_main, WM_SYSCOMMAND, SC_MONITORPOWER, 2 );
}
}
}
}
Expand All @@ -80,16 +130,9 @@ LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam
mii.wID = MENU_EXIT;
_InsertMenuItemW( g_hMenuSub_tray, 0, TRUE, &mii );

_memzero( &g_nid, sizeof( NOTIFYICONDATA ) );
g_nid.cbSize = NOTIFYICONDATA_V2_SIZE; // 5.0 (Windows 2000) and newer.
g_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
g_nid.hWnd = hWnd;
g_nid.uCallbackMessage = WM_TRAY_NOTIFY;
g_nid.uID = 1000;
g_nid.hIcon = ( HICON )_LoadImageW( GetModuleHandleW( NULL ), MAKEINTRESOURCE( IDI_ICON ), IMAGE_ICON, 16, 16, LR_SHARED );
_wmemcpy_s( g_nid.szTip, sizeof( g_nid.szTip ) / sizeof( g_nid.szTip[ 0 ] ), L"Middle click the system tray icon or press Ctrl + Shift + F4 to turn the monitor off.\0", 86 );
g_nid.szTip[ 85 ] = 0; // Sanity.
_Shell_NotifyIconW( NIM_ADD, &g_nid );
InitializeSystemTray( hWnd );

WM_TASKBARCREATED = _RegisterWindowMessageW( L"TaskbarCreated" );

return 0;
}
Expand Down Expand Up @@ -159,6 +202,11 @@ LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam

default:
{
if ( msg == WM_TASKBARCREATED )
{
InitializeSystemTray( hWnd );
}

return _DefWindowProcW( hWnd, msg, wParam, lParam );
}
break;
Expand Down Expand Up @@ -190,6 +238,22 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
MSG msg;
_memzero( &msg, sizeof( MSG ) );

_memzero( vk_list, sizeof( BYTE ) * 4 );
vk_list_count = 0;

int argCount = 0;
LPWSTR *szArgList = _CommandLineToArgvW( GetCommandLineW(), &argCount );
if ( szArgList != NULL )
{
for ( int arg = 1; arg < argCount && arg <= 4; ++arg )
{
vk_list[ vk_list_count++ ] = ( BYTE )_wcstoul( szArgList[ arg ], NULL, 16 );
}

// Free the parameter list.
LocalFree( szArgList );
}

HHOOK hHook = _SetWindowsHookExW( WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0 );

// Initialize our window class.
Expand Down

0 comments on commit d2d84eb

Please sign in to comment.