1: /*
2: ============================================================================
3: xoblite™ -> an advanced "extended shell" for Microsoft® Windows® 11
4: Copyright © 2002-2026 Karl Henrik Henriksson [qwilk/@xoblite]
5: Copyright © 2001-2004 The Blackbox for Windows Development Team
6: http://xoblite.net/ + https://github.com/xoblite/
7: ============================================================================
8:
9: Blackbox for Windows is free software, released under the
10: GNU General Public License (GPL version 2 or later), with an extension
11: that allows linking of proprietary modules under a controlled interface.
12: What this means is that plugins etc. are allowed to be released
13: under any license the author wishes. Please note, however, that the
14: original Blackbox gradient math code used in Blackbox for Windows
15: is available under the BSD license.
16:
17: http://www.fsf.org/licenses/gpl.html
18: http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
19: http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
20:
21: This program is distributed in the hope that it will be useful,
22: but WITHOUT ANY WARRANTY; without even the implied warranty of
23: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24: GNU General Public License for more details.
25:
26: For additional license information, please read the included license.html.
27:
28: ============================================================================
29: */
30:
31: #pragma warning(disable: 4996) // "'GetVersionExA' was declared deprecated"
32:
33: #include "Blackbox.h"
34:
35: BImage *pBImage;
36: Console* pConsole;
37: Desktop* pDesktop;
38: Dock* pDock;
39: Hotkeys* pHotkeys;
40: Menu* pMenu;
41: MenuCommon* pMenuCommon;
42: MessageManager* pMessageManager;
43: PluginManager* pPluginManager;
44: PopupDialog* pPopupDialog;
45: PreviewItem* pPreviewItem;
46: Settings* pSettings;
47: Taskbar* pTaskbar;
48: Toolbar *pToolbar;
49: Tooltips* pTooltips;
50: Wallpaper* pWallpaper;
51: Workspaces *pWorkspaces;
52:
53: #include <gdiplus.h>
54: using namespace Gdiplus;
55: GdiplusStartupInput gdiplusStartupInput;
56: ULONG_PTR gdiplusToken;
57:
58: //====================
59:
60: const char szMainClass[] = "xoblite";
61: HINSTANCE hMainInstance = NULL;
62: HWND hMainWnd = NULL;
63: HANDLE hMutex;
64:
65: //HANDLE hShellReadyEvent;
66:
67: NOTIFYICONDATA xobIconData;
68:
69: static UINT WM_TASKBARCREATED_MESSAGE;
70:
71: bool pausedRestart = false;
72: int shutdownState;
73: bool exitInProgress = false;
74:
75: bool debugLogoff = false;
76: bool debugReboot = false;
77: bool debugShutdown = false;
78:
79: int sessionDuration = 0;
80:
81: //====================
82:
83: HMODULE hShell32Module = NULL;
84:
85: typedef void (__stdcall *MSWINSHUTDOWNPROC)(HWND);
86: MSWINSHUTDOWNPROC MSWinShutdown = NULL;
87: typedef void (__stdcall *RUNDLGPROC)(HWND, HICON, LPCSTR, LPCSTR, LPCSTR, int);
88: RUNDLGPROC RunDlg = NULL;
89: //typedef void (__stdcall *STTWTYPE)(HWND, int);
90: //STTWTYPE BBSwitchToThisWindow;
91:
92: typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS2) (HANDLE, USHORT*, USHORT*);
93: typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
94:
95: typedef BOOL (WINAPI *LPFN_WOW64_DISABLE_REDIRECTION)(PVOID);
96: LPFN_WOW64_DISABLE_REDIRECTION BBWow64DisableRedirection;
97: typedef BOOL (WINAPI *LPFN_WOW64_REVERT_REDIRECTION)(PVOID);
98: LPFN_WOW64_REVERT_REDIRECTION BBWow64RevertRedirection;
99:
100: typedef BOOL (WINAPI *LPFN_SHUTDOWN_BLOCK_REASON_CREATE)(HWND, LPCWSTR);
101: LPFN_SHUTDOWN_BLOCK_REASON_CREATE BBShutdownBlockReasonCreate;
102:
103: //FARPROC (__stdcall *RegisterShellHook) (HWND, DWORD) = NULL; // Legacy legacy shell hook...
104:
105: // ############################################################
106: // ##### Experimental stuff, not otherwise enabled yet... #####
107: // ##### (cf. useLegacyShellHook boolean setting below) #####
108: // ############################################################
109: HMODULE hShellHookDLL = NULL;
110: typedef bool (*PrepareShellHookFunc)(HWND, unsigned int, bool);
111: PrepareShellHookFunc PrepareShellHook;
112: typedef bool (*ShellHookStartFunc)(HWND, unsigned int, bool);
113: ShellHookStartFunc StartShellHook;
114: typedef bool (*ShellHookStopFunc)();
115: ShellHookStopFunc StopShellHook;
116: HOOKPROC ShellHookProcInDLL;
117: // ############################################################
118:
119: HHOOK shellHook = NULL;
120: unsigned int WM_SHELLHOOKMESSAGE = 0;
121: bool useLegacyShellHook = true;
122:
123: #define ID_HOTKEY 0
124:
125: #ifndef ENDSESSION_CLOSEAPP
126: #define ENDSESSION_CLOSEAPP 0x00000001
127: #endif
128: #ifndef ENDSESSION_CRITICAL
129: #define ENDSESSION_CRITICAL 0x40000000
130: #endif
131:
132: bool somethingIsFullscreen = false;
133: uint8_t lastFullscreenCheckStatus = 0;
134: #ifndef QUNS_APP
135: #define QUNS_APP 7
136: #endif
137:
138: //===========================================================================
139:
140: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
141: {
142: hMainInstance = hInstance;
143:
144: // Extract switches...
145: char option[MAX_LINE_LENGTH], extra[MAX_LINE_LENGTH];
146: char* tokens[1];
147: tokens[0] = option;
148: option[0] = extra[0] = '\0';
149: BBTokenize(lpCmdLine, tokens, 1, extra);
150:
151: //====================
152:
153: if (strnlen_s(option, sizeofArray(option))) // -> Switches included when calling the .exe -> Let's parse them instead of launching the regular way!
154: {
155: if ((!_stricmp(option, "-broam") || !_stricmp(option, "-exec")) && extra[0] == '@') // Support for sending bro@ms (i.e. using Blackbox.exe as a command line tool)
156: {
157: HWND xobhwnd = FindWindow(szMainClass, NULL);
158: if (xobhwnd)
159: {
160: COPYDATASTRUCT cds;
161: cds.dwData = BB_BROADCAST;
162: cds.cbData = MAX_LINE_LENGTH;
163: cds.lpData = &extra;
164: SendMessage(xobhwnd, WM_COPYDATA, NULL, (LPARAM)(&cds));
165: }
166: return 0;
167: }
168: else if (strchr(option, ':')) // Support for double clicking on .style files (nb. ...because filesystem paths always include a colon... :) )
169: {
170: if (strnlen_s(extra, sizeofArray(extra))) strcat_s(option, sizeofArray(option), extra);
171: if (!FileExists(option)) return 1;
172:
173: HWND xobhwnd = FindWindow(szMainClass, NULL);
174: if (xobhwnd)
175: {
176: COPYDATASTRUCT cds;
177: cds.dwData = BB_SETSTYLE;
178: cds.cbData = MAX_LINE_LENGTH;
179: cds.lpData = &option;
180: SendMessage(xobhwnd, WM_COPYDATA, NULL, (LPARAM)(&cds));
181: }
182: return 0;
183: }
184: }
185:
186: //====================
187:
188: // Check if Blackbox is already running...
189: hMutex = CreateMutex(NULL, false, "Blackbox");
190: if (GetLastError() == ERROR_ALREADY_EXISTS)
191: {
192: MessageBox(0, "Previously running instance of xoblite/Blackbox detected!\n(please quit that one first, then try to launch this one again) ", "xoblite", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
193: CloseHandle(hMutex);
194: return 1;
195: }
196:
197: //====================
198:
199: // Get addresses to undocumented Windows API calls...
200: hShell32Module = GetModuleHandle("SHELL32.DLL");
201: if (!hShell32Module) hShell32Module = LoadLibrary("SHELL32.DLL");
202: MSWinShutdown = (MSWINSHUTDOWNPROC)(GetProcAddress(hShell32Module, (LPCSTR)MAKELPARAM(0x3C, 0)));
203: RunDlg = (RUNDLGPROC)GetProcAddress(hShell32Module, (LPCSTR)MAKELPARAM(61, 0));
204: // RegisterShellHook = (FARPROC(__stdcall*) (HWND, DWORD))GetProcAddress(hShell32Module, (LPCSTR)((long)0xb5));
205:
206: //hUser32Module = GetModuleHandle("USER32.DLL");
207: //if (!hUser32Module) hUser32Module = LoadLibrary("USER32.DLL");
208: //BBSwitchToThisWindow = (STTWTYPE)GetProcAddress(GetModuleHandle("USER32.DLL"), "SwitchToThisWindow");
209:
210: //====================
211:
212: // Hide minimized windows...
213: MINIMIZEDMETRICS mm;
214: ZeroMemory(&mm, sizeof(MINIMIZEDMETRICS));
215: mm.cbSize = sizeof(MINIMIZEDMETRICS);
216: SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &mm, false);
217: mm.iArrange |= ARW_HIDE;
218: SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &mm, false);
219:
220: //====================
221:
222: // Set up the xoblite main class...
223: WNDCLASS wc;
224: ZeroMemory(&wc, sizeof(wc));
225: wc.hInstance = hMainInstance;
226: wc.lpfnWndProc = MainWndProc;
227: wc.lpszClassName = szMainClass;
228:
229: if (!RegisterClass(&wc))
230: {
231: MBoxErrorValue("Error registering xoblite class!");
232: Log("Error registering xoblite class!", NULL);
233: CloseHandle(hMutex);
234: return 1;
235: }
236:
237: // Set up the xoblite main window... (nb. this is only used for misc message handling, not as a UI element in itself)
238: hMainWnd = CreateWindowEx(
239: WS_EX_TOOLWINDOW | WS_EX_ACCEPTFILES | WS_EX_NOACTIVATE, // window style
240: szMainClass, // window class
241: NULL, // window name
242: WS_POPUP, // window parameters
243: 0, // x position
244: 0, // y position
245: 0, // window width
246: 0, // window height
247: NULL, // owner window
248: NULL, // no menu
249: hMainInstance, // hInstance assigned by the system
250: NULL // no window creation data
251: );
252:
253: if (!hMainWnd)
254: {
255: MBoxErrorValue("Error creating the xoblite main window!");
256: Log("Error creating the xoblite main window!", NULL);
257: UnregisterClass(szMainClass, hMainInstance);
258: CloseHandle(hMutex);
259: return 1;
260: }
261:
262: //====================
263:
264: // Initialize the xoblite message manager and settings...
265: // (nb. these need to be started *before* all other subsystems
266: // - see startBlackbox() etc below - as they are used by all of them)
267: pMessageManager = new MessageManager;
268: pSettings = new Settings;
269: pSettings->accessLock = false;
270:
271: //====================
272:
273: // Are we running alongside Explorer? (check for the systray window class,
274: // however note that this will also lock on to e.g. a stand alone systray plugin,
275: // so we need to do this before starting the rest of the shell...)
276: if (FindWindow("Shell_TrayWnd", NULL) != NULL) pSettings->underExplorer = true;
277: else pSettings->underExplorer = false;
278:
279: // Check and save OS version as a single integer for easier lookup later...
280: // Win95 -> 0400, Win98 -> 0410, WinME -> 0490, WinNT4 -> 1400,
281: // Win2k -> 1500, WinXP/32bit -> 1501, WinXP/64bit (and Server2003 & WHS) -> 1502,
282: // WinVista (and Server2008) -> 1600, Win7 (and Server2008R2) -> 1601,
283: // Win8 (and Server2012) -> 1602, Win81 (and Server2012R2) -> 1603
284: OSVERSIONINFO osInfo;
285: ZeroMemory(&osInfo, sizeof(osInfo));
286: osInfo.dwOSVersionInfoSize = sizeof(osInfo);
287: GetVersionEx(&osInfo);
288: pSettings->operatingSystemVersion = (osInfo.dwMajorVersion*100) + osInfo.dwMinorVersion;
289: if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) pSettings->operatingSystemVersion += 1000;
290:
291: // Check whether we're running under 64-bit Windows, and if possible on which CPU/machine architecture...
292: // (nb. ...we're only shipping 32-bit x86 binaries currently, but maybe in the future we'll add e.g. 64-bit ARM64 builds if such machines take off...)
293: pSettings->machineArchitecture = IMAGE_FILE_MACHINE_UNKNOWN;
294: pSettings->runningUnderWOW64 = FALSE;
295:
296: LPFN_ISWOW64PROCESS2 BBIsWow64Process2 = (LPFN_ISWOW64PROCESS2)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process2");
297: if (BBIsWow64Process2 != NULL)
298: {
299: USHORT is64bit = 0;
300: BBIsWow64Process2(GetCurrentProcess(), &is64bit, &pSettings->machineArchitecture);
301: if (is64bit == IMAGE_FILE_MACHINE_UNKNOWN) pSettings->runningUnderWOW64 = TRUE;
302: }
303: else
304: {
305: LPFN_ISWOW64PROCESS BBIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
306: if (BBIsWow64Process != NULL) BBIsWow64Process(GetCurrentProcess(), &pSettings->runningUnderWOW64);
307: else pSettings->runningUnderWOW64 = FALSE;
308: pSettings->machineArchitecture = IMAGE_FILE_MACHINE_UNKNOWN; // Note: IsWow64Process does not provide information about the CPU architecture, only the WoW64-or-not status.
309: }
310:
311: // Get system calls to enable/disable filesystem redirection under 64-bit Windows...
312: // -> "Wow64DisableWow64FsRedirection disables file system redirection for the calling thread. File system redirection is enabled by default."
313: // -> "Wow64RevertWow64FsRedirection restores file system redirection for the calling thread."
314: BBWow64DisableRedirection = (LPFN_WOW64_DISABLE_REDIRECTION)GetProcAddress(GetModuleHandle("kernel32"),"Wow64DisableWow64FsRedirection");
315: BBWow64RevertRedirection = (LPFN_WOW64_REVERT_REDIRECTION)GetProcAddress(GetModuleHandle("kernel32"),"Wow64RevertWow64FsRedirection");
316:
317: // Provide seed for pseudorandom number generation... (used by e.g. @xoblite Random <Style/Wallpaper> )
318: srand((unsigned int)time(NULL));
319:
320: //====================
321:
322: // Initialize a Shell Hook to receive continuous information regarding Windows task handling activities etc...
323:
324: WM_SHELLHOOKMESSAGE = RegisterWindowMessage("SHELLHOOK"); // Note: This is used by both the newer (via xShellHook.dll) and legacy (in core .exe) shell hook
325: // implementations to communicate information to the taskbar etc via the internal *box message bus.
326: /*
327: if (!useLegacyShellHook)
328: {
329: hShellHookDLL = LoadLibrary("xShellHook.dll");
330:
331: if (hShellHookDLL != NULL) // -> xShellHook.dll found!
332: {
333: PrepareShellHook = (PrepareShellHookFunc)(GetProcAddress(hShellHookDLL, "PrepareShellHook"));
334: StartShellHook = (ShellHookStartFunc)(GetProcAddress(hShellHookDLL, "StartShellHook"));
335: StopShellHook = (ShellHookStopFunc)(GetProcAddress(hShellHookDLL, "StopShellHook"));
336: ShellHookProcInDLL = (HOOKPROC)GetProcAddress(hShellHookDLL, "ShellHookProc");
337:
338: if (StartShellHook != NULL)
339: {
340: StartShellHook(hMainWnd, WM_SHELLHOOKMESSAGE, pSettings->debugLogging); // (...where the DLL in turn calls SetWindowsHookEx() etc.)
341: // PrepareShellHook(hMainWnd, WM_SHELLHOOKMESSAGE, pSettings->debugLogging);
342: // shellHook = SetWindowsHookEx(WH_SHELL, ShellHookProcInDLL, hShellHookDLL, 0);
343: useLegacyShellHook = false;
344: }
345: else
346: {
347: FreeLibrary(hShellHookDLL);
348: hShellHookDLL = NULL;
349: }
350: }
351: }
352: */
353: if (useLegacyShellHook || (hShellHookDLL == NULL)) // -> Fall back to the legacy RegisterShellHookWindow() function... (e.g. because xShellHook.dll was not found or otherwise disabled)
354: {
355: /*
356: if (RegisterShellHook)
357: {
358: // This was an undocumented older legacy call, at some point seemingly replaced by the slightly more documented but nowadays
359: // also to be considered legacy RegisterShellHookWindow() as per below... (this kept here only for historic reference)
360: // (cf. https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registershellhookwindow )
361:
362: RegisterShellHook(NULL, true);
363: if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) RegisterShellHook(hMainWnd, 1);
364: else RegisterShellHook(hMainWnd, 3);
365: }
366: */
367: useLegacyShellHook = (bool)RegisterShellHookWindow(hMainWnd);
368: }
369:
370: //====================
371:
372: // Hide the Explorer desktop icons...
373: HideDesktopIcons(true);
374:
375: // Start GDI+... (used by e.g. the menu PreviewItem, for any image-instead-of-gradient use per element, etc)
376: GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
377:
378: // Start all xoblite subsystems...
379: startBlackbox();
380: MakeSticky(hMainWnd);
381: SetForegroundWindow(hMainWnd);
382:
383: //####################
384: //####################
385: //####################
386:
387: // Retrieve messages from the message queue for any window
388: // that belongs to this thread until we recieve WM_QUIT...
389: BOOL value;
390: MSG msg;
391:
392: while ((value = GetMessage(&msg, NULL, 0, 0 )) != 0)
393: {
394: if (value == -1) break;
395: else
396: {
397: TranslateMessage(&msg);
398: DispatchMessage(&msg);
399: }
400: }
401:
402: //####################
403: //####################
404: //####################
405:
406: // Stop all xoblite subsystems...
407: // (nb. this is now done *before* exiting the message queue; see elsewhere below)
408: // exitBlackbox();
409:
410: // Shutdown GDI+...
411: GdiplusShutdown(gdiplusToken);
412:
413: // Show the Explorer desktop icons...
414: HideDesktopIcons(false);
415:
416: // Release the shell hook...
417: if (useLegacyShellHook)
418: {
419: // if (RegisterShellHook) RegisterShellHook(hMainWnd, 0); // Older undocumented legacy shell hook (kept here only for historic reference, cf. similar comments above)
420: DeregisterShellHookWindow(hMainWnd);
421: }
422: /*
423: else if (hShellHookDLL != NULL)
424: {
425: if (StopShellHook != NULL) StopShellHook();
426: // UnhookWindowsHookEx(shellHook);
427: FreeLibrary(hShellHookDLL);
428: }
429: */
430: DestroyWindow(hMainWnd);
431: UnregisterClass(szMainClass, hMainInstance);
432: CloseHandle(hMutex);
433:
434: bool debugLogging = pSettings->debugLogging;
435: if (pSettings) delete pSettings;
436: if (pMessageManager) delete pMessageManager;
437:
438: if (debugLogging)
439: {
440: if (debugShutdown && debugReboot) Log("xoblite", "Exiting properly (External Shutdown/Reboot)");
441: else if (debugShutdown) Log("xoblite", "Exiting properly (Shutdown)");
442: else if (debugReboot) Log("xoblite", "Exiting properly (Reboot)");
443: else if (debugLogoff) Log("xoblite", "Exiting properly (Logoff)");
444: else Log("xoblite", "Exiting properly (Quit)");
445: }
446:
447: return 0;
448: }
449:
450: //===========================================================================
451: // Function: startBlackbox
452: // Purpose: ...
453: //===========================================================================
454:
455: void startBlackbox()
456: {
457: // Get the paths to the default xoblite.rc or blackbox.rc/extensions.rc...
458: pSettings->GetShellFolders();
459:
460: //====================
461:
462: // Read only those settings from the default .rc
463: // that are required to set the correct theme at startup...
464: strcpy_s(pSettings->themesFolder, sizeofArray(pSettings->themesFolder), ReadString(pSettings->xobrcDefaultFile, "xoblite.themesFolder:", "$Blackbox$\\themes"));
465: if (strchr(pSettings->themesFolder, '\"')) StrRemoveEncap(pSettings->themesFolder);
466: if (strchr(pSettings->themesFolder, '$')) ReplaceShellFolders(pSettings->themesFolder);
467: if (strchr(pSettings->themesFolder, '%')) ReplaceEnvVars(pSettings->themesFolder);
468: strcpy_s(pSettings->selectedTheme, sizeofArray(pSettings->selectedTheme), ReadString(pSettings->xobrcDefaultFile, "xoblite.selected.theme:", "[Default]"));
469: if (!_stricmp(pSettings->selectedTheme, "<Default>")) strcpy_s(pSettings->selectedTheme, sizeofArray(pSettings->selectedTheme), "[Default]"); // (changed to avoid similarity to editable string/integer menu items, as it is also shown in the Themes menu)
470:
471: if (!_stricmp(pSettings->selectedTheme, "[Default]")) // -> Use the default theme...
472: {
473: SetTheme(pSettings->SF_blackboxPath, true);
474: }
475: else // -> Set a specific theme...
476: {
477: char themePath[MAX_PATH];
478: strcpy_s(themePath, sizeofArray(themePath), pSettings->themesFolder);
479: strcat_s(themePath, sizeofArray(themePath), "\\");
480: strcat_s(themePath, sizeofArray(themePath), pSettings->selectedTheme);
481: SetTheme(themePath, true);
482: }
483:
484: //====================
485:
486: // Read configuration settings and style parameters for the chosen theme...
487: pSettings->ReadConfiguration();
488: pSettings->ReadStyle();
489: RegisterThemeFonts();
490:
491: // Set time locale if configured...
492: if (strnlen_s(pSettings->timeDateLocale, sizeofArray(pSettings->timeDateLocale)) > 0) setlocale(LC_TIME, pSettings->timeDateLocale);
493: else setlocale(LC_TIME, ""); // Not configured -> Set the time locale to the user default obtained from the operating system...
494:
495: // Should we hide the Explorer taskbar etc already on startup?
496: if (pSettings->underExplorer && pSettings->explorerHidden) HideExplorer(true);
497:
498: //====================
499:
500: // ####################################################################
501: // ##### Note: The order things are started below is important!!! #####
502: // ####################################################################
503:
504: pBImage = new BImage;
505: pDesktop = new Desktop(hMainInstance);
506: pConsole = new Console(hMainInstance);
507:
508: // Display welcome message in the console...
509: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_SHELL_MESSAGE, (LPARAM)"Welcome to xoblite.");
510: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_PLAIN_MESSAGE, (LPARAM)" http://xoblite.net/");
511: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_PLAIN_MESSAGE, (LPARAM)" https://github.com/xoblite/");
512:
513: // Set time stamp for beginning of session...
514: Log("----------------------------------------", "");
515: SessionTimeStamp(true);
516: /*
517: if (pSettings->debugLogging)
518: {
519: char msg[255];
520: sprintf_s(msg, sizeofArray(msg), "Operating system: %s ", GetOSInfo());
521: if (pSettings->runningUnderWOW64) strcat_s(msg, sizeofArray(msg), "(64-bit).");
522: else strcat_s(msg, sizeofArray(msg), "(32-bit).");
523: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
524:
525: // char msg[255];
526: // sprintf_s(msg, sizeofArray(msg), "Time locale set to %s.", setlocale(LC_TIME, NULL));
527: // SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
528: }
529: */
530: /*
531: if (useLegacyShellHook) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_ERROR_MESSAGE, (LPARAM)"xShellHook .DLL not found (or disabled) -> Falling back to legacy shell hook implementation.");
532: else if (hShellHookDLL != NULL) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"xShellHook .DLL found -> Using alternative new shell hook implementation.");
533: if (pSettings->debugLogging)
534: {
535: if (hShellHookDLL != NULL)
536: {
537: // SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"DEBUG -> xShellHook.dll loaded.");
538: if (PrepareShellHook != NULL) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"... PrepareShellHook() function found.");
539: if (StartShellHook != NULL) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"... StartShellHook() function found.");
540: if (StopShellHook != NULL) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"... StopShellHook() function found.");
541: if (ShellHookProcInDLL != NULL) SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"... ShellHookProc() function found.");
542: }
543: }
544: */
545: pWorkspaces = new Workspaces(hMainInstance);
546: pMenuCommon = new MenuCommon;
547: pPreviewItem = new PreviewItem(hMainInstance);
548: pDock = new Dock(hMainInstance);
549: pTooltips = new Tooltips();
550: pTaskbar = new Taskbar();
551:
552: pPluginManager = new PluginManager(hMainInstance);
553: pToolbar = new Toolbar(hMainInstance);
554: pPopupDialog = new PopupDialog(hMainInstance);
555:
556: pMenuCommon->Initialize(hMainInstance);
557: pTaskbar->InitializeTaskList(); // Enumerate tasks for the taskbar...
558:
559: pHotkeys = new Hotkeys(hMainInstance);
560:
561: if (pSettings->underExplorer)
562: {
563: // Add the xoblite icon to the system tray... =]
564: ZeroMemory(&xobIconData, sizeof(NOTIFYICONDATA));
565: xobIconData.cbSize = sizeof(NOTIFYICONDATA); // Older Windows versions -> NOTIFYICONDATA_V3_SIZE
566: xobIconData.hIcon = LoadIcon(hMainInstance, MAKEINTRESOURCE(IDI_XOBLITE));
567: // LoadIconMetric(hMainInstance, MAKEINTRESOURCE(IDI_XOBLITE), LIM_SMALL, &(xobIconData.hIcon));
568: strcpy_s(xobIconData.szTip, sizeofArray(xobIconData.szTip), "xoblite");
569: xobIconData.hWnd = GetBBWnd();
570: xobIconData.uID = 0;
571: xobIconData.uVersion = NOTIFYICON_VERSION_4; // // Older Windows versions -> 3
572: xobIconData.uCallbackMessage = BB_TRAYICONMESSAGE;
573: xobIconData.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
574: Shell_NotifyIcon(NIM_ADD, &xobIconData);
575:
576: }
577:
578: WM_TASKBARCREATED_MESSAGE = RegisterWindowMessage(TEXT("TaskbarCreated"));
579:
580: // SendMessage(GetDesktopWindow(), 0x400, 0, 0); // ...hmm, not quite sure what this did anymore...?! ;)
581:
582: // Show/hide the plugins based on the related xoblite.rc setting...
583: if (pSettings->pluginsHidden) SendMessage(hMainWnd, BB_BROADCAST, 0, (LPARAM)"@BBHidePlugins");
584: else SendMessage(hMainWnd, BB_BROADCAST, 0, (LPARAM)"@BBShowPlugins");
585:
586: // Finally, as a "security precausion" we move the xoblite desktop window to the bottom...
587: SetWindowPos(pDesktop->hDesktopWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
588:
589: // Execute the current style's rootCommand...
590: _beginthread(ExecuteRootCommand, 0, NULL);
591:
592: PlaySoundFX(SFX_STARTUP);
593:
594: if (pSettings->debugLogging) Log("xoblite", "All subsystems started successfully.");
595:
596: //====================
597:
598: // Check if the Blackbox font pack is installed, and if not display a warning message...
599: HFONT checkPackFont = CreateFont(12, 0, 0, 0, FW_NORMAL, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "mints-strong");
600: if (checkPackFont)
601: {
602: HDC temphdc = CreateCompatibleDC(NULL);
603: HGDIOBJ oldfont = SelectObject(temphdc, checkPackFont);
604: char createdFontName[33];
605: GetTextFace(temphdc, 32, createdFontName);
606: if (_stricmp(createdFontName, "mints-strong"))
607: {
608: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)"The Blackbox font pack does not seem to be installed. Get it from the xoblite website! -> http://xoblite.net/");
609: }
610:
611: DeleteObject(checkPackFont);
612: DeleteObject(SelectObject(temphdc, oldfont));
613: DeleteDC(temphdc);
614: }
615:
616: //====================
617: /*
618: if (pSettings->debugLogging) // ### DEPRECATED (read: old boundary failsafe introduced by BlackboxZero, nowadays outgrown [>300 bytes] anyway...) ###
619: {
620: char msg[255];
621: sprintf_s(msg, sizeofArray(msg), "Debug: Size of StyleItem struct -> %d bytes.", sizeof(StyleItem));
622: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
623: }
624: */
625: //====================
626:
627: // Set a 1 second recurring timer to check for applications entering/exiting fullscreen...
628: // (i.e. to hide/show the xoblite core UI elements when this happens; see WM_TIMER handling in MainWndProc() below)
629: SetTimer(GetBBWnd(), CHECK_FOR_FULLSCREEN_TIMER, 1000, (TIMERPROC)NULL);
630:
631: // Once everything else is up and running, we first wait another 3 seconds, then perform a check for updates...
632: SetTimer(GetBBWnd(), CHECK_FOR_UPDATES_DELAY_TIMER, 3000, (TIMERPROC)NULL);
633: }
634:
635: //===========================================================================
636: // Function: exitBlackbox
637: // Purpose: ...
638: //===========================================================================
639:
640: void exitBlackbox()
641: {
642: // Just a security precausion... ;)
643: if (exitInProgress) return;
644: else exitInProgress = true;
645:
646: // Set time stamp for end of session...
647: SessionTimeStamp(false);
648:
649: ClearSticky();
650:
651: DestroyRunBox(); // ...just in case the user left the run box open upon exit...
652:
653: pSettings->accessLock = true;
654:
655: if (pSettings->underExplorer) Shell_NotifyIcon(NIM_DELETE, &xobIconData);
656:
657: if (pHotkeys) delete pHotkeys;
658: if (pPopupDialog) delete pPopupDialog;
659: if (pToolbar) delete pToolbar;
660: if (pPluginManager) delete pPluginManager;
661: if (pTaskbar) delete pTaskbar;
662: if (pTooltips) delete pTooltips;
663: if (pDock) delete pDock;
664: if (pPreviewItem) delete pPreviewItem;
665: if (pMenuCommon) delete pMenuCommon;
666: if (pWorkspaces) delete pWorkspaces;
667: if (pConsole) delete pConsole;
668: if (pDesktop) delete pDesktop;
669: if (pBImage) delete pBImage;
670:
671: UnregisterThemeFonts();
672:
673: if (pSettings->underExplorer)
674: {
675: Shell_NotifyIcon(NIM_DELETE, &xobIconData);
676: DestroyIcon(xobIconData.hIcon);
677: }
678:
679: if (pSettings->underExplorer && pSettings->explorerHidden) ShowExplorer();
680:
681: // if (pSettings->debugLogging) Log("xoblite", "exitBlackbox() completed successfully.");
682: }
683:
684: //===========================================================================
685: // Functions: restartBlackboxStop / restartBlackboxStart
686: // Purpose: Restarts applicable xoblite subsystems
687: // (optionally with a "wait for user" pause in between stop and restart)
688: //===========================================================================
689:
690: void restartBlackboxStop()
691: {
692: // Disable dock transparency (for some reason this needs to be
693: // done to avoid visual artifacts) and hide the dock window...
694: if (pDock)
695: {
696: SetTransparency(pDock->hDockWnd, 255);
697: ShowWindow(pDock->hDockWnd, SW_HIDE);
698: }
699:
700: // Unload all plugins...
701: if (pPluginManager) delete pPluginManager;
702:
703: // Shall we pause the restart to let the user do something before continuing?
704: if ((GetAsyncKeyState(VK_SHIFT) & 0x8000) || pausedRestart)
705: {
706: MessageBox(GetBBWnd(), "Restart paused, press OK to continue... ", "xoblite", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
707: pausedRestart = false;
708: }
709: }
710:
711: //===========================================================================
712:
713: void restartBlackboxStart()
714: {
715: int existingWorkspaces = pSettings->numberOfWorkspaces;
716:
717: // Stop applicable subsystems...
718: if (pHotkeys) delete pHotkeys;
719: if (pPreviewItem) delete pPreviewItem;
720: if (pMenuCommon) delete pMenuCommon;
721:
722: // Read configuration settings and style parameters...
723: pSettings->ReadConfiguration();
724: pSettings->ReadStyle();
725:
726: // Set time locale if configured...
727: if (strnlen_s(pSettings->timeDateLocale, sizeofArray(pSettings->timeDateLocale)) > 0) setlocale(LC_TIME, pSettings->timeDateLocale);
728: else setlocale(LC_TIME, ""); // Not configured -> Reset the time locale to the user default obtained from the operating system...
729: pToolbar->GetClockText(true);
730: /*
731: if (pSettings->debugLogging)
732: {
733: char msg[255];
734: sprintf_s(msg, sizeofArray(msg), "Time locale set to %s.", setlocale(LC_TIME, NULL));
735: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
736: }
737: */
738: //====================
739:
740: if (existingWorkspaces != pSettings->numberOfWorkspaces)
741: {
742: // if (pWorkspaces) delete pWorkspaces;
743: // pWorkspaces = new Workspaces(hMainInstance);
744: pWorkspaces->GatherWindows();
745: if (pSettings->currentWorkspace > (pSettings->numberOfWorkspaces - 1))
746: {
747: pWorkspaces->SwitchToWorkspace(pSettings->numberOfWorkspaces - 1);
748: }
749: }
750:
751: pWorkspaces->UpdateWorkspaceNames();
752:
753: //====================
754:
755: // Start applicable subsystems again...
756: pMenuCommon = new MenuCommon();
757: pMenuCommon->Initialize(hMainInstance);
758: pPreviewItem = new PreviewItem(hMainInstance);
759: pPluginManager = new PluginManager(hMainInstance);
760: pHotkeys = new Hotkeys(hMainInstance);
761:
762: // Update toolbar+dock+console size, position and alpha transparency...
763: pToolbar->UpdatePosition();
764: pDock->UpdateDockWindow();
765: pConsole->UpdatePosition();
766: pPopupDialog->UpdatePopupDialog();
767:
768: // Show/hide the toolbar, console and plugins based on their applicable .rc settings...
769: ShowWindow(pToolbar->hToolbarWnd, pSettings->toolbarHidden ? SW_HIDE : SW_SHOWNOACTIVATE);
770: ShowWindow(pConsole->hConsoleWnd, pSettings->consoleHidden ? SW_HIDE : SW_SHOWNOACTIVATE);
771: if (pSettings->pluginsHidden) SendMessage(hMainWnd, BB_BROADCAST, 0, (LPARAM)"@BBHidePlugins");
772: else SendMessage(hMainWnd, BB_BROADCAST, 0, (LPARAM)"@BBShowPlugins");
773:
774: // Force update of any external system tray plugins... (nb. as of xoblite bb5, the internal systray has been discontinued, but keeping this "just in case"... ;))
775: PostMessage(hMainWnd, BB_TRAYUPDATE, NULL, (LPARAM)TRAYICON_REFRESH);
776:
777: // Ask the desktop to update...
778: pDesktop->GetClockText(true);
779: pDesktop->UpdateDesktopWindow();
780: // Finally, as a "security precausion" we move the xoblite desktop window to the bottom...
781: SetWindowPos(pDesktop->hDesktopWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
782: // ...and move the console->dock->toolbar, if not hidden, to the top...
783: if (!pSettings->consoleHidden) SetForegroundWindow(pConsole->hConsoleWnd);
784: if (!pSettings->dockHidden) SetForegroundWindow(pDock->hDockWnd);
785: if (!pSettings->toolbarHidden) SetForegroundWindow(pToolbar->hToolbarWnd);
786:
787: // Should we hide or show the Explorer taskbar etc? (i.e. if the related setting has changed)
788: if (pSettings->underExplorer && pSettings->explorerHidden) HideExplorer(true);
789: else ShowExplorer();
790:
791: // Start Designer Mode (i.e. load the xDesignerGUI.dll privileged plugin) again if it was enabled before the core restart...
792: if (pSettings->designerModeEnabled)
793: {
794: char xDGUIpath[MAX_PATH];
795: sprintf_s(xDGUIpath, sizeofArray(xDGUIpath), "%s\\%s", pSettings->SF_blackboxPath, "xDesignerGUI.dll");
796: if (!pPluginManager->IsPluginLoaded("xDesignerGUI.dll")) pPluginManager->LoadPlugin(xDGUIpath);
797: }
798:
799: //====================
800:
801: _beginthread(ExecuteRootCommand, 0, NULL);
802: }
803:
804: //===========================================================================
805: // Function: MainWndProc
806: // Purpose: xoblite main window process (nb. non-visible window)
807: //===========================================================================
808:
809: LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
810: {
811: switch (uMsg)
812: {
813: //====================
814:
815: case WM_HELP:
816: {
817: BBExecute(GetDesktopWindow(), NULL, "http://xoblite.net/shell/", "", "", SW_SHOWNORMAL, true);
818: return TRUE;
819: }
820:
821: //====================
822:
823: case WM_HOTKEY:
824: {
825: if (pHotkeys) pHotkeys->ExecuteHotkey((int)wParam);
826: }
827: break;
828:
829: //====================
830:
831: case WM_QUERYENDSESSION:
832: {
833: if (lParam & ENDSESSION_CRITICAL)
834: {
835: if (lParam & ENDSESSION_LOGOFF) debugLogoff = true;
836: else debugShutdown = debugReboot = true;
837: if (pSettings->debugLogging) Log("xoblite", "WM_QUERYENDSESSION | SYSTEM/CRITICAL");
838: return TRUE;
839: }
840: else if (debugLogoff || debugReboot || debugShutdown)
841: {
842: if (pSettings->debugLogging)
843: {
844: if (debugLogoff) Log("xoblite", "WM_QUERYENDSESSION | XOBLITE/LOGOFF");
845: else if (debugReboot) Log("xoblite", "WM_QUERYENDSESSION | XOBLITE/REBOOT");
846: else Log("xoblite", "WM_QUERYENDSESSION | XOBLITE/SHUTDOWN");
847: }
848: return TRUE;
849: }
850: else
851: {
852: if (pSettings->debugLogging)
853: {
854: if (lParam & ENDSESSION_CLOSEAPP) Log("xoblite", "WM_QUERYENDSESSION | SYSTEM/CLOSEAPP");
855: else if (lParam & ENDSESSION_LOGOFF) Log("xoblite", "WM_QUERYENDSESSION | SYSTEM/LOGOFF");
856: else Log("xoblite", "WM_QUERYENDSESSION | SYSTEM/SHUTDOWN_or_REBOOT");
857: }
858: /*
859: if (pSettings->debugLogging)
860: {
861: if (MessageBox(GetBBWnd(), "Windows has requested a logoff/reboot/shutdown. \n\nAre you sure you want to quit? \n", "xoblite", MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND | MB_TOPMOST) != IDYES)
862: {
863: Log("xoblite", "WM_QUERYENDSESSION | === BLOCKED BY USER ===");
864: return FALSE;
865: }
866: }
867: */
868: }
869:
870: if (lParam & ENDSESSION_LOGOFF) debugLogoff = true;
871: else debugShutdown = debugReboot = true;
872: // PostMessage(hMainWnd, WM_CLOSE, 0, 0);
873: return TRUE;
874: }
875:
876: case WM_ENDSESSION:
877: {
878: if ((wParam == TRUE) && pSettings->debugLogging) Log("xoblite", "WM_ENDSESSION");
879: // exitBlackbox();
880: return 0;
881: }
882:
883: //====================
884:
885: case WM_SYSCOMMAND:
886: case WM_KEYDOWN:
887: {
888: if (wParam == SC_CLOSE)
889: {
890: if (pSettings->debugLogging) Log("xoblite", "SC_CLOSE");
891: PostMessage(GetBBWnd(), BB_SHUTDOWN, 255, 0); // Open the standard Windows shutdown menu...
892: return 0;
893: }
894: else return DefWindowProc(hWnd, uMsg, wParam, lParam);
895: }
896:
897: //====================
898:
899: case WM_CLOSE:
900: case BB_QUIT:
901: {
902: if (pSettings->debugLogging && (uMsg==WM_CLOSE)) Log("xoblite", "SC_CLOSE");
903: exitBlackbox();
904: PostQuitMessage(0);
905: }
906: break;
907:
908: //====================
909:
910: case BB_SHUTDOWN:
911: {
912: switch (wParam)
913: {
914: case 0: // Shutdown
915: ShutdownWindows(0, ((int)lParam == 1));
916: break;
917: case 1: // Reboot
918: ShutdownWindows(1, ((int)lParam == 1));
919: break;
920: case 2: // Log off
921: ShutdownWindows(2, ((int)lParam == 1));
922: break;
923: case 3: // Hibernate (a.k.a. "safe sleep" and "suspend to disk")
924: ShutdownWindows(3, ((int)lParam == 1));
925: break;
926: case 4: // Standby (a.k.a. "sleep" and "suspend to RAM")
927: ShutdownWindows(4, ((int)lParam == 1));
928: break;
929: case 5: // LockWorkstation
930: // BBExecute(GetDesktopWindow(), NULL, "rundll32.exe", "user32.dll,LockWorkStation", NULL, SW_HIDE, false);
931: LockWorkStation();
932: PlaySoundFX(SFX_LOCK_WORKSTATION);
933: break;
934: default: // Standard Windows shutdown menu (does not work from the xoblite main menu)
935: MSWinShutdown(hMainWnd);
936: break;
937: }
938: return 0;
939: }
940:
941: //====================
942:
943: case BB_RESTART:
944: {
945: if (exitInProgress) // Restart after a failed shutdown/reboot/etc attempt...
946: {
947: exitInProgress = false;
948: startBlackbox();
949: }
950: else if (!pausedRestart) // Regular restart...
951: {
952: // Lock the dock to avoid repeated SLIT_REMOVE/ADD
953: // messages from plugins when restarting...
954: pDock->ReconfigureLock(true);
955: if (wParam) pausedRestart = true;
956: restartBlackboxStop();
957: restartBlackboxStart();
958: SendMessage(pDesktop->hDesktopWnd, BB_RECONFIGURE, 0, 0);
959: }
960: }
961: break;
962:
963: //====================
964:
965: case BB_SETTHEME: // Introducing xoblite *THEMES*! :D
966: {
967: if (lParam != 0)
968: {
969: char themePath[MAX_LINE_LENGTH];
970: strcpy_s(themePath, sizeofArray(themePath), (LPCSTR)lParam);
971: SetTheme(themePath, false);
972: }
973: }
974: break;
975:
976: //====================
977:
978: case BB_SETSTYLE:
979: {
980: // Load a new style or refresh the current one?
981: if (lParam != 0)
982: {
983: char style[MAX_LINE_LENGTH];
984: strcpy_s(style, sizeofArray(style), (LPCSTR)lParam);
985: if (strchr(style, '\"')) StrRemoveEncap(style);
986: if (strchr(style, '$')) ReplaceShellFolders(style);
987: if (strchr(style, '%')) ReplaceEnvVars(style);
988:
989: if (!FileExists(style))
990: {
991: MBoxErrorFile(style);
992: break;
993: }
994: stylePath(style); // Save the new style path to blackbox.rc etc.
995: }
996:
997: // Read the new style settings...
998: pSettings->ReadStyle();
999:
1000: // Show style change message in the console...
1001: char msg[MAX_LINE_LENGTH], a1[MAX_LINE_LENGTH], a2[MAX_LINE_LENGTH]; // , a3[MAX_LINE_LENGTH];
1002: strcpy_s(a1, sizeofArray(a1), ReadString(pSettings->styleFile, "style.name:", "[Style name not specified]"));
1003: strcpy_s(a2, sizeofArray(a2), ReadString(pSettings->styleFile, "style.author:", "[Author not specified]"));
1004: // strcpy_s(a3, sizeofArray(a3), ReadString(pSettings->styleFile, "style.wallpaper:", ""));
1005: // if (strnlen_s(a3, sizeofArray(a3))) sprintf_s(msg, sizeofArray(msg), "Applying \"%s\" by %s... (suggested wallpaper -> %s )", a1, a2, a3);
1006: // else sprintf_s(msg, sizeofArray(msg), "Applying \"%s\" by %s...", a1, a2);
1007: sprintf_s(msg, sizeofArray(msg), "Applying \"%s\" by %s...", a1, a2);
1008: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
1009:
1010: // Update global menu settings (item heights, fonts...)
1011: pMenuCommon->Configure();
1012:
1013: // Temporarily lock the dock to avoid repeated SLIT_UPDATE messages from plugins... (i.e. repeated repaints of the dock window)
1014: pDock->ReconfigureLock(true);
1015:
1016: // Reconfigure...
1017: SendMessage(GetBBWnd(), BB_RECONFIGURE, 0, 0);
1018:
1019: // As a "security precausion", we also move the desktop window to the bottom...
1020: // SetWindowPos(pDesktop->hDesktopWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
1021: SetWindowPos(pDesktop->hDesktopWnd, GetDesktopWindow(), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
1022:
1023: // Finally, we execute the rootCommand (nb. only "bsetbg" or "bsetroot", now internally parsed, allowed!) in a separate thread...
1024: if (!wParam && !pSettings->disableRootCommands) _beginthread(ExecuteRootCommand, 0, NULL);
1025:
1026: pSettings->Statistics.changedStyle++; // Update statistics...
1027: }
1028: break;
1029:
1030: //====================
1031:
1032: case WM_DISPLAYCHANGE:
1033: {
1034: if (!pSettings->disableRootCommands) _beginthread(ExecuteRootCommand, 0, NULL); // Refresh the desktop wallpaper by re-running the current style's rootCommand...
1035: }
1036: break;
1037:
1038: //====================
1039:
1040: case WM_DPICHANGED:
1041: {
1042: int dpiValue = (int)LOWORD(wParam);
1043: int scaleFactor = 0;
1044:
1045: switch (dpiValue)
1046: {
1047: case 384: { scaleFactor = 400; } break; // 384 DPI -> 400%
1048: case 336: { scaleFactor = 350; } break; // 336 DPI -> 350%
1049: case 288: { scaleFactor = 300; } break; // 288 DPI -> 300%
1050: case 240: { scaleFactor = 250; } break; // 240 DPI -> 250%
1051: case 216: { scaleFactor = 225; } break; // 216 DPI -> 225%
1052: case 192: { scaleFactor = 200; } break; // 192 DPI -> 200%
1053: case 168: { scaleFactor = 175; } break; // 168 DPI -> 175%
1054: case 144: { scaleFactor = 150; } break; // 144 DPI -> 150%
1055: case 120: { scaleFactor = 125; } break; // 120 DPI -> 125%
1056: case 96: { scaleFactor = 100; } break; // 96 DPI -> 100%
1057: default: break; // Unknown DPI value
1058: }
1059:
1060: char msg[350];
1061: if (scaleFactor > 0) sprintf_s(msg, sizeofArray(msg), "Windows UI scaling factor has changed to %d%%. xoblite HiDPI scaling factor is set to %dx. ", scaleFactor, pSettings->scalingFactorHiDPI);
1062: else sprintf_s(msg, sizeofArray(msg), "Windows UI scaling resolution has changed to %d DPI. xoblite HiDPI scaling factor is set to %dx. ", dpiValue, pSettings->scalingFactorHiDPI);
1063: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1064:
1065: return 0;
1066: }
1067:
1068: //====================
1069:
1070: case BB_EDITFILE:
1071: {
1072: switch (wParam)
1073: {
1074: case 0: // Open the current style file for editing
1075: BBExecute(GetDesktopWindow(), NULL, pSettings->preferredEditor, pSettings->styleFile, NULL, SW_SHOWNORMAL, false);
1076: break;
1077: case 1: // Open the current menu.rc file for editing
1078: BBExecute(GetDesktopWindow(), NULL, pSettings->preferredEditor, pSettings->menuFile, NULL, SW_SHOWNORMAL, false);
1079: break;
1080: case 2: // Open the current plugins.rc file for editing
1081: BBExecute(GetDesktopWindow(), NULL, pSettings->preferredEditor, pSettings->pluginsFile, NULL, SW_SHOWNORMAL, false);
1082: break;
1083: case 3: // Open the current theme's xoblite.rc (or if used, legacy extensions.rc) file for editing
1084: BBExecute(GetDesktopWindow(), NULL, pSettings->preferredEditor, pSettings->xobrcFile, NULL, SW_SHOWNORMAL, false);
1085: break;
1086: case 4: // Open the default xoblite.rc (or if used, legacy blackbox.rc) file for editing
1087: BBExecute(GetDesktopWindow(), NULL, pSettings->preferredEditor, pSettings->xobrcDefaultFile, NULL, SW_SHOWNORMAL, false);
1088: break;
1089: default:
1090: break;
1091: }
1092: return 0;
1093: }
1094: break;
1095:
1096: //====================
1097:
1098: case BB_TOGGLEPLUGINS:
1099: {
1100: if (pSettings->pluginsHidden)
1101: {
1102: SendMessage(hMainWnd, BB_BROADCAST, 0, (LPARAM)"@BBShowPlugins");
1103: pSettings->pluginsHidden = false;
1104: }
1105: else
1106: {
1107: SendMessage(hMainWnd, BB_BROADCAST, 0, (LPARAM)"@BBHidePlugins");
1108: pSettings->pluginsHidden = true;
1109: }
1110:
1111: // Move the console->dock->toolbar, if not hidden, back to the top... (i.e. so they're not covered by any non-alwaysontop plugins)
1112: if (!pSettings->consoleHidden) SetForegroundWindow(pConsole->hConsoleWnd);
1113: if (!pSettings->dockHidden) SetForegroundWindow(pDock->hDockWnd);
1114: if (!pSettings->toolbarHidden) SetForegroundWindow(pToolbar->hToolbarWnd);
1115:
1116: WriteBool(pSettings->xobrcFile, "xoblite.plugins.hidden:", pSettings->pluginsHidden);
1117: }
1118: break;
1119:
1120: //====================
1121:
1122: case BB_RUN: // This is called e.g. from a menu [run] item...
1123: {
1124: if ((int)lParam == 1) BBSmartExecute("@xoblite Run"); // -> The xoblite super-powered run box... (i.e. this includes support for bro@ms, @script as well as regular commands, but lacks a "Browse..." function etc)
1125: else RunDlg( NULL, NULL, NULL, NULL, NULL, 0 ); // -> The regular Windows run dialog... (i.e. this lacks support for bro@ms and @script of course, but has a "Browse..." function etc)
1126: }
1127: break;
1128:
1129: case WM_CTLCOLOREDIT: // Used by the xoblite run box edit window... (nb. for menu string item edit windows this is handled by the item's parent menu)
1130: {
1131: // SetTextColor((HDC)wParam, pSettings->Toolbar->TextColor);
1132: // SetBkColor((HDC)wParam, pSettings->Toolbar->Color);
1133: SetTextColor((HDC)wParam, 0x000000);
1134: SetBkColor((HDC)wParam, 0xffffff);
1135: return (LRESULT)GetStockObject(NULL_BRUSH);
1136: }
1137: break;
1138:
1139: //====================
1140:
1141: case BB_REGISTERMESSAGE:
1142: {
1143: UINT *msgArray = (UINT*)lParam;
1144: for (int size = 0; msgArray[size] != 0; size++)
1145: {
1146: pMessageManager->AddMessage(msgArray[size], (HWND)wParam);
1147: }
1148: break;
1149: }
1150:
1151: case BB_UNREGISTERMESSAGE:
1152: {
1153: UINT *msgArray = (UINT*)lParam;
1154: for (int size = 0; msgArray[size] != 0; size++)
1155: {
1156: pMessageManager->RemoveMessage(msgArray[size], (HWND)wParam);
1157: }
1158: break;
1159: }
1160:
1161: //====================
1162:
1163: case WM_COPYDATA: // Used by Blackbox.exe -broam <string>
1164: {
1165: PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
1166: if (pcds->dwData == BB_BROADCAST) SendMessage(GetBBWnd(), BB_BROADCAST, 0, (LPARAM)pcds->lpData);
1167: else if (pcds->dwData == BB_SETSTYLE) PostMessage(GetBBWnd(), BB_SETSTYLE, 0, (LPARAM)pcds->lpData);
1168: break;
1169: }
1170:
1171: //====================
1172:
1173: case WM_DROPFILES:
1174: {
1175: // Forward any drag'n'drop messages to the Desktop for parsing...
1176: if (pDesktop) return PostMessage(pDesktop->hDesktopWnd, WM_DROPFILES, wParam, lParam);
1177: }
1178: break;
1179:
1180: //====================
1181:
1182: case WM_TIMER:
1183: {
1184: // CHECK_EXPLORER_HIDDEN_TIMER:
1185: // -> Timer to check whether the Explorer taskbar has gone visible again,
1186: // despite having been previously hidden... (read: I'm not 100% sure why/when
1187: // this happens yet, so continuously checking is more "foolproof" for now ;) )
1188: if (wParam == CHECK_EXPLORER_HIDDEN_TIMER)
1189: {
1190: if (pSettings->explorerHidden)
1191: {
1192: if (pSettings->underExplorer && IsWindowVisible(FindWindow("Shell_TrayWnd", NULL)))
1193: {
1194: HideExplorer(true);
1195: HideDesktopIcons(true);
1196: }
1197: }
1198:
1199: return 0;
1200: }
1201:
1202: // SESSION_DURATION_TIMER:
1203: // -> Timer to measure the length of the session in minutes...
1204: // (used to calculate the duration of the session when it ends)
1205: else if (wParam == SESSION_DURATION_TIMER)
1206: {
1207: sessionDuration++;
1208: return 0;
1209: }
1210:
1211: // CHECK_FOR_FULLSCREEN_TIMER:
1212: // -> Timer to recurringly check for applications entering/exiting fullscreen,
1213: // and to hide/show the xoblite core UI elements when this happens...
1214: else if (wParam == CHECK_FOR_FULLSCREEN_TIMER)
1215: {
1216: if (!pSettings->fullscreenDetection) return 0;
1217:
1218: char msg[MAX_LINE_LENGTH], windowText[MAX_LINE_LENGTH];
1219:
1220: HWND window = NULL;
1221: if (pTaskbar) window = pTaskbar->GetActiveWindow(); // First we check if the application window being focused is visible on the taskbar...
1222: if (window == NULL) window = GetForegroundWindow(); // ...then fallback in case of a non-taskbar (i.e. normal taskbar IsAppWindow() checks failed) application window being focused.
1223: if (window == NULL) return 0;
1224: if (IsIconic(window)) return 0;
1225:
1226: GetWindowText(window, windowText, sizeof(windowText));
1227: if (!_stricmp(windowText, "Program Manager")) return 0;
1228: // if (strlen(windowText) == 0) return 0;
1229:
1230: RECT r;
1231: GetWindowRect(window, &r);
1232: int windowWidth = r.right - r.left;
1233: int windowHeight = r.bottom - r.top;
1234:
1235: int fullscreenWidth = GetSystemMetrics(SM_CXSCREEN);
1236: int fullscreenHeight = GetSystemMetrics(SM_CYSCREEN);
1237:
1238: QUERY_USER_NOTIFICATION_STATE quns;
1239: SHQueryUserNotificationState(&quns);
1240:
1241: // Note: For reasons yet to be understood, the QUNS_BUSY state (and/or the related do-not-disturb focus mode handling by Windows) is not fully
1242: // reliable and can lead to ping-pong hide/show scenarios; hence not relied upon below, in favour of simple window-vs-screen size match checking.
1243:
1244: // if (((windowWidth == fullscreenWidth) && (windowHeight == fullscreenHeight)) || (quns == QUNS_RUNNING_D3D_FULL_SCREEN) || (quns == QUNS_PRESENTATION_MODE))
1245: if ((!pSettings->explorerHidden && (windowWidth == fullscreenWidth) && (windowHeight == fullscreenHeight)) || (quns == QUNS_RUNNING_D3D_FULL_SCREEN) || (quns == QUNS_PRESENTATION_MODE))
1246: {
1247: if (!somethingIsFullscreen)
1248: {
1249: somethingIsFullscreen = true;
1250: pDesktop->FullscreenDetected(true);
1251: pToolbar->FullscreenDetected(true);
1252: pDock->FullscreenDetected(true);
1253: pConsole->FullscreenDetected(true);
1254:
1255: if (pSettings->debugLogging)
1256: {
1257: sprintf_s(msg, sizeofArray(msg), "DEBUG -> Blackbox::MainWndProc -> \"%s\" has entered fullscreen mode.", windowText);
1258: switch (quns)
1259: {
1260: case QUNS_RUNNING_D3D_FULL_SCREEN: { strcat_s(msg, sizeofArray(msg), " | QUNS_RUNNING_D3D_FULL_SCREEN"); break; }
1261: case QUNS_PRESENTATION_MODE: { strcat_s(msg, sizeofArray(msg), " | QUNS_PRESENTATION_MODE"); break; }
1262: default: { strcat_s(msg, sizeofArray(msg), " | WINDOW_SIZE_MATCH"); break; }
1263: }
1264: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1265: Log(msg, "");
1266:
1267: }
1268: // else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"...suspending xoblite core UI elements, following an application having entered fullscreen mode.");
1269: }
1270: }
1271: else
1272: {
1273: if (somethingIsFullscreen)
1274: {
1275: somethingIsFullscreen = false;
1276: pDesktop->FullscreenDetected(false);
1277: pToolbar->FullscreenDetected(false);
1278: pDock->FullscreenDetected(false);
1279: pConsole->FullscreenDetected(false);
1280:
1281: if (pSettings->debugLogging)
1282: {
1283: sprintf_s(msg, sizeofArray(msg), "DEBUG -> Blackbox::MainWndProc -> \"%s\" has exited fullscreen mode.", windowText);
1284: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1285: Log(msg, "");
1286: }
1287: // else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"...resuming xoblite core UI elements, following an application having exited fullscreen mode.");
1288: }
1289: }
1290: /*
1291: QUERY_USER_NOTIFICATION_STATE quns;
1292: SHQueryUserNotificationState(&quns);
1293: switch (quns)
1294: {
1295: // case QUNS_BUSY: // Note: For reasons yet to be understood, the QUNS_BUSY state (and/or the Windows do-not-disturb focus mode handling) is not fully reliable and can lead to ping-pong hide/show scenarios :( -> FFS?
1296: case QUNS_RUNNING_D3D_FULL_SCREEN:
1297: case QUNS_PRESENTATION_MODE:
1298: {
1299: if ((uint8_t)quns != lastFullscreenCheckStatus)
1300: {
1301: if (pSettings->debugLogging)
1302: {
1303: switch (quns)
1304: {
1305: // case QUNS_BUSY: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_BUSY"); break; } // -> "A full-screen application is running or Presentation Settings are applied."
1306: case QUNS_RUNNING_D3D_FULL_SCREEN: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_RUNNING_D3D_FULL_SCREEN"); break; } // -> "A full-screen (exclusive mode) Direct3D application is running."
1307: case QUNS_PRESENTATION_MODE: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_PRESENTATION_MODE"); break; } // -> "The user has activated Windows presentation settings to block notifications and pop-up messages."
1308: default: { break; }
1309: }
1310:
1311: sprintf_s(msg, sizeofArray(msg), "DEBUG -> Blackbox::MainWndProc -> The application \"%s\" has entered fullscreen mode. | %s", windowText, qunsModeText);
1312: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1313: Log("xoblite", msg);
1314: }
1315:
1316: if (!somethingIsFullscreen)
1317: {
1318: somethingIsFullscreen = true;
1319: pDesktop->FullscreenDetected(true);
1320: pToolbar->FullscreenDetected(true);
1321: pDock->FullscreenDetected(true);
1322: pConsole->FullscreenDetected(true);
1323: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"...suspending xoblite core UI elements, following an application having entered fullscreen mode.");
1324: }
1325:
1326: lastFullscreenCheckStatus = (uint8_t)quns;
1327: }
1328:
1329: break;
1330: }
1331:
1332: default:
1333: {
1334: if ((uint8_t)quns != lastFullscreenCheckStatus)
1335: {
1336: if (pSettings->debugLogging)
1337: {
1338: switch (quns)
1339: {
1340: case QUNS_NOT_PRESENT: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_NOT_PRESENT"); break; } // -> "A screen saver is displayed, the machine is locked, or a nonactive Fast User Switching session is in progress."
1341: case QUNS_BUSY: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_BUSY"); break; } // -> "A full-screen application is running or Presentation Settings are applied."
1342: // case QUNS_RUNNING_D3D_FULL_SCREEN: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_RUNNING_D3D_FULL_SCREEN"); break; } // -> "A full-screen (exclusive mode) Direct3D application is running."
1343: // case QUNS_PRESENTATION_MODE: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_PRESENTATION_MODE"); break; } // -> "The user has activated Windows presentation settings to block notifications and pop-up messages."
1344: case QUNS_ACCEPTS_NOTIFICATIONS: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_ACCEPTS_NOTIFICATIONS"); break; } // -> "None of the other states are found, notifications can be freely sent."
1345: case QUNS_QUIET_TIME: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_QUIET_TIME"); break; } // -> "The current user is in "quiet time", which is the first hour after a new user logs into his or her account for the first time."
1346: case QUNS_APP: { strcpy_s(qunsModeText, sizeofArray(qunsModeText), "QUNS_APP"); break; } // -> "A Windows Store app is running."
1347: default: { sprintf_s(qunsModeText, sizeofArray(qunsModeText), "UNKNOWN QUNS VALUE (%d)", quns); break; }
1348: }
1349:
1350: sprintf_s(msg, sizeofArray(msg), "DEBUG -> Blackbox::MainWndProc -> The system's user notification state has changed. | %s / %s", qunsModeText, windowText);
1351: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1352: Log("xoblite", msg);
1353: }
1354:
1355: if (somethingIsFullscreen)
1356: {
1357: somethingIsFullscreen = false;
1358: pDesktop->FullscreenDetected(false);
1359: pToolbar->FullscreenDetected(false);
1360: pDock->FullscreenDetected(false);
1361: pConsole->FullscreenDetected(false);
1362: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INDENTED_MESSAGE, (LPARAM)"...resuming xoblite core UI elements, following an application having exited fullscreen mode.");
1363: }
1364:
1365: lastFullscreenCheckStatus = (uint8_t)quns;
1366: }
1367:
1368: break;
1369: }
1370: }
1371: */
1372: return 0;
1373: }
1374:
1375: // CHECK_FOR_UPDATES_DELAY_TIMER:
1376: // -> On first launch, and when resuming from sleep/hibernate,
1377: // we perform a check for updates, but only after a certain delay
1378: // to allow all other things as well as the user to warm up first... ;)
1379: else if (wParam == CHECK_FOR_UPDATES_DELAY_TIMER)
1380: {
1381: KillTimer(GetBBWnd(), CHECK_FOR_UPDATES_DELAY_TIMER);
1382: CheckForUpdates();
1383: return 0;
1384: }
1385:
1386: return 0;
1387: }
1388:
1389: //====================
1390:
1391: case BB_BROADCAST:
1392: {
1393: char broam[MAX_LINE_LENGTH];
1394: strcpy_s(broam, sizeofArray(broam), (LPCSTR)lParam);
1395: if (ExecuteBroam(broam, hMainInstance)) return 0;
1396: }
1397:
1398: //====================
1399:
1400: case BB_TRAYICONMESSAGE:
1401: {
1402: switch (LOWORD(lParam))
1403: {
1404: case WM_LBUTTONUP:
1405: {
1406: if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && pWorkspaces) pWorkspaces->NextWorkspace();
1407: else if (pToolbar)
1408: {
1409: // pToolbar->UpdatePosition();
1410: SetWindowPos(pToolbar->hToolbarWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
1411: SetForegroundWindow(pToolbar->hToolbarWnd);
1412: PlaySoundFX(SFX_MENU_CLICK);
1413: }
1414: break;
1415: }
1416:
1417: case WM_RBUTTONDOWN:
1418: {
1419: if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && pWorkspaces) pWorkspaces->PreviousWorkspace();
1420: else if (pTaskbar) pTaskbar->MinimizeAllWindows();
1421: break;
1422: }
1423:
1424: case WM_MOUSEWHEEL: // TEMPORARY "FOR TESTING" PLACEHOLDER
1425: {
1426: PlaySoundFX(SFX_MENU_NAVIGATE);
1427: break;
1428: }
1429:
1430: default: { break; }
1431: }
1432: }
1433:
1434: //====================
1435:
1436: default:
1437: {
1438: if (uMsg == WM_TASKBARCREATED_MESSAGE)
1439: {
1440: if (pSettings->underExplorer)
1441: {
1442: // The Explorer system tray has been recreated (e.g. due to Explorer crashing), so we need to re-add the xoblite icon to the system tray...
1443: DestroyIcon(xobIconData.hIcon);
1444: ZeroMemory(&xobIconData, sizeof(NOTIFYICONDATA));
1445: xobIconData.cbSize = sizeof(NOTIFYICONDATA); // Older Windows versions -> NOTIFYICONDATA_V3_SIZE
1446: xobIconData.hIcon = LoadIcon(hMainInstance, MAKEINTRESOURCE(IDI_XOBLITE));
1447: // LoadIconMetric(hMainInstance, MAKEINTRESOURCE(IDI_XOBLITE), LIM_SMALL, &(xobIconData.hIcon));
1448: strcpy_s(xobIconData.szTip, sizeofArray(xobIconData.szTip), "xoblite");
1449: xobIconData.hWnd = GetBBWnd();
1450: xobIconData.uID = 0;
1451: xobIconData.uVersion = NOTIFYICON_VERSION_4; // // Older Windows versions -> 3
1452: xobIconData.uCallbackMessage = BB_TRAYICONMESSAGE;
1453: xobIconData.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
1454: Shell_NotifyIcon(NIM_ADD, &xobIconData);
1455: }
1456: return 0;
1457: }
1458:
1459: //====================
1460:
1461: if (pMessageManager)
1462: {
1463: unsigned int shellMessage = uMsg;
1464: WPARAM replaceParam = wParam;
1465:
1466: if (shellMessage == WM_SHELLHOOKMESSAGE)
1467: {
1468: if (wParam == HSHELL_WINDOWCREATED) shellMessage = BB_ADDTASK;
1469: else if (wParam == HSHELL_WINDOWDESTROYED) shellMessage = BB_REMOVETASK;
1470: else if (wParam == HSHELL_ACTIVATESHELLWINDOW) shellMessage = BB_ACTIVATESHELLWINDOW;
1471: else if (wParam == HSHELL_WINDOWACTIVATED) shellMessage = BB_ACTIVETASK;
1472: else if (wParam == HSHELL_RUDEAPPACTIVATED)
1473: {
1474: // Could there be a better way to support fullscreen windows?
1475: // (e.g. unloading everything or disable alwaysontop elements)
1476: shellMessage = BB_ACTIVETASK;
1477: /*
1478: if (pTaskbar)
1479: {
1480: HWND window = (HWND)lParam;
1481: if (pTaskbar->FindTask(window) >= 0) shellMessage = BB_ACTIVETASK;
1482: else shellMessage = BB_ADDTASK;
1483: }
1484: else shellMessage = BB_ACTIVETASK;
1485:
1486: if (pSettings->debugLogging && pTaskbar)
1487: {
1488: char msg[MAX_LINE_LENGTH], windowText[MAX_LINE_LENGTH], windowClass[MAX_LINE_LENGTH];
1489: GetWindowText((HWND)lParam, windowText, sizeof(windowText));
1490: if (!strnlen_s(windowText, sizeofArray(windowText))) strcpy_s(windowText, sizeofArray(windowText), "NULL");
1491: GetClassName((HWND)lParam, windowClass, sizeof(windowClass));
1492: if (!strnlen_s(windowClass, sizeofArray(windowClass))) strcpy_s(windowClass, sizeofArray(windowClass), "NULL");
1493: sprintf_s(msg, sizeofArray(msg), "WM_SHELLHOOKMESSAGE -> HSHELL_RUDEAPPACTIVATED -> %s | %s | Already on taskbar: ", windowText, windowClass);
1494: HWND window = (HWND)lParam;
1495: if (pTaskbar->FindTask(window) >= 0) strcat_s(msg, sizeofArray(msg), "Yes");
1496: else strcat_s(msg, sizeofArray(msg), "No");
1497:
1498: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1499: Log("xoblite", msg);
1500: }
1501: */
1502: }
1503: else if (wParam == HSHELL_GETMINRECT) shellMessage = BB_MINMAXTASK;
1504: else if (wParam == HSHELL_REDRAW) shellMessage = BB_REDRAW;
1505: else if (wParam == HSHELL_FLASH)
1506: {
1507: // Insert flashing code here...
1508: shellMessage = BB_REDRAW;
1509: pTaskbar->flashingHwnd = (HWND)lParam;
1510: }
1511: else // -> Unsupported HSHELL message received!
1512: {
1513: /*
1514: if (pSettings->debugLogging)
1515: {
1516: char msg[MAX_LINE_LENGTH], windowText[MAX_LINE_LENGTH], windowClass[MAX_LINE_LENGTH];
1517: GetWindowText((HWND)lParam, windowText, sizeof(windowText));
1518: if (!strnlen_s(windowText, sizeofArray(windowText))) strcpy_s(windowText, sizeofArray(windowText), "NULL");
1519: GetClassName((HWND)lParam, windowClass, sizeof(windowClass));
1520: if (!strnlen_s(windowClass, sizeofArray(windowClass))) strcpy_s(windowClass, sizeofArray(windowClass), "NULL");
1521:
1522: if (wParam == HSHELL_TASKMAN) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_TASKMAN");
1523: else if (wParam == HSHELL_LANGUAGE) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_LANGUAGE");
1524: else if (wParam == HSHELL_SYSMENU) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_SYSMENU");
1525: else if (wParam == HSHELL_ENDTASK) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_ENDTASK -> %s | %s", windowText, windowClass);
1526: else if (wParam == HSHELL_ACCESSIBILITYSTATE) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_ACCESSIBILITYSTATE");
1527: else if (wParam == HSHELL_APPCOMMAND) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_APPCOMMAND");
1528: else if (wParam == HSHELL_WINDOWREPLACED) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_WINDOWREPLACED -> %s | %s", windowText, windowClass);
1529: else if (wParam == HSHELL_WINDOWREPLACING) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_WINDOWREPLACING -> %s | %s", windowText, windowClass);
1530: else if (wParam == HSHELL_MONITORCHANGED) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_MONITORCHANGED -> %s | %s", windowText, windowClass);
1531: else sprintf_s(msg, sizeofArray(msg), "Unknown HSHELL message -> 0x%lx -> %s | %s", (LONG)wParam, windowText, windowClass);
1532:
1533: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1534: Log("xoblite", msg);
1535: }
1536: */
1537: return DefWindowProc(hWnd, uMsg, wParam, lParam);
1538: }
1539:
1540: replaceParam = (WPARAM)lParam; // Replacement wParam set to the hwnd
1541: }
1542:
1543: //====================
1544:
1545: if (pMessageManager->HandlerExists(shellMessage))
1546: {
1547: LRESULT lResult;
1548: if (pMessageManager->SendMessage(shellMessage, replaceParam, lParam, &lResult)) return lResult;
1549: }
1550: }
1551:
1552: return DefWindowProc(hWnd, uMsg, wParam, lParam);
1553: }
1554:
1555: //====================
1556: }
1557:
1558: return DefWindowProc(hWnd, uMsg, wParam, lParam);
1559: }
1560:
1561: //===========================================================================
1562: // Function: ShellHookProc
1563: // Purpose: WH_SHELL hook procedure (see SetWindowsHookEx etc above)
1564: //===========================================================================
1565:
1566: LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)
1567: {
1568: if (nCode < 0)
1569: {
1570: if (pSettings->debugLogging) Log("DEBUG -> ShellHookProc -> nCode < 0 (i.e. \"do not process this message\")", "");
1571: return CallNextHookEx(shellHook, nCode, wParam, lParam);
1572: }
1573:
1574: if (pSettings->debugLogging)
1575: {
1576: char msg[MAX_LINE_LENGTH];
1577: switch (nCode)
1578: {
1579: case HSHELL_WINDOWCREATED: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_WINDOWCREATED"); break; }
1580: case HSHELL_WINDOWDESTROYED: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_WINDOWDESTROYED"); break; }
1581: case HSHELL_ACTIVATESHELLWINDOW: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_ACTIVATESHELLWINDOW"); break; }
1582: case HSHELL_WINDOWACTIVATED: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_WINDOWACTIVATED"); break; }
1583: case HSHELL_GETMINRECT: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_GETMINRECT"); break; }
1584: case HSHELL_REDRAW: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_REDRAW"); break; }
1585: case HSHELL_TASKMAN: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_TASKMAN"); break; }
1586: case HSHELL_LANGUAGE: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_LANGUAGE"); break; }
1587:
1588: case HSHELL_ACCESSIBILITYSTATE: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_ACCESSIBILITYSTATE"); break; }
1589: case HSHELL_APPCOMMAND: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_APPCOMMAND"); break; }
1590: case HSHELL_WINDOWREPLACED: { strcpy_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> HSHELL_WINDOWREPLACED"); break; }
1591:
1592: default: { sprintf_s(msg, sizeofArray(msg), "DEBUG -> ShellHookProc -> Unknown HSHELL message -> 0x%lx", (LONG)nCode); break; }
1593: }
1594: strcat_s(msg, sizeofArray(msg), " -> Forwarding to the *box internal message bus for further processing.");
1595: PostMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1596: Log("xoblite", msg);
1597: }
1598:
1599: if (pMessageManager) PostMessage(GetBBWnd(), WM_SHELLHOOKMESSAGE, (WPARAM)nCode, (LPARAM)wParam);
1600:
1601: return CallNextHookEx(shellHook, nCode, wParam, lParam);
1602: /*
1603: if (pMessageManager)
1604: {
1605: unsigned int shellMessage = nCode;
1606: WPARAM replaceParam = wParam;
1607:
1608: //====================
1609:
1610: if (nCode == HSHELL_WINDOWCREATED) shellMessage = BB_ADDTASK;
1611: else if (nCode == HSHELL_WINDOWDESTROYED) shellMessage = BB_REMOVETASK;
1612: else if (nCode == HSHELL_ACTIVATESHELLWINDOW) shellMessage = BB_ACTIVATESHELLWINDOW;
1613: else if (nCode == HSHELL_WINDOWACTIVATED) shellMessage = BB_ACTIVETASK;
1614: else if (nCode == HSHELL_RUDEAPPACTIVATED)
1615: {
1616: // Could there be a better way to support fullscreen windows?
1617: // (e.g. unloading everything or disable alwaysontop elements)
1618: shellMessage = BB_ACTIVETASK;
1619:
1620: // if (pTaskbar)
1621: // {
1622: // HWND window = (HWND)lParam;
1623: // if (pTaskbar->FindTask(window) >= 0) shellMessage = BB_ACTIVETASK;
1624: // else shellMessage = BB_ADDTASK;
1625: // }
1626: // else shellMessage = BB_ACTIVETASK;
1627: //
1628: // if (pSettings->debugLogging && pTaskbar)
1629: // {
1630: // char msg[MAX_LINE_LENGTH], windowText[MAX_LINE_LENGTH], windowClass[MAX_LINE_LENGTH];
1631: // GetWindowText((HWND)lParam, windowText, sizeof(windowText));
1632: // if (!strnlen_s(windowText, sizeofArray(windowText))) strcpy_s(windowText, sizeofArray(windowText), "NULL");
1633: // GetClassName((HWND)lParam, windowClass, sizeof(windowClass));
1634: // if (!strnlen_s(windowClass, sizeofArray(windowClass))) strcpy_s(windowClass, sizeofArray(windowClass),"NULL");
1635: // sprintf_s(msg, sizeofArray(msg), "WM_SHELLHOOKMESSAGE -> HSHELL_RUDEAPPACTIVATED -> %s | %s | Already on taskbar: ", windowText, windowClass);
1636: // HWND window = (HWND)lParam;
1637: // if (pTaskbar->FindTask(window) >= 0) strcat_s(msg, sizeofArray(msg), "Yes");
1638: // else strcat_s(msg, sizeofArray(msg), "No");
1639: //
1640: // SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1641: // Log("xoblite", msg);
1642: // }
1643: }
1644: else if (nCode == HSHELL_GETMINRECT) shellMessage = BB_MINMAXTASK;
1645: else if (nCode == HSHELL_REDRAW) shellMessage = BB_REDRAW;
1646: else if (nCode == HSHELL_FLASH)
1647: {
1648: // Insert flashing code here...
1649: shellMessage = BB_REDRAW;
1650: pTaskbar->flashingHwnd = (HWND)lParam;
1651: }
1652: else // -> Unsupported HSHELL message received!
1653: {
1654: if (pSettings->debugLogging)
1655: {
1656: char msg[MAX_LINE_LENGTH], windowText[MAX_LINE_LENGTH], windowClass[MAX_LINE_LENGTH];
1657: GetWindowText((HWND)wParam, windowText, sizeof(windowText));
1658: if (!strnlen_s(windowText, sizeofArray(windowText))) strcpy_s(windowText, sizeofArray(windowText), "NULL");
1659: GetClassName((HWND)wParam, windowClass, sizeof(windowClass));
1660: if (!strnlen_s(windowClass, sizeofArray(windowText))) strcpy_s(windowClass, sizeofArray(windowClass), "NULL");
1661:
1662: if (nCode == HSHELL_TASKMAN) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_TASKMAN");
1663: else if (nCode == HSHELL_LANGUAGE) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_LANGUAGE");
1664: else if (nCode == HSHELL_SYSMENU) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_SYSMENU");
1665: else if (nCode == HSHELL_ENDTASK) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_ENDTASK -> %s | %s", windowText, windowClass);
1666: else if (nCode == HSHELL_ACCESSIBILITYSTATE) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_ACCESSIBILITYSTATE");
1667: else if (nCode == HSHELL_APPCOMMAND) strcpy_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_APPCOMMAND");
1668: else if (nCode == HSHELL_WINDOWREPLACED) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_WINDOWREPLACED -> %s | %s", windowText, windowClass);
1669: else if (nCode == HSHELL_WINDOWREPLACING) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_WINDOWREPLACING -> %s | %s", windowText, windowClass);
1670: else if (nCode == HSHELL_MONITORCHANGED) sprintf_s(msg, sizeofArray(msg), "Unsupported HSHELL message -> HSHELL_MONITORCHANGED -> %s | %s", windowText, windowClass);
1671: else sprintf_s(msg, sizeofArray(msg), "Unknown HSHELL message -> 0x%lx -> %s | %s", (LONG)nCode, windowText, windowClass);
1672:
1673: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_INFORMATION_MESSAGE, (LPARAM)msg);
1674: Log("xoblite", msg);
1675: }
1676:
1677: return CallNextHookEx(shellHook, nCode, wParam, lParam);
1678: }
1679:
1680: //====================
1681:
1682: if (pMessageManager->HandlerExists(shellMessage))
1683: {
1684: if (pSettings->debugLogging) Log("DEBUG -> In ShellHookProc, about to pMessageManager->SendMessage...", "");
1685:
1686: LRESULT lResult;
1687: if (pMessageManager->SendMessage(shellMessage, wParam, lParam, &lResult)) return lResult;
1688: }
1689: }
1690:
1691: return CallNextHookEx(shellHook, nCode, wParam, lParam);
1692: */
1693: }
1694:
1695: //===========================================================================
1696: // Function: ExecuteRootCommand
1697: // Purpose: ...
1698: //===========================================================================
1699:
1700: void ExecuteRootCommand(void *)
1701: {
1702: if (!pSettings->disableRootCommands)
1703: {
1704: if (!(GetAsyncKeyState(VK_CONTROL) & 0x8000)) // -> Do not run the rootCommand if the control key is held down...
1705: {
1706: char temp[MAX_LINE_LENGTH] = "", param[32];
1707:
1708: if (pSettings->wallpaperPerWorkspace && (pSettings->currentWorkspace > 0))
1709: {
1710: sprintf_s(param, sizeofArray(param), "rootCommand%d:", (pSettings->currentWorkspace + 1));
1711: strcpy_s(temp, sizeofArray(temp), ReadString(stylePath(), param, ""));
1712: }
1713:
1714: if (strnlen_s(temp, sizeofArray(temp)) == 0) strcpy_s(temp, sizeofArray(temp), ReadString(stylePath(), "rootCommand:", ""));
1715:
1716: if (strnlen_s(temp, sizeofArray(temp)) > 0)
1717: {
1718: strcpy_s(pSettings->rootCommand, sizeofArray(pSettings->rootCommand), temp);
1719: pWallpaper->ExecuteRootCommand();
1720: }
1721: }
1722: }
1723: else SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); // Trigger desktop repaint under Windows Vista (...iirc?)
1724:
1725: _endthread();
1726: }
1727:
1728: //===========================================================================
1729: // Functions: ShutdownWindows / ShutdownThread
1730: // Purpose: ...
1731: //===========================================================================
1732:
1733: void ShutdownWindows(int state, bool skipAsking) // 0=Shutdown, 1=Reboot, 2=Logoff, 3=Hibernate, 4=Standby/Suspend
1734: {
1735: if (!skipAsking)
1736: {
1737: PlaySoundFX(SFX_MENU_CLICK);
1738:
1739: if (state == 0) SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"Are you sure you want to shut down your computer?", (LPARAM)"@xoblite System Shutdown");
1740: else if (state == 1) SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"Are you sure you want to reboot your computer?", (LPARAM)"@xoblite System Reboot");
1741: else if (state == 2) SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"Are you sure you want to log off?", (LPARAM)"@xoblite System LogOff");
1742: else if (state == 3) SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"Are you sure you want to hibernate?", (LPARAM)"@xoblite System Hibernate");
1743: else if (state == 4) SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"Are you sure you want to standby?", (LPARAM)"@xoblite System Standby");
1744: else return;
1745: }
1746: else
1747: {
1748: if (state < 3)
1749: {
1750: // To avoid a hanging Blackbox.exe due to e.g. slow unloading
1751: // plugins or certain hooks we perform the shell exit procedure
1752: // before initiating shutdown/reboot/logoff. Note that we can
1753: // always startBlackbox() again if the shutdown fails! (see below)
1754: exitBlackbox();
1755: }
1756: else
1757: {
1758: // Hibernate or standby -> Set time stamp for end of session...
1759: SessionTimeStamp(false);
1760: }
1761:
1762: // Run the shutdown functions in their own thread...
1763: shutdownState = state;
1764: _beginthread(ShutdownThread, 0, NULL);
1765: }
1766: }
1767:
1768: //===========================================================================
1769:
1770: void ShutdownThread(void *) // Supporting function to ShutdownWindows() (see above)
1771: {
1772: // Log off?
1773: if (shutdownState == 2)
1774: {
1775: if (!ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_FLAG_PLANNED))
1776: {
1777: MBoxErrorValue("Log off failed");
1778: PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
1779: }
1780: else
1781: {
1782: debugLogoff = true;
1783: // PostMessage(hMainWnd, WM_CLOSE, 0, 0);
1784: PostQuitMessage(0);
1785: }
1786:
1787: _endthread();
1788: }
1789:
1790: //====================
1791:
1792: HANDLE hToken = NULL;
1793: TOKEN_PRIVILEGES tkp;
1794:
1795: OSVERSIONINFO osInfo;
1796: ZeroMemory(&osInfo, sizeof(osInfo));
1797: osInfo.dwOSVersionInfoSize = sizeof(osInfo);
1798: GetVersionEx(&osInfo);
1799:
1800: // Under WinNT/2k/XP we need to adjust priviliges to be able to shutdown/reboot/hibernate/standby...
1801: if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
1802: {
1803: // Get a token for this process...
1804: if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
1805: {
1806: MBoxErrorValue("OpenProcessToken failed");
1807: PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
1808: _endthread();
1809: }
1810:
1811: // Get the LUID for the shutdown privilege...
1812: LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
1813: tkp.PrivilegeCount = 1; // one privilege to set
1814: tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1815:
1816: // Get the shutdown privileges for this process...
1817: AdjustTokenPrivileges(hToken, false, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
1818: if (GetLastError() != ERROR_SUCCESS)
1819: {
1820: MBoxErrorValue("AdjustTokenPrivileges failed");
1821: PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
1822: _endthread();
1823: }
1824: }
1825:
1826: //====================
1827:
1828: if (shutdownState == 0) // Shutdown?
1829: {
1830: if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_POWEROFF, SHTDN_REASON_FLAG_PLANNED))
1831: {
1832: MBoxErrorValue("Shutdown failed!");
1833: PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
1834: }
1835: else
1836: {
1837: debugShutdown = true;
1838: // PostMessage(hMainWnd, WM_CLOSE, 0, 0);
1839: PostQuitMessage(0);
1840: }
1841: }
1842: else if (shutdownState == 1) // Reboot?
1843: {
1844: if (!ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_FLAG_PLANNED))
1845: {
1846: MBoxErrorValue("Reboot failed!");
1847: // As the (un)installer may initiate a reboot we need to check
1848: // if the reboot was initiated by the (un)installer before
1849: // attempting to restart the shell... (see ShutdownWindows above)
1850: PostMessage(GetBBWnd(), BB_RESTART, 0, 0);
1851: }
1852: else
1853: {
1854: debugReboot = true;
1855: // PostMessage(hMainWnd, WM_CLOSE, 0, 0);
1856: PostQuitMessage(0);
1857: }
1858: }
1859: else if (shutdownState == 3) // Hibernate? (a.k.a. "safe sleep" and "suspend to disk")
1860: {
1861: if (!SetSystemPowerState(FALSE, FALSE)) MBoxErrorValue("Hibernate failed!");
1862: // ZeroMemory(&pSettings->Statistics, sizeof(pSettings->Statistics)); // Reset statistics...
1863: Sleep(3000); // Allow system clock some time to update after waking up... (note that we're running in a separate thread)
1864: SessionTimeStamp(true); // Begin new session...
1865: SetTimer(GetBBWnd(), CHECK_FOR_UPDATES_DELAY_TIMER, 3000, (TIMERPROC)NULL); // Wait 3 seconds, then perform a check for updates...
1866: }
1867: else if (shutdownState == 4) // Standby? (a.k.a. "sleep" and "suspend to RAM")
1868: {
1869: if (!SetSystemPowerState(TRUE, FALSE)) MBoxErrorValue("Standby failed!");
1870: // ZeroMemory(&pSettings->Statistics, sizeof(pSettings->Statistics)); // Reset statistics...
1871: Sleep(3000); // Allow system clock some time to update after waking up... (note that we're running in a separate thread)
1872: SessionTimeStamp(true); // Begin new session...
1873: SetTimer(GetBBWnd(), CHECK_FOR_UPDATES_DELAY_TIMER, 3000, (TIMERPROC)NULL); // Wait 3 seconds, then perform a check for updates...
1874: }
1875:
1876: // Disable shutdown privilege...
1877: tkp.Privileges[0].Attributes = 0;
1878: AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
1879:
1880: _endthread();
1881: }
1882:
1883: //===========================================================================
1884: // Function: HideDesktopIcons
1885: // Purpose: ...
1886: //===========================================================================
1887:
1888: bool desktopIconsPreviouslyHidden = false;
1889:
1890: void HideDesktopIcons(bool hide)
1891: {
1892: HWND window = FindWindow("Progman", "Program Manager");
1893: if (window != NULL)
1894: {
1895: window = FindWindowEx(window, NULL, "SHELLDLL_DefView", "");
1896: if (window != NULL)
1897: {
1898: window = FindWindowEx(window, NULL, "SysListView32", "FolderView");
1899: if (window != NULL)
1900: {
1901: if (hide)
1902: {
1903: if (IsWindowVisible(window))
1904: {
1905: ShowWindow(window, SW_HIDE);
1906: desktopIconsPreviouslyHidden = true;
1907: }
1908: }
1909: else if (desktopIconsPreviouslyHidden) ShowWindow(window, SW_SHOWNOACTIVATE);
1910: return;
1911: }
1912: }
1913: }
1914: /*
1915: window = FindWindow("", "WorkerW");
1916: if (window != NULL)
1917: {
1918: window = FindWindowEx(window, NULL, "SHELLDLL_DefView", "");
1919: if (window != NULL)
1920: {
1921: window = FindWindowEx(window, NULL, "SysListView32", "FolderView");
1922: if (window != NULL)
1923: {
1924: if (hide) ShowWindow(window, SW_HIDE);
1925: else ShowWindow(window, SW_SHOWNOACTIVATE);
1926: return;
1927: }
1928: }
1929: }
1930: */
1931: }
1932:
1933: //===========================================================================
1934: // Function: SessionTimeStamp
1935: // Purpose: ...
1936: //===========================================================================
1937:
1938: void SessionTimeStamp(bool beginSession)
1939: {
1940: time_t systemSessionTime;
1941: struct tm *localSessionTime;
1942: char timeStampString[MAX_LINE_LENGTH], msg[MAX_LINE_LENGTH];
1943:
1944: time(&systemSessionTime);
1945: localSessionTime = localtime(&systemSessionTime);
1946:
1947: //====================
1948:
1949: _locale_t timestampLocale = _create_locale(LC_TIME, "en-US"); // -> Always use en-US format for the console timestamp...
1950: if (strstr(pSettings->toolbarClockFormat, "%p"))
1951: {
1952: // 12-hour clock including the current locale's AM/PM indicator
1953: _strftime_l(timeStampString, MAX_LINE_LENGTH, "%a %#d %b at %I:%M %p", localSessionTime, timestampLocale);
1954: }
1955: else
1956: {
1957: // 24-hour clock
1958: _strftime_l(timeStampString, MAX_LINE_LENGTH, "%a %#d %b at %H:%M", localSessionTime, timestampLocale);
1959: }
1960: _free_locale(timestampLocale);
1961:
1962: //====================
1963:
1964: if (beginSession)
1965: {
1966: sessionDuration = 0;
1967: SetTimer(GetBBWnd(), SESSION_DURATION_TIMER, 60000, (TIMERPROC)NULL);
1968: sprintf_s(msg, sizeofArray(msg), "Session begins %s.", timeStampString);
1969: }
1970: else
1971: {
1972: KillTimer(GetBBWnd(), SESSION_DURATION_TIMER);
1973: int durHours = sessionDuration / 60;
1974: int durMinutes = sessionDuration % 60;
1975: // sprintf_s(msg, sizeofArray(msg), "Session ends %s (duration %d hour(s) %d minute(s)).", timeStampString, durHours, durMinutes);
1976: sprintf_s(msg, sizeofArray(msg), "Session ends %s (duration %d:%02d).", timeStampString, durHours, durMinutes);
1977: }
1978:
1979: SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
1980: Log("TimeStamp", msg);
1981: }
1982:
1983: //===========================================================================
1984:
1985: void CheckForUpdates()
1986: {
1987: if (pPluginManager && _stricmp(pSettings->checkedForUpdates, "*Disabled*")) _beginthread(periodicCheckForUpdates, 0, NULL);
1988: }
1989:
1990: //===========================================================================
1991:
| w | e | b | c | p | p |
|
| |||||