Compare commits
192 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5998c235f1 | |||
|
|
caa84730cc | ||
|
|
7410e6ddb1 | ||
|
|
04d5187a36 | ||
|
|
56084fefb7 | ||
|
|
51561cd0ac | ||
|
|
c58b785b7b | ||
|
|
841128b2f3 | ||
|
|
13b4657c5b | ||
|
|
8f6af5bba9 | ||
|
|
b679f71607 | ||
|
|
154bed9106 | ||
|
|
b13ce0578b | ||
|
|
9c6fe40c1c | ||
|
|
ca4b30e1d7 | ||
|
|
793c6a626f | ||
|
|
892db32a81 | ||
|
|
69a624e0f9 | ||
|
|
4a8ef09334 | ||
|
|
cc62e8dc38 | ||
|
|
b335db994a | ||
|
|
21271a7c4b | ||
|
|
0fa28c9e3e | ||
|
|
2c1fa58da6 | ||
|
|
f6b7c29d2c | ||
|
|
d2342e80f5 | ||
|
|
306621f084 | ||
|
|
f0ae48cd10 | ||
|
|
aef812ae92 | ||
|
|
50a290d57e | ||
|
|
93ca902e1f | ||
|
|
7234547e3d | ||
|
|
8f5bdce45b | ||
|
|
fdc0d28ab7 | ||
|
|
e0670bea6d | ||
|
|
bcd6716fcb | ||
|
|
e3187f62c3 | ||
|
|
174edb0aaa | ||
|
|
654dbf6be0 | ||
|
|
7ea2d75f37 | ||
|
|
7602f6df4d | ||
|
|
e8e91d87cd | ||
|
|
91216a8778 | ||
|
|
f94859613c | ||
|
|
1beddc7695 | ||
|
|
69baa0e28c | ||
|
|
34026dbc8d | ||
|
|
fef15a326d | ||
|
|
a07aace682 | ||
|
|
39d2983852 | ||
|
|
e7ad120d92 | ||
|
|
8939e71a99 | ||
|
|
7a3c1ae092 | ||
|
|
67513d7c23 | ||
|
|
360aa81df6 | ||
|
|
c6cfed377a | ||
|
|
f18779ef28 | ||
|
|
a570e61c8b | ||
|
|
28e7fa0ad7 | ||
|
|
972c56a15b | ||
|
|
7dd1875e1d | ||
|
|
f1e0a17b3d | ||
|
|
c1dd3ae999 | ||
|
|
309ce4702b | ||
|
|
5e878f98cf | ||
|
|
2c86c796f5 | ||
|
|
2e7dafbbac | ||
|
|
961cedb975 | ||
|
|
e990647e1b | ||
|
|
9079225a29 | ||
|
|
6e4d38544e | ||
|
|
5d17a98ca0 | ||
|
|
bce106ce5f | ||
|
|
2b32d3f8f8 | ||
|
|
000ecc527f | ||
|
|
e7bcb43cd1 | ||
|
|
28e5ec10fc | ||
|
|
55ea523d34 | ||
|
|
52fc4cdcab | ||
|
|
1c273f6337 | ||
|
|
edd9da0ce4 | ||
|
|
c9581062f6 | ||
|
|
e0fa6632cd | ||
|
|
4054dac5f1 | ||
|
|
291e1f0d16 | ||
|
|
97784e31ae | ||
|
|
475d868825 | ||
|
|
f718eb4d51 | ||
|
|
c5c5d6d714 | ||
|
|
59f7eb76bd | ||
|
|
ef8b514527 | ||
|
|
39229500f6 | ||
|
|
493abda875 | ||
|
|
1a17c89074 | ||
|
|
bbf9941fd4 | ||
|
|
012ad25462 | ||
|
|
06e32d9063 | ||
|
|
ef0a73d819 | ||
|
|
bd4712a7db | ||
|
|
710fc5aecd | ||
|
|
39ed21c334 | ||
|
|
c1e2d5279d | ||
|
|
ab9e9d9b18 | ||
|
|
ea0c0773e6 | ||
|
|
efb000f4ec | ||
|
|
36a6d1a888 | ||
|
|
67e821a33c | ||
|
|
69a1ea88f5 | ||
|
|
0c0f9c765e | ||
|
|
b8c4a712f9 | ||
|
|
b07bcbfa6d | ||
|
|
531400b700 | ||
|
|
15d3bcca5c | ||
|
|
fa1ac0dfc9 | ||
|
|
14c5e5560b | ||
|
|
6f312892e8 | ||
|
|
1ed794d640 | ||
|
|
c43c176538 | ||
|
|
fd51e72432 | ||
|
|
403cfafedb | ||
|
|
866402a7b3 | ||
|
|
717d744195 | ||
|
|
2c16c265ca | ||
|
|
82c2d2d15f | ||
|
|
925bb43a6d | ||
|
|
b02cc93c6d | ||
|
|
e6b36b3b94 | ||
|
|
51e907a7d0 | ||
|
|
6533f53aaa | ||
|
|
f2b1af5cba | ||
|
|
b14c11f98e | ||
|
|
99fbc7392c | ||
|
|
ab20d2ec8c | ||
|
|
678eef08c9 | ||
|
|
4269ded2f6 | ||
|
|
44270fd601 | ||
|
|
c7d3ae27d1 | ||
|
|
3245d93436 | ||
|
|
7e3fcb1fc3 | ||
|
|
607330267f | ||
|
|
5d7536d5fd | ||
|
|
5e6f59f946 | ||
|
|
cbb7373cc1 | ||
|
|
58e6635bae | ||
|
|
b2413ad307 | ||
|
|
49d22b8a13 | ||
|
|
d4aa908ea2 | ||
|
|
4dfb5d8554 | ||
|
|
2ff4ee0c9c | ||
|
|
24a17d0287 | ||
|
|
6943fc563b | ||
|
|
b8466d176b | ||
|
|
48c8f542bc | ||
|
|
d16b7254da | ||
|
|
349a9a9d0d | ||
|
|
2aa96bc024 | ||
|
|
e0724dc0c7 | ||
|
|
99d851f368 | ||
|
|
ef30558e0a | ||
|
|
1ff398ad70 | ||
|
|
cbe1fb7551 | ||
|
|
1b8ec3b152 | ||
|
|
84f106938d | ||
|
|
f761ac6cf7 | ||
|
|
3cbe91cf89 | ||
|
|
fd3abe1795 | ||
|
|
42f0f268d9 | ||
|
|
6ce9166a92 | ||
|
|
e19e3d399b | ||
|
|
d7a3802571 | ||
|
|
a074441a99 | ||
|
|
59937a8690 | ||
|
|
613b998348 | ||
|
|
e0461949ae | ||
|
|
acc63b5aa6 | ||
|
|
64d69162ab | ||
|
|
6ac03d7a1b | ||
|
|
0d237c5039 | ||
|
|
714fe3a4ae | ||
|
|
5d0a3f1ccf | ||
|
|
d7e5d10209 | ||
|
|
d01b18e035 | ||
|
|
6c40ba9886 | ||
|
|
0d0e37b561 | ||
|
|
bda528569b | ||
|
|
9bb0dfd24b | ||
|
|
ef88804240 | ||
|
|
a494e057c9 | ||
|
|
7910340133 | ||
|
|
b736576829 | ||
|
|
94f4e71b20 | ||
|
|
9e67a3d81b |
22
.github/workflows/msbuild.yml
vendored
@@ -16,23 +16,23 @@ env:
|
|||||||
# Path to the solution file relative to the root of the project.
|
# Path to the solution file relative to the root of the project.
|
||||||
SOLUTION_FILE_PATH: .
|
SOLUTION_FILE_PATH: .
|
||||||
|
|
||||||
# Configuration type to build.
|
|
||||||
# You can convert this to a build matrix if you need coverage of multiple configuration types.
|
|
||||||
# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
|
|
||||||
BUILD_CONFIGURATION: Release
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
BUILD_CONFIGURATION: [Release, Debug]
|
||||||
|
BUILD_PLATFORM: [x64, x86]
|
||||||
|
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: Add MSBuild to PATH
|
- name: Add MSBuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v2
|
||||||
|
|
||||||
- name: Restore NuGet packages
|
- name: Restore NuGet packages
|
||||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||||
@@ -42,4 +42,10 @@ jobs:
|
|||||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||||
# Add additional options to the MSBuild command line here (like platform or verbosity level).
|
# Add additional options to the MSBuild command line here (like platform or verbosity level).
|
||||||
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
|
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
|
||||||
run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
|
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
|
||||||
|
|
||||||
|
- name: Upload Artifacts
|
||||||
|
uses: actions/upload-artifact@v4.3.1
|
||||||
|
with:
|
||||||
|
name: progmgr-${{matrix.BUILD_CONFIGURATION}}-${{matrix.BUILD_PLATFORM}}
|
||||||
|
path: ${{env.SOLUTION_FILE_PATH}}/bin
|
||||||
12
.gitignore
vendored
@@ -44,17 +44,23 @@
|
|||||||
|
|
||||||
# Kernel Module Compile Results
|
# Kernel Module Compile Results
|
||||||
*.mod*
|
*.mod*
|
||||||
*.cmd
|
|
||||||
.tmp_versions/
|
.tmp_versions/
|
||||||
modules.order
|
modules.order
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
/.vs/Program-Manager-II
|
/.vs
|
||||||
/planning
|
/planning
|
||||||
/progmgr/RCa10968
|
/progmgr/RCa*
|
||||||
/progmgr/icons/Thumbs.db
|
/progmgr/icons/Thumbs.db
|
||||||
/bin/
|
/bin/
|
||||||
/misc/supermiumman.png
|
/misc/supermiumman.png
|
||||||
/bin.7z
|
/bin.7z
|
||||||
*.zip
|
*.zip
|
||||||
|
*.res
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
|
||||||
|
release
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Vortesys
|
Copyright (c) 2023-2024 Vortesys
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.6.33723.286
|
VisualStudioVersion = 17.6.33723.286
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "progmgr", "progmgr\progmgr.vcxproj", "{B76B940D-B61A-456E-8569-72F64CF91AFB}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProgMgr", "ProgMgr\ProgMgr.vcxproj", "{B76B940D-B61A-456E-8569-72F64CF91AFB}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
16
README.md
@@ -1,15 +1,21 @@
|
|||||||
|

|
||||||
|
|
||||||
[](https://github.com/Vortesys/Program-Manager-II/releases) [](https://github.com/Vortesys/Program-Manager-II/releases)
|
[](https://github.com/Vortesys/Program-Manager-II/releases) [](https://github.com/Vortesys/Program-Manager-II/releases)
|
||||||
# Program Manager *II* for Windows NT
|
|
||||||

|
|
||||||
|
|
||||||
## What is Program Manager?
|
## What is Program Manager?
|
||||||
Program Manager was the shell that shipped with Microsoft Windows by default from Windows 3.0/NT 3.1 to 3.11/NT 3.51. The Program Manager shell was included with Windows as an option until Windows 2000. The new Program Manager is a shell that aims to mimic the original desktop metaphor that the original Program Manager was designed for while adding modern amenities.
|
Program Manager was the default shell for Windows (NT) 3.x. The Program Manager shell was included as an optional component in Windows until Windows 2000. It contained a basic task manager, a group-based program launcher and a shutdown dialog.
|
||||||
|
|
||||||
|
## So, what about Program Manager II?
|
||||||
|
Program Manager II is a shell designed to supercede the original Microsoft Program Manager with better compatibility, stability, and usability. It's currently in alpha and doesn't contain all of the necessary functionality, but progress is being made.
|
||||||
|
|
||||||
## What does it run on?
|
## What does it run on?
|
||||||
Program Manager should run on ~~every AMD64 version of Windows and every 32-bit version back to 2000. The ultimate goal is to run on NT 3.51 just as well as it can run on Windows 11~~ Windows Vista and above.
|
Program Manager II will run on Windows Vista and above with no problem. Support for XP and older is not guaranteed, nor will it be ported to 9x.
|
||||||
|
|
||||||
## Where do I get it?
|
## Where do I get it?
|
||||||
The [releases page](https://github.com/Vortesys/Program-Manager-II/releases) will contain the latest version of Program Manager.
|
The [releases page](https://github.com/Vortesys/Program-Manager-II/releases) will contain the latest "stable" version of Program Manager II. Build artifacts can be found for most commits made since April and contain pre-release builds.
|
||||||
|
|
||||||
|
## What's planned for the future?
|
||||||
|
You can look through all of the issues in the issue tracker with the Beta milestone attached to them to see what's planned. Otherwise, you can message me, 'freedom_usa' on Discord and ask about the direction of the project after feature parity is reached.
|
||||||
|
|
||||||
## How can I help?
|
## How can I help?
|
||||||
Submitting [issues](https://github.com/Vortesys/Program-Manager-II/issues) with bug reports, suggestions or comments always helps. If you're able to, contributing with a [pull request](https://github.com/Vortesys/Program-Manager-II/pulls) is much appreciated.
|
Submitting [issues](https://github.com/Vortesys/Program-Manager-II/issues) with bug reports, suggestions or comments always helps. If you're able to, contributing with a [pull request](https://github.com/Vortesys/Program-Manager-II/pulls) is much appreciated.
|
||||||
|
|||||||
37
build.cmd
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
set DIR_ROOT=%~dp0.
|
||||||
|
set DIR_PROGMGR=%DIR_ROOT%\progmgr
|
||||||
|
set DIR_RELEASE=%DIR_ROOT%\release
|
||||||
|
|
||||||
|
rmdir /S /Q "%DIR_RELEASE%" > nul 2>&1
|
||||||
|
if not exist "%DIR_RELEASE%" mkdir "%DIR_RELEASE%"
|
||||||
|
|
||||||
|
git rev-parse HEAD > %DIR_RELEASE%\.git_hash
|
||||||
|
set /P GIT_HASH=<%DIR_RELEASE%\.git_hash
|
||||||
|
set "GIT_HASH=%GIT_HASH:~0,8%"
|
||||||
|
|
||||||
|
if "%1" == "debug" (
|
||||||
|
set CL=/MT /Od /Zi /RTC1 /Fdprogmgr.pdb /fsanitize=address /DUNICODE /D_DEBUG /DPROGMGR_DEBUG /DPROGMGR_GIT_HASH="%GIT_HASH%"
|
||||||
|
set LINK=/DEBUG
|
||||||
|
) else (
|
||||||
|
set CL=/O1 /GS- /DUNICODE /DNDEBUG /DPROGMGR_RELEASE /DPROGMGR_GIT_HASH="%GIT_HASH%"
|
||||||
|
rem set LINK=/NODEFAULTLIB /OPT:REF /OPT:ICF
|
||||||
|
set LINK=/OPT:REF /OPT:ICF
|
||||||
|
)
|
||||||
|
|
||||||
|
pushd "%DIR_RELEASE%"
|
||||||
|
rc /nologo /DPROGMGR_GIT_HASH="""%GIT_HASH%""" /i "%DIR_PROGMGR%" "%DIR_PROGMGR%\lang\dlg_en-US.rc"
|
||||||
|
rc /nologo /DPROGMGR_GIT_HASH="""%GIT_HASH%""" /i "%DIR_PROGMGR%" "%DIR_PROGMGR%\lang\res_en-US.rc"
|
||||||
|
rc /nologo /DPROGMGR_GIT_HASH="""%GIT_HASH%""" /i "%DIR_PROGMGR%" "%DIR_PROGMGR%\resource.rc"
|
||||||
|
cl /nologo /W3 /WX /MP /Feprogmgr.exe ^
|
||||||
|
"%DIR_PROGMGR%\*.c" ^
|
||||||
|
"%DIR_PROGMGR%\resource.res" ^
|
||||||
|
"%DIR_PROGMGR%\lang\dlg_en-US.res" ^
|
||||||
|
"%DIR_PROGMGR%\lang\res_en-US.res" ^
|
||||||
|
/link /INCREMENTAL:NO /SUBSYSTEM:WINDOWS /FIXED /merge:_RDATA=.rdata ^
|
||||||
|
/MANIFEST:EMBED /MANIFESTINPUT:%DIR_PROGMGR%\progmgr.exe.manifest ^
|
||||||
|
kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib ^
|
||||||
|
secur32.lib comdlg32.lib pathcch.lib shlwapi.lib version.lib ^
|
||||||
|
comctl32.lib uxtheme.lib
|
||||||
|
popd
|
||||||
BIN
misc/pman.pdn
BIN
misc/pman2.png
|
Before Width: | Height: | Size: 21 KiB |
BIN
misc/pman64.png
|
Before Width: | Height: | Size: 11 KiB |
BIN
misc/progman.jpg
Normal file
|
After Width: | Height: | Size: 212 KiB |
@@ -1,203 +0,0 @@
|
|||||||
/* * * * * * * *\
|
|
||||||
DESKTOP.C -
|
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
|
||||||
DESCRIPTION -
|
|
||||||
Program Manager's desktop window.
|
|
||||||
Only visible as the default shell.
|
|
||||||
LICENSE INFORMATION -
|
|
||||||
MIT License, see LICENSE.txt in the root folder
|
|
||||||
\* * * * * * * */
|
|
||||||
|
|
||||||
/* Headers */
|
|
||||||
#include "progmgr.h"
|
|
||||||
#include "resource.h"
|
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <CommCtrl.h>
|
|
||||||
|
|
||||||
/* Structures */
|
|
||||||
typedef struct _mrp
|
|
||||||
{
|
|
||||||
HWND hWndMRP;
|
|
||||||
DWORD dwFlags;
|
|
||||||
} MRP, * PMRP;
|
|
||||||
|
|
||||||
/* Defines */
|
|
||||||
// MRP Flags
|
|
||||||
#define MRP_ICONIFIED 0x000000001
|
|
||||||
#define MRP_FLASHING 0x000000002
|
|
||||||
// Miscellaneous
|
|
||||||
#define MAXTITLELEN 256
|
|
||||||
#define ID_LISTVIEW 1000
|
|
||||||
|
|
||||||
/* Variables */
|
|
||||||
HWND hWndDesktop;
|
|
||||||
HWND hWndListView;
|
|
||||||
RECT rcRoot;
|
|
||||||
|
|
||||||
/* Functions */
|
|
||||||
LRESULT CALLBACK DeskWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
||||||
HWND CreateListView(HWND hWndParent, RECT rc);
|
|
||||||
|
|
||||||
/* * * *\
|
|
||||||
CreateDesktopWindow -
|
|
||||||
Creates the invisible desktop window.
|
|
||||||
RETURNS -
|
|
||||||
True if successful, false if unsuccessful.
|
|
||||||
\* * * */
|
|
||||||
BOOL CreateDesktopWindow()
|
|
||||||
{
|
|
||||||
MSG msg = { 0 };
|
|
||||||
WNDCLASSEX wc = { 0 };
|
|
||||||
WCHAR szBuffer[MAX_PATH];
|
|
||||||
WCHAR szClass[16];
|
|
||||||
|
|
||||||
// If we fail, we shouldn't be here anyways.
|
|
||||||
//if (GetShellWindow())
|
|
||||||
// return FALSE;
|
|
||||||
|
|
||||||
// Get size of the root HWND
|
|
||||||
GetWindowRect(GetDesktopWindow(), &rcRoot);
|
|
||||||
|
|
||||||
// Load the window class string
|
|
||||||
LoadString(hAppInstance, IDS_DTCLASS, szClass, ARRAYSIZE(szClass));
|
|
||||||
|
|
||||||
// Refresh the wallpaper...
|
|
||||||
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, szBuffer, 0);
|
|
||||||
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szBuffer, SPIF_SENDCHANGE);
|
|
||||||
|
|
||||||
// Reset the work area (removes dead-space after switching from another shell)
|
|
||||||
// May have unintended consequences. Doesn't work with multiple monitors.
|
|
||||||
SystemParametersInfo(SPI_SETWORKAREA, 0, &rcRoot, SPIF_SENDCHANGE);
|
|
||||||
|
|
||||||
// Register the desktop window
|
|
||||||
wc.cbSize = sizeof(WNDCLASSEX);
|
|
||||||
wc.lpfnWndProc = DeskWndProc;
|
|
||||||
wc.hInstance = hAppInstance;
|
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
wc.hbrBackground = (HBRUSH)GetStockObject(COLOR_WINDOW);
|
|
||||||
wc.style = CS_NOCLOSE;
|
|
||||||
wc.lpszClassName = szClass;
|
|
||||||
if (!RegisterClassEx(&wc))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (CreateWindowEx(WS_EX_TOOLWINDOW, wc.lpszClassName,
|
|
||||||
NULL, WS_VISIBLE, rcRoot.left, rcRoot.top,
|
|
||||||
rcRoot.right - rcRoot.left, rcRoot.bottom - rcRoot.top,
|
|
||||||
NULL, NULL, hAppInstance, NULL) == NULL);
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
while (GetMessage(&msg, NULL, 0, 0) > 0)
|
|
||||||
{
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* * * *\
|
|
||||||
DeskWndProc -
|
|
||||||
Program Manager's desktop window procedure.
|
|
||||||
RETURNS -
|
|
||||||
Zero if nothing, otherwise returns the good stuff.
|
|
||||||
\* * * */
|
|
||||||
LRESULT CALLBACK DeskWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
|
|
||||||
case WM_CREATE:
|
|
||||||
// Populate hWndDesktop
|
|
||||||
hWndDesktop = hWnd;
|
|
||||||
|
|
||||||
// Set the window position to shell
|
|
||||||
// SetShellWindow(hWndDesktop);
|
|
||||||
ShowWindow(hWndDesktop, SW_MAXIMIZE);
|
|
||||||
|
|
||||||
// Strip the border from the desktop window
|
|
||||||
SetWindowLongPtr(hWndDesktop, GWL_STYLE, WS_POPUP);
|
|
||||||
|
|
||||||
// Size the window to take up the primary monitor's desktop
|
|
||||||
SetWindowPos(hWndDesktop, HWND_BOTTOM,
|
|
||||||
rcRoot.left, rcRoot.top, rcRoot.right - rcRoot.left, rcRoot.bottom - rcRoot.top,
|
|
||||||
SWP_FRAMECHANGED | SWP_NOACTIVATE);
|
|
||||||
|
|
||||||
// Finally, bring Program Manager to the foreground.
|
|
||||||
SetWindowPos(hWndProgMgr, HWND_TOP,
|
|
||||||
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
||||||
|
|
||||||
// Finally, Create the ListView control
|
|
||||||
//hWndListView = CreateListView(hWndDesktop, rcRoot);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_ACTIVATE:
|
|
||||||
case WM_DPICHANGED:
|
|
||||||
case WM_DISPLAYCHANGE:
|
|
||||||
case WM_DEVICECHANGE:
|
|
||||||
// Get size of the root HWND
|
|
||||||
GetWindowRect(GetDesktopWindow(), &rcRoot);
|
|
||||||
SetWindowPos(hWndDesktop, HWND_BOTTOM,
|
|
||||||
rcRoot.left, rcRoot.top, rcRoot.right - rcRoot.left, rcRoot.bottom - rcRoot.top,
|
|
||||||
SWP_NOACTIVATE);
|
|
||||||
//if (hWndListView)
|
|
||||||
// SetWindowPos(hWndListView, hWndDesktop,
|
|
||||||
// rcRoot.left, rcRoot.top, rcRoot.right - rcRoot.left, rcRoot.bottom - rcRoot.top,
|
|
||||||
// SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_WINDOWPOSCHANGING:
|
|
||||||
case WM_SYSCOMMAND:
|
|
||||||
case WM_COMMAND:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_DESTROY:
|
|
||||||
case WM_CLOSE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* * * *\
|
|
||||||
CreateListView -
|
|
||||||
Creates the Desktop's ListView.
|
|
||||||
RETURNS -
|
|
||||||
HWND to the listview if successfull,
|
|
||||||
NULL otherwise.
|
|
||||||
\* * * */
|
|
||||||
HWND CreateListView(HWND hWndParent, RECT rc)
|
|
||||||
{
|
|
||||||
HWND hWndListView;
|
|
||||||
LVITEM lviTestItem;
|
|
||||||
WCHAR szTestItem[] = L"Test Item";
|
|
||||||
|
|
||||||
// Create the ListView
|
|
||||||
hWndListView = CreateWindowEx(WS_EX_LEFT, WC_LISTVIEW, L"",
|
|
||||||
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
|
|
||||||
LVS_ICON | LVS_SINGLESEL,
|
|
||||||
rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
|
|
||||||
hWndParent, (HMENU)ID_LISTVIEW, hAppInstance,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if(hWndListView == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ListView_SetBkColor(hWndListView, CLR_NONE);
|
|
||||||
|
|
||||||
lviTestItem.mask = LVIF_STATE | LVIF_TEXT;
|
|
||||||
lviTestItem.iItem = 0;
|
|
||||||
lviTestItem.iSubItem = 0;
|
|
||||||
lviTestItem.state = 0;
|
|
||||||
lviTestItem.stateMask = 0;
|
|
||||||
lviTestItem.pszText = (LPWSTR)&szTestItem;
|
|
||||||
lviTestItem.cchTextMax = MAXTITLELEN;
|
|
||||||
// lviTestItem.iImage = 1;
|
|
||||||
|
|
||||||
ListView_InsertItem(hWndListView, &lviTestItem);
|
|
||||||
|
|
||||||
return hWndListView;
|
|
||||||
}
|
|
||||||
363
progmgr/dialog.c
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
DIALOG.C -
|
DIALOG.C -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's dialogs and related
|
Program Manager's dialogs and related
|
||||||
common functions.
|
common functions.
|
||||||
@@ -9,14 +9,21 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Commctrl.h>
|
||||||
|
#include <Commdlg.h>
|
||||||
|
#include <Shlobj.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <strsafe.h>
|
||||||
#include "progmgr.h"
|
#include "progmgr.h"
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
/* Variables */
|
||||||
#include <Shlobj.h>
|
WCHAR szDlgTitle[64];
|
||||||
#include <strsafe.h>
|
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
@@ -28,22 +35,11 @@
|
|||||||
\* * * */
|
\* * * */
|
||||||
BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
GROUP grp = {
|
static GROUP grp = { 0 };
|
||||||
.dwSignature = GRP_SIGNATURE,
|
|
||||||
.wVersion = GRP_VERSION,
|
|
||||||
.wChecksum = 0,
|
|
||||||
.szName = L"",
|
|
||||||
.dwFlags = 0,
|
|
||||||
.ftLastWrite = 0,
|
|
||||||
.cItems = 0,
|
|
||||||
.iItems = NULL
|
|
||||||
};
|
|
||||||
BOOL bOKEnabled = FALSE;
|
BOOL bOKEnabled = FALSE;
|
||||||
WCHAR szBuffer[MAX_TITLE_LENGTH] = { L"\0" };
|
WCHAR szBuffer[MAX_TITLE_LENGTH] = { TEXT("\0") };
|
||||||
HICON hIconDef = NULL;
|
HICON hIconDef = NULL;
|
||||||
HICON hIconDlg = NULL;
|
HICON hIconDlg = NULL;
|
||||||
WCHAR szIconPath[MAX_PATH] = { L"\0" };
|
|
||||||
INT iIconIndex = 0;
|
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
@@ -54,16 +50,28 @@ BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM
|
|||||||
// if permissions are available.
|
// if permissions are available.
|
||||||
// TODO:
|
// TODO:
|
||||||
// fix minor GDI font/region leak
|
// fix minor GDI font/region leak
|
||||||
|
|
||||||
|
// Reset the necessary parts of the group structure
|
||||||
|
grp.dwSignature = GRP_SIGNATURE;
|
||||||
|
grp.wVersion = GRP_VERSION;
|
||||||
|
grp.wChecksum = 0;
|
||||||
|
grp.dwFlags = 0;
|
||||||
|
grp.cItemArray = 0;
|
||||||
|
// grp.pItemArray = 0; TODO: idk make sure this ain't all screwed up
|
||||||
|
|
||||||
|
// Set the window title
|
||||||
|
LoadString(g_hAppInstance, IDS_DLT_GRP_NEW, szDlgTitle, ARRAYSIZE(szDlgTitle));
|
||||||
|
SetWindowText(hWndDlg, szDlgTitle);
|
||||||
|
|
||||||
// Populate the icon with the default path and index.
|
// Populate the icon with the default path and index.
|
||||||
GetModuleFileName(NULL, (LPWSTR)&szIconPath, MAX_PATH);
|
GetModuleFileName(g_hAppInstance, (LPWSTR)&grp.szIconPath, ARRAYSIZE(grp.szIconPath));
|
||||||
iIconIndex = IDI_PROGGRP - 1;
|
grp.iIconIndex = IDI_PROGGRP - 1;
|
||||||
|
|
||||||
// Get the default hIcon so we can delete it later
|
// Get the default hIcon so we can delete it later
|
||||||
hIconDef = (HICON)SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_GETICON, 0, 0);
|
hIconDef = (HICON)SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_GETICON, 0, 0);
|
||||||
|
|
||||||
// Set the icon in the dialog
|
// Set the icon in the dialog
|
||||||
hIconDlg = ExtractIcon(hAppInstance, (LPWSTR)&szIconPath, iIconIndex);
|
hIconDlg = ExtractIcon(g_hAppInstance, (LPWSTR)&grp.szIconPath, grp.iIconIndex);
|
||||||
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
||||||
|
|
||||||
// Set the maximum input length of the text boxes
|
// Set the maximum input length of the text boxes
|
||||||
@@ -72,6 +80,9 @@ BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM
|
|||||||
// Disable the OK button since we're starting with no text in the box.
|
// Disable the OK button since we're starting with no text in the box.
|
||||||
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
|
||||||
|
// Enable the common group checkbox if perms are good
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_COMMGROUP), g_bPermAdmin);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
@@ -92,22 +103,20 @@ BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM
|
|||||||
{
|
{
|
||||||
|
|
||||||
case IDD_CHICON:
|
case IDD_CHICON:
|
||||||
if (PickIconDlg(hWndDlg, (LPWSTR)&szIconPath, ARRAYSIZE(szIconPath), &iIconIndex) == TRUE)
|
if (PickIconDlg(hWndDlg, (LPWSTR)&grp.szIconPath, ARRAYSIZE(grp.szIconPath), &grp.iIconIndex) == TRUE)
|
||||||
{
|
{
|
||||||
// Since we've got the new icon...
|
// Since we've got the new icon...
|
||||||
hIconDlg = ExtractIcon(hAppInstance, (LPWSTR)&szIconPath, iIconIndex);
|
hIconDlg = ExtractIcon(g_hAppInstance, (LPWSTR)&grp.szIconPath, grp.iIconIndex);
|
||||||
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDD_OK:
|
case IDD_OK:
|
||||||
// Check that all the applicable fields are filled out
|
// Check that all the applicable fields are filled out,
|
||||||
bOKEnabled = GetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)&szBuffer, ARRAYSIZE(szBuffer));
|
// and if not then set the focus to the offending field
|
||||||
|
if (!(bOKEnabled = GetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)&szBuffer, ARRAYSIZE(szBuffer))))
|
||||||
// If not, set the focus to the offending field
|
SetFocus(GetDlgItem(hWndDlg, IDD_NAME));
|
||||||
if (!bOKEnabled)
|
|
||||||
SendDlgItemMessage(hWndDlg, IDD_NAME, EM_TAKEFOCUS, 0, 0);
|
|
||||||
|
|
||||||
// Enable or disable the OK button based on the information
|
// Enable or disable the OK button based on the information
|
||||||
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
@@ -121,17 +130,14 @@ BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM
|
|||||||
if (SendDlgItemMessage(hWndDlg, IDD_COMMGROUP, BM_GETCHECK, 0, 0) != BST_UNCHECKED)
|
if (SendDlgItemMessage(hWndDlg, IDD_COMMGROUP, BM_GETCHECK, 0, 0) != BST_UNCHECKED)
|
||||||
grp.dwFlags = grp.dwFlags || GRP_FLAG_COMMON;
|
grp.dwFlags = grp.dwFlags || GRP_FLAG_COMMON;
|
||||||
|
|
||||||
// TODO: set FILETIME
|
// Set FILETIME
|
||||||
|
GetSystemTimeAsFileTime(&grp.ftLastWrite);
|
||||||
|
|
||||||
// Set the rectangle of the group to be CW_USEDEFAULT
|
// Set the rectangle of the group to be CW_USEDEFAULT
|
||||||
grp.rcGroup.left = grp.rcGroup.top = grp.rcGroup.right = grp.rcGroup.bottom = CW_USEDEFAULT;
|
grp.rcGroup.left = grp.rcGroup.top = grp.rcGroup.right = grp.rcGroup.bottom = CW_USEDEFAULT;
|
||||||
|
|
||||||
// Set icon properties
|
|
||||||
StringCchCopy(grp.szIconPath, ARRAYSIZE(szIconPath), szIconPath);
|
|
||||||
grp.iIconIndex = iIconIndex;
|
|
||||||
|
|
||||||
// Group's ready!
|
// Group's ready!
|
||||||
if (CreateGroupWindow(&grp) != NULL)
|
if (CreateGroup(&grp) != NULL)
|
||||||
{
|
{
|
||||||
EndDialog(hWndDlg, FALSE);
|
EndDialog(hWndDlg, FALSE);
|
||||||
break;
|
break;
|
||||||
@@ -174,17 +180,253 @@ BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM
|
|||||||
\* * * */
|
\* * * */
|
||||||
BOOL CALLBACK NewItemDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
BOOL CALLBACK NewItemDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
static ITEM itm = { 0 };
|
||||||
|
BOOL bOKEnabled = FALSE;
|
||||||
|
BOOL bWorkPath = FALSE;
|
||||||
|
WCHAR szBuffer[MAX_TITLE_LENGTH] = { TEXT("\0") };
|
||||||
|
WCHAR szPathBuffer[MAX_PATH] = { TEXT("\0") };
|
||||||
|
HICON hIconDef = NULL;
|
||||||
|
HICON hIconDlg = NULL;
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
|
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
// Place message cases here.
|
// TODO:
|
||||||
|
// require a valid group to be selected or else the dialog won't
|
||||||
|
// EVEN BE AVAILABLE!!! or let you press ok.
|
||||||
|
|
||||||
|
// Reset the necessary parts of the item structure
|
||||||
|
itm.dwFlags = 0;
|
||||||
|
itm.uiHotkeyModifiers = 0;
|
||||||
|
itm.uiHotkeyVirtualKey = 0;
|
||||||
|
|
||||||
|
// Set the window title
|
||||||
|
LoadString(g_hAppInstance, IDS_DLT_ITEM_NEW, szDlgTitle, ARRAYSIZE(szDlgTitle));
|
||||||
|
SetWindowText(hWndDlg, szDlgTitle);
|
||||||
|
|
||||||
|
// Populate the icon with the default path and index.
|
||||||
|
GetModuleFileName(NULL, (LPWSTR)&itm.szIconPath, MAX_PATH);
|
||||||
|
itm.iIconIndex = IDI_PROGITM - 1;
|
||||||
|
|
||||||
|
// Get the default hIcon so we can delete it later
|
||||||
|
hIconDef = (HICON)SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_GETICON, 0, 0);
|
||||||
|
|
||||||
|
// Set the icon in the dialog
|
||||||
|
hIconDlg = ExtractIcon(g_hAppInstance, (LPWSTR)&itm.szIconPath, itm.iIconIndex);
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
||||||
|
|
||||||
|
// Set the maximum input length of the text boxes
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_NAME, EM_LIMITTEXT, MAX_TITLE_LENGTH, 0);
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_PATH, EM_LIMITTEXT, MAX_PATH, 0);
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_WORKPATH, EM_LIMITTEXT, MAX_PATH, 0);
|
||||||
|
|
||||||
|
// Disable the OK button since we're starting with no text in the box.
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
|
if (HIWORD(wParam) == EN_CHANGE)
|
||||||
|
{
|
||||||
|
if ((LOWORD(wParam) == IDD_NAME) || (LOWORD(wParam) == IDD_PATH) || (LOWORD(wParam) == IDD_WORKPATH))
|
||||||
|
{
|
||||||
|
// A control has changed. See what's up...
|
||||||
|
bOKEnabled = GetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)&szBuffer, ARRAYSIZE(szBuffer));
|
||||||
|
bOKEnabled = bOKEnabled && GetDlgItemText(hWndDlg, IDD_PATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer));
|
||||||
|
|
||||||
|
if (bWorkPath)
|
||||||
|
bOKEnabled = bOKEnabled && GetDlgItemText(hWndDlg, IDD_WORKPATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer));
|
||||||
|
|
||||||
|
// Check that we have selected an MDI child window as well
|
||||||
|
if ((HWND)SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, FALSE) == (HWND)NULL)
|
||||||
|
bOKEnabled = FALSE;
|
||||||
|
|
||||||
|
// Enable or disable the relevant controls based on the information
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
case IDD_BROWSE:
|
||||||
|
{
|
||||||
|
OPENFILENAME ofn;
|
||||||
|
LPVOID lpData;
|
||||||
|
DWORD dwVerBuffer = 0;
|
||||||
|
UINT uiTitleLen = MAX_TITLE_LENGTH;
|
||||||
|
WCHAR szNameBuffer[MAX_TITLE_LENGTH] = { TEXT("\0") };
|
||||||
|
WCHAR szFileBuffer[MAX_PATH] = { TEXT("\0") };
|
||||||
|
|
||||||
|
GetDlgItemText(hWndDlg, IDD_PATH, (LPWSTR)&szFileBuffer, ARRAYSIZE(szFileBuffer));
|
||||||
|
|
||||||
|
// Initialize the structure
|
||||||
|
ZeroMemory(&ofn, sizeof(ofn));
|
||||||
|
ofn.lStructSize = sizeof(ofn);
|
||||||
|
ofn.hwndOwner = hWndDlg;
|
||||||
|
ofn.lpstrFilter = TEXT("Programs\0*.exe;*.bat;*.com;*.cmd;*.lnk\0All Files (*.*)\0*.*\0");
|
||||||
|
ofn.nFilterIndex = 1;
|
||||||
|
ofn.lpstrFile = (LPWSTR)&szFileBuffer;
|
||||||
|
// ofn.lpstrFile[0] = '\0';
|
||||||
|
ofn.nMaxFile = ARRAYSIZE(szFileBuffer);
|
||||||
|
ofn.lpstrFileTitle = NULL;
|
||||||
|
ofn.nMaxFileTitle = 0;
|
||||||
|
ofn.lpstrInitialDir = NULL;
|
||||||
|
ofn.Flags = OFN_FILEMUSTEXIST;
|
||||||
|
|
||||||
|
if (GetOpenFileName(&ofn) == TRUE)
|
||||||
|
SetDlgItemText(hWndDlg, IDD_PATH, (LPWSTR)&szFileBuffer);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
// copy the filename to a new buffer for later
|
||||||
|
StringCchCopy(szNameBuffer, ARRAYSIZE(szNameBuffer), szFileBuffer);
|
||||||
|
|
||||||
|
// let's retrieve the application's friendly name too
|
||||||
|
dwVerBuffer = GetFileVersionInfoSize((LPCWSTR)szFileBuffer, NULL);
|
||||||
|
// if (dwVerBuffer != 0)
|
||||||
|
if (NULL)
|
||||||
|
{
|
||||||
|
lpData = malloc(dwVerBuffer);
|
||||||
|
// TODO: totally redo this it doesn't work
|
||||||
|
|
||||||
|
if (lpData != NULL)
|
||||||
|
GetFileVersionInfo((LPCWSTR)szFileBuffer, (DWORD)0, dwVerBuffer, lpData);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TODO: this is hardcoded to english. make it dynamic later
|
||||||
|
// TODO: this is so busted lol, really make it dynamic so it works
|
||||||
|
VerQueryValue(lpData,
|
||||||
|
TEXT("\\StringFileInfo\\040904b0\\FileDescription"),
|
||||||
|
(LPVOID)&szNameBuffer, &uiTitleLen); // == 0
|
||||||
|
|
||||||
|
if (lpData)
|
||||||
|
free(lpData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PathStripPath((LPWSTR)&szNameBuffer);
|
||||||
|
PathRemoveExtension((LPWSTR)&szNameBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)szNameBuffer);
|
||||||
|
|
||||||
|
// let's get the icon now
|
||||||
|
if (ExtractIcon(g_hAppInstance, (LPWSTR)szFileBuffer, -1) > 0)
|
||||||
|
{
|
||||||
|
// file contains at least one icon, set the itm struct values
|
||||||
|
StringCchCopy(itm.szIconPath, ARRAYSIZE(itm.szIconPath), szFileBuffer);
|
||||||
|
itm.iIconIndex = 0;
|
||||||
|
|
||||||
|
// update icon
|
||||||
|
hIconDlg = ExtractIcon(g_hAppInstance, (LPWSTR)itm.szIconPath, itm.iIconIndex);
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IDD_BROWSE2:
|
||||||
|
{
|
||||||
|
OPENFILENAME ofn;
|
||||||
|
|
||||||
|
GetDlgItemText(hWndDlg, IDD_WORKPATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer));
|
||||||
|
|
||||||
|
// Initialize the structure
|
||||||
|
ZeroMemory(&ofn, sizeof(ofn));
|
||||||
|
ofn.lStructSize = sizeof(ofn);
|
||||||
|
ofn.hwndOwner = hWndDlg;
|
||||||
|
ofn.lpstrFilter = TEXT("Folders\0");
|
||||||
|
ofn.nFilterIndex = 1;
|
||||||
|
ofn.lpstrFile = (LPWSTR)&szPathBuffer;
|
||||||
|
// ofn.lpstrFile[0] = '\0';
|
||||||
|
ofn.nMaxFile = ARRAYSIZE(szPathBuffer);
|
||||||
|
ofn.lpstrFileTitle = NULL;
|
||||||
|
ofn.nMaxFileTitle = 0;
|
||||||
|
ofn.lpstrInitialDir = NULL;
|
||||||
|
ofn.Flags = OFN_FILEMUSTEXIST;
|
||||||
|
|
||||||
|
if (GetOpenFileName(&ofn) == TRUE) {
|
||||||
|
SetDlgItemText(hWndDlg, IDD_WORKPATH, (LPWSTR)&szPathBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case IDD_CHICON:
|
||||||
|
if (PickIconDlg(hWndDlg, (LPWSTR)&itm.szIconPath, ARRAYSIZE(itm.szIconPath), &itm.iIconIndex) == TRUE)
|
||||||
|
{
|
||||||
|
// Since we've got the new icon...
|
||||||
|
hIconDlg = ExtractIcon(g_hAppInstance, (LPWSTR)itm.szIconPath, itm.iIconIndex);
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDD_WORKDIR:
|
||||||
|
bWorkPath = IsDlgButtonChecked(hWndDlg, IDD_WORKDIR);
|
||||||
|
|
||||||
|
if (bWorkPath)
|
||||||
|
{
|
||||||
|
GetDlgItemText(hWndDlg, IDD_PATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer));
|
||||||
|
PathRemoveFileSpec((LPWSTR)&szPathBuffer);
|
||||||
|
SetDlgItemText(hWndDlg, IDD_WORKPATH, (LPWSTR)&szPathBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetWindowText(GetDlgItem(hWndDlg, IDD_WORKPATH), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_STAT_WORKDIR), bWorkPath);
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_WORKPATH), bWorkPath);
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_BROWSE2), bWorkPath);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDD_OK:
|
||||||
|
// Check that all the applicable fields are filled out,
|
||||||
|
// and if not then set the focus to the offending field
|
||||||
|
if (!(bOKEnabled = GetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)&szBuffer, ARRAYSIZE(szBuffer))))
|
||||||
|
SetFocus(GetDlgItem(hWndDlg, IDD_NAME));
|
||||||
|
if (!(bOKEnabled = GetDlgItemText(hWndDlg, IDD_PATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer))))
|
||||||
|
SetFocus(GetDlgItem(hWndDlg, IDD_PATH));
|
||||||
|
if (bWorkPath)
|
||||||
|
{
|
||||||
|
if (!(bOKEnabled = GetDlgItemText(hWndDlg, IDD_WORKPATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer))))
|
||||||
|
SetFocus(GetDlgItem(hWndDlg, IDD_WORKPATH));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable or disable the OK button based on the information
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
|
||||||
|
if (bOKEnabled)
|
||||||
|
{
|
||||||
|
// Set the name of the item
|
||||||
|
StringCchCopy(itm.szName, ARRAYSIZE(szBuffer), szBuffer);
|
||||||
|
|
||||||
|
// And the paths...
|
||||||
|
GetDlgItemText(hWndDlg, IDD_PATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer));
|
||||||
|
StringCchCopy(itm.szExecPath, ARRAYSIZE(szPathBuffer), szPathBuffer);
|
||||||
|
GetDlgItemText(hWndDlg, IDD_WORKPATH, (LPWSTR)&szPathBuffer, ARRAYSIZE(szPathBuffer));
|
||||||
|
StringCchCopy(itm.szWorkPath, ARRAYSIZE(szPathBuffer), szPathBuffer);
|
||||||
|
|
||||||
|
// Item's ready!
|
||||||
|
if (CreateItem((HWND)SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, 0), &itm) != NULL)
|
||||||
|
{
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure!
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case IDD_CANCEL:
|
case IDD_CANCEL:
|
||||||
EndDialog(hWndDlg, FALSE);
|
EndDialog(hWndDlg, FALSE);
|
||||||
break;
|
break;
|
||||||
@@ -194,8 +436,57 @@ BOOL CALLBACK NewItemDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM l
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// Cleanup
|
||||||
|
if (hIconDef)
|
||||||
|
DestroyIcon(hIconDef);
|
||||||
|
if (hIconDlg)
|
||||||
|
DestroyIcon(hIconDlg);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
ShutdownDlgProc -
|
||||||
|
Dialog procedure for powering off the computer.
|
||||||
|
RETURNS -
|
||||||
|
TRUE if message is handled, FALSE otherwise.
|
||||||
|
\* * * */
|
||||||
|
BOOL CALLBACK ShutdownDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
HICON hIconDlg = NULL;
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
{
|
||||||
|
|
||||||
|
case IDD_OK:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
case IDD_CANCEL:
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Cleanup
|
||||||
|
if (hIconDlg)
|
||||||
|
DestroyIcon(hIconDlg);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
DIALOG.H -
|
DIALOG.H -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Dialog function prototypes and related
|
Dialog function prototypes and related
|
||||||
common dialog functions.
|
common dialog functions.
|
||||||
@@ -14,3 +14,4 @@
|
|||||||
/* Function Prototypes */
|
/* Function Prototypes */
|
||||||
BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
BOOL CALLBACK NewItemDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
BOOL CALLBACK NewItemDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
BOOL CALLBACK ShutdownDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|||||||
737
progmgr/group.c
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
GROUP.C -
|
GROUP.C -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Group window and program group/item functions.
|
Group window and program group/item functions.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -8,19 +8,24 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#include <CommCtrl.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <uxtheme.h>
|
||||||
#include "progmgr.h"
|
#include "progmgr.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <strsafe.h>
|
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
WNDCLASSEX wcGrp;
|
WNDCLASSEX wcGrp;
|
||||||
WCHAR szGrpClass[16];
|
WCHAR szGrpClass[16];
|
||||||
PGROUPWND pgwArray[];
|
|
||||||
HWND hWndMDIClient = NULL;
|
HWND hWndMDIClient = NULL;
|
||||||
|
HWND hWndFoundGroup = NULL;
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
@@ -32,36 +37,40 @@ HWND hWndMDIClient = NULL;
|
|||||||
TRUE if groups are successfully created.
|
TRUE if groups are successfully created.
|
||||||
FALSE if otherwise.
|
FALSE if otherwise.
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL InitializeGroups()
|
BOOL InitializeGroups(VOID)
|
||||||
{
|
{
|
||||||
CLIENTCREATESTRUCT ccs = { 0 };
|
CLIENTCREATESTRUCT ccs = { 0 };
|
||||||
WNDCLASSEX wce = { 0 };
|
WNDCLASSEX wce = { 0 };
|
||||||
RECT rcFrame;
|
RECT rcFrame;
|
||||||
|
|
||||||
// Create the MDI Client Window
|
// Create the MDI Client Window
|
||||||
ccs.hWindowMenu = GetSubMenu(GetMenu(hWndProgMgr), IDM_WINDOW);
|
ccs.hWindowMenu = GetSubMenu(GetMenu(g_hWndProgMgr), 2);
|
||||||
ccs.idFirstChild = IDM_WINDOW_CHILDSTART;
|
ccs.idFirstChild = IDM_WINDOW_CHILDSTART;
|
||||||
|
|
||||||
GetClientRect(hWndProgMgr, &rcFrame);
|
GetClientRect(g_hWndProgMgr, &rcFrame);
|
||||||
|
|
||||||
if (!(hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED, L"MDIClient",
|
if ((hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED,
|
||||||
NULL, WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
|
TEXT("MDIClient"), NULL, WS_CLIPCHILDREN | WS_CHILD |
|
||||||
|
WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
|
||||||
rcFrame.left, rcFrame.top, rcFrame.right, rcFrame.bottom,
|
rcFrame.left, rcFrame.top, rcFrame.right, rcFrame.bottom,
|
||||||
hWndProgMgr, (HMENU)1, hAppInstance, (LPWSTR)&ccs)))
|
g_hWndProgMgr, (HMENU)1, g_hAppInstance, (LPWSTR)&ccs)) == NULL)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the group class string
|
// Load the group class string
|
||||||
LoadString(hAppInstance, IDS_GRPCLASS, szGrpClass, ARRAYSIZE(szGrpClass));
|
LoadString(g_hAppInstance, IDS_GRPCLASS,
|
||||||
|
szGrpClass, ARRAYSIZE(szGrpClass));
|
||||||
|
|
||||||
// Register the group window Class
|
// Register the group window class
|
||||||
wce.cbSize = sizeof(WNDCLASSEX);
|
wce.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wce.style = CS_DBLCLKS;
|
||||||
wce.lpfnWndProc = GroupWndProc;
|
wce.lpfnWndProc = GroupWndProc;
|
||||||
wce.cbClsExtra = 0;
|
wce.cbClsExtra = 0;
|
||||||
wce.cbWndExtra = 0;
|
wce.cbWndExtra = 0;
|
||||||
wce.hInstance = hAppInstance;
|
wce.hInstance = g_hAppInstance;
|
||||||
wce.hIcon = hGroupIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON,
|
wce.hIcon = g_hGroupIcon = LoadImage(g_hAppInstance,
|
||||||
|
MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON,
|
||||||
0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
||||||
wce.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wce.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||||
@@ -70,161 +79,491 @@ BOOL InitializeGroups()
|
|||||||
|
|
||||||
if (!RegisterClassEx(&wce))
|
if (!RegisterClassEx(&wce))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
// Now we can create the groups
|
||||||
|
if(LoadConfig(FALSE, FALSE, TRUE) != RCE_SUCCESS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
// CreateGroupWindow(NULL);
|
// TODO: if loading groups fails, throw an error
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
CreateGroupWindow -
|
CreateGroup -
|
||||||
Create an MDI window from a group structure
|
Create an MDI window from a group structure
|
||||||
RETURNS -
|
RETURNS -
|
||||||
Pointer to a group window structure
|
Handle to the new group window
|
||||||
or NULL on failure
|
or NULL on failure
|
||||||
\* * * */
|
\* * * */
|
||||||
PGROUPWND CreateGroupWindow(PGROUP pgGroup)
|
HWND CreateGroup(_In_ PGROUP pg)
|
||||||
{
|
{
|
||||||
GROUPWND gw = { NULL };
|
|
||||||
MDICREATESTRUCT mcs = { NULL };
|
MDICREATESTRUCT mcs = { NULL };
|
||||||
HICON hIconBig = NULL;
|
PGROUP pGroup = NULL;
|
||||||
|
HICON hIconLarge = NULL;
|
||||||
HICON hIconSmall = NULL;
|
HICON hIconSmall = NULL;
|
||||||
|
HICON hIconTemp = NULL;
|
||||||
// Copy group structure to our group window
|
HWND hWndGroup = NULL;
|
||||||
gw.grp = *pgGroup;
|
HIMAGELIST hImageList = NULL;
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
RECT rcGroupWindow = { 0 };
|
||||||
|
LVCOLUMN lvc = { 0 };
|
||||||
|
|
||||||
// TODO: allocate memory from pgwArray in here
|
if (pg == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// TODO: Automatically add itself to the array of
|
// error checking, if we get trash don't try to
|
||||||
// PGW pointers?
|
// make a group out of it
|
||||||
|
// TODO: if a group is garbled, throw an error
|
||||||
|
// and ask the user if they want to delete it!
|
||||||
|
if (pg->dwSignature != GRP_SIGNATURE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
// Get group minimized/maximized flags
|
// allocate memory for a new group
|
||||||
|
pGroup = (PGROUP)malloc(CalculateGroupMemory(pg, 1, 0));
|
||||||
|
if (pGroup == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// clean up the memory if it's valid
|
||||||
|
ZeroMemory(pGroup, sizeof(*pGroup));
|
||||||
|
|
||||||
|
// copy over the group structure
|
||||||
|
*pGroup = *pg;
|
||||||
|
|
||||||
|
// TODO: get group minimized/maximized flags
|
||||||
|
|
||||||
mcs.szClass = szGrpClass;
|
mcs.szClass = szGrpClass;
|
||||||
mcs.szTitle = gw.grp.szName;
|
mcs.szTitle = pg->szName;
|
||||||
mcs.hOwner = hAppInstance;
|
mcs.hOwner = g_hAppInstance;
|
||||||
if ((gw.grp.rcGroup.left == CW_USEDEFAULT) & (gw.grp.rcGroup.right == CW_USEDEFAULT))
|
if ((pg->rcGroup.left == CW_USEDEFAULT) & (pg->rcGroup.right == CW_USEDEFAULT))
|
||||||
{
|
{
|
||||||
mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT;
|
mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT;
|
||||||
}
|
}
|
||||||
else
|
mcs.style = WS_VISIBLE | WS_THICKFRAME | WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
|
||||||
{
|
// TODO: should I pass the pointer to the group through here
|
||||||
mcs.x = gw.grp.rcGroup.left;
|
// or is it better and easier to just do it with GWLP_USERDATA?
|
||||||
mcs.y = gw.grp.rcGroup.top;
|
mcs.lParam = (LPARAM)NULL;
|
||||||
mcs.cx = gw.grp.rcGroup.right - gw.grp.rcGroup.left;
|
|
||||||
mcs.cy = gw.grp.rcGroup.bottom - gw.grp.rcGroup.top;
|
|
||||||
}
|
|
||||||
mcs.style = WS_VISIBLE;
|
|
||||||
mcs.lParam = (LPARAM)pgGroup;
|
|
||||||
|
|
||||||
if (!(gw.hWndGroup = (HWND)SendMessage(hWndMDIClient, WM_MDICREATE, 0, (LPARAM)(LPTSTR)&mcs)))
|
if ((hWndGroup = (HWND)SendMessage(hWndMDIClient, WM_MDICREATE, 0,
|
||||||
|
(LPARAM)(LPTSTR)&mcs)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// Associate the group structure pointer to the group window
|
||||||
|
SetWindowLongPtr(hWndGroup, GWLP_USERDATA, (LONG_PTR)pGroup);
|
||||||
|
|
||||||
|
// Resize the group
|
||||||
|
if (pg->wp.length == sizeof(WINDOWPLACEMENT))
|
||||||
|
SetWindowPlacement(hWndGroup, &pg->wp);
|
||||||
|
|
||||||
// Load the group icon
|
// Load the group icon
|
||||||
ExtractIconEx(gw.grp.szIconPath, gw.grp.iIconIndex, &hIconBig, &hIconSmall, 0);
|
if (ExtractIconEx(pg->szIconPath, pg->iIconIndex, &hIconLarge, &hIconSmall, 1))
|
||||||
SendMessage(gw.hWndGroup, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall);
|
{
|
||||||
SendMessage(gw.hWndGroup, WM_SETICON, ICON_BIG, (LPARAM)hIconBig);
|
if (hIconTemp = (HICON)SendMessage(hWndGroup, WM_SETICON,
|
||||||
|
ICON_SMALL, (LPARAM)hIconSmall))
|
||||||
|
DestroyIcon(hIconTemp);
|
||||||
|
if (hIconTemp = (HICON)SendMessage(hWndGroup, WM_SETICON,
|
||||||
|
ICON_BIG, (LPARAM)hIconLarge))
|
||||||
|
DestroyIcon(hIconTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the group window rect
|
||||||
|
GetClientRect(hWndGroup, &rcGroupWindow);
|
||||||
|
|
||||||
|
// Create the group window ListView control
|
||||||
|
if ((hWndListView = CreateWindowEx(WS_EX_LEFT, WC_LISTVIEW,
|
||||||
|
TEXT("ListView"),
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
|
||||||
|
LVS_ICON | LVS_SINGLESEL | LVS_AUTOARRANGE,
|
||||||
|
mcs.x, mcs.y, mcs.cx, mcs.cy,
|
||||||
|
hWndGroup, NULL, g_hAppInstance, NULL)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// ((LVS_AUTOARRANGE & bAutoArrange) * LVS_AUTOARRANGE)
|
||||||
|
|
||||||
|
// Resize it to fit the window
|
||||||
|
SetWindowPos(hWndListView, NULL,
|
||||||
|
rcGroupWindow.left, rcGroupWindow.top,
|
||||||
|
rcGroupWindow.right - rcGroupWindow.left,
|
||||||
|
rcGroupWindow.bottom - rcGroupWindow.top, SWP_NOZORDER);
|
||||||
|
|
||||||
|
// Add the explorer style because it looks good
|
||||||
|
SetWindowTheme(hWndListView, TEXT("Explorer"), NULL);
|
||||||
|
|
||||||
|
// Get this bad boy an image list
|
||||||
|
// TODO: if cxicon/cyicon change make sure we handle that
|
||||||
|
// don't require a program restart, DPI!!!
|
||||||
|
hImageList = ImageList_Create(GetSystemMetrics(SM_CXICON),
|
||||||
|
GetSystemMetrics(SM_CYICON), ILC_COLOR32, 0, 1);
|
||||||
|
ListView_SetImageList(hWndListView, hImageList, LVSIL_NORMAL);
|
||||||
|
|
||||||
|
// since the list is viewing we can load items if applicable
|
||||||
|
if (pGroup->cItemArray > 0)
|
||||||
|
LoadItems(hWndGroup);
|
||||||
|
|
||||||
// TODO: make sure the groups delete their icons upon destruction!
|
// TODO: make sure the groups delete their icons upon destruction!
|
||||||
|
// AND IMAGE LIST!!!!!!!!? i think it's nuked w/ listview though
|
||||||
return &gw;
|
return hWndGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
SetGroupFlags -
|
RemoveGroup -
|
||||||
Retrieve the flags of a group window.
|
Removes and cleans up a group window
|
||||||
RETURNS -
|
RETURNS -
|
||||||
TRUE if the flag mask is applied
|
TRUE if cleanup is successful,
|
||||||
FALSE if the flags aren't set
|
FALSE otherwise.
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL SetGroupFlags(PGROUPWND pgw, DWORD dwFlags)
|
BOOL RemoveGroup(_In_ HWND hWndGroup, _In_ BOOL bEliminate)
|
||||||
{
|
{
|
||||||
|
PGROUP pGroup = NULL;
|
||||||
|
BOOL bReturn = TRUE;
|
||||||
|
|
||||||
|
// TODO: do i have to delete the titlebar icons?
|
||||||
|
|
||||||
|
if (bEliminate == TRUE)
|
||||||
|
{
|
||||||
|
// TODO: remove group from registry
|
||||||
|
// if successful blah blah blah
|
||||||
|
bEliminate = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the group struct pointer
|
||||||
|
if ((pGroup = (PGROUP)GetWindowLongPtr(hWndGroup, GWLP_USERDATA)) == NULL)
|
||||||
|
bReturn = FALSE;
|
||||||
|
else
|
||||||
|
free(pGroup);
|
||||||
|
|
||||||
|
// close the group window
|
||||||
|
SendMessage(hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndGroup, 0);
|
||||||
|
|
||||||
|
return bReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
CreateItem -
|
||||||
|
Creates a new program item
|
||||||
|
RETURNS -
|
||||||
|
Pointer to the item if successful
|
||||||
|
NULL otherwise
|
||||||
|
\* * * */
|
||||||
|
PITEM CreateItem(_In_ HWND hWndGroup, _In_ PITEM pi)
|
||||||
|
{
|
||||||
|
PGROUP pGroup = NULL;
|
||||||
|
PGROUP pNewGroup = NULL;
|
||||||
|
PITEM pItem = NULL;
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
HIMAGELIST hImageList = NULL;
|
||||||
|
HICON hIcon = NULL;
|
||||||
|
LVITEM lvi = { 0 };
|
||||||
|
|
||||||
|
// we actually just want the group pointer lol
|
||||||
|
pGroup = (PGROUP)GetWindowLongPtr(hWndGroup, GWLP_USERDATA);
|
||||||
|
|
||||||
|
// return NULL if we can't get to the group or item
|
||||||
|
if (hWndGroup == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (pGroup == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (pi == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// get the listview window
|
||||||
|
hWndListView = FindWindowEx(hWndGroup, NULL, WC_LISTVIEW, NULL);
|
||||||
|
if (hWndListView == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// if we reallocate memory then send the new pointer in
|
||||||
|
pNewGroup = realloc(pGroup, CalculateGroupMemory(pGroup, 1, 0));
|
||||||
|
if (pNewGroup != NULL)
|
||||||
|
{
|
||||||
|
pGroup = pNewGroup;
|
||||||
|
SetWindowLongPtr(hWndGroup, GWLP_USERDATA, (LONG_PTR)pGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the item
|
||||||
|
pItem = pGroup->pItemArray + pGroup->cItemArray;
|
||||||
|
*pItem = *pi;
|
||||||
|
|
||||||
|
// increment the item counter
|
||||||
|
pGroup->cItemArray++;
|
||||||
|
|
||||||
|
// then get the pointer to the group's image list
|
||||||
|
hImageList = ListView_GetImageList(hWndListView, LVSIL_NORMAL);
|
||||||
|
|
||||||
|
// extract that icon son!!
|
||||||
|
hIcon = ExtractIcon(g_hAppInstance, (LPWSTR)pItem->szIconPath, pItem->iIconIndex);
|
||||||
|
|
||||||
|
// populate the listview with the relevant information
|
||||||
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||||||
|
lvi.iItem = pGroup->cItemArray;
|
||||||
|
lvi.iSubItem = 0;
|
||||||
|
lvi.pszText = pItem->szName;
|
||||||
|
lvi.cchTextMax = ARRAYSIZE(pItem->szName);
|
||||||
|
lvi.iImage = ImageList_AddIcon(hImageList, hIcon);
|
||||||
|
lvi.lParam = (LPARAM)pItem;
|
||||||
|
|
||||||
|
// copy that bad boy into the listview
|
||||||
|
ListView_InsertItem(hWndListView, &lvi);
|
||||||
|
|
||||||
|
// get that hicon outta here
|
||||||
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
|
// this is all terrible i'm gonna rewrite this whole file
|
||||||
|
// why is the listview even touched here just... omg...
|
||||||
|
// BAD!! bad functions
|
||||||
|
|
||||||
|
// TODO: fail if the listview item isn't added
|
||||||
|
return pItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
LoadItems -
|
||||||
|
Loads all of the items in a group structure
|
||||||
|
RETURNS -
|
||||||
|
TRUE if successful
|
||||||
|
FALSE otherwise
|
||||||
|
\* * * */
|
||||||
|
BOOL LoadItems(_In_ HWND hWndGroup)
|
||||||
|
{
|
||||||
|
PGROUP pGroup = NULL;
|
||||||
|
PGROUP pNewGroup = NULL;
|
||||||
|
PITEM pItem = NULL;
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
HIMAGELIST hImageList = NULL;
|
||||||
|
LVITEM lvi = { 0 };
|
||||||
|
UINT cItemIndex = 0;
|
||||||
|
HICON hIcon = NULL;
|
||||||
|
|
||||||
|
// return NULL if we can't get to the group
|
||||||
|
if (hWndGroup == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// retrieve the group pointer
|
||||||
|
pGroup = (PGROUP)GetWindowLongPtr(hWndGroup, GWLP_USERDATA);
|
||||||
|
if (pGroup == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// get the listview window
|
||||||
|
hWndListView = FindWindowEx(hWndGroup, NULL, WC_LISTVIEW, NULL);
|
||||||
|
if (hWndListView == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// make sure we have enough memory for the items
|
||||||
|
pNewGroup = realloc(pGroup, CalculateGroupMemory(pGroup, 0, 1));
|
||||||
|
if (pNewGroup != NULL)
|
||||||
|
{
|
||||||
|
pGroup = pNewGroup;
|
||||||
|
SetWindowLongPtr(hWndGroup, GWLP_USERDATA, (LONG_PTR)pGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
// then get the pointer to the group's image list
|
||||||
|
hImageList = ListView_GetImageList(hWndListView, LVSIL_NORMAL);
|
||||||
|
|
||||||
|
while (pGroup->cItemArray > cItemIndex)
|
||||||
|
{
|
||||||
|
pItem = pGroup->pItemArray + cItemIndex;
|
||||||
|
|
||||||
|
// extract that icon son!!
|
||||||
|
hIcon = ExtractIcon(g_hAppInstance, (LPWSTR)pItem->szIconPath, pItem->iIconIndex);
|
||||||
|
|
||||||
|
// populate the listview with the relevant information
|
||||||
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||||||
|
lvi.iItem = cItemIndex;
|
||||||
|
lvi.iSubItem = 0;
|
||||||
|
lvi.pszText = pItem->szName;
|
||||||
|
lvi.cchTextMax = ARRAYSIZE(pItem->szName);
|
||||||
|
lvi.iImage = ImageList_AddIcon(hImageList, hIcon);
|
||||||
|
lvi.lParam = (LPARAM)pItem;
|
||||||
|
|
||||||
|
// copy that bad boy into the listview
|
||||||
|
ListView_InsertItem(hWndListView, &lvi);
|
||||||
|
|
||||||
|
cItemIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hIcon)
|
||||||
|
// get that hicon outta here
|
||||||
|
DestroyIcon(hIcon);
|
||||||
|
|
||||||
|
// TODO: fail if the listview item isn't added
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
RemoveItem -
|
||||||
|
Removes a program item
|
||||||
|
RETURNS -
|
||||||
|
TRUE if item was successfully removed
|
||||||
|
FALSE otherwise
|
||||||
|
\* * * */
|
||||||
|
BOOL RemoveItem(_In_ PITEM pi)
|
||||||
|
{
|
||||||
|
// TODO: implement this
|
||||||
|
// return NULL if we can't get to the group
|
||||||
|
if (pi == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
GetGroupFlags -
|
ExecuteItem -
|
||||||
Retrieve the flags of a group window.
|
Runs a program item
|
||||||
RETURNS -
|
RETURNS -
|
||||||
TRUE if the flag mask is applied
|
TRUE if item was successfully ran
|
||||||
FALSE if the flags aren't set
|
FALSE otherwise
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL GetGroupFlags(PGROUPWND pgw, DWORD dwFlags)
|
BOOL ExecuteItem(_In_ PITEM pi)
|
||||||
{
|
{
|
||||||
HWND hWndGrp;
|
// TODO: nCmdShow from program item flags
|
||||||
|
ShellExecute(g_hWndProgMgr, TEXT("open"),
|
||||||
|
pi->szExecPath, NULL,
|
||||||
|
(pi->szWorkPath != TEXT("")) ? pi->szWorkPath : NULL,
|
||||||
|
SW_NORMAL);
|
||||||
|
|
||||||
// Cancel if the group window doesn't exist
|
// TODO: if item has run as admin as a flag,
|
||||||
if (pgw == NULL)
|
// run it as an admin
|
||||||
return 0xFFFFFFFF;
|
|
||||||
|
|
||||||
// Get the window handle
|
// TODO: if path is invalid or other error then tell the user
|
||||||
hWndGrp = pgw->hWndGroup;
|
|
||||||
|
|
||||||
if (hWndGrp != NULL)
|
// TODO: make sure environment is
|
||||||
{
|
// refreshed before execution
|
||||||
// NOTE: come back to this lol
|
return FALSE;
|
||||||
// TODO: establish better what this actually does
|
|
||||||
// min/max flags are pulled from hwnd
|
|
||||||
// common/readonly flags are set upon group creation
|
|
||||||
// this means that some flags are static whereas
|
|
||||||
// others change over time, this means that we can
|
|
||||||
// either assume certain flags never change over time
|
|
||||||
// or grab them every time.
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
SaveGroup -
|
UpdateGroup -
|
||||||
Saves group from a group window
|
Updates group information to prepare
|
||||||
into a GROUP structure.
|
it for being saved.
|
||||||
ABSTRACT -
|
ABSTRACT -
|
||||||
This function will extract all of the
|
This function will update all of the
|
||||||
necessary information from a group window
|
relevant structures in a group struct
|
||||||
in order to produce a group structure.
|
in preparation for saving the group.
|
||||||
RETURNS -
|
RETURNS -
|
||||||
Formatted GROUP structure.
|
Nothing.
|
||||||
Upon failure, wChecksum will be 0.
|
|
||||||
\* * * */
|
\* * * */
|
||||||
GROUP SaveGroup(PGROUPWND pgw)
|
VOID UpdateGroup(_In_ PGROUP pg)
|
||||||
{
|
{
|
||||||
GROUP grp = {
|
DWORD dwFlags = 0;
|
||||||
.dwSignature = GRP_SIGNATURE,
|
HWND hWndGroup = NULL;
|
||||||
.wVersion = GRP_VERSION,
|
|
||||||
.wChecksum = 0,
|
|
||||||
.szName = L"",
|
|
||||||
.dwFlags = 0,
|
|
||||||
.ftLastWrite = 0,
|
|
||||||
.cItems = 0,
|
|
||||||
.iItems = NULL
|
|
||||||
};
|
|
||||||
HWND hWndGrp;
|
|
||||||
WCHAR szGroupName[MAX_TITLE_LENGTH];
|
|
||||||
|
|
||||||
// Find the group and copy it
|
// Set the important flags
|
||||||
grp = pgw->grp;
|
pg->dwSignature = GRP_SIGNATURE;
|
||||||
|
pg->wVersion = GRP_VERSION;
|
||||||
// Get the window handle as well
|
|
||||||
hWndGrp = pgw->hWndGroup;
|
|
||||||
|
|
||||||
// Set the group checksum
|
// Set the group checksum
|
||||||
grp.wChecksum = 1; // NOTE: implement this for real later lol
|
pg->wChecksum = 1; // NOTE: implement this for real later lol
|
||||||
|
|
||||||
// Copy group information
|
// TODO: group flags
|
||||||
GetWindowText(hWndGrp, szGroupName, MAX_TITLE_LENGTH);
|
// pg->dwFlags = GRP_FLAG_MAXIMIZED;// GetGroupFlags(pgw);
|
||||||
StringCchCopy(grp.szName, MAX_TITLE_LENGTH, szGroupName);
|
|
||||||
|
|
||||||
grp.dwFlags = GRP_FLAG_MAXIMIZED;// GetGroupFlags(pgw);
|
// Set FILETIME
|
||||||
|
GetSystemTimeAsFileTime(&pg->ftLastWrite);
|
||||||
|
|
||||||
|
if (hWndGroup = GetHwndFromPGroup(pg))
|
||||||
|
{
|
||||||
|
// Get the group window rect and name
|
||||||
|
pg->wp.length = sizeof(WINDOWPLACEMENT);
|
||||||
|
GetWindowPlacement(hWndGroup, &pg->wp);
|
||||||
|
GetWindowText(hWndGroup, pg->szName, ARRAYSIZE(pg->szName));
|
||||||
|
}
|
||||||
|
|
||||||
GetSystemTimeAsFileTime(&grp.ftLastWrite);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Save items...
|
/* * * *\
|
||||||
grp.cItems = 0;
|
GetHwndFromPGroup -
|
||||||
// TODO: iterate through listview to save items
|
In goes a PGROUP out comes a HWND
|
||||||
|
RETURNS -
|
||||||
|
HWND.
|
||||||
|
\* * * */
|
||||||
|
HWND GetHwndFromPGroup(_In_ PGROUP pg)
|
||||||
|
{
|
||||||
|
EnumChildWindows(g_hWndProgMgr, (WNDENUMPROC)GetHwndFromPGroupEnum, (LPARAM)pg);
|
||||||
|
|
||||||
return grp;
|
return hWndFoundGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
GetHwndFromPGroupEnum -
|
||||||
|
Enum Function
|
||||||
|
RETURNS -
|
||||||
|
HWND.
|
||||||
|
\* * * */
|
||||||
|
BOOL GetHwndFromPGroupEnum(_In_ HWND hwnd, _In_ LPARAM lParam)
|
||||||
|
{
|
||||||
|
if (lParam == GetWindowLongPtr(hwnd, GWLP_USERDATA))
|
||||||
|
{
|
||||||
|
hWndFoundGroup = hwnd;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hWndFoundGroup = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
VerifyGroup -
|
||||||
|
Verifies that a group contains the
|
||||||
|
correct information about itself.
|
||||||
|
ABSTRACT -
|
||||||
|
This function will check the checksum,
|
||||||
|
verify the number of items, check other
|
||||||
|
parts of the strucutre. If requested,
|
||||||
|
it will repair the group if it is damaged.
|
||||||
|
RETURNS -
|
||||||
|
TRUE if group appears to be fine
|
||||||
|
FALSE if the group is damaged
|
||||||
|
\* * * */
|
||||||
|
BOOL VerifyGroup(_In_ PGROUP pg, _In_ BOOL bRepair)
|
||||||
|
{
|
||||||
|
if (pg->dwSignature != GRP_SIGNATURE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// if (pg->wVersion != GRP_VERSION)
|
||||||
|
// some sort of version difference handling
|
||||||
|
|
||||||
|
if (pg->wChecksum == 1234)
|
||||||
|
// TODO: calculate checksum function
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// TODO: use ftlastwrite to throw an error
|
||||||
|
// if system clock is in the future
|
||||||
|
|
||||||
|
// calculate the size of the group based on item of numbers
|
||||||
|
|
||||||
|
// TODO: change to return a dword error value
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
CalculateGroupMemory -
|
||||||
|
Calculates the memory needed by a group.
|
||||||
|
Takes a group structure pointer and the
|
||||||
|
number of desired items as input.
|
||||||
|
RETURNS -
|
||||||
|
Size in bytes that a group should take up.
|
||||||
|
\* * * */
|
||||||
|
UINT CalculateGroupMemory(_In_ PGROUP pGroup, _In_ UINT cItems, _In_ BOOL bLean)
|
||||||
|
{
|
||||||
|
UINT cbGroupSize = 0;
|
||||||
|
UINT cItemBlock = 0;
|
||||||
|
|
||||||
|
// first add the size of a group strucutre
|
||||||
|
cbGroupSize += sizeof(GROUP);
|
||||||
|
|
||||||
|
// calculate the total amount of items wanted
|
||||||
|
cItemBlock = pGroup->cItemArray + cItems;
|
||||||
|
|
||||||
|
if (!bLean)
|
||||||
|
// round the amount of items to the nearest but highest ITEM_BATCH_COUNT
|
||||||
|
cItemBlock = ((cItemBlock + ITEM_BATCH_COUNT) / ITEM_BATCH_COUNT) * ITEM_BATCH_COUNT;
|
||||||
|
|
||||||
|
// finally calculate the total group size
|
||||||
|
cbGroupSize += cItemBlock * sizeof(ITEM);
|
||||||
|
|
||||||
|
return cbGroupSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
@@ -235,15 +574,181 @@ GROUP SaveGroup(PGROUPWND pgw)
|
|||||||
\* * * */
|
\* * * */
|
||||||
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
|
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
break;
|
CREATESTRUCT* pCreateStruct;
|
||||||
}
|
MDICREATESTRUCT* pMDICreateStruct;
|
||||||
default:
|
|
||||||
// GroupProcDefault:
|
// code borrowed from winprog
|
||||||
|
pCreateStruct = (CREATESTRUCT*)lParam;
|
||||||
|
pMDICreateStruct = (MDICREATESTRUCT*)pCreateStruct->lpCreateParams;
|
||||||
|
|
||||||
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_SYSCOMMAND:
|
||||||
|
{
|
||||||
|
if (CmdProc(hWnd, wParam, lParam))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_CONTEXTMENU:
|
||||||
|
{
|
||||||
|
POINT pt = { 0 };
|
||||||
|
HMENU hMenu = NULL;
|
||||||
|
BOOL bPopup = FALSE;
|
||||||
|
|
||||||
|
// LVHT_ONITEM
|
||||||
|
// LVHT_NOWHERE
|
||||||
|
|
||||||
|
pt.x = GET_X_LPARAM(lParam);
|
||||||
|
pt.y = GET_Y_LPARAM(lParam);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
return ShowWindow(hWnd, SW_MINIMIZE);
|
||||||
|
|
||||||
|
case WM_NOTIFY:
|
||||||
|
{
|
||||||
|
LPNMHDR lpnmhdr = (LPNMHDR)lParam;
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
|
||||||
|
// find the listview control
|
||||||
|
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
|
||||||
|
if (hWndListView == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (lpnmhdr->code)
|
||||||
|
{
|
||||||
|
|
||||||
|
case NM_DBLCLK:
|
||||||
|
{
|
||||||
|
LVITEM lvi = { 0 };
|
||||||
|
PITEM pItem = NULL;
|
||||||
|
|
||||||
|
// what info do we want?
|
||||||
|
lvi.mask = LVIF_PARAM;
|
||||||
|
lvi.iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
|
||||||
|
|
||||||
|
// get the listview item
|
||||||
|
ListView_GetItem(hWndListView, &lvi);
|
||||||
|
|
||||||
|
// get the item pointer
|
||||||
|
pItem = (PITEM)lvi.lParam;
|
||||||
|
|
||||||
|
// verify...
|
||||||
|
if (pItem)
|
||||||
|
{
|
||||||
|
// and execute!
|
||||||
|
ExecuteItem(pItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_SIZE:
|
||||||
|
{
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
RECT rcGroupWindow = { 0 };
|
||||||
|
|
||||||
|
// get the group window rect
|
||||||
|
GetClientRect(hWnd, &rcGroupWindow);
|
||||||
|
|
||||||
|
// find the listview control
|
||||||
|
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
|
||||||
|
if (hWndListView == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// resize it to fit the window
|
||||||
|
SetWindowPos(hWndListView, NULL,
|
||||||
|
rcGroupWindow.left, rcGroupWindow.top,
|
||||||
|
rcGroupWindow.right - rcGroupWindow.left,
|
||||||
|
rcGroupWindow.bottom - rcGroupWindow.top, SWP_NOZORDER);
|
||||||
|
|
||||||
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
GroupCmdProc -
|
||||||
|
Group syscommand procedure.
|
||||||
|
RETURNS -
|
||||||
|
Zero if nothing, otherwise returns the good stuff.
|
||||||
|
\* * * */
|
||||||
|
LRESULT CALLBACK GroupCmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
{
|
||||||
|
case IDM_FILE_OPEN:
|
||||||
|
{
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
LVITEM lvi = { 0 };
|
||||||
|
PITEM pItem = NULL;
|
||||||
|
|
||||||
|
// find the listview control
|
||||||
|
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
|
||||||
|
if (hWndListView == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// what info do we want?
|
||||||
|
lvi.mask = LVIF_PARAM;
|
||||||
|
lvi.iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
|
||||||
|
|
||||||
|
// get the listview item
|
||||||
|
ListView_GetItem(hWndListView, &lvi);
|
||||||
|
|
||||||
|
// get the item pointer
|
||||||
|
pItem = (PITEM)lvi.lParam;
|
||||||
|
|
||||||
|
// verify...
|
||||||
|
if (pItem)
|
||||||
|
{
|
||||||
|
// and execute!
|
||||||
|
ExecuteItem(pItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case IDM_FILE_MOVE:
|
||||||
|
// TODO: ITEM Create dialog with other MDI groups, pick one to move item
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_FILE_COPY:
|
||||||
|
// TODO: ITEM Copy item structure to clipboard
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_FILE_DELETE:
|
||||||
|
// TODO: ITEM/GROUP Delete selected item, if no items selected or no items
|
||||||
|
// exist then delete the group
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_FILE_PROPS:
|
||||||
|
// TODO: ITEM/GROUP Open properties of selected item or if nothing selected
|
||||||
|
// then open group properties
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
GROUP.H -
|
GROUP.H -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program group/item structures, functions and definitons
|
Program group/item structures, functions and definitons
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -13,18 +13,21 @@
|
|||||||
/* Definitions */
|
/* Definitions */
|
||||||
#define MAX_GROUPS 512
|
#define MAX_GROUPS 512
|
||||||
#define MAX_ITEMS 512
|
#define MAX_ITEMS 512
|
||||||
#define MAX_TITLE_LENGTH MAX_PATH
|
#define MAX_TITLE_LENGTH 255 // Same as the registry key name max length
|
||||||
|
#define ITEM_BATCH_COUNT 8
|
||||||
// Group Format Definitions
|
// Group Format Definitions
|
||||||
#define GRP_SIGNATURE 0x47324D50L // PM2G
|
#define GRP_SIGNATURE 0x47324D50L // PM2G
|
||||||
#define GRP_VERSION 1 // Increment for breaking changes
|
#define GRP_VERSION 2 // Increment for breaking changes, format version
|
||||||
// Group Flag Values (DWORD)
|
// Group Flag Values (DWORD)
|
||||||
#define GRP_FLAG_COMMON 0x00000001
|
#define GRP_FLAG_COMMON 0x00000001
|
||||||
#define GRP_FLAG_READONLY 0x00000002
|
#define GRP_FLAG_READONLY 0x00000002
|
||||||
#define GRP_FLAG_MINIMIZED 0x00000004
|
#define GRP_FLAG_MINIMIZED 0x00000004
|
||||||
#define GRP_FLAG_MAXIMIZED 0x00000008
|
#define GRP_FLAG_MAXIMIZED 0x00000008
|
||||||
// Item Flag Values (DWORD)
|
// Item Flag Values (DWORD)
|
||||||
#define ITM_FLAG_MINIMIZED 0x00000001
|
#define ITM_FLAG_HOTKEY 0x00000001
|
||||||
#define ITM_FLAG_MAXIMIZED 0x00000002
|
#define ITM_FLAG_PRIVILEGE 0x00000002
|
||||||
|
#define ITM_FLAG_MINIMIZED 0x00000004
|
||||||
|
#define ITM_FLAG_MAXIMIZED 0x00000008
|
||||||
|
|
||||||
/* Structures */
|
/* Structures */
|
||||||
// Item Structure
|
// Item Structure
|
||||||
@@ -54,35 +57,37 @@ typedef struct _GROUP {
|
|||||||
FILETIME ftLastWrite;
|
FILETIME ftLastWrite;
|
||||||
// Window information
|
// Window information
|
||||||
RECT rcGroup;
|
RECT rcGroup;
|
||||||
|
WINDOWPLACEMENT wp;
|
||||||
// Icon
|
// Icon
|
||||||
WCHAR szIconPath[MAX_PATH];
|
WCHAR szIconPath[MAX_PATH];
|
||||||
INT iIconIndex;
|
INT iIconIndex;
|
||||||
// Items
|
// Items
|
||||||
WORD cItems; // Number of items
|
WORD cItemArray; // Number of items in pItemArray
|
||||||
PITEM iItems; // Array of items
|
ITEM pItemArray[1]; // Array of items
|
||||||
} GROUP, * PGROUP;
|
} GROUP, * PGROUP;
|
||||||
|
|
||||||
// Group window information
|
|
||||||
typedef struct _GROUPWND {
|
|
||||||
// Windows
|
|
||||||
HWND hWndGroup;
|
|
||||||
HWND hWndListView;
|
|
||||||
// Group
|
|
||||||
GROUP grp; // Pointer to GROUP structure
|
|
||||||
} GROUPWND, * PGROUPWND;
|
|
||||||
|
|
||||||
/* Global Variables */
|
/* Global Variables */
|
||||||
extern HWND hWndMDIClient;
|
extern HWND hWndMDIClient;
|
||||||
|
|
||||||
/* Local Variables */
|
/* Local Variables */
|
||||||
|
|
||||||
/* Function Prototypes */
|
/* Function Prototypes */
|
||||||
BOOL InitializeGroups();
|
BOOL InitializeGroups(VOID);
|
||||||
|
// Group Management
|
||||||
|
HWND CreateGroup(_In_ PGROUP pg);
|
||||||
|
BOOL RemoveGroup(_In_ HWND hWndGroup, _In_ BOOL bEliminate);
|
||||||
|
// Item Management
|
||||||
|
PITEM CreateItem(_In_ HWND hWndGroup, _In_ PITEM pi);
|
||||||
|
BOOL LoadItems(_In_ HWND hWndGroup);
|
||||||
|
BOOL RemoveItem(_In_ PITEM pi);
|
||||||
|
BOOL ExecuteItem(_In_ PITEM pi);
|
||||||
|
// Save/Load helper functions
|
||||||
|
VOID UpdateGroup(_In_ PGROUP pg);
|
||||||
|
BOOL VerifyGroup(_In_ PGROUP pg, _In_ BOOL bRepair);
|
||||||
|
// Helper functions
|
||||||
|
UINT CalculateGroupMemory(_In_ PGROUP pGroup, _In_ UINT cItems, _In_ BOOL bLean);
|
||||||
|
HWND GetHwndFromPGroup(_In_ PGROUP pg);
|
||||||
|
BOOL GetHwndFromPGroupEnum(_In_ HWND hwnd, _In_ LPARAM lParam);
|
||||||
// Group Window
|
// Group Window
|
||||||
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
PGROUPWND CreateGroupWindow(PGROUP pgGroup);
|
LRESULT CALLBACK GroupCmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
// Group information
|
|
||||||
BOOL SetGroupFlags(PGROUPWND pgw, DWORD dwFlags);
|
|
||||||
BOOL GetGroupFlags(PGROUPWND pgw, DWORD dwFlags);
|
|
||||||
// Import/export functions
|
|
||||||
GROUP SaveGroup(PGROUPWND pgw);
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
GRPUPDAT.H -
|
GRPUPDAT.H -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Header containing classic program group structures
|
Header containing classic program group structures
|
||||||
in order to facilitate conversion to the new format.
|
in order to facilitate conversion to the new format.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 766 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
progmgr/icons/progmgrd.ico
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
progmgr/icons/src/progmgrd.ico
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
progmgr/icons/src/progmgrd.pdn
Normal file
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
PROGMGR.C -
|
PROGMGR.C -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's main file, now with extra wWinMain!
|
Program Manager's main file, now with extra wWinMain!
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -8,32 +8,57 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define SECURITY_WIN32
|
||||||
|
#include <Windows.h>
|
||||||
#include "progmgr.h"
|
#include "progmgr.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#define SECURITY_WIN32
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
// Global
|
// Global
|
||||||
BOOL bIsDefaultShell = FALSE;
|
#ifdef _DEBUG
|
||||||
|
BOOL g_bIsDebugBuild = TRUE;
|
||||||
|
#else
|
||||||
|
BOOL g_bIsDebugBuild = FALSE;
|
||||||
|
#endif
|
||||||
|
BOOL g_bIsDefaultShell = FALSE;
|
||||||
// Handles
|
// Handles
|
||||||
HINSTANCE hAppInstance;
|
HINSTANCE g_hAppInstance;
|
||||||
HANDLE hAppHeap;
|
HWND g_hWndProgMgr = NULL;
|
||||||
HWND hWndProgMgr = NULL;
|
|
||||||
// Icons
|
// Icons
|
||||||
HICON hProgMgrIcon = NULL;
|
HICON g_hProgMgrIcon = NULL;
|
||||||
HICON hGroupIcon = NULL;
|
HICON g_hGroupIcon = NULL;
|
||||||
// Global Strings
|
// Global Strings
|
||||||
WCHAR szAppTitle[32];
|
WCHAR g_szAppTitle[64];
|
||||||
WCHAR szProgMgr[] = L"progmgr";
|
WCHAR g_szProgMgr[] = TEXT("progmgr");
|
||||||
WCHAR szWebsite[64];
|
WCHAR g_szWebsite[64];
|
||||||
WCHAR szClass[16];
|
WCHAR g_szClass[16];
|
||||||
|
// Permissions
|
||||||
|
BOOL g_bPermAdmin; // Has Administrator permissions
|
||||||
|
BOOL g_bPermGuest; // Has Guest permissions
|
||||||
|
BOOL g_bPermPower; // Has power option permissions
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
UpdatePermissions -
|
||||||
|
Update the permissions for the user based
|
||||||
|
on account settings.
|
||||||
|
RETURNS -
|
||||||
|
TRUE if permissions are found successfully.
|
||||||
|
FALSE if otherwise.
|
||||||
|
\* * * */
|
||||||
|
BOOL UpdatePermissions(VOID)
|
||||||
|
{
|
||||||
|
// SE_SHUTDOWN_NAME
|
||||||
|
g_bPermAdmin = FALSE;
|
||||||
|
g_bPermGuest = FALSE;
|
||||||
|
g_bPermPower = FALSE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
wWinMain -
|
wWinMain -
|
||||||
Program Manager's entry point.
|
Program Manager's entry point.
|
||||||
@@ -44,41 +69,49 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
HANDLE hAccel;
|
HANDLE hAccel;
|
||||||
HMENU hMenu;
|
HMENU hMenu;
|
||||||
HMENU hSystemMenu;
|
HMENU hSystemMenu;
|
||||||
|
HWND hOldProgMgr;
|
||||||
WNDCLASS wc = { 0 };
|
WNDCLASS wc = { 0 };
|
||||||
WCHAR szBuffer[MAX_PATH];
|
WCHAR szBuffer[MAX_PATH];
|
||||||
RECT rcRoot;
|
RECT rcRoot;
|
||||||
POINT ptOffset;
|
POINT ptOffset = { 0 };
|
||||||
|
|
||||||
// Initialize the instance
|
// Grab the instance
|
||||||
hAppInstance = hInstance;
|
g_hAppInstance = hInstance;
|
||||||
|
|
||||||
// Create our global heap handle
|
|
||||||
hAppHeap = GetProcessHeap();
|
|
||||||
|
|
||||||
// Create Strings
|
// Create Strings
|
||||||
LoadString(hAppInstance, IDS_PMCLASS, szClass, ARRAYSIZE(szClass));
|
LoadString(g_hAppInstance, IDS_PMCLASS, g_szClass, ARRAYSIZE(g_szClass));
|
||||||
LoadString(hAppInstance, IDS_APPTITLE, szAppTitle, ARRAYSIZE(szAppTitle));
|
LoadString(g_hAppInstance, IDS_APPTITLE, g_szAppTitle, ARRAYSIZE(g_szAppTitle));
|
||||||
LoadString(hAppInstance, IDS_WEBSITE, szWebsite, ARRAYSIZE(szWebsite));
|
LoadString(g_hAppInstance, IDS_WEBSITE, g_szWebsite, ARRAYSIZE(g_szWebsite));
|
||||||
|
|
||||||
|
// Lazily search for another instance of Program Manager
|
||||||
|
// If we find one, switch focus to it and then abort.
|
||||||
|
hOldProgMgr = FindWindowEx(NULL, NULL, g_szClass, NULL);
|
||||||
|
|
||||||
|
if (hOldProgMgr != NULL)
|
||||||
|
{
|
||||||
|
SwitchToThisWindow(hOldProgMgr, FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// Get Desktop background color
|
// Get Desktop background color
|
||||||
//CreateSolidBrush(GetBackgroundColor
|
//CreateSolidBrush(GetBackgroundColor
|
||||||
|
|
||||||
// Register the Frame Window Class
|
// Register the Frame Window Class
|
||||||
wc.lpfnWndProc = WndProc;
|
wc.lpfnWndProc = WndProc;
|
||||||
wc.hInstance = hAppInstance;
|
wc.hInstance = g_hAppInstance;
|
||||||
wc.hIcon = hProgMgrIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGMGR), IMAGE_ICON,
|
wc.hIcon = g_hProgMgrIcon = LoadImage(g_hAppInstance, MAKEINTRESOURCE(IDI_PROGMGR), IMAGE_ICON,
|
||||||
0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
// wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
|
// wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
|
||||||
wc.hbrBackground = NULL;
|
wc.hbrBackground = NULL;
|
||||||
wc.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
|
wc.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
|
||||||
wc.lpszClassName = szClass;
|
wc.lpszClassName = g_szClass;
|
||||||
|
|
||||||
if (!RegisterClass(&wc))
|
if (!RegisterClass(&wc))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Load the Accelerator table
|
// Load the Accelerator table
|
||||||
hAccel = LoadAccelerators(hAppInstance, MAKEINTRESOURCE(IDA_ACCELS));
|
hAccel = LoadAccelerators(g_hAppInstance, MAKEINTRESOURCE(IDA_ACCELS));
|
||||||
if (!hAccel)
|
if (!hAccel)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -86,7 +119,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
if (!InitializeRegistryKeys())
|
if (!InitializeRegistryKeys())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
bIsDefaultShell = IsProgMgrDefaultShell();
|
g_bIsDefaultShell = IsProgMgrDefaultShell();
|
||||||
|
|
||||||
// Load configuration, but don't load groups yet
|
// Load configuration, but don't load groups yet
|
||||||
if(LoadConfig(TRUE, TRUE, FALSE) != RCE_SUCCESS)
|
if(LoadConfig(TRUE, TRUE, FALSE) != RCE_SUCCESS)
|
||||||
@@ -101,22 +134,23 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
// Create main window with a default size
|
// Create main window with a default size
|
||||||
// TODO: i pulled 320x240 out of my ass, make this dynamic later
|
// TODO: i pulled 320x240 out of my ass, make this dynamic later
|
||||||
if (!(hWndProgMgr = CreateWindowW(wc.lpszClassName, szAppTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
if ((g_hWndProgMgr = CreateWindowW(wc.lpszClassName, g_szAppTitle,
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
rcRoot.left + ptOffset.x, rcRoot.top + ptOffset.y,
|
rcRoot.left + ptOffset.x, rcRoot.top + ptOffset.y,
|
||||||
rcRoot.left + ptOffset.x + 320, rcRoot.top + ptOffset.y + 240,
|
rcRoot.left + ptOffset.x + 320, rcRoot.top + ptOffset.y + 240,
|
||||||
0, 0, hAppInstance, NULL)))
|
0, 0, g_hAppInstance, NULL)) == NULL)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
// Set the window size from the registry, but only if the coords make sense
|
// Set the window size from the registry, but only if the coords make sense
|
||||||
if ((rcMainWindow.left != rcMainWindow.right) && (rcMainWindow.top != rcMainWindow.bottom))
|
if ((rcMainWindow.left != rcMainWindow.right) && (rcMainWindow.top != rcMainWindow.bottom))
|
||||||
SetWindowPos(hWndProgMgr, NULL,
|
SetWindowPos(g_hWndProgMgr, NULL,
|
||||||
rcMainWindow.left, rcMainWindow.top,
|
rcMainWindow.left, rcMainWindow.top,
|
||||||
rcMainWindow.right - rcMainWindow.left,
|
rcMainWindow.right - rcMainWindow.left,
|
||||||
rcMainWindow.bottom - rcMainWindow.top, SWP_NOZORDER);
|
rcMainWindow.bottom - rcMainWindow.top, SWP_NOZORDER);
|
||||||
|
|
||||||
// Load the menus...
|
// Load the menus...
|
||||||
hMenu = GetMenu(hWndProgMgr);
|
hMenu = GetMenu(g_hWndProgMgr);
|
||||||
hSystemMenu = GetSystemMenu(hWndProgMgr, FALSE);
|
hSystemMenu = GetSystemMenu(g_hWndProgMgr, FALSE);
|
||||||
|
|
||||||
// Update relevant parts of the window
|
// Update relevant parts of the window
|
||||||
UpdateChecks(bAutoArrange, IDM_OPTIONS, IDM_OPTIONS_AUTOARRANGE);
|
UpdateChecks(bAutoArrange, IDM_OPTIONS, IDM_OPTIONS_AUTOARRANGE);
|
||||||
@@ -129,21 +163,21 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
// Update settings based on their values
|
// Update settings based on their values
|
||||||
if (bTopMost)
|
if (bTopMost)
|
||||||
SetWindowPos(hWndProgMgr, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
SetWindowPos(g_hWndProgMgr, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
|
||||||
if (bIsDefaultShell)
|
if (g_bIsDefaultShell)
|
||||||
{
|
{
|
||||||
// Modify the context menus since we're the default shell
|
// Modify the context menus since we're the default shell
|
||||||
DeleteMenu(hSystemMenu, SC_CLOSE, MF_BYCOMMAND);
|
DeleteMenu(hSystemMenu, SC_CLOSE, MF_BYCOMMAND);
|
||||||
|
|
||||||
LoadString(hAppInstance, IDS_SHUTDOWN, szBuffer, ARRAYSIZE(szBuffer));
|
LoadString(g_hAppInstance, IDS_SHUTDOWN, szBuffer, ARRAYSIZE(szBuffer));
|
||||||
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_SHUTDOWN, szBuffer);
|
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_SHUTDOWN, szBuffer);
|
||||||
ModifyMenu(hMenu, IDM_FILE_EXIT, MF_BYCOMMAND | MF_STRING, IDM_SHUTDOWN, szBuffer);
|
ModifyMenu(hMenu, IDM_FILE_EXIT, MF_BYCOMMAND | MF_STRING, IDM_SHUTDOWN, szBuffer);
|
||||||
|
|
||||||
LoadString(hAppInstance, IDS_RUN, szBuffer, ARRAYSIZE(szBuffer));
|
LoadString(g_hAppInstance, IDS_RUN, szBuffer, ARRAYSIZE(szBuffer));
|
||||||
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_FILE_RUN, szBuffer);
|
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_FILE_RUN, szBuffer);
|
||||||
|
|
||||||
LoadString(hAppInstance, IDS_TASKMGR, szBuffer, ARRAYSIZE(szBuffer));
|
LoadString(g_hAppInstance, IDS_TASKMGR, szBuffer, ARRAYSIZE(szBuffer));
|
||||||
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_TASKMGR, szBuffer);
|
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_TASKMGR, szBuffer);
|
||||||
|
|
||||||
// Create the desktop window...
|
// Create the desktop window...
|
||||||
@@ -157,7 +191,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
while (GetMessage(&msg, NULL, 0, 0) > 0)
|
while (GetMessage(&msg, NULL, 0, 0) > 0)
|
||||||
{
|
{
|
||||||
if (!TranslateMDISysAccel(hWndMDIClient, &msg) &&
|
if (!TranslateMDISysAccel(hWndMDIClient, &msg) &&
|
||||||
!TranslateAccelerator(hWndProgMgr, hAccel, &msg))
|
!TranslateAccelerator(g_hWndProgMgr, hAccel, &msg))
|
||||||
{
|
{
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
@@ -165,3 +199,34 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
// NOTE(u130b8): We used to compile Release builds with /NODEFAULTLIB
|
||||||
|
// but I've temporarily removed it so malloc and free works.
|
||||||
|
|
||||||
|
// NOTE(u130b8): We're compiling without the C runtime by default in Release builds.
|
||||||
|
// But in Debug builds, we need the C runtime, otherwise the address sanitizer and
|
||||||
|
// MSVC debug tools break because they use the wWinMainCRTStartup entrypoint to initialize.
|
||||||
|
|
||||||
|
#ifdef PROGMGR_RELEASE
|
||||||
|
#pragma function(memset)
|
||||||
|
void *memset(char* dst, int value, size_t count) {
|
||||||
|
while (count--) { *dst++ = value; }
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma function(memcpy)
|
||||||
|
void *memcpy(char *dst, const char *src, size_t count) {
|
||||||
|
while (count--) { *dst++ = *src++; }
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __stdcall wWinMainCRTStartup() {
|
||||||
|
int code = wWinMain(GetModuleHandle(0), 0, 0, 0);
|
||||||
|
ExitProcess(code);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -1,22 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
<assemblyIdentity
|
<asmv3:application>
|
||||||
type="win32"
|
<asmv3:windowsSettings>
|
||||||
name="Vortesys.ProgramManagerII.ProgMgr"
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
|
||||||
version="2.0.0.0"
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||||
processorArchitecture="*"
|
</asmv3:windowsSettings>
|
||||||
/>
|
</asmv3:application>
|
||||||
<description>Program Manager II</description>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity
|
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
|
||||||
type="win32"
|
|
||||||
name="Microsoft.Windows.Common-Controls"
|
|
||||||
version="6.0.0.0"
|
|
||||||
processorArchitecture="*"
|
|
||||||
publicKeyToken="6595b64144ccf1df"
|
|
||||||
language="*"
|
|
||||||
/>
|
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</dependency>
|
</dependency>
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
@@ -33,20 +25,4 @@
|
|||||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||||
</application>
|
</application>
|
||||||
</compatibility>
|
</compatibility>
|
||||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<security>
|
|
||||||
<requestedPrivileges>
|
|
||||||
<!--
|
|
||||||
UAC settings:
|
|
||||||
- app should run at same integrity level as calling process
|
|
||||||
- app does not need to manipulate windows belonging to
|
|
||||||
higher-integrity-level processes
|
|
||||||
-->
|
|
||||||
<requestedExecutionLevel
|
|
||||||
level="asInvoker"
|
|
||||||
uiAccess="false"
|
|
||||||
/>
|
|
||||||
</requestedPrivileges>
|
|
||||||
</security>
|
|
||||||
</trustInfo>
|
|
||||||
</assembly>
|
</assembly>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
PROGMGR.H -
|
PROGMGR.H -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's primary header file.
|
Program Manager's primary header file.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -9,11 +9,13 @@
|
|||||||
|
|
||||||
/* Pragmas */
|
/* Pragmas */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#pragma comment(lib, "ComCtl32.lib")
|
||||||
#pragma comment(lib, "Shlwapi.lib")
|
#pragma comment(lib, "Shlwapi.lib")
|
||||||
|
#pragma comment(lib, "Shell32.lib")
|
||||||
#pragma comment(lib, "Secur32.lib")
|
#pragma comment(lib, "Secur32.lib")
|
||||||
|
#pragma comment(lib, "UxTheme.lib")
|
||||||
/* Includes */
|
#pragma comment(lib, "Version.lib")
|
||||||
#include <wtypes.h>
|
#pragma comment(lib, "Winmm.lib")
|
||||||
|
|
||||||
/* Macros and Defines */
|
/* Macros and Defines */
|
||||||
#define GET_WM_COMMAND_ID(wParam, lParam) LOWORD(wParam)
|
#define GET_WM_COMMAND_ID(wParam, lParam) LOWORD(wParam)
|
||||||
@@ -29,23 +31,25 @@
|
|||||||
#define RF_RETRY 0x0002 // Cancel the operation, but leave the dialog open
|
#define RF_RETRY 0x0002 // Cancel the operation, but leave the dialog open
|
||||||
|
|
||||||
/* Global Variables */
|
/* Global Variables */
|
||||||
extern BOOL bIsDefaultShell;
|
extern BOOL g_bIsDefaultShell;
|
||||||
// Handles
|
// Handles
|
||||||
extern HINSTANCE hAppInstance;
|
extern HINSTANCE g_hAppInstance;
|
||||||
extern HANDLE hAppHeap;
|
extern HWND g_hWndProgMgr;
|
||||||
extern HWND hWndProgMgr;
|
|
||||||
// Icons
|
// Icons
|
||||||
extern HICON hProgMgrIcon;
|
extern HICON g_hProgMgrIcon;
|
||||||
extern HICON hGroupIcon;
|
extern HICON g_hGroupIcon;
|
||||||
// Strings
|
// Strings
|
||||||
extern WCHAR szAppTitle[32];
|
extern WCHAR g_szAppTitle[64];
|
||||||
extern WCHAR szProgMgr[];
|
extern WCHAR g_szProgMgr[];
|
||||||
extern WCHAR szWebsite[64];
|
extern WCHAR g_szWebsite[64];
|
||||||
extern WCHAR szClass[16];
|
extern WCHAR g_szClass[16];
|
||||||
|
// Permissions
|
||||||
|
extern BOOL g_bPermAdmin; // Has Administrator permissions
|
||||||
|
extern BOOL g_bPermGuest; // Has Guest permissions
|
||||||
|
extern BOOL g_bPermPower; // Has power option permissions
|
||||||
|
|
||||||
/* Function Prototypes */
|
/* Function Prototypes */
|
||||||
// DESKTOP.C
|
BOOL UpdatePermissions(VOID);
|
||||||
BOOL CreateDesktopWindow();// SYSINT.C
|
|
||||||
// SYSINT.C
|
// SYSINT.C
|
||||||
BOOL RunFileDlg(HWND hWndOwner, HICON hIcon, LPWSTR lpszDir, LPWSTR lpszTitle, LPWSTR lpszDesc, DWORD dwFlags);
|
BOOL RunFileDlg(HWND hWndOwner, HICON hIcon, LPWSTR lpszDir, LPWSTR lpszTitle, LPWSTR lpszDesc, DWORD dwFlags);
|
||||||
BOOL ExitWindowsDialog(HWND hWndOwner);
|
BOOL ExitWindowsDialog(HWND hWndOwner);
|
||||||
@@ -54,4 +58,4 @@ BOOL SetShellWindow(HWND hWndShell);
|
|||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
VOID UpdateChecks(BOOL bVarMenu, UINT uSubMenu, UINT uID);
|
VOID UpdateChecks(BOOL bVarMenu, UINT uSubMenu, UINT uID);
|
||||||
VOID UpdateWindowTitle();
|
VOID UpdateWindowTitle(VOID);
|
||||||
|
|||||||
@@ -29,26 +29,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -71,23 +71,23 @@
|
|||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(OutDir)</IntDir>
|
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(OutDir)</IntDir>
|
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(OutDir)</IntDir>
|
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(OutDir)</IntDir>
|
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
@@ -96,6 +96,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -104,6 +105,9 @@
|
|||||||
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||||
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
|
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
|
||||||
</Link>
|
</Link>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ResourceCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -113,6 +117,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -130,6 +135,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -138,6 +144,9 @@
|
|||||||
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||||
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
|
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
|
||||||
</Link>
|
</Link>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ResourceCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -147,6 +156,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -167,7 +177,6 @@
|
|||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="desktop.c" />
|
|
||||||
<ClCompile Include="dialog.c" />
|
<ClCompile Include="dialog.c" />
|
||||||
<ClCompile Include="progmgr.c" />
|
<ClCompile Include="progmgr.c" />
|
||||||
<ClCompile Include="registry.c" />
|
<ClCompile Include="registry.c" />
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
<Filter Include="Language Resources">
|
<Filter Include="Language Resources">
|
||||||
<UniqueIdentifier>{71dbbd6d-c82a-4fac-a0ff-74be88190f82}</UniqueIdentifier>
|
<UniqueIdentifier>{71dbbd6d-c82a-4fac-a0ff-74be88190f82}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Resource Files\en-US">
|
||||||
|
<UniqueIdentifier>{2a11d118-5a5c-4681-86dc-31de4f0251ff}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="progmgr.h">
|
<ClInclude Include="progmgr.h">
|
||||||
@@ -44,9 +47,6 @@
|
|||||||
<ClCompile Include="registry.c">
|
<ClCompile Include="registry.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="desktop.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="sysint.c">
|
<ClCompile Include="sysint.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -64,11 +64,11 @@
|
|||||||
<ResourceCompile Include="resource.rc">
|
<ResourceCompile Include="resource.rc">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<ResourceCompile Include="lang\dlg_en-US.rc">
|
|
||||||
<Filter>Language Resources</Filter>
|
|
||||||
</ResourceCompile>
|
|
||||||
<ResourceCompile Include="lang\res_en-US.rc">
|
<ResourceCompile Include="lang\res_en-US.rc">
|
||||||
<Filter>Language Resources</Filter>
|
<Filter>Resource Files\en-US</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
<ResourceCompile Include="lang\dlg_en-US.rc">
|
||||||
|
<Filter>Resource Files\en-US</Filter>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
REGISTRY.C -
|
REGISTRY.C -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's registry and settings related functions.
|
Program Manager's registry and settings related functions.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -8,13 +8,13 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
#include "progmgr.h"
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include "group.h"
|
|
||||||
#include "registry.h"
|
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
#include "progmgr.h"
|
||||||
|
#include "group.h"
|
||||||
|
#include "registry.h"
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
// Global HKEYs
|
// Global HKEYs
|
||||||
@@ -36,11 +36,12 @@ DWORD dwSettingsMask = {
|
|||||||
};
|
};
|
||||||
RECT rcMainWindow;
|
RECT rcMainWindow;
|
||||||
// Registry Subkeys
|
// Registry Subkeys
|
||||||
PWSTR pszProgramGroups = L"Program Groups";
|
PWSTR pszProgramGroups = TEXT("Program Groups");
|
||||||
PWSTR pszSettings = L"Settings";
|
PWSTR pszSettings = TEXT("Settings");
|
||||||
// Settings Subkeys
|
// Settings Subkeys
|
||||||
PWSTR pszSettingsWindow = L"Window";
|
PWSTR pszSettingsWindow = TEXT("Window");
|
||||||
PWSTR pszSettingsMask = L"SettingsMask";
|
PWSTR pszSettingsMask = TEXT("SettingsMask");
|
||||||
|
// Permissions (Global)
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
@@ -51,15 +52,15 @@ PWSTR pszSettingsMask = L"SettingsMask";
|
|||||||
RETURNS -
|
RETURNS -
|
||||||
TRUE if successful, FALSE if unsuccessful.
|
TRUE if successful, FALSE if unsuccessful.
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL InitializeRegistryKeys()
|
BOOL InitializeRegistryKeys(VOID)
|
||||||
{
|
{
|
||||||
if (!RegCreateKeyEx(HKEY_CURRENT_USER, PROGMGR_KEY, 0, szProgMgr, 0,
|
if (!RegCreateKeyEx(HKEY_CURRENT_USER, PROGMGR_KEY, 0, g_szProgMgr, 0,
|
||||||
KEY_READ | KEY_WRITE, NULL, &hKeyProgramManager, NULL))
|
KEY_READ | KEY_WRITE, NULL, &hKeyProgramManager, NULL))
|
||||||
{
|
{
|
||||||
// Create Program Groups and Settings keys
|
// Create Program Groups and Settings keys
|
||||||
RegCreateKeyEx(hKeyProgramManager, pszProgramGroups, 0, szProgMgr, 0,
|
RegCreateKeyEx(hKeyProgramManager, pszProgramGroups, 0, g_szProgMgr, 0,
|
||||||
KEY_READ | KEY_WRITE, NULL, &hKeyProgramGroups, NULL);
|
KEY_READ | KEY_WRITE, NULL, &hKeyProgramGroups, NULL);
|
||||||
RegCreateKeyEx(hKeyProgramManager, pszSettings, 0, szProgMgr, 0,
|
RegCreateKeyEx(hKeyProgramManager, pszSettings, 0, g_szProgMgr, 0,
|
||||||
KEY_READ | KEY_WRITE, NULL, &hKeySettings, NULL);
|
KEY_READ | KEY_WRITE, NULL, &hKeySettings, NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -74,20 +75,20 @@ BOOL InitializeRegistryKeys()
|
|||||||
TRUE if Program Manager is the default shell,
|
TRUE if Program Manager is the default shell,
|
||||||
FALSE if otherwise or an error occurs.
|
FALSE if otherwise or an error occurs.
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL IsProgMgrDefaultShell()
|
BOOL IsProgMgrDefaultShell(VOID)
|
||||||
{
|
{
|
||||||
HKEY hKeyWinlogon;
|
HKEY hKeyWinlogon;
|
||||||
WCHAR szShell[HKEYMAXLEN] = L"";
|
WCHAR szShell[HKEYMAXLEN] = TEXT("");
|
||||||
DWORD dwType;
|
DWORD dwType;
|
||||||
DWORD dwBufferSize = sizeof(szShell);
|
DWORD dwBufferSize = sizeof(szShell);
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINLOGON_KEY,
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINLOGON_KEY,
|
||||||
0, KEY_READ, &hKeyWinlogon) == ERROR_SUCCESS)
|
0, KEY_READ, &hKeyWinlogon) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (RegQueryValueEx(hKeyWinlogon, L"Shell", 0, &dwType,
|
if (RegQueryValueEx(hKeyWinlogon, TEXT("Shell"), 0, &dwType,
|
||||||
(LPBYTE)szShell, &dwBufferSize) == ERROR_SUCCESS)
|
(LPBYTE)szShell, &dwBufferSize) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (StrStr(szShell, szProgMgr))
|
if (StrStr(szShell, g_szProgMgr))
|
||||||
{
|
{
|
||||||
// ProgMgr detected >:)
|
// ProgMgr detected >:)
|
||||||
RegCloseKey(hKeyWinlogon);
|
RegCloseKey(hKeyWinlogon);
|
||||||
@@ -112,48 +113,44 @@ BOOL IsProgMgrDefaultShell()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
SaveGroupToRegistry -
|
RegistrySaveGroup -
|
||||||
Saves a group structure to registry.
|
Saves a group structure to the registry.
|
||||||
RETURNS -
|
RETURNS -
|
||||||
RCE_* configuration error value
|
RCE_* configuration error value
|
||||||
\* * * */
|
\* * * */
|
||||||
DWORD SaveGroupToRegistry(_In_ PGROUP pg)
|
DWORD RegistrySaveGroup(_In_ PGROUP pg)
|
||||||
{
|
{
|
||||||
DWORD dwConfigStatus = RCE_SUCCESS;
|
// If the pointer or HKEY is invalid then fail out
|
||||||
|
if ((pg == NULL) || (hKeyProgramGroups == NULL))
|
||||||
// If the pointer is invalid then fail out
|
|
||||||
if (pg == NULL)
|
|
||||||
return RCE_FAILURE;
|
return RCE_FAILURE;
|
||||||
|
|
||||||
// Save group
|
// Save group
|
||||||
|
UpdateGroup(pg);
|
||||||
if (!RegSetValueEx(hKeyProgramGroups, pg->szName, 0, REG_BINARY,
|
if (!RegSetValueEx(hKeyProgramGroups, pg->szName, 0, REG_BINARY,
|
||||||
(const BYTE*)pg, (sizeof(*pg) + sizeof(ITEM) * pg->cItems)) == ERROR_SUCCESS)
|
(const BYTE*)pg, sizeof(*pg)) == ERROR_SUCCESS)
|
||||||
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
return RCE_GROUPS;
|
||||||
|
|
||||||
return dwConfigStatus;
|
return RCE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
LoadGroupFromRegistry -
|
RegistryRemoveGroup -
|
||||||
Loads a group structure from the registry.
|
Removes a group structure from the registry.
|
||||||
RETURNS -
|
RETURNS -
|
||||||
RCE_* configuration error value
|
RCE_* configuration error value
|
||||||
\* * * */
|
\* * * */
|
||||||
DWORD LoadGroupFromRegistry(_Inout_ PGROUP pg, _Out_ DWORD dwBufferSize)
|
DWORD RegistryRemoveGroup(_In_ PGROUP pg)
|
||||||
{
|
{
|
||||||
DWORD dwConfigStatus = RCE_SUCCESS;
|
// If the pointer or HKEY is invalid then fail out
|
||||||
DWORD dwType = REG_BINARY;
|
if ((pg == NULL) || (hKeyProgramGroups == NULL))
|
||||||
|
|
||||||
// If the pointer is invalid then fail out
|
|
||||||
if (pg == NULL)
|
|
||||||
return RCE_FAILURE;
|
return RCE_FAILURE;
|
||||||
|
|
||||||
// Load group
|
// Try to remove the group matching the name
|
||||||
if (!RegQueryValueEx(hKeyProgramGroups, pg->szName, 0, &dwType,
|
// If we fail, group does not exist in the registry
|
||||||
(LPBYTE)pg, &dwBufferSize) == ERROR_SUCCESS)
|
if (RegDeleteValue(hKeyProgramGroups, pg->szName) != ERROR_SUCCESS)
|
||||||
dwConfigStatus = dwConfigStatus && RCE_POSITION;
|
return RCE_FAILURE;
|
||||||
|
|
||||||
return dwConfigStatus;
|
return RCE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
@@ -163,7 +160,7 @@ DWORD LoadGroupFromRegistry(_Inout_ PGROUP pg, _Out_ DWORD dwBufferSize)
|
|||||||
RETURNS -
|
RETURNS -
|
||||||
RCE_* configuration error value
|
RCE_* configuration error value
|
||||||
\* * * */
|
\* * * */
|
||||||
DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
|
DWORD SaveConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups, _In_ BOOL bExit)
|
||||||
{
|
{
|
||||||
DWORD dwConfigStatus = RCE_SUCCESS;
|
DWORD dwConfigStatus = RCE_SUCCESS;
|
||||||
|
|
||||||
@@ -186,12 +183,12 @@ DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
|
|||||||
|
|
||||||
if (bPos)
|
if (bPos)
|
||||||
{
|
{
|
||||||
WINDOWPLACEMENT wpProgMgr;
|
WINDOWPLACEMENT wpProgMgr = { 0 };
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
|
|
||||||
// Get and save window position
|
// Get and save window position
|
||||||
wpProgMgr.length = sizeof(WINDOWPLACEMENT);
|
wpProgMgr.length = sizeof(WINDOWPLACEMENT);
|
||||||
GetWindowPlacement(hWndProgMgr, &wpProgMgr);
|
GetWindowPlacement(g_hWndProgMgr, &wpProgMgr);
|
||||||
CopyRect(&rcWindow, &wpProgMgr.rcNormalPosition);
|
CopyRect(&rcWindow, &wpProgMgr.rcNormalPosition);
|
||||||
|
|
||||||
if (!RegSetValueEx(hKeySettings, pszSettingsWindow, 0, REG_BINARY,
|
if (!RegSetValueEx(hKeySettings, pszSettingsWindow, 0, REG_BINARY,
|
||||||
@@ -201,15 +198,61 @@ DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
|
|||||||
|
|
||||||
if (bGroups)
|
if (bGroups)
|
||||||
{
|
{
|
||||||
// TODO: Get list of groups, iterate through,
|
HWND hWndGroup = NULL;
|
||||||
// save each one as an individual subkey based
|
|
||||||
// on the name of the group
|
EnumChildWindows(hWndMDIClient, &SaveWindowEnumProc, (LPARAM)bExit);
|
||||||
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dwConfigStatus;
|
return dwConfigStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
SaveWindowEnumProc() -
|
||||||
|
Procedure for enumeration
|
||||||
|
of group windows to save
|
||||||
|
or close them
|
||||||
|
NOTES -
|
||||||
|
lParam is a BOOL that determines
|
||||||
|
whether to close the group or not
|
||||||
|
RETURNS -
|
||||||
|
TRUE to continue
|
||||||
|
FALSE to stop
|
||||||
|
\* * * */
|
||||||
|
BOOL CALLBACK SaveWindowEnumProc(HWND hWndGroup, LPARAM lParam)
|
||||||
|
{
|
||||||
|
PGROUP pNewGroup = NULL;
|
||||||
|
PGROUP pGroup = NULL;
|
||||||
|
|
||||||
|
if (hWndGroup == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pGroup = (PGROUP)GetWindowLongPtr(hWndGroup, GWLP_USERDATA);
|
||||||
|
|
||||||
|
if (pGroup == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// lean it...
|
||||||
|
/*pNewGroup = realloc(pGroup, CalculateGroupMemory(pGroup, 1, 1));
|
||||||
|
if (pNewGroup != NULL)
|
||||||
|
{
|
||||||
|
pGroup = pNewGroup;
|
||||||
|
SetWindowLongPtr(hWndGroup, GWLP_USERDATA, (LONG_PTR)pGroup);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// save it...
|
||||||
|
if (RegistrySaveGroup(pGroup) != RCE_SUCCESS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// close it...
|
||||||
|
if ((BOOL)lParam == TRUE)
|
||||||
|
{
|
||||||
|
RemoveGroup(hWndGroup, FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
LoadConfig() -
|
LoadConfig() -
|
||||||
Finds all settings and retrieves them
|
Finds all settings and retrieves them
|
||||||
@@ -217,7 +260,7 @@ DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
|
|||||||
RETURNS -
|
RETURNS -
|
||||||
RCE_* configuration error value
|
RCE_* configuration error value
|
||||||
\* * * */
|
\* * * */
|
||||||
DWORD LoadConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
|
DWORD LoadConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups)
|
||||||
{
|
{
|
||||||
DWORD dwConfigStatus = RCE_SUCCESS;
|
DWORD dwConfigStatus = RCE_SUCCESS;
|
||||||
|
|
||||||
@@ -252,8 +295,111 @@ DWORD LoadConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
|
|||||||
|
|
||||||
if (bGroups)
|
if (bGroups)
|
||||||
{
|
{
|
||||||
// TODO: this is unbearable
|
DWORD dwBufferSize = sizeof(dwSettingsMask);
|
||||||
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
DWORD dwType = REG_BINARY;
|
||||||
|
UINT cGroupVals = 0;
|
||||||
|
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Loading groups...\n"));
|
||||||
|
|
||||||
|
// Get the num of group values, if we fail then ABORT!
|
||||||
|
if (!(RegQueryInfoKey(hKeyProgramGroups, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, &cGroupVals,
|
||||||
|
NULL, NULL, NULL, NULL) == ERROR_SUCCESS))
|
||||||
|
{
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_SETTINGS;
|
||||||
|
|
||||||
|
// I can get away with returning here upon
|
||||||
|
// failure since this is the last one
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Failed to get # of values!\n"));
|
||||||
|
return dwConfigStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enumerate through the registry values
|
||||||
|
if (cGroupVals)
|
||||||
|
{
|
||||||
|
DWORD i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < cGroupVals; i++)
|
||||||
|
{
|
||||||
|
WCHAR szGroupValName[MAX_TITLE_LENGTH] = TEXT("");
|
||||||
|
UINT cbGroupValName = ARRAYSIZE(szGroupValName);
|
||||||
|
UINT cbGroup = 0;
|
||||||
|
PGROUP pGroup = NULL;
|
||||||
|
LSTATUS error = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// TODO: figure out where i'm really going to store the
|
||||||
|
// group name, if not in the group structure then in
|
||||||
|
// the name of the registry key (val 3 here)
|
||||||
|
|
||||||
|
// get the size of the group
|
||||||
|
error = RegEnumValue(hKeyProgramGroups, i, (LPWSTR)&szGroupValName,
|
||||||
|
&cbGroupValName, NULL, NULL, NULL, &cbGroup);
|
||||||
|
|
||||||
|
if (error == ERROR_NO_MORE_ITEMS)
|
||||||
|
break;
|
||||||
|
else if (error != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: RegEnumValue failure.\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// allocate memory for the group
|
||||||
|
pGroup = malloc(cbGroup);
|
||||||
|
|
||||||
|
if (pGroup == NULL)
|
||||||
|
{
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
||||||
|
return dwConfigStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve the group
|
||||||
|
error = RegGetValue(hKeyProgramGroups, NULL, szGroupValName, RRF_RT_REG_BINARY, NULL, pGroup, &cbGroup);
|
||||||
|
|
||||||
|
if (error == ERROR_FILE_NOT_FOUND)
|
||||||
|
{
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Group not found!\n"));
|
||||||
|
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
||||||
|
}
|
||||||
|
if (error == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Buffer too small!\n"));
|
||||||
|
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
||||||
|
}
|
||||||
|
else if (error != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Group retrieval failed!\n"));
|
||||||
|
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Group retrieved.\n"));
|
||||||
|
|
||||||
|
// create the group
|
||||||
|
if (pGroup)
|
||||||
|
{
|
||||||
|
if (pGroup->dwSignature == GRP_SIGNATURE)
|
||||||
|
{
|
||||||
|
CreateGroup(pGroup);
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Group created.\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Group creation aborted.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// free memory
|
||||||
|
free(pGroup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
|
||||||
|
OutputDebugString(TEXT("REGISTRY.C: Failed to create group!\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dwConfigStatus;
|
return dwConfigStatus;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
REGISTRY.H -
|
REGISTRY.H -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's header file for registry related functions.
|
Program Manager's header file for registry related functions.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -10,16 +10,13 @@
|
|||||||
/* Pragmas */
|
/* Pragmas */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* Includes */
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
/* Defines */
|
/* Defines */
|
||||||
#define HKEYMAXLEN 261
|
#define HKEYMAXLEN 261
|
||||||
// Key Paths
|
// Key Paths
|
||||||
#define WINLOGON_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
|
#define WINLOGON_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
|
||||||
// #define PROGMAN_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager"
|
// #define PROGMAN_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager")
|
||||||
// #define WINDOWS_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
|
// #define WINDOWS_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows")
|
||||||
#define PROGMGR_KEY L"Software\\Vortesys\\Program Manager II"
|
#define PROGMGR_KEY TEXT("Software\\Vortesys\\Program Manager II")
|
||||||
// Registry configuration error values (DWORD)
|
// Registry configuration error values (DWORD)
|
||||||
#define RCE_SUCCESS 0x0000000
|
#define RCE_SUCCESS 0x0000000
|
||||||
#define RCE_FAILURE 0x0000001
|
#define RCE_FAILURE 0x0000001
|
||||||
@@ -50,8 +47,10 @@ extern RECT rcMainWindow;
|
|||||||
BOOL InitializeRegistryKeys(VOID);
|
BOOL InitializeRegistryKeys(VOID);
|
||||||
BOOL IsProgMgrDefaultShell(VOID);
|
BOOL IsProgMgrDefaultShell(VOID);
|
||||||
// Groups
|
// Groups
|
||||||
DWORD SaveGroupToRegistry(_In_ PGROUP pg);
|
DWORD RegistrySaveGroup(_In_ PGROUP pg);
|
||||||
DWORD LoadGroupFromRegistry(_Inout_ PGROUP pg, _Out_ DWORD dwBufferSize);
|
DWORD RegistryRemoveGroup(_In_ PGROUP pg);
|
||||||
// Settings
|
// Settings
|
||||||
DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups);
|
DWORD SaveConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups, _In_ BOOL bExit);
|
||||||
DWORD LoadConfig(BOOL bSettings, BOOL bPos, BOOL bGroups);
|
DWORD LoadConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups);
|
||||||
|
// Miscellaneous
|
||||||
|
BOOL CALLBACK SaveWindowEnumProc(HWND hWndGroup, LPARAM lParam);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
RESOURCE.RC -
|
RESOURCE.RC -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
This file contains Program Manager's resources.
|
This file contains Program Manager's resources.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/* Necessary Evil */
|
/* Necessary Evil */
|
||||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||||
#include <afxres.h>
|
#include <windows.h>
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||||
|
|
||||||
@@ -21,16 +21,22 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||||||
|
|
||||||
/* Icon Library */
|
/* Icon Library */
|
||||||
// Primary
|
// Primary
|
||||||
|
#ifndef _DEBUG
|
||||||
IDI_PROGMGR ICON icons\progmgr.ico
|
IDI_PROGMGR ICON icons\progmgr.ico
|
||||||
|
#else
|
||||||
|
IDI_PROGMGR ICON icons\progmgrd.ico
|
||||||
|
#endif
|
||||||
IDI_PROGGRP ICON icons\pmgroup.ico
|
IDI_PROGGRP ICON icons\pmgroup.ico
|
||||||
IDI_PROGITM ICON icons\pmitem.ico
|
IDI_PROGITM ICON icons\pmitem.ico
|
||||||
|
IDI_COMMON ICON icons\common.ico
|
||||||
|
IDI_PERSONAL ICON icons\personal.ico
|
||||||
// Secondary
|
// Secondary
|
||||||
IDI_COMMS ICON icons\comms.ico
|
// IDI_COMMS ICON icons\comms.ico
|
||||||
IDI_CONSOLE ICON icons\console.ico
|
// IDI_CONSOLE ICON icons\console.ico
|
||||||
IDI_DOCUMENT ICON icons\document.ico
|
// IDI_DOCUMENT ICON icons\document.ico
|
||||||
IDI_SPREADSHEET ICON icons\spsheet.ico
|
// IDI_SPREADSHEET ICON icons\spsheet.ico
|
||||||
// Tertiary
|
// Tertiary
|
||||||
IDI_SUPERMAN ICON icons\misc\superman.ico
|
// IDI_SUPERMAN ICON icons\misc\superman.ico
|
||||||
|
|
||||||
/* Manifest */
|
/* Manifest */
|
||||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "progmgr.exe.manifest"
|
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "progmgr.exe.manifest"
|
||||||
@@ -39,6 +45,13 @@ CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "progmgr.exe.manifest"
|
|||||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||||
#include "version.inc"
|
#include "version.inc"
|
||||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||||
|
|
||||||
|
// NOTE(u130b8): Example of using PROGMGR_GIT_HASH in the resource file
|
||||||
|
#ifdef PROGMGR_GIT_HASH
|
||||||
|
#undef VER_PRODUCTVERSION_STR
|
||||||
|
#define VER_PRODUCTVERSION_STR "git-" PROGMGR_GIT_HASH
|
||||||
|
#endif
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION VER_FILEVERSION
|
FILEVERSION VER_FILEVERSION
|
||||||
PRODUCTVERSION VER_PRODUCTVERSION
|
PRODUCTVERSION VER_PRODUCTVERSION
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
SYSINT.C -
|
SYSINT.C -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's system interface functions.
|
Program Manager's system export functions.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
MIT License, see LICENSE.txt in the root folder
|
MIT License, see LICENSE.txt in the root folder
|
||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
#include "progmgr.h"
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include "progmgr.h"
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ BOOL RunFileDlg(HWND hWndOwner,
|
|||||||
LPWSTR lpszDesc,
|
LPWSTR lpszDesc,
|
||||||
DWORD dwFlags)
|
DWORD dwFlags)
|
||||||
{
|
{
|
||||||
HMODULE hLib = LoadLibrary(L"shell32.dll");
|
HMODULE hLib = LoadLibrary(TEXT("shell32.dll"));
|
||||||
|
|
||||||
if (hLib)
|
if (hLib)
|
||||||
{
|
{
|
||||||
@@ -50,7 +50,7 @@ BOOL RunFileDlg(HWND hWndOwner,
|
|||||||
\* * * */
|
\* * * */
|
||||||
BOOL ExitWindowsDialog(HWND hWndOwner)
|
BOOL ExitWindowsDialog(HWND hWndOwner)
|
||||||
{
|
{
|
||||||
HMODULE hLib = LoadLibrary(L"shell32.dll");
|
HMODULE hLib = LoadLibrary(TEXT("shell32.dll"));
|
||||||
|
|
||||||
if (hLib)
|
if (hLib)
|
||||||
{
|
{
|
||||||
@@ -73,7 +73,7 @@ BOOL ExitWindowsDialog(HWND hWndOwner)
|
|||||||
\* * * */
|
\* * * */
|
||||||
BOOL SetShellWindow(HWND hWndShell)
|
BOOL SetShellWindow(HWND hWndShell)
|
||||||
{
|
{
|
||||||
HMODULE hLib = GetModuleHandle(L"user32.dll");
|
HMODULE hLib = GetModuleHandle(TEXT("user32.dll"));
|
||||||
|
|
||||||
if (hLib)
|
if (hLib)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* * * * * * * *\
|
/* * * * * * * *\
|
||||||
WNDPROC.C -
|
WNDPROC.C -
|
||||||
Copyright (c) 2023 freedom7341, Vortesys
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
DESCRIPTION -
|
DESCRIPTION -
|
||||||
Program Manager's window procedure.
|
Program Manager's window procedure.
|
||||||
LICENSE INFORMATION -
|
LICENSE INFORMATION -
|
||||||
@@ -8,17 +8,19 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#define SECURITY_WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <Lmcons.h>
|
||||||
|
#include <security.h>
|
||||||
|
#include <Mmsystem.h>
|
||||||
#include "progmgr.h"
|
#include "progmgr.h"
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#define SECURITY_WIN32
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <strsafe.h>
|
|
||||||
#include <Lmcons.h>
|
|
||||||
#include <security.h>
|
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
@@ -35,7 +37,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
{
|
{
|
||||||
break;
|
// Play the logon sound. (But only if we're the default shell)
|
||||||
|
if (g_bIsDefaultShell)
|
||||||
|
PlaySound(TEXT("WindowsLogon"), NULL, SND_ALIAS | SND_ASYNC);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_SYSCOMMAND:
|
case WM_SYSCOMMAND:
|
||||||
@@ -44,7 +50,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
if (wParam == IDM_TASKMGR)
|
if (wParam == IDM_TASKMGR)
|
||||||
{
|
{
|
||||||
ShellExecute(hWndProgMgr, L"open", L"TASKMGR.EXE", NULL, NULL, SW_NORMAL);
|
ShellExecute(g_hWndProgMgr, TEXT("open"), TEXT("TASKMGR.EXE"), NULL, NULL, SW_NORMAL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,31 +58,27 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto WndProcDefault;
|
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
if (CmdProc(hWnd, wParam, lParam))
|
if (CmdProc(hWnd, wParam, lParam))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
goto WndProcDefault;
|
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
||||||
|
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
|
case WM_ENDSESSION:
|
||||||
if (bSaveSettings)
|
if (bSaveSettings)
|
||||||
SaveConfig(TRUE, TRUE, TRUE);
|
SaveConfig(TRUE, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
if (bIsDefaultShell && (GetShellWindow() != NULL))
|
if (g_bIsDefaultShell && (GetShellWindow() != NULL))
|
||||||
SetShellWindow(0);
|
SetShellWindow(0);
|
||||||
|
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_ENDSESSION:
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WndProcDefault:
|
|
||||||
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -95,15 +97,23 @@ LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
|
|
||||||
case IDM_SHUTDOWN:
|
case IDM_SHUTDOWN:
|
||||||
ExitWindowsDialog(hWnd);
|
DialogBox(g_hAppInstance, MAKEINTRESOURCE(DLG_POWER), hWnd, (DLGPROC)ShutdownDlgProc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_FILE_NEW_GROUP:
|
case IDM_FILE_NEW_GROUP:
|
||||||
DialogBox(hAppInstance, MAKEINTRESOURCE(DLG_GROUP), hWnd, (DLGPROC)NewGroupDlgProc);
|
DialogBox(g_hAppInstance, MAKEINTRESOURCE(DLG_GROUP), hWnd, (DLGPROC)NewGroupDlgProc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_FILE_NEW_ITEM:
|
case IDM_FILE_NEW_ITEM:
|
||||||
DialogBox(hAppInstance, MAKEINTRESOURCE(DLG_ITEM), hWnd, (DLGPROC)NewItemDlgProc);
|
DialogBox(g_hAppInstance, MAKEINTRESOURCE(DLG_ITEM), hWnd, (DLGPROC)NewItemDlgProc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_FILE_OPEN:
|
||||||
|
case IDM_FILE_MOVE:
|
||||||
|
case IDM_FILE_COPY:
|
||||||
|
case IDM_FILE_DELETE:
|
||||||
|
case IDM_FILE_PROPS:
|
||||||
|
SendMessage((HWND)SendMessage(hWnd, WM_MDIGETACTIVE, (WPARAM)NULL, (LPARAM)NULL), WM_COMMAND, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_FILE_RUN:
|
case IDM_FILE_RUN:
|
||||||
@@ -126,7 +136,7 @@ LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
case IDM_OPTIONS_TOPMOST:
|
case IDM_OPTIONS_TOPMOST:
|
||||||
bTopMost = !bTopMost;
|
bTopMost = !bTopMost;
|
||||||
SetWindowPos(hWndProgMgr, bTopMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
SetWindowPos(g_hWndProgMgr, bTopMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
UpdateChecks(bTopMost, IDM_OPTIONS, IDM_OPTIONS_TOPMOST);
|
UpdateChecks(bTopMost, IDM_OPTIONS, IDM_OPTIONS_TOPMOST);
|
||||||
goto SaveConfig;
|
goto SaveConfig;
|
||||||
|
|
||||||
@@ -143,23 +153,51 @@ LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
case IDM_OPTIONS_SAVENOW:
|
case IDM_OPTIONS_SAVENOW:
|
||||||
SaveConfig:
|
SaveConfig:
|
||||||
SaveConfig(TRUE, TRUE, TRUE);
|
SaveConfig(TRUE, TRUE, TRUE, FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_WINDOW_CASCADE:
|
||||||
|
SendMessage(hWndMDIClient, WM_MDICASCADE, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_WINDOW_TILE:
|
||||||
|
SendMessage(hWndMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_WINDOW_TILEHORIZONTALLY:
|
||||||
|
SendMessage(hWndMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_WINDOW_ARRANGEICONS:
|
||||||
|
SendMessage(hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_HELP_INDEX:
|
case IDM_HELP_INDEX:
|
||||||
ShellExecute(NULL, L"open", szWebsite, NULL, NULL, SW_SHOWNORMAL);
|
ShellExecute(NULL, TEXT("open"), g_szWebsite, NULL, NULL, SW_SHOWNORMAL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_HELP_ABOUT:
|
case IDM_HELP_ABOUT:
|
||||||
{
|
{
|
||||||
WCHAR szTitle[40];
|
WCHAR szTitle[40];
|
||||||
|
|
||||||
LoadString(hAppInstance, IDS_APPTITLE, szTitle, ARRAYSIZE(szTitle));
|
LoadString(g_hAppInstance, IDS_APPTITLE, szTitle, ARRAYSIZE(szTitle));
|
||||||
ShellAbout(hWndProgMgr, szTitle, NULL, hProgMgrIcon);
|
ShellAbout(g_hWndProgMgr, szTitle, NULL, g_hProgMgrIcon);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (GET_WM_COMMAND_ID(wParam, lParam) >= IDM_WINDOW_CHILDSTART)
|
||||||
|
{
|
||||||
|
DefFrameProc(hWnd, hWndMDIClient, 0, wParam, lParam);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HWND hChild = (HWND)SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, 0);
|
||||||
|
if (hChild)
|
||||||
|
{
|
||||||
|
SendMessage(hChild, WM_COMMAND, wParam, lParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +214,7 @@ VOID UpdateChecks(BOOL bVarMenu, UINT uSubMenu, UINT uID)
|
|||||||
{
|
{
|
||||||
HMENU hMenu;
|
HMENU hMenu;
|
||||||
|
|
||||||
hMenu = GetMenu(hWndProgMgr);
|
hMenu = GetMenu(g_hWndProgMgr);
|
||||||
CheckMenuItem(hMenu, uID, (WORD)(bVarMenu ? MF_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hMenu, uID, (WORD)(bVarMenu ? MF_CHECKED : MF_UNCHECKED));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -189,36 +227,25 @@ VOID UpdateChecks(BOOL bVarMenu, UINT uSubMenu, UINT uID)
|
|||||||
RETURNS -
|
RETURNS -
|
||||||
Nothing!
|
Nothing!
|
||||||
\* * * */
|
\* * * */
|
||||||
VOID UpdateWindowTitle()
|
VOID UpdateWindowTitle(VOID)
|
||||||
{
|
{
|
||||||
WCHAR szUsername[UNLEN + 1] = L"";
|
WCHAR szUsername[UNLEN] = TEXT("");
|
||||||
DWORD dwUsernameLen = UNLEN;
|
DWORD dwUsernameLen = UNLEN;
|
||||||
WCHAR szWindowTitle[UNLEN + ARRAYSIZE(szAppTitle) + 4] = L"";
|
WCHAR szWindowTitle[UNLEN + ARRAYSIZE(g_szAppTitle) + 4] = TEXT("");
|
||||||
|
|
||||||
// Get user and domain name
|
// Get user and domain name
|
||||||
GetUserNameEx(NameSamCompatible, szUsername, &dwUsernameLen);
|
GetUserNameEx(NameSamCompatible, szUsername, &dwUsernameLen);
|
||||||
|
|
||||||
// Add username to window title if settings permit
|
// Add username to window title if settings permit
|
||||||
StringCchCopy(szWindowTitle, ARRAYSIZE(szAppTitle), szAppTitle);
|
StringCchCopy(szWindowTitle, ARRAYSIZE(g_szAppTitle), g_szAppTitle);
|
||||||
|
|
||||||
if (bShowUsername)
|
if (bShowUsername)
|
||||||
{
|
{
|
||||||
StringCchCat(szWindowTitle, ARRAYSIZE(szWindowTitle), L" - ");
|
StringCchCat(szWindowTitle, ARRAYSIZE(szWindowTitle), TEXT(" - "));
|
||||||
StringCchCat(szWindowTitle, ARRAYSIZE(szWindowTitle), szUsername);
|
StringCchCat(szWindowTitle, ARRAYSIZE(szWindowTitle), szUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetWindowText(hWndProgMgr, (LPCWSTR)&szWindowTitle);
|
SetWindowText(g_hWndProgMgr, (LPCWSTR)&szWindowTitle);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
|
||||||
ChildWndProc -
|
|
||||||
Program Manager's window procedure.
|
|
||||||
RETURNS -
|
|
||||||
Zero if nothing, otherwise returns the good stuff.
|
|
||||||
\* * * */
|
|
||||||
LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|||||||