Compare commits
224 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 | ||
|
|
2972d54777 | ||
|
|
6aaabd480a | ||
|
|
e400645956 | ||
|
|
77512dd72d | ||
|
|
8fb871de34 | ||
|
|
d41f0b868b | ||
|
|
b9cea5b8e6 | ||
|
|
745030da99 | ||
|
|
739c56e314 | ||
|
|
78f612e684 | ||
|
|
1bb6e0b05a | ||
|
|
541c86b4a2 | ||
|
|
f632229b3c | ||
|
|
488070e73d | ||
|
|
f8578360f8 | ||
|
|
a4f7046760 | ||
|
|
364afc7438 | ||
|
|
bbde0b6acb | ||
|
|
3441f7771a | ||
|
|
6302272d96 | ||
|
|
7409d6cc41 | ||
|
|
db71fb2ab3 | ||
|
|
84c62213d7 | ||
|
|
437703e26d | ||
|
|
fbdb45b4df | ||
|
|
ba276117d7 | ||
|
|
35a28f698f | ||
|
|
bf2c7ce3da | ||
|
|
4095f501c1 | ||
|
|
2632512881 | ||
|
|
af3e493085 | ||
|
|
d875363d72 |
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
|
||||||
13
.gitignore
vendored
@@ -44,16 +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
|
||||||
|
*.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.
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
7z a -r "%~dp0bin\bin.7z" "%~dp0bin\*.exe"
|
|
||||||
WinRAR a -r "%~dp0bin\bin.rar" "%~dp0bin\*.exe"
|
|
||||||
del /s "%~dp0bin\*.exe"
|
|
||||||
pause
|
|
||||||
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: 20 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;
|
|
||||||
}
|
|
||||||
492
progmgr/dialog.c
Normal file
@@ -0,0 +1,492 @@
|
|||||||
|
/* * * * * * * *\
|
||||||
|
DIALOG.C -
|
||||||
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
|
DESCRIPTION -
|
||||||
|
Program Manager's dialogs and related
|
||||||
|
common functions.
|
||||||
|
LICENSE INFORMATION -
|
||||||
|
MIT License, see LICENSE.txt in the root folder
|
||||||
|
\* * * * * * * */
|
||||||
|
|
||||||
|
/* 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 "dialog.h"
|
||||||
|
#include "group.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
/* Variables */
|
||||||
|
WCHAR szDlgTitle[64];
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
NewGroupDlgProc -
|
||||||
|
Dialog procedure for creating a group.
|
||||||
|
RETURNS -
|
||||||
|
TRUE if message is handled, FALSE otherwise.
|
||||||
|
\* * * */
|
||||||
|
BOOL CALLBACK NewGroupDlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
static GROUP grp = { 0 };
|
||||||
|
BOOL bOKEnabled = FALSE;
|
||||||
|
WCHAR szBuffer[MAX_TITLE_LENGTH] = { TEXT("\0") };
|
||||||
|
HICON hIconDef = NULL;
|
||||||
|
HICON hIconDlg = NULL;
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
// TODO:
|
||||||
|
// Enable creation of common groups (enable the controls)
|
||||||
|
// if permissions are available.
|
||||||
|
// TODO:
|
||||||
|
// 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.
|
||||||
|
GetModuleFileName(g_hAppInstance, (LPWSTR)&grp.szIconPath, ARRAYSIZE(grp.szIconPath));
|
||||||
|
grp.iIconIndex = IDI_PROGGRP - 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)&grp.szIconPath, grp.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);
|
||||||
|
|
||||||
|
// Disable the OK button since we're starting with no text in the box.
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
|
||||||
|
// Enable the common group checkbox if perms are good
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_COMMGROUP), g_bPermAdmin);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
|
||||||
|
if (HIWORD(wParam) == EN_CHANGE)
|
||||||
|
{
|
||||||
|
if (LOWORD(wParam) == IDD_NAME)
|
||||||
|
{
|
||||||
|
// Name text control changed. See what's up...
|
||||||
|
bOKEnabled = GetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)&szBuffer, ARRAYSIZE(szBuffer));
|
||||||
|
|
||||||
|
// Enable or disable the OK button based on the information
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
{
|
||||||
|
|
||||||
|
case IDD_CHICON:
|
||||||
|
if (PickIconDlg(hWndDlg, (LPWSTR)&grp.szIconPath, ARRAYSIZE(grp.szIconPath), &grp.iIconIndex) == TRUE)
|
||||||
|
{
|
||||||
|
// Since we've got the new icon...
|
||||||
|
hIconDlg = ExtractIcon(g_hAppInstance, (LPWSTR)&grp.szIconPath, grp.iIconIndex);
|
||||||
|
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// Enable or disable the OK button based on the information
|
||||||
|
EnableWindow(GetDlgItem(hWndDlg, IDD_OK), bOKEnabled);
|
||||||
|
|
||||||
|
if (bOKEnabled)
|
||||||
|
{
|
||||||
|
// Set the name of the group
|
||||||
|
StringCchCopy(grp.szName, ARRAYSIZE(szBuffer), szBuffer);
|
||||||
|
|
||||||
|
// Set the flags of the group
|
||||||
|
if (SendDlgItemMessage(hWndDlg, IDD_COMMGROUP, BM_GETCHECK, 0, 0) != BST_UNCHECKED)
|
||||||
|
grp.dwFlags = grp.dwFlags || GRP_FLAG_COMMON;
|
||||||
|
|
||||||
|
// Set FILETIME
|
||||||
|
GetSystemTimeAsFileTime(&grp.ftLastWrite);
|
||||||
|
|
||||||
|
// Set the rectangle of the group to be CW_USEDEFAULT
|
||||||
|
grp.rcGroup.left = grp.rcGroup.top = grp.rcGroup.right = grp.rcGroup.bottom = CW_USEDEFAULT;
|
||||||
|
|
||||||
|
// Group's ready!
|
||||||
|
if (CreateGroup(&grp) != NULL)
|
||||||
|
{
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure!
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDD_CANCEL:
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Cleanup
|
||||||
|
if (hIconDef)
|
||||||
|
DestroyIcon(hIconDef);
|
||||||
|
if (hIconDlg)
|
||||||
|
DestroyIcon(hIconDlg);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
NewItemDlgProc -
|
||||||
|
Dialog procedure for creating or modifying
|
||||||
|
an item.
|
||||||
|
RETURNS -
|
||||||
|
TRUE if message is handled, FALSE otherwise.
|
||||||
|
\* * * */
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
|
||||||
|
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:
|
||||||
|
EndDialog(hWndDlg, FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Cleanup
|
||||||
|
if (hIconDef)
|
||||||
|
DestroyIcon(hIconDef);
|
||||||
|
if (hIconDlg)
|
||||||
|
DestroyIcon(hIconDlg);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
17
progmgr/dialog.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* * * * * * * *\
|
||||||
|
DIALOG.H -
|
||||||
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
|
DESCRIPTION -
|
||||||
|
Dialog function prototypes and related
|
||||||
|
common dialog functions.
|
||||||
|
LICENSE INFORMATION -
|
||||||
|
MIT License, see LICENSE.txt in the root folder
|
||||||
|
\* * * * * * * */
|
||||||
|
|
||||||
|
/* Pragmas */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Function Prototypes */
|
||||||
|
BOOL CALLBACK NewGroupDlgProc(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);
|
||||||
742
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,18 +8,564 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* 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>
|
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
WNDCLASSEX wcGrp;
|
WNDCLASSEX wcGrp;
|
||||||
|
WCHAR szGrpClass[16];
|
||||||
|
HWND hWndMDIClient = NULL;
|
||||||
|
HWND hWndFoundGroup = NULL;
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
InitializeGroups -
|
||||||
|
Create the MDI Client window and initialize
|
||||||
|
the group window class.
|
||||||
|
RETURNS -
|
||||||
|
TRUE if groups are successfully created.
|
||||||
|
FALSE if otherwise.
|
||||||
|
\* * * */
|
||||||
|
BOOL InitializeGroups(VOID)
|
||||||
|
{
|
||||||
|
CLIENTCREATESTRUCT ccs = { 0 };
|
||||||
|
WNDCLASSEX wce = { 0 };
|
||||||
|
RECT rcFrame;
|
||||||
|
|
||||||
|
// Create the MDI Client Window
|
||||||
|
ccs.hWindowMenu = GetSubMenu(GetMenu(g_hWndProgMgr), 2);
|
||||||
|
ccs.idFirstChild = IDM_WINDOW_CHILDSTART;
|
||||||
|
|
||||||
|
GetClientRect(g_hWndProgMgr, &rcFrame);
|
||||||
|
|
||||||
|
if ((hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED,
|
||||||
|
TEXT("MDIClient"), NULL, WS_CLIPCHILDREN | WS_CHILD |
|
||||||
|
WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
|
||||||
|
rcFrame.left, rcFrame.top, rcFrame.right, rcFrame.bottom,
|
||||||
|
g_hWndProgMgr, (HMENU)1, g_hAppInstance, (LPWSTR)&ccs)) == NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the group class string
|
||||||
|
LoadString(g_hAppInstance, IDS_GRPCLASS,
|
||||||
|
szGrpClass, ARRAYSIZE(szGrpClass));
|
||||||
|
|
||||||
|
// Register the group window class
|
||||||
|
wce.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wce.style = CS_DBLCLKS;
|
||||||
|
wce.lpfnWndProc = GroupWndProc;
|
||||||
|
wce.cbClsExtra = 0;
|
||||||
|
wce.cbWndExtra = 0;
|
||||||
|
wce.hInstance = g_hAppInstance;
|
||||||
|
wce.hIcon = g_hGroupIcon = LoadImage(g_hAppInstance,
|
||||||
|
MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON,
|
||||||
|
0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
||||||
|
wce.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||||
|
wce.lpszMenuName = NULL;
|
||||||
|
wce.lpszClassName = szGrpClass;
|
||||||
|
|
||||||
|
if (!RegisterClassEx(&wce))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Now we can create the groups
|
||||||
|
if(LoadConfig(FALSE, FALSE, TRUE) != RCE_SUCCESS)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// TODO: if loading groups fails, throw an error
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
CreateGroup -
|
||||||
|
Create an MDI window from a group structure
|
||||||
|
RETURNS -
|
||||||
|
Handle to the new group window
|
||||||
|
or NULL on failure
|
||||||
|
\* * * */
|
||||||
|
HWND CreateGroup(_In_ PGROUP pg)
|
||||||
|
{
|
||||||
|
MDICREATESTRUCT mcs = { NULL };
|
||||||
|
PGROUP pGroup = NULL;
|
||||||
|
HICON hIconLarge = NULL;
|
||||||
|
HICON hIconSmall = NULL;
|
||||||
|
HICON hIconTemp = NULL;
|
||||||
|
HWND hWndGroup = NULL;
|
||||||
|
HIMAGELIST hImageList = NULL;
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
RECT rcGroupWindow = { 0 };
|
||||||
|
LVCOLUMN lvc = { 0 };
|
||||||
|
|
||||||
|
if (pg == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// error checking, if we get trash don't try to
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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.szTitle = pg->szName;
|
||||||
|
mcs.hOwner = g_hAppInstance;
|
||||||
|
if ((pg->rcGroup.left == CW_USEDEFAULT) & (pg->rcGroup.right == CW_USEDEFAULT))
|
||||||
|
{
|
||||||
|
mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
// or is it better and easier to just do it with GWLP_USERDATA?
|
||||||
|
mcs.lParam = (LPARAM)NULL;
|
||||||
|
|
||||||
|
if ((hWndGroup = (HWND)SendMessage(hWndMDIClient, WM_MDICREATE, 0,
|
||||||
|
(LPARAM)(LPTSTR)&mcs)) == 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
|
||||||
|
if (ExtractIconEx(pg->szIconPath, pg->iIconIndex, &hIconLarge, &hIconSmall, 1))
|
||||||
|
{
|
||||||
|
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!
|
||||||
|
// AND IMAGE LIST!!!!!!!!? i think it's nuked w/ listview though
|
||||||
|
return hWndGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
RemoveGroup -
|
||||||
|
Removes and cleans up a group window
|
||||||
|
RETURNS -
|
||||||
|
TRUE if cleanup is successful,
|
||||||
|
FALSE otherwise.
|
||||||
|
\* * * */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
ExecuteItem -
|
||||||
|
Runs a program item
|
||||||
|
RETURNS -
|
||||||
|
TRUE if item was successfully ran
|
||||||
|
FALSE otherwise
|
||||||
|
\* * * */
|
||||||
|
BOOL ExecuteItem(_In_ PITEM pi)
|
||||||
|
{
|
||||||
|
// TODO: nCmdShow from program item flags
|
||||||
|
ShellExecute(g_hWndProgMgr, TEXT("open"),
|
||||||
|
pi->szExecPath, NULL,
|
||||||
|
(pi->szWorkPath != TEXT("")) ? pi->szWorkPath : NULL,
|
||||||
|
SW_NORMAL);
|
||||||
|
|
||||||
|
// TODO: if item has run as admin as a flag,
|
||||||
|
// run it as an admin
|
||||||
|
|
||||||
|
// TODO: if path is invalid or other error then tell the user
|
||||||
|
|
||||||
|
// TODO: make sure environment is
|
||||||
|
// refreshed before execution
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
UpdateGroup -
|
||||||
|
Updates group information to prepare
|
||||||
|
it for being saved.
|
||||||
|
ABSTRACT -
|
||||||
|
This function will update all of the
|
||||||
|
relevant structures in a group struct
|
||||||
|
in preparation for saving the group.
|
||||||
|
RETURNS -
|
||||||
|
Nothing.
|
||||||
|
\* * * */
|
||||||
|
VOID UpdateGroup(_In_ PGROUP pg)
|
||||||
|
{
|
||||||
|
DWORD dwFlags = 0;
|
||||||
|
HWND hWndGroup = NULL;
|
||||||
|
|
||||||
|
// Set the important flags
|
||||||
|
pg->dwSignature = GRP_SIGNATURE;
|
||||||
|
pg->wVersion = GRP_VERSION;
|
||||||
|
|
||||||
|
// Set the group checksum
|
||||||
|
pg->wChecksum = 1; // NOTE: implement this for real later lol
|
||||||
|
|
||||||
|
// TODO: group flags
|
||||||
|
// pg->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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
GetHwndFromPGroup -
|
||||||
|
In goes a PGROUP out comes a HWND
|
||||||
|
RETURNS -
|
||||||
|
HWND.
|
||||||
|
\* * * */
|
||||||
|
HWND GetHwndFromPGroup(_In_ PGROUP pg)
|
||||||
|
{
|
||||||
|
EnumChildWindows(g_hWndProgMgr, (WNDENUMPROC)GetHwndFromPGroupEnum, (LPARAM)pg);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
GroupWndProc -
|
GroupWndProc -
|
||||||
Group window procedure.
|
Group window procedure.
|
||||||
@@ -28,49 +574,181 @@ WNDCLASSEX wcGrp;
|
|||||||
\* * * */
|
\* * * */
|
||||||
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:
|
||||||
|
{
|
||||||
|
CREATESTRUCT* pCreateStruct;
|
||||||
|
MDICREATESTRUCT* pMDICreateStruct;
|
||||||
|
|
||||||
|
// code borrowed from winprog
|
||||||
|
pCreateStruct = (CREATESTRUCT*)lParam;
|
||||||
|
pMDICreateStruct = (MDICREATESTRUCT*)pCreateStruct->lpCreateParams;
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// GroupProcDefault:
|
break;
|
||||||
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
}
|
||||||
|
return DefMDIChildProc(hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
InitGroups -
|
GroupCmdProc -
|
||||||
Initialize variables for the betterment of groups forever
|
Group syscommand procedure.
|
||||||
Make great glorious MDI Client
|
|
||||||
RETURNS -
|
RETURNS -
|
||||||
Zero if nothing, otherwise returns the good stuff.
|
Zero if nothing, otherwise returns the good stuff.
|
||||||
\* * * */
|
\* * * */
|
||||||
|
LRESULT CALLBACK GroupCmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||||
/* * * *\
|
|
||||||
TempCreateGroup -
|
|
||||||
th
|
|
||||||
RETURNS -
|
|
||||||
handle to window
|
|
||||||
\* * * */
|
|
||||||
HWND TempCreateGroup(HWND hMDIClient)
|
|
||||||
{
|
{
|
||||||
MDICREATESTRUCT mcs;
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
HWND hChild;
|
{
|
||||||
|
case IDM_FILE_OPEN:
|
||||||
|
{
|
||||||
|
HWND hWndListView = NULL;
|
||||||
|
LVITEM lvi = { 0 };
|
||||||
|
PITEM pItem = NULL;
|
||||||
|
|
||||||
mcs.szClass = szGrpClass;
|
// find the listview control
|
||||||
mcs.szTitle = L"";
|
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
|
||||||
mcs.hOwner = hAppInstance;
|
if (hWndListView == NULL)
|
||||||
mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT;
|
break;
|
||||||
mcs.style = WS_VISIBLE;
|
|
||||||
|
|
||||||
hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)(LPTSTR)&mcs);
|
// what info do we want?
|
||||||
// if (!hChild)
|
lvi.mask = LVIF_PARAM;
|
||||||
// {
|
lvi.iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
|
||||||
// MessageBox(hMDIClient, L"MDI Child creation failed.", L"Oh Oh...",
|
|
||||||
// MB_ICONEXCLAMATION | MB_OK);
|
// get the listview item
|
||||||
// }
|
ListView_GetItem(hWndListView, &lvi);
|
||||||
return hChild;
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 -
|
||||||
@@ -10,32 +10,39 @@
|
|||||||
/* Pragmas */
|
/* Pragmas */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* Includes */
|
|
||||||
#include <wtypes.h>
|
|
||||||
|
|
||||||
/* 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 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)
|
||||||
|
#define ITM_FLAG_HOTKEY 0x00000001
|
||||||
|
#define ITM_FLAG_PRIVILEGE 0x00000002
|
||||||
|
#define ITM_FLAG_MINIMIZED 0x00000004
|
||||||
|
#define ITM_FLAG_MAXIMIZED 0x00000008
|
||||||
|
|
||||||
/* Structures */
|
/* Structures */
|
||||||
// Item Structure
|
// Item Structure
|
||||||
typedef struct _ITEM {
|
typedef struct _ITEM {
|
||||||
// Item executable and name
|
// Item executable and name
|
||||||
WCHAR szItemName[MAX_TITLE_LENGTH];
|
WCHAR szName[MAX_TITLE_LENGTH];
|
||||||
WCHAR szExecPath[MAX_PATH]; // Path of the item executable
|
WCHAR szExecPath[MAX_PATH]; // Path of the executable
|
||||||
WCHAR szWorkPath[MAX_PATH]; // Working directory
|
WCHAR szWorkPath[MAX_PATH]; // Working directory
|
||||||
|
// Item flags
|
||||||
|
DWORD dwFlags; // Use with ITM_FLAG_* values.
|
||||||
|
UINT uiHotkeyModifiers;
|
||||||
|
UINT uiHotkeyVirtualKey;
|
||||||
// Icon
|
// Icon
|
||||||
WCHAR szIconPath[MAX_PATH]; // Path of the icon
|
WCHAR szIconPath[MAX_PATH];
|
||||||
UINT uiIconIndex; // Index of the icon
|
INT iIconIndex;
|
||||||
} ITEM, * PITEM;
|
} ITEM, * PITEM;
|
||||||
|
|
||||||
// Group format, .GRP
|
// Group format, .GRP
|
||||||
@@ -44,27 +51,43 @@ typedef struct _GROUP {
|
|||||||
DWORD dwSignature; // Set to GRP_SIGNATURE
|
DWORD dwSignature; // Set to GRP_SIGNATURE
|
||||||
WORD wVersion; // Group format version
|
WORD wVersion; // Group format version
|
||||||
WORD wChecksum;
|
WORD wChecksum;
|
||||||
|
|
||||||
// Group information
|
// Group information
|
||||||
WCHAR szGroupName[MAX_TITLE_LENGTH];
|
WCHAR szName[MAX_TITLE_LENGTH];
|
||||||
DWORD dwFlags; // Use with GRP_FLAG_* values.
|
DWORD dwFlags; // Use with GRP_FLAG_* values.
|
||||||
FILETIME ftLastWrite;
|
FILETIME ftLastWrite;
|
||||||
|
// Window information
|
||||||
|
RECT rcGroup;
|
||||||
|
WINDOWPLACEMENT wp;
|
||||||
|
// Icon
|
||||||
|
WCHAR szIconPath[MAX_PATH];
|
||||||
|
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
|
/* Global Variables */
|
||||||
typedef struct _GROUPWND {
|
extern HWND hWndMDIClient;
|
||||||
// Window information
|
|
||||||
HWND hWndGroup;
|
|
||||||
RECT rcGroup; // Window rectangle
|
|
||||||
|
|
||||||
// Group information
|
/* Local Variables */
|
||||||
HANDLE hGroup; // Handle to GROUP object
|
|
||||||
} GROUPINFO, * PGROUPINFO;
|
|
||||||
|
|
||||||
/* Function Prototypes */
|
/* Function Prototypes */
|
||||||
|
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
|
||||||
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
HWND TempCreateGroup(HWND hMDIClient);
|
LRESULT CALLBACK GroupCmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
|
|||||||
38
progmgr/grpupdat.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* * * * * * * *\
|
||||||
|
GRPUPDAT.H -
|
||||||
|
Copyright (c) 2024 Vortesys, Brady McDermott
|
||||||
|
DESCRIPTION -
|
||||||
|
Header containing classic program group structures
|
||||||
|
in order to facilitate conversion to the new format.
|
||||||
|
LICENSE INFORMATION -
|
||||||
|
MIT License, see LICENSE.txt in the root folder
|
||||||
|
\* * * * * * * */
|
||||||
|
|
||||||
|
/* Pragmas */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Includes */
|
||||||
|
#include <wtypes.h>
|
||||||
|
|
||||||
|
/* Definitions */
|
||||||
|
// Group signatures
|
||||||
|
#define OLDGRP_SIGNATURE 0x43554D50L // PMUC
|
||||||
|
|
||||||
|
/* Structures */
|
||||||
|
// Old group format, .GRP
|
||||||
|
typedef struct _OLDGROUP {
|
||||||
|
DWORD dwMagic; // Set to OLDGRP_SIGNATURE
|
||||||
|
WORD wCheckSum; // Seemingly unused
|
||||||
|
WORD cbGroup; // Size of group
|
||||||
|
RECT rcNormal; // Window rect
|
||||||
|
POINT ptMin; // Minimized window position
|
||||||
|
WORD nCmdShow; // Min/max state
|
||||||
|
WORD pName; // Group name
|
||||||
|
WORD cxIcon; // Icon width
|
||||||
|
WORD cyIcon; // Icon height
|
||||||
|
WORD wIconFormat;
|
||||||
|
WORD wReserved; // Unused
|
||||||
|
|
||||||
|
WORD cItems; // Number of items
|
||||||
|
WORD rgiItems[1]; // Array of item offsets
|
||||||
|
} OLDGROUP, * POLDGROUP;
|
||||||
|
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 |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 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 |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 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
|
||||||
// Window Related
|
BOOL g_bIsDebugBuild = TRUE;
|
||||||
HICON hProgMgrIcon = NULL;
|
#else
|
||||||
HICON hGroupIcon = NULL;
|
BOOL g_bIsDebugBuild = FALSE;
|
||||||
HINSTANCE hAppInstance;
|
#endif
|
||||||
HWND hWndProgMgr = NULL;
|
BOOL g_bIsDefaultShell = FALSE;
|
||||||
HWND hWndMDIClient = NULL;
|
// Handles
|
||||||
|
HINSTANCE g_hAppInstance;
|
||||||
|
HWND g_hWndProgMgr = NULL;
|
||||||
|
// Icons
|
||||||
|
HICON g_hProgMgrIcon = 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];
|
||||||
WCHAR szGrpClass[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,66 +69,61 @@ 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 };
|
||||||
WNDCLASSEX wce = { 0 };
|
|
||||||
WCHAR szBuffer[MAX_PATH];
|
WCHAR szBuffer[MAX_PATH];
|
||||||
RECT rcRoot;
|
RECT rcRoot;
|
||||||
POINT ptOffset;
|
POINT ptOffset = { 0 };
|
||||||
|
|
||||||
hAppInstance = hInstance;
|
// Grab the instance
|
||||||
|
g_hAppInstance = hInstance;
|
||||||
|
|
||||||
// Create Strings
|
// Create Strings
|
||||||
LoadString(hAppInstance, IDS_PMCLASS, szClass, ARRAYSIZE(szClass));
|
LoadString(g_hAppInstance, IDS_PMCLASS, g_szClass, ARRAYSIZE(g_szClass));
|
||||||
LoadString(hAppInstance, IDS_GRPCLASS, szGrpClass, ARRAYSIZE(szGrpClass));
|
LoadString(g_hAppInstance, IDS_APPTITLE, g_szAppTitle, ARRAYSIZE(g_szAppTitle));
|
||||||
LoadString(hAppInstance, IDS_APPTITLE, szAppTitle, ARRAYSIZE(szAppTitle));
|
LoadString(g_hAppInstance, IDS_WEBSITE, g_szWebsite, ARRAYSIZE(g_szWebsite));
|
||||||
LoadString(hAppInstance, IDS_WEBSITE, szWebsite, ARRAYSIZE(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;
|
||||||
|
|
||||||
// Register the Group Window Class
|
|
||||||
wce.cbSize = sizeof(WNDCLASSEX);
|
|
||||||
wce.lpfnWndProc = GroupWndProc;
|
|
||||||
wce.cbClsExtra = 0;
|
|
||||||
wce.cbWndExtra = 0;
|
|
||||||
wce.hInstance = hAppInstance;
|
|
||||||
wce.hIcon = hGroupIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON,
|
|
||||||
0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
|
||||||
wce.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
||||||
wce.lpszMenuName = NULL;
|
|
||||||
wce.lpszClassName = szGrpClass;
|
|
||||||
if (!RegisterClassEx(&wce))
|
|
||||||
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;
|
||||||
|
|
||||||
// Perform Registry actions, close if registry is inaccessible.
|
// Perform Registry actions, close if registry is inaccessible.
|
||||||
if (InitializeRegistryKeys())
|
if (!InitializeRegistryKeys())
|
||||||
{
|
return FALSE;
|
||||||
bIsDefaultShell = IsProgMgrDefaultShell();
|
|
||||||
LoadConfig();
|
g_bIsDefaultShell = IsProgMgrDefaultShell();
|
||||||
}
|
|
||||||
else
|
// Load configuration, but don't load groups yet
|
||||||
{
|
if(LoadConfig(TRUE, TRUE, FALSE) != RCE_SUCCESS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
// Get size of the root HWND
|
// Get size of the root HWND
|
||||||
GetWindowRect(GetDesktopWindow(), &rcRoot);
|
GetWindowRect(GetDesktopWindow(), &rcRoot);
|
||||||
@@ -113,23 +133,24 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
|||||||
SystemParametersInfo(SPI_ICONVERTICALSPACING, 0, &ptOffset.y, 0);
|
SystemParametersInfo(SPI_ICONVERTICALSPACING, 0, &ptOffset.y, 0);
|
||||||
|
|
||||||
// Create main window with a default size
|
// Create main window with a default size
|
||||||
// NOTE: i pulled 320x240 out of my ass, make this dynamic later
|
// TODO: i pulled 320x240 out of my ass, make this dynamic later
|
||||||
if (!CreateWindow(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);
|
||||||
@@ -142,31 +163,35 @@ 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...
|
||||||
// CreateDesktopWindow();
|
// CreateDesktopWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the frame window
|
||||||
|
if (!InitializeGroups())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -174,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,22 +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 */
|
||||||
// PROGMGR.C
|
extern BOOL g_bIsDefaultShell;
|
||||||
extern BOOL bIsDefaultShell;
|
// Handles
|
||||||
extern HICON hProgMgrIcon;
|
extern HINSTANCE g_hAppInstance;
|
||||||
extern HICON hGroupIcon;
|
extern HWND g_hWndProgMgr;
|
||||||
extern HINSTANCE hAppInstance;
|
// Icons
|
||||||
extern HWND hWndProgMgr;
|
extern HICON g_hProgMgrIcon;
|
||||||
extern HWND hWndMDIClient;
|
extern HICON g_hGroupIcon;
|
||||||
extern WCHAR szAppTitle[32];
|
// Strings
|
||||||
extern WCHAR szProgMgr[];
|
extern WCHAR g_szAppTitle[64];
|
||||||
extern WCHAR szWebsite[64];
|
extern WCHAR g_szProgMgr[];
|
||||||
extern WCHAR szClass[16];
|
extern WCHAR g_szWebsite[64];
|
||||||
extern WCHAR szGrpClass[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);
|
||||||
@@ -53,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>
|
||||||
@@ -159,13 +169,15 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="dialog.h" />
|
||||||
<ClInclude Include="group.h" />
|
<ClInclude Include="group.h" />
|
||||||
|
<ClInclude Include="grpupdat.h" />
|
||||||
<ClInclude Include="progmgr.h" />
|
<ClInclude Include="progmgr.h" />
|
||||||
<ClInclude Include="registry.h" />
|
<ClInclude Include="registry.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="desktop.c" />
|
<ClCompile Include="dialog.c" />
|
||||||
<ClCompile Include="progmgr.c" />
|
<ClCompile Include="progmgr.c" />
|
||||||
<ClCompile Include="registry.c" />
|
<ClCompile Include="registry.c" />
|
||||||
<ClCompile Include="group.c" />
|
<ClCompile Include="group.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">
|
||||||
@@ -30,6 +33,12 @@
|
|||||||
<ClInclude Include="group.h">
|
<ClInclude Include="group.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="grpupdat.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="dialog.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="progmgr.c">
|
<ClCompile Include="progmgr.c">
|
||||||
@@ -38,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>
|
||||||
@@ -50,16 +56,19 @@
|
|||||||
<ClCompile Include="group.c">
|
<ClCompile Include="group.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="dialog.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<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,12 +8,13 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
#include "progmgr.h"
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#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
|
||||||
@@ -35,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 */
|
||||||
|
|
||||||
@@ -50,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;
|
||||||
@@ -73,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);
|
||||||
@@ -110,24 +112,63 @@ BOOL IsProgMgrDefaultShell()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
RegistrySaveGroup -
|
||||||
|
Saves a group structure to the registry.
|
||||||
|
RETURNS -
|
||||||
|
RCE_* configuration error value
|
||||||
|
\* * * */
|
||||||
|
DWORD RegistrySaveGroup(_In_ PGROUP pg)
|
||||||
|
{
|
||||||
|
// If the pointer or HKEY is invalid then fail out
|
||||||
|
if ((pg == NULL) || (hKeyProgramGroups == NULL))
|
||||||
|
return RCE_FAILURE;
|
||||||
|
|
||||||
|
// Save group
|
||||||
|
UpdateGroup(pg);
|
||||||
|
if (!RegSetValueEx(hKeyProgramGroups, pg->szName, 0, REG_BINARY,
|
||||||
|
(const BYTE*)pg, sizeof(*pg)) == ERROR_SUCCESS)
|
||||||
|
return RCE_GROUPS;
|
||||||
|
|
||||||
|
return RCE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* * * *\
|
||||||
|
RegistryRemoveGroup -
|
||||||
|
Removes a group structure from the registry.
|
||||||
|
RETURNS -
|
||||||
|
RCE_* configuration error value
|
||||||
|
\* * * */
|
||||||
|
DWORD RegistryRemoveGroup(_In_ PGROUP pg)
|
||||||
|
{
|
||||||
|
// If the pointer or HKEY is invalid then fail out
|
||||||
|
if ((pg == NULL) || (hKeyProgramGroups == NULL))
|
||||||
|
return RCE_FAILURE;
|
||||||
|
|
||||||
|
// Try to remove the group matching the name
|
||||||
|
// If we fail, group does not exist in the registry
|
||||||
|
if (RegDeleteValue(hKeyProgramGroups, pg->szName) != ERROR_SUCCESS)
|
||||||
|
return RCE_FAILURE;
|
||||||
|
|
||||||
|
return RCE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
SaveConfig -
|
SaveConfig -
|
||||||
Finds and collapses all settings
|
Finds and collapses all settings
|
||||||
and saves them to the registry.
|
and saves them to the registry.
|
||||||
RETURNS -
|
RETURNS -
|
||||||
TRUE if successful, FALSE if unsuccessful.
|
RCE_* configuration error value
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups)
|
DWORD SaveConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups, _In_ BOOL bExit)
|
||||||
{
|
{
|
||||||
BOOL bConfigStatus = TRUE;
|
DWORD dwConfigStatus = RCE_SUCCESS;
|
||||||
WINDOWPLACEMENT wpProgMgr;
|
|
||||||
RECT rcWindow;
|
|
||||||
|
|
||||||
if (bSettings)
|
if (bSettings)
|
||||||
{
|
{
|
||||||
// Shrink the settings into the bitmask and save it
|
// Shrink the settings into the bitmask and save it
|
||||||
// There's definitely a better way to do this but...
|
// There's definitely a better way to do this but...
|
||||||
// I'll get to it later :)
|
// TODO: do this more efficiently
|
||||||
dwSettingsMask =
|
dwSettingsMask =
|
||||||
(bAutoArrange && PMS_AUTOARRANGE) * PMS_AUTOARRANGE |
|
(bAutoArrange && PMS_AUTOARRANGE) * PMS_AUTOARRANGE |
|
||||||
(bMinOnRun && PMS_MINONRUN) * PMS_MINONRUN |
|
(bMinOnRun && PMS_MINONRUN) * PMS_MINONRUN |
|
||||||
@@ -137,54 +178,229 @@ BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups)
|
|||||||
|
|
||||||
if (!RegSetValueEx(hKeySettings, pszSettingsMask, 0, REG_DWORD,
|
if (!RegSetValueEx(hKeySettings, pszSettingsMask, 0, REG_DWORD,
|
||||||
(const BYTE*)&dwSettingsMask, sizeof(dwSettingsMask)) == ERROR_SUCCESS)
|
(const BYTE*)&dwSettingsMask, sizeof(dwSettingsMask)) == ERROR_SUCCESS)
|
||||||
bConfigStatus = FALSE;
|
dwConfigStatus = dwConfigStatus && RCE_SETTINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bPos)
|
if (bPos)
|
||||||
{
|
{
|
||||||
|
WINDOWPLACEMENT wpProgMgr = { 0 };
|
||||||
|
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,
|
||||||
(const BYTE*)&rcWindow, sizeof(rcWindow)) == ERROR_SUCCESS)
|
(const BYTE*)&rcWindow, sizeof(rcWindow)) == ERROR_SUCCESS)
|
||||||
bConfigStatus = FALSE;
|
dwConfigStatus = dwConfigStatus && RCE_POSITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bConfigStatus;
|
if (bGroups)
|
||||||
|
{
|
||||||
|
HWND hWndGroup = NULL;
|
||||||
|
|
||||||
|
EnumChildWindows(hWndMDIClient, &SaveWindowEnumProc, (LPARAM)bExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwConfigStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * *\
|
/* * * *\
|
||||||
BOOL LoadConfig() -
|
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() -
|
||||||
Finds all settings and retrieves them
|
Finds all settings and retrieves them
|
||||||
from the registry.
|
from the registry.
|
||||||
RETURNS -
|
RETURNS -
|
||||||
TRUE if successful, FALSE if unsuccessful.
|
RCE_* configuration error value
|
||||||
\* * * */
|
\* * * */
|
||||||
BOOL LoadConfig()
|
DWORD LoadConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups)
|
||||||
{
|
{
|
||||||
BOOL bConfigStatus = TRUE;
|
DWORD dwConfigStatus = RCE_SUCCESS;
|
||||||
DWORD dwType;
|
|
||||||
DWORD dwBufferSize = sizeof(dwSettingsMask);
|
|
||||||
DWORD dwRectBufferSize = sizeof(rcMainWindow);
|
|
||||||
|
|
||||||
// Load settings bitmask
|
if (bSettings)
|
||||||
if (!RegQueryValueEx(hKeySettings, pszSettingsMask, 0, &dwType,
|
{
|
||||||
(LPBYTE)&dwSettingsMask, &dwBufferSize) == ERROR_SUCCESS)
|
DWORD dwBufferSize = sizeof(dwSettingsMask);
|
||||||
bConfigStatus = FALSE;
|
DWORD dwType = REG_DWORD;
|
||||||
|
|
||||||
// Apply bitmask to booleans
|
|
||||||
bAutoArrange = (dwSettingsMask & PMS_AUTOARRANGE);
|
|
||||||
bMinOnRun = (dwSettingsMask & PMS_MINONRUN);
|
|
||||||
bTopMost = (dwSettingsMask & PMS_TOPMOST);
|
|
||||||
bSaveSettings = (dwSettingsMask & PMS_SAVESETTINGS);
|
|
||||||
bShowUsername = (dwSettingsMask & PMS_SHOWUSERNAME);
|
|
||||||
|
|
||||||
// Load window position... and apply it!
|
// Load settings bitmask
|
||||||
if (!RegQueryValueEx(hKeySettings, pszSettingsWindow, 0, &dwType,
|
if (!RegQueryValueEx(hKeySettings, pszSettingsMask, 0, &dwType,
|
||||||
(LPBYTE)&rcMainWindow, &dwRectBufferSize) == ERROR_SUCCESS)
|
(LPBYTE)&dwSettingsMask, &dwBufferSize) == ERROR_SUCCESS)
|
||||||
bConfigStatus = FALSE;
|
dwConfigStatus = dwConfigStatus && RCE_SETTINGS;
|
||||||
|
|
||||||
return bConfigStatus;
|
// Apply bitmask to booleans
|
||||||
|
bAutoArrange = (dwSettingsMask & PMS_AUTOARRANGE);
|
||||||
|
bMinOnRun = (dwSettingsMask & PMS_MINONRUN);
|
||||||
|
bTopMost = (dwSettingsMask & PMS_TOPMOST);
|
||||||
|
bSaveSettings = (dwSettingsMask & PMS_SAVESETTINGS);
|
||||||
|
bShowUsername = (dwSettingsMask & PMS_SHOWUSERNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bPos)
|
||||||
|
{
|
||||||
|
DWORD dwRectBufferSize = sizeof(rcMainWindow);
|
||||||
|
DWORD dwType = REG_BINARY;
|
||||||
|
|
||||||
|
// Load window position
|
||||||
|
if (!RegQueryValueEx(hKeySettings, pszSettingsWindow, 0, &dwType,
|
||||||
|
(LPBYTE)&rcMainWindow, &dwRectBufferSize) == ERROR_SUCCESS)
|
||||||
|
dwConfigStatus = dwConfigStatus && RCE_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bGroups)
|
||||||
|
{
|
||||||
|
DWORD dwBufferSize = sizeof(dwSettingsMask);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,17 +10,20 @@
|
|||||||
/* 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")
|
||||||
// Settings Bitmask Values (DWORD)
|
// Registry configuration error values (DWORD)
|
||||||
|
#define RCE_SUCCESS 0x0000000
|
||||||
|
#define RCE_FAILURE 0x0000001
|
||||||
|
#define RCE_SETTINGS 0x0000002
|
||||||
|
#define RCE_POSITION 0x0000004
|
||||||
|
#define RCE_GROUPS 0x0000008
|
||||||
|
// Settings values (DWORD)
|
||||||
#define PMS_AUTOARRANGE 0x00000001
|
#define PMS_AUTOARRANGE 0x00000001
|
||||||
#define PMS_MINONRUN 0x00000002
|
#define PMS_MINONRUN 0x00000002
|
||||||
#define PMS_TOPMOST 0x00000004
|
#define PMS_TOPMOST 0x00000004
|
||||||
@@ -43,5 +46,11 @@ extern RECT rcMainWindow;
|
|||||||
/* Function Prototypes */
|
/* Function Prototypes */
|
||||||
BOOL InitializeRegistryKeys(VOID);
|
BOOL InitializeRegistryKeys(VOID);
|
||||||
BOOL IsProgMgrDefaultShell(VOID);
|
BOOL IsProgMgrDefaultShell(VOID);
|
||||||
BOOL LoadConfig(VOID);
|
// Groups
|
||||||
BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups);
|
DWORD RegistrySaveGroup(_In_ PGROUP pg);
|
||||||
|
DWORD RegistryRemoveGroup(_In_ PGROUP pg);
|
||||||
|
// Settings
|
||||||
|
DWORD SaveConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups, _In_ BOOL bExit);
|
||||||
|
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
|
||||||
|
|
||||||
@@ -17,19 +17,26 @@
|
|||||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
#pragma code_page(65001) // UTF-8
|
#pragma code_page(65001) // UTF-8
|
||||||
#include "lang\res_en-US.rc" // English (US)
|
#include "lang\res_en-US.rc" // English (US)
|
||||||
|
#include "lang\dlg_en-US.rc" // English (US)
|
||||||
|
|
||||||
/* 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"
|
||||||
@@ -38,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,16 +8,19 @@
|
|||||||
\* * * * * * * */
|
\* * * * * * * */
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
#include "progmgr.h"
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include "group.h"
|
|
||||||
#include "resource.h"
|
|
||||||
#include "registry.h"
|
|
||||||
// #define WIN32_LEAN_AND_MEAN
|
|
||||||
#define SECURITY_WIN32
|
#define SECURITY_WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
#include <shellapi.h>
|
||||||
#include <Lmcons.h>
|
#include <Lmcons.h>
|
||||||
#include <security.h>
|
#include <security.h>
|
||||||
|
#include <Mmsystem.h>
|
||||||
|
#include "progmgr.h"
|
||||||
|
#include "dialog.h"
|
||||||
|
#include "group.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "registry.h"
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
@@ -31,74 +34,53 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case WM_CREATE:
|
|
||||||
|
case WM_CREATE:
|
||||||
|
{
|
||||||
|
// 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:
|
||||||
|
{
|
||||||
|
if ((wParam >= IDM_MAIN) && (wParam <= IDM_TASKMGR))
|
||||||
{
|
{
|
||||||
CLIENTCREATESTRUCT ccs;
|
if (wParam == IDM_TASKMGR)
|
||||||
RECT rc;
|
|
||||||
|
|
||||||
// Frame Window
|
|
||||||
hWndProgMgr = hWnd;
|
|
||||||
|
|
||||||
// Create the MDI Client Window
|
|
||||||
ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), IDM_WINDOW);
|
|
||||||
ccs.idFirstChild = IDM_WINDOW_CHILDSTART;
|
|
||||||
|
|
||||||
GetClientRect(hWndProgMgr, &rc);
|
|
||||||
|
|
||||||
if (!(hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED, L"MDIClient",
|
|
||||||
NULL, WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
|
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
|
||||||
hWnd, (HMENU)1, hAppInstance, (LPWSTR)&ccs)))
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
ShellExecute(g_hWndProgMgr, TEXT("open"), TEXT("TASKMGR.EXE"), NULL, NULL, SW_NORMAL);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TempCreateGroup(hWndMDIClient);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_SYSCOMMAND:
|
|
||||||
{
|
|
||||||
if ((wParam >= IDM_MAIN) || (wParam <= IDM_TASKMGR))
|
|
||||||
{
|
|
||||||
if (wParam == IDM_TASKMGR)
|
|
||||||
{
|
|
||||||
ShellExecute(hWndProgMgr, L"open", L"TASKMGR.EXE", NULL, NULL, SW_NORMAL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CmdProc(hWnd, wParam, lParam))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto WndProcDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_COMMAND:
|
|
||||||
if (CmdProc(hWnd, wParam, lParam))
|
if (CmdProc(hWnd, wParam, lParam))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
goto WndProcDefault;
|
|
||||||
|
|
||||||
case WM_CLOSE:
|
|
||||||
if (bSaveSettings)
|
|
||||||
SaveConfig(TRUE, TRUE, TRUE);
|
|
||||||
|
|
||||||
if (bIsDefaultShell && (GetShellWindow() != NULL))
|
|
||||||
SetShellWindow(0);
|
|
||||||
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_ENDSESSION:
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
WndProcDefault:
|
|
||||||
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
if (CmdProc(hWnd, wParam, lParam))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
case WM_ENDSESSION:
|
||||||
|
if (bSaveSettings)
|
||||||
|
SaveConfig(TRUE, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
if (g_bIsDefaultShell && (GetShellWindow() != NULL))
|
||||||
|
SetShellWindow(0);
|
||||||
|
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -115,9 +97,25 @@ 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:
|
||||||
|
DialogBox(g_hAppInstance, MAKEINTRESOURCE(DLG_GROUP), hWnd, (DLGPROC)NewGroupDlgProc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDM_FILE_NEW_ITEM:
|
||||||
|
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;
|
||||||
|
|
||||||
case IDM_FILE_RUN:
|
case IDM_FILE_RUN:
|
||||||
RunFileDlg(hWnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
|
RunFileDlg(hWnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
|
||||||
break;
|
break;
|
||||||
@@ -138,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;
|
||||||
|
|
||||||
@@ -154,24 +152,52 @@ LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
goto SaveConfig;
|
goto SaveConfig;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,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;
|
||||||
@@ -201,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;
|
|
||||||
}
|
|
||||||
|
|||||||