diff --git a/Monitor_Off/Monitor_Off.rc b/Monitor_Off/Monitor_Off.rc index d1b1918..5d91a3f 100644 --- a/Monitor_Off/Monitor_Off.rc +++ b/Monitor_Off/Monitor_Off.rc @@ -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 @@ -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" diff --git a/Monitor_Off/lite_dlls.cpp b/Monitor_Off/lite_dlls.cpp index aeb27b7..5b03597 100644 --- a/Monitor_Off/lite_dlls.cpp +++ b/Monitor_Off/lite_dlls.cpp @@ -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 diff --git a/Monitor_Off/lite_dlls.h b/Monitor_Off/lite_dlls.h index 098bd10..ecd5eba 100644 --- a/Monitor_Off/lite_dlls.h +++ b/Monitor_Off/lite_dlls.h @@ -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 diff --git a/Monitor_Off/lite_ntdll.cpp b/Monitor_Off/lite_ntdll.cpp index 2df7cf5..8b5ebde 100644 --- a/Monitor_Off/lite_ntdll.cpp +++ b/Monitor_Off/lite_ntdll.cpp @@ -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 @@ -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. @@ -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; diff --git a/Monitor_Off/lite_ntdll.h b/Monitor_Off/lite_ntdll.h index 54f4542..0ff4cae 100644 --- a/Monitor_Off/lite_ntdll.h +++ b/Monitor_Off/lite_ntdll.h @@ -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 @@ -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 ) ) @@ -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(); diff --git a/Monitor_Off/lite_shell32.cpp b/Monitor_Off/lite_shell32.cpp index 07f8f9a..b6bcff9 100644 --- a/Monitor_Off/lite_shell32.cpp +++ b/Monitor_Off/lite_shell32.cpp @@ -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 @@ -21,6 +21,7 @@ #ifndef SHELL32_USE_STATIC_LIB + pCommandLineToArgvW _CommandLineToArgvW; pShell_NotifyIconW _Shell_NotifyIconW; HMODULE hModule_shell32 = NULL; @@ -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; diff --git a/Monitor_Off/lite_shell32.h b/Monitor_Off/lite_shell32.h index 48bb9a8..2156f7f 100644 --- a/Monitor_Off/lite_shell32.h +++ b/Monitor_Off/lite_shell32.h @@ -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 @@ -35,6 +35,7 @@ #include + #define _CommandLineToArgvW CommandLineToArgvW #define _Shell_NotifyIconW Shell_NotifyIconW #else @@ -42,8 +43,10 @@ #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; diff --git a/Monitor_Off/lite_user32.cpp b/Monitor_Off/lite_user32.cpp index 1c210a5..b9106e6 100644 --- a/Monitor_Off/lite_user32.cpp +++ b/Monitor_Off/lite_user32.cpp @@ -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 @@ -34,6 +34,7 @@ pLoadImageW _LoadImageW; pPostQuitMessage _PostQuitMessage; pRegisterClassExW _RegisterClassExW; + pRegisterWindowMessageW _RegisterWindowMessageW; pSendMessageW _SendMessageW; pSetForegroundWindow _SetForegroundWindow; pSetWindowsHookExW _SetWindowsHookExW; @@ -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" ) ) diff --git a/Monitor_Off/lite_user32.h b/Monitor_Off/lite_user32.h index 88b2ee1..189608e 100644 --- a/Monitor_Off/lite_user32.h +++ b/Monitor_Off/lite_user32.h @@ -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 @@ -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 @@ -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 ); @@ -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; diff --git a/Monitor_Off/main.cpp b/Monitor_Off/main.cpp index 0040840..4747423 100644 --- a/Monitor_Off/main.cpp +++ b/Monitor_Off/main.cpp @@ -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 @@ -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 ) @@ -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 ); + } } } } @@ -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; } @@ -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; @@ -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.