234 Commits

Author SHA1 Message Date
5998c235f1 Upload files to "/"
Some checks failed
MSBuild / build (Debug, x64) (push) Has been cancelled
MSBuild / build (Debug, x86) (push) Has been cancelled
MSBuild / build (Release, x64) (push) Has been cancelled
MSBuild / build (Release, x86) (push) Has been cancelled
2026-02-27 13:41:14 +00:00
Brady McDermott
caa84730cc I dont know no more 2024-10-22 11:54:40 -06:00
Brady McDermott
7410e6ddb1 pretty code 2024-10-22 03:35:39 -06:00
Brady McDermott
04d5187a36 fix warning 2024-10-22 03:32:21 -06:00
Brady McDermott
56084fefb7 remove probably useless +1 2024-10-22 03:28:30 -06:00
Brady McDermott
51561cd0ac increment version cause we made loads of progress!!! 2024-10-22 03:26:29 -06:00
Brady McDermott
c58b785b7b update readme and banner 2024-10-22 03:22:27 -06:00
Brady McDermott
841128b2f3 get rid of unused assets 2024-10-22 03:10:58 -06:00
Brady McDermott
13b4657c5b changes 2024-10-22 03:09:21 -06:00
Brady McDermott
8f6af5bba9 so real 2024-10-22 00:20:57 -06:00
Brady McDermott
b679f71607 let's go gambling 2024-10-21 18:34:06 -06:00
Brady McDermott
154bed9106 remove all the +1 ill probably be okay without them 2024-10-21 18:27:21 -06:00
Brady McDermott
b13ce0578b less maintenance if i do it thi way 2024-10-21 17:31:52 -06:00
Brady McDermott
9c6fe40c1c Solve issue #11 2024-10-21 16:06:39 -06:00
Brady McDermott
ca4b30e1d7 fix release icon 2024-10-21 00:25:27 -06:00
Brady McDermott
793c6a626f move other stuff to misc directory 2024-10-20 21:43:47 -06:00
Brady McDermott
892db32a81 Now put them back in the "progmgr" folder 2024-10-20 21:20:53 -06:00
Brady McDermott
69a624e0f9 GET RID OF the ProgMgr directory on GITHUB!!! 2024-10-20 21:20:00 -06:00
Brady McDermott
4a8ef09334 rename directory 2024-10-20 21:18:56 -06:00
Brady McDermott
cc62e8dc38 rename dir 1 2024-10-20 21:18:14 -06:00
Brady McDermott
b335db994a registry.... wndproc 2024-10-20 21:15:17 -06:00
Brady McDermott
21271a7c4b Delete progmgr/progmgr.vcxproj 2024-10-20 21:14:25 -06:00
Brady McDermott
0fa28c9e3e Delete progmgr/progmgr.vcxproj.filters 2024-10-20 21:14:18 -06:00
Brady McDermott
2c1fa58da6 cheaper listview resize 2024-10-20 17:05:27 -06:00
Brady McDermott
f6b7c29d2c Update group.c
lol if itbwoeks... programming from my phone..
2024-10-20 02:03:29 -06:00
Brady McDermott
d2342e80f5 save window pos/placement for program groups 2024-10-20 01:40:07 -06:00
Brady McDermott
306621f084 fix registry loading once and for all or something 2024-10-20 00:54:56 -06:00
Brady McDermott
f0ae48cd10 it no longer freezes on startup and falls into an infinite loop of loading program groups (that may or may not exist!) 2024-10-20 00:23:32 -06:00
Brady McDermott
aef812ae92 we don't use and don't need the app heap 2024-10-19 23:25:49 -06:00
Brady McDermott
50a290d57e lang res 2024-10-19 23:25:02 -06:00
Brady McDermott
93ca902e1f add:
startup sound when set as default shell
rename global variables for easier identification
2024-10-19 23:24:53 -06:00
Brady McDermott
7234547e3d remove unused filter 2024-07-30 22:58:40 -06:00
Brady McDermott
8f5bdce45b yeah 2024-07-30 22:20:56 -06:00
Brady McDermott
fdc0d28ab7 fix output dir 2024-07-30 22:19:58 -06:00
Brady McDermott
e0670bea6d caps 2024-07-30 22:18:38 -06:00
Brady McDermott
bcd6716fcb license year 2024-07-30 22:18:31 -06:00
Brady McDermott
e3187f62c3 reorganize and move things out of headers 2024-07-30 22:08:30 -06:00
Brady McDermott
174edb0aaa use v142 tools again 2024-07-30 22:02:05 -06:00
Brady McDermott
654dbf6be0 happy new years 2024-07-30 22:01:18 -06:00
Brady McDermott
7ea2d75f37 TODO: get rid of all the TODO comments 2024-04-02 14:40:33 -06:00
Brady McDermott
7602f6df4d readme 2024-04-01 17:53:20 -06:00
Brady McDermott
e8e91d87cd yeah that'll do'er 2024-03-30 18:23:10 -06:00
Brady McDermott
91216a8778 upload artifacts 2024-03-30 18:19:42 -06:00
Brady McDermott
f94859613c update msbuild and action checkout 2024-03-30 18:10:56 -06:00
Brady McDermott
1beddc7695 try it again... 2024-03-30 18:03:05 -06:00
Brady McDermott
69baa0e28c Update msbuild.yml 2024-03-30 17:56:42 -06:00
Brady McDermott
34026dbc8d lord please 2024-03-30 17:48:46 -06:00
Brady McDermott
fef15a326d hohoho 2024-03-30 17:30:55 -06:00
Brady McDermott
a07aace682 please build 2024-03-30 17:06:09 -06:00
Brady McDermott
39d2983852 Revert "Update msbuild.yml???"
This reverts commit 972c56a15b.
2024-03-30 16:44:36 -06:00
Brady McDermott
e7ad120d92 nuke vs2010 support 2024-03-30 13:03:09 -06:00
Brady McDermott
8939e71a99 i don't know what i was doing here
this is all getting rewritten
2024-03-30 13:01:12 -06:00
freedom
7a3c1ae092 Update msbuild.yml 2023-12-04 13:50:54 -07:00
freedom
67513d7c23 Update msbuild.yml 2023-12-04 13:50:19 -07:00
freedom
360aa81df6 Update msbuild.yml 2023-12-04 13:45:34 -07:00
freedom
c6cfed377a Update msbuild.yml 2023-12-04 13:44:52 -07:00
freedom
f18779ef28 moar yml 2023-12-04 13:41:24 -07:00
freedom
a570e61c8b Merge branch 'master' of https://github.com/Vortesys/Program-Manager-II 2023-12-04 13:30:37 -07:00
freedom
28e7fa0ad7 registry file update 2023-12-04 13:29:59 -07:00
Brady McDermott
972c56a15b Update msbuild.yml??? 2023-12-04 13:25:26 -07:00
Brady McDermott
7dd1875e1d i hate this 2023-10-28 22:15:24 -06:00
Brady McDermott
f1e0a17b3d sorta load items 2023-10-25 13:51:57 -06:00
Brady McDermott
c1dd3ae999 GROUPS LOAD 2023-10-25 11:49:37 -06:00
Brady McDermott
309ce4702b pain; suffering 2023-10-24 19:38:51 -06:00
Brady McDermott
5e878f98cf load gorup? 2023-10-24 15:43:10 -06:00
Brady McDermott
2c86c796f5 de bug 2023-10-24 08:24:34 -06:00
Brady McDermott
2e7dafbbac i lied 2023-10-23 16:39:44 -06:00
Brady McDermott
961cedb975 vista compatibility and vs2010 compile
final commit solely focused on this
2023-10-23 16:26:17 -06:00
Brady McDermott
e990647e1b fix'er'again 2023-10-23 15:09:53 -06:00
Brady McDermott
9079225a29 Update Program-Manager-II-2010.sln
compile...
2023-10-23 15:07:44 -06:00
Brady McDermott
6e4d38544e vista compatibility complete 2023-10-23 14:06:02 -06:00
freedom
5d17a98ca0 vista compatibility, remove pathcch 2023-10-23 13:51:04 -06:00
freedom
bce106ce5f more vista-readiness 2023-10-23 13:46:39 -06:00
Brady McDermott
2b32d3f8f8 brogramming 2023-10-22 13:49:50 -06:00
Brady McDermott
000ecc527f vista+ compatibility part 1 2023-10-21 13:40:47 -06:00
Brady McDermott
e7bcb43cd1 Update .gitignore 2023-10-21 12:56:06 -06:00
Brady McDermott
28e5ec10fc add vs2010 solution and project 2023-10-21 12:55:48 -06:00
Brady McDermott
55ea523d34 Update .gitignore
no .user either
2023-10-21 12:10:19 -06:00
Brady McDermott
52fc4cdcab add suo to gitignore 2023-10-21 12:05:16 -06:00
freedom
1c273f6337 plelaasee 2023-10-19 10:50:44 -06:00
freedom
edd9da0ce4 back on 143 tools, will create new project files later for vs2010 2023-10-18 15:32:00 -06:00
freedom
c9581062f6 idek i'll do it later 2023-10-18 15:31:40 -06:00
Brady McDermott
e0fa6632cd stuff 2023-10-16 14:40:03 -06:00
Brady McDermott
4054dac5f1 balla 2023-10-16 12:19:20 -06:00
freedom
291e1f0d16 load group wip 2023-10-14 16:59:18 -06:00
freedom
97784e31ae save groups 2023-10-13 12:24:05 -06:00
freedom
475d868825 make item batch count a define instead of being as hard-coded 2023-10-13 08:28:33 -06:00
freedom
f718eb4d51 Merge pull request #38 from u130b8/fix-realloc
update pGroup after realloc
2023-10-13 08:21:28 -06:00
freedom
c5c5d6d714 Merge pull request #37 from u130b8/master
Fix build.cmd
2023-10-13 08:16:53 -06:00
u130b8
59f7eb76bd update pGroup after realloc 2023-10-13 13:28:11 +03:00
u130b8
ef8b514527 build with crt for now, add libraries 2023-10-13 13:14:46 +03:00
freedom
39229500f6 fix item dialog not passing the paths 2023-10-13 01:01:38 -06:00
freedom
493abda875 program execution works now just gotta fix the item creation dialog 2023-10-13 00:42:52 -06:00
freedom
1a17c89074 more progress 2023-10-12 22:12:18 -06:00
freedom
bbf9941fd4 almost add double click functionality and execution, add the image list and improve readability when my screen is squished 2023-10-12 14:54:44 -06:00
freedom
012ad25462 coding style 2023-10-12 11:04:54 -06:00
freedom
06e32d9063 possibly solves #34, check again later 2023-10-12 01:47:44 -06:00
freedom
ef0a73d819 temporarily disable the functionality of the program item friendly name finder, will come back to it later but this is how progman did it and it's more reliable atm 2023-10-12 01:40:10 -06:00
freedom
bd4712a7db i am strength 2023-10-12 01:35:54 -06:00
freedom
710fc5aecd more for compile and whatnot, icons appear now 2023-10-12 01:24:00 -06:00
freedom
39ed21c334 vs2019 wants to use v142 build tools, here i'll let it temporarily 2023-10-12 00:52:35 -06:00
freedom
c1e2d5279d idek if this compiled lol image list 2023-10-12 00:50:57 -06:00
freedom7341
ab9e9d9b18 Progress on #17: we have listview with items, beginning context menu implementation, just need to be able to execute the items and then remove groups and items, as well as give icons to all of the items, we are so close!!! 2023-10-11 14:28:01 -06:00
freedom7341
ea0c0773e6 column is unnecessary, remove 2023-10-11 12:24:05 -06:00
freedom7341
efb000f4ec add listview explorer style 2023-10-11 12:23:24 -06:00
freedom7341
36a6d1a888 positions correctly on initialization now 2023-10-11 12:18:18 -06:00
freedom7341
67e821a33c listview works and positions correctly 2023-10-11 12:13:35 -06:00
freedom7341
69a1ea88f5 rename in case of conflict 2023-10-11 11:44:53 -06:00
freedom7341
0c0f9c765e remove unnecessary cast 2023-10-11 11:38:31 -06:00
freedom7341
b8c4a712f9 fix compile complaints 2023-10-11 11:37:07 -06:00
freedom
b07bcbfa6d pain 2023-10-11 11:11:59 -06:00
freedom
531400b700 a step closer now i just need the item.. to appear. 2023-10-11 11:03:24 -06:00
freedom
15d3bcca5c it no longer crashes 2023-10-11 10:49:34 -06:00
freedom7341
fa1ac0dfc9 i wanna work on this on my desktop 2023-10-11 10:17:34 -06:00
freedom7341
14c5e5560b cast 2023-10-10 16:32:25 -06:00
freedom7341
6f312892e8 begin listviewery 2023-10-10 16:31:19 -06:00
freedom7341
1ed794d640 switch L"" to TEXT("") 2023-10-10 16:31:06 -06:00
freedom7341
c43c176538 grup 2023-10-10 13:14:29 -06:00
freedom
fd51e72432 i'll fix this later 2023-10-04 21:00:06 -06:00
freedom
403cfafedb createitem 2023-10-04 14:54:00 -06:00
freedom7341
866402a7b3 item functions 2023-10-04 14:42:16 -06:00
freedom7341
717d744195 really round up 2023-10-04 13:27:22 -06:00
freedom7341
2c16c265ca use pointers instead :D 2023-10-04 13:20:01 -06:00
freedom7341
82c2d2d15f remove unnecessary variable 2023-10-04 13:10:50 -06:00
freedom7341
925bb43a6d fix memory calculation 2023-10-04 13:02:03 -06:00
freedom7341
b02cc93c6d lil issue 2023-10-04 12:37:53 -06:00
freedom7341
e6b36b3b94 accidentally referenced old function name 2023-10-04 12:37:23 -06:00
freedom7341
51e907a7d0 lil correction in a header 2023-10-04 12:34:40 -06:00
freedom7341
6533f53aaa group and memory management stuff 2023-10-04 12:34:33 -06:00
freedom
f2b1af5cba cleanyup 2023-10-02 23:21:56 -06:00
freedom
b14c11f98e pulls the right icon now 2023-10-02 22:29:35 -06:00
freedom7341
99fbc7392c gotte 2023-10-02 16:30:12 -06:00
freedom7341
ab20d2ec8c item dialog icon 2023-10-02 16:25:14 -06:00
freedom7341
678eef08c9 item dialog icon 2023-10-02 16:22:26 -06:00
freedom7341
4269ded2f6 more 2023-10-02 16:17:14 -06:00
freedom7341
44270fd601 fixed name retrieval for files without a description 2023-10-02 14:13:24 -06:00
freedom
c7d3ae27d1 retrieve name from file description, as a backup just input the name of the file, almost got a cool feature here just wip it up a little more, not working properly yet 2023-10-02 13:47:57 -06:00
freedom7341
3245d93436 wip wip wip wip committing so i can get to it from another pc 2023-10-02 12:21:23 -06:00
freedom7341
7e3fcb1fc3 ;ji oua eg uagr iua g 2023-09-29 17:57:55 -06:00
freedom7341
607330267f removed a lil cruft, proper shutdown dialog coming soon i swear please i swear 2023-09-29 17:46:45 -06:00
freedom7341
5d7536d5fd program groups are now.. INVINCIBLE 2023-09-29 17:16:18 -06:00
freedom7341
5e6f59f946 make it compile again 2023-09-28 10:49:42 -06:00
freedom7341
cbb7373cc1 update group format variable names 2023-09-27 13:58:44 -06:00
freedom7341
58e6635bae update group format to account for that \0 2023-09-27 13:39:03 -06:00
freedom7341
b2413ad307 shutdown dialog stuff 2023-09-27 13:37:42 -06:00
freedom7341
49d22b8a13 memory management will happen in a different way :D 2023-09-27 12:22:37 -06:00
freedom7341
d4aa908ea2 begin shutdown dialog and a few other small things, come back to this later 2023-09-27 12:22:01 -06:00
freedom7341
4dfb5d8554 groups coming sooner than expected... or later i guess, i was supposed to have this done 2 weeks ago 2023-09-27 12:21:37 -06:00
freedom7341
2ff4ee0c9c remove unused function 2023-09-27 11:54:08 -06:00
freedom7341
24a17d0287 prep for memory management 2023-09-22 14:17:16 -06:00
freedom7341
6943fc563b desktop rewrite coming soon 2023-09-18 11:13:16 -06:00
freedom7341
b8466d176b some framework for permissions down the line 2023-09-18 10:57:56 -06:00
freedom7341
48c8f542bc work is happening 2023-09-15 11:46:01 -06:00
freedom7341
d16b7254da update file headers and version information 2023-09-14 14:41:25 -06:00
freedom
349a9a9d0d minor cool changes 2023-09-07 14:52:41 -06:00
freedom
2aa96bc024 [DEBUG] 2023-09-07 14:52:13 -06:00
freedom
e0724dc0c7 fix the window menu 2023-09-07 14:52:05 -06:00
freedom
99d851f368 some group changes 2023-09-07 14:25:20 -06:00
freedom
ef30558e0a update debug icon 2023-09-07 14:24:18 -06:00
freedom
1ff398ad70 re-added manifest compatibility info to fix winver reporting 2023-09-07 14:24:10 -06:00
freedom
cbe1fb7551 make it easy to spot pesky debug builds 2023-09-07 04:09:36 -06:00
freedom
1b8ec3b152 Merge pull request #31 from u130b8/master
add older dpi scaling options
2023-09-07 02:38:54 -07:00
u130b8
84f106938d add older dpi scaling options 2023-09-07 12:36:26 +03:00
freedom
f761ac6cf7 Merge pull request #30 from u130b8/master
add hidpi support and simplify manifest (closes #21)
2023-09-07 02:29:34 -07:00
u130b8
3cbe91cf89 Merge branch 'master' of https://github.com/u130b8/Program-Manager-II 2023-09-07 12:20:28 +03:00
freedom
fd3abe1795 Merge branch 'master' of https://github.com/Vortesys/Program-Manager-II 2023-09-07 03:19:37 -06:00
freedom
42f0f268d9 update gitignore to work a lil better 2023-09-07 03:19:32 -06:00
freedom
6ce9166a92 Merge pull request #29 from u130b8/master
build release without crt, build debug with crt
2023-09-07 02:15:36 -07:00
u130b8
e19e3d399b simplify manifest and add hidpi support 2023-09-07 11:14:24 +03:00
u130b8
d7a3802571 use custom defines to prevent vs builds from breaking 2023-09-07 11:11:47 +03:00
u130b8
a074441a99 fix failing build when PROGMGR_GIT_HASH is not defined 2023-09-07 11:06:58 +03:00
u130b8
59937a8690 comment the no_crt situation 2023-09-07 10:59:31 +03:00
u130b8
613b998348 include git hash in build 2023-09-07 10:54:02 +03:00
u130b8
e0461949ae move UNICODE define out of defs 2023-09-07 10:33:12 +03:00
u130b8
acc63b5aa6 rename zipbuild to zip.cmd 2023-09-07 10:32:11 +03:00
u130b8
64d69162ab build release without crt by default, build debug with crt 2023-09-07 10:31:55 +03:00
freedom
6ac03d7a1b more... group... 2023-09-06 06:09:25 -06:00
freedom
0d237c5039 Merge pull request #28 from u130b8/master
make debug build work, remove /NODEFAULTLIB for now
2023-09-06 05:08:35 -07:00
freedom
714fe3a4ae Merge branch 'master' into master 2023-09-06 05:08:23 -07:00
u130b8
5d0a3f1ccf make debug build work, remove /NODEFAULTLIB for now 2023-09-06 15:05:22 +03:00
freedom
d7e5d10209 fix build 2023-09-06 05:41:42 -06:00
freedom
d01b18e035 Merge pull request #27 from u130b8/master
add build.cmd and make it build from command line
2023-09-06 04:37:27 -07:00
freedom
6c40ba9886 ok so now the variables do the needful 2023-09-06 05:23:39 -06:00
u130b8
0d0e37b561 add build.cmd and make it build from command line 2023-09-06 14:16:24 +03:00
freedom
bda528569b i just want groups to work man PLEASe man well listview looks like it works so that's something i guess but now i gotta really add items to it oh my GOD 2023-09-06 04:42:32 -06:00
freedom
9bb0dfd24b better dialoggery 2023-09-06 03:23:44 -06:00
freedom
ef88804240 some more dialogger while i procrastinate listview 2023-09-05 03:36:37 -06:00
freedom
a494e057c9 icon restructure 2023-09-04 21:30:07 -06:00
freedom
7910340133 listviewery? 2023-08-16 21:10:15 -06:00
freedom
b736576829 set filetime 2023-08-16 21:08:04 -06:00
freedom
94f4e71b20 comment correction 2023-08-16 21:07:45 -06:00
freedom
9e67a3d81b mdi tiling for dummys 2023-08-16 03:28:26 -06:00
freedom
2972d54777 modify bat to produce zip releases 2023-08-16 03:18:43 -06:00
freedom
6aaabd480a close when you press ok 2023-08-16 03:13:56 -06:00
freedom
e400645956 we're getting there 2023-08-16 03:12:03 -06:00
freedom
77512dd72d indentation 2023-08-16 02:13:35 -06:00
freedom
8fb871de34 Revert "load/unload registry keys on demand"
This reverts commit d41f0b868b.
2023-08-16 02:03:08 -06:00
freedom
d41f0b868b load/unload registry keys on demand 2023-08-16 02:00:09 -06:00
freedom
b9cea5b8e6 no more mr. unreferenced code paths 2023-08-16 01:27:19 -06:00
freedom
745030da99 TODO: 2023-08-15 22:09:34 -06:00
freedom
739c56e314 dialog work so far, has a gdi resource leak 2023-08-15 22:05:04 -06:00
freedom
78f612e684 update resources 2023-08-15 22:04:28 -06:00
freedom
1bb6e0b05a update resources 2023-08-15 20:02:40 -06:00
freedom
541c86b4a2 update indentation 2023-08-14 14:50:25 -06:00
freedom
f632229b3c prep for more dialoggery 2023-08-14 14:50:16 -06:00
freedom
488070e73d more dialoggery 2023-08-14 14:40:01 -06:00
freedom
f8578360f8 rename stuff 2023-08-11 17:47:48 -06:00
freedom
a4f7046760 resources... i hate them
the dialogs are pretty chill though
2023-08-11 02:17:23 -06:00
freedom
364afc7438 fixed it 2023-08-11 01:59:43 -06:00
freedom
bbde0b6acb removed wtypes since it doesn't seem to complain if i do that 2023-08-11 01:48:57 -06:00
freedom
3441f7771a i did this stuff in a haze and don't even remember most of it, i don't think it works yet 2023-08-11 01:42:52 -06:00
freedom
6302272d96 and God said to the world
"Let there be dialogs"
 - Gates 3:86
2023-08-11 01:42:20 -06:00
freedom
7409d6cc41 this cmd bat thing sucks but have it as it sits 2023-08-11 01:41:40 -06:00
freedom
db71fb2ab3 minor changes to the group format 2023-08-11 01:41:25 -06:00
freedom
84c62213d7 begin preparing some structures for converting old program manager groups to the new format 2023-08-10 16:25:53 -06:00
freedom
437703e26d delete old builds before zipping new ones just incase, rar still funny layout 2023-08-10 16:25:20 -06:00
freedom
fbdb45b4df working on #17, program mdi window is now created and sized properly, close to completing the group part once i finish... registry functions and a group dialog 2023-08-10 13:37:45 -06:00
freedom
ba276117d7 refactoring of group code from main program file, memory operations, updates to group format, we are getting REAL in here! also handle the changes introduced in the registry functions 2023-08-10 02:14:35 -06:00
freedom
35a28f698f registry config function modifications, prepping for future error handling 2023-08-10 01:23:05 -06:00
freedom
bf2c7ce3da update github branding 2023-08-10 00:59:11 -06:00
freedom
4095f501c1 update 32x32 icon again because i'm chill like that 2023-08-10 00:19:10 -06:00
freedom
2632512881 update thing 2023-08-09 20:19:37 -06:00
freedom
af3e493085 Revert "program manager ii!"
This reverts commit d875363d72.
2023-08-09 20:19:14 -06:00
freedom
d875363d72 program manager ii! 2023-08-09 20:18:43 -06:00
freedom
456426f7bf delete all build files after compressing them to ensure fresh builds 2023-08-09 19:20:31 -06:00
freedom
c1f6cc41ac update 32x32 icon 2023-08-09 18:38:05 -06:00
freedom
f6d8a032d3 woopsie on the wce stuff 2023-08-09 18:37:53 -06:00
freedom
c16ebce58c fix some stuff 2023-08-09 13:29:25 -06:00
freedom
dbd33f1e5d code formatting (newline at end of file) 2023-08-09 13:25:44 -06:00
freedom
e333bec949 preliminary group file structures 2023-08-09 13:25:29 -06:00
freedom
4cf88a12af something something desktop window blah blah blah WE HAVE MDI!!!! 2023-08-06 00:23:57 -06:00
freedom
738cb64646 fixed system menu not forwarding messages properly 2023-08-06 00:07:25 -06:00
freedom
1206264a68 so much... mdi stuff.. AND IT'S STILL NOT OVER 2023-08-02 00:59:58 -06:00
freedom
8ab85cecf0 fix website link 2023-08-01 13:24:20 -06:00
71 changed files with 2045 additions and 503 deletions

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,15 +1,21 @@
![Program Manager II by Vortesys](/misc/progman.jpg)
[![Latest version](https://img.shields.io/github/v/release/Vortesys/Program-Manager-II?label=latest%20version&sort=semver&style=plastic)](https://github.com/Vortesys/Program-Manager-II/releases) [![Latest pre-release version](https://img.shields.io/github/v/release/Vortesys/Program-Manager-II?label=latest%20pre-release%20version&sort=semver&style=plastic&include_prereleases)](https://github.com/Vortesys/Program-Manager-II/releases) [![Latest version](https://img.shields.io/github/v/release/Vortesys/Program-Manager-II?label=latest%20version&sort=semver&style=plastic)](https://github.com/Vortesys/Program-Manager-II/releases) [![Latest pre-release version](https://img.shields.io/github/v/release/Vortesys/Program-Manager-II?label=latest%20pre-release%20version&sort=semver&style=plastic&include_prereleases)](https://github.com/Vortesys/Program-Manager-II/releases)
# Program Manager *II* for Windows NT
![Progmgr banner](/misc/pman2.png)
## 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.

View File

@@ -1,3 +0,0 @@
7z a -r "%~dp0bin\bin.7z" "%~dp0bin\*.exe"
WinRAR a -r "%~dp0bin\bin.rar" "%~dp0bin\*.exe"
pause

BIN
bin.zip Normal file

Binary file not shown.

37
build.cmd Normal file
View 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

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

BIN
misc/progman.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

View File

@@ -1,202 +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\0";
// Create the ListView
hWndListView = CreateWindowEx(WS_EX_LEFT, WC_LISTVIEW, L"",
WS_VISIBLE | WS_CHILD | WS_BORDER | 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 = &szTestItem;
lviTestItem.cchTextMax = MAXTITLELEN;
// lviTestItem.iImage = 1;
ListView_InsertItem(hWndListView, &lviTestItem);
return hWndListView;
}

492
progmgr/dialog.c Normal file
View 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
View 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);

View File

@@ -1,18 +1,754 @@
/* * * * * * * *\ /* * * * * * * *\
GROUP.C - GROUP.C -
Copyright (c) 2023 freedom7341, Vortesys Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION - DESCRIPTION -
Group window and program item functions. Group window and program group/item 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 */
#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>
/* Functions */ /* Variables */
WNDCLASSEX wcGrp;
WCHAR szGrpClass[16];
HWND hWndMDIClient = NULL;
HWND hWndFoundGroup = NULL;
/* 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 -
Group window procedure.
RETURNS -
Zero if nothing, otherwise returns the good stuff.
\* * * */
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
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;
}
default:
break;
}
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
case WM_SIZE:
{
HWND hWndListView = NULL;
RECT rcGroupWindow = { 0 };
// get the group window rect
GetClientRect(hWnd, &rcGroupWindow);
// find the listview control
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
if (hWndListView == NULL)
break;
// resize it to fit the window
SetWindowPos(hWndListView, NULL,
rcGroupWindow.left, rcGroupWindow.top,
rcGroupWindow.right - rcGroupWindow.left,
rcGroupWindow.bottom - rcGroupWindow.top, SWP_NOZORDER);
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
default:
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
/* * * *\
GroupCmdProc -
Group syscommand procedure.
RETURNS -
Zero if nothing, otherwise returns the good stuff.
\* * * */
LRESULT CALLBACK GroupCmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDM_FILE_OPEN:
{
HWND hWndListView = NULL;
LVITEM lvi = { 0 };
PITEM pItem = NULL;
// find the listview control
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
if (hWndListView == NULL)
break;
// what info do we want?
lvi.mask = LVIF_PARAM;
lvi.iItem = ((LPNMITEMACTIVATE)lParam)->iItem;
// get the listview item
ListView_GetItem(hWndListView, &lvi);
// get the item pointer
pItem = (PITEM)lvi.lParam;
// verify...
if (pItem)
{
// and execute!
ExecuteItem(pItem);
}
}
case IDM_FILE_MOVE:
// TODO: ITEM Create dialog with other MDI groups, pick one to move item
break;
case IDM_FILE_COPY:
// TODO: ITEM Copy item structure to clipboard
break;
case IDM_FILE_DELETE:
// TODO: ITEM/GROUP Delete selected item, if no items selected or no items
// exist then delete the group
break;
case IDM_FILE_PROPS:
// TODO: ITEM/GROUP Open properties of selected item or if nothing selected
// then open group properties
break;
default:
return 0;
}
return 0;
}

View File

@@ -1,8 +1,8 @@
/* * * * * * * *\ /* * * * * * * *\
GROUP.H - GROUP.H -
Copyright (c) 2023 freedom7341, Vortesys Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION - DESCRIPTION -
Program group and item structures and... stuff. Program group/item structures, functions and definitons
LICENSE INFORMATION - LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder MIT License, see LICENSE.txt in the root folder
\* * * * * * * */ \* * * * * * * */
@@ -10,6 +10,84 @@
/* Pragmas */ /* Pragmas */
#pragma once #pragma once
/* Includes */ /* Definitions */
#include <wtypes.h> #define MAX_GROUPS 512
#define MAX_ITEMS 512
#define MAX_TITLE_LENGTH 255 // Same as the registry key name max length
#define ITEM_BATCH_COUNT 8
// Group Format Definitions
#define GRP_SIGNATURE 0x47324D50L // PM2G
#define GRP_VERSION 2 // Increment for breaking changes, format version
// Group Flag Values (DWORD)
#define GRP_FLAG_COMMON 0x00000001
#define GRP_FLAG_READONLY 0x00000002
#define GRP_FLAG_MINIMIZED 0x00000004
#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 */
// Item Structure
typedef struct _ITEM {
// Item executable and name
WCHAR szName[MAX_TITLE_LENGTH];
WCHAR szExecPath[MAX_PATH]; // Path of the executable
WCHAR szWorkPath[MAX_PATH]; // Working directory
// Item flags
DWORD dwFlags; // Use with ITM_FLAG_* values.
UINT uiHotkeyModifiers;
UINT uiHotkeyVirtualKey;
// Icon
WCHAR szIconPath[MAX_PATH];
INT iIconIndex;
} ITEM, * PITEM;
// Group format, .GRP
typedef struct _GROUP {
// Group file header
DWORD dwSignature; // Set to GRP_SIGNATURE
WORD wVersion; // Group format version
WORD wChecksum;
// Group information
WCHAR szName[MAX_TITLE_LENGTH];
DWORD dwFlags; // Use with GRP_FLAG_* values.
FILETIME ftLastWrite;
// Window information
RECT rcGroup;
WINDOWPLACEMENT wp;
// Icon
WCHAR szIconPath[MAX_PATH];
INT iIconIndex;
// Items
WORD cItemArray; // Number of items in pItemArray
ITEM pItemArray[1]; // Array of items
} GROUP, * PGROUP;
/* Global Variables */
extern HWND hWndMDIClient;
/* Local Variables */
/* 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 GroupCmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam);

38
progmgr/grpupdat.h Normal file
View 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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
progmgr/icons/progmgrd.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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,28 +8,57 @@
\* * * * * * * */ \* * * * * * * */
/* Headers */ /* Headers */
#include "progmgr.h" #define WIN32_LEAN_AND_MEAN
#include "resource.h"
#include "registry.h"
// #define WIN32_LEAN_AND_MEAN
#define SECURITY_WIN32 #define SECURITY_WIN32
#include <Windows.h> #include <Windows.h>
#include "progmgr.h"
#include "group.h"
#include "resource.h"
#include "registry.h"
/* Variables */ /* Variables */
// Global // Global
BOOL bIsDefaultShell = FALSE; #ifdef _DEBUG
BOOL g_bIsDebugBuild = TRUE;
#else
BOOL g_bIsDebugBuild = FALSE;
#endif
BOOL g_bIsDefaultShell = FALSE;
// Handles
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];
// Window Related WCHAR g_szClass[16];
HICON hProgMgrIcon = NULL; // Permissions
HINSTANCE hAppInstance; BOOL g_bPermAdmin; // Has Administrator permissions
HWND hWndProgMgr = NULL; BOOL g_bPermGuest; // Has Guest permissions
HWND hWndMDIClient = NULL; 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.
@@ -40,49 +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 };
WCHAR szBuffer[MAX_PATH]; WCHAR szBuffer[MAX_PATH];
WCHAR szClass[16];
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_APPTITLE, szAppTitle, ARRAYSIZE(szAppTitle)); LoadString(g_hAppInstance, IDS_APPTITLE, g_szAppTitle, ARRAYSIZE(g_szAppTitle));
LoadString(hAppInstance, IDS_WEBSITE, szWebsite, ARRAYSIZE(szWebsite)); LoadString(g_hAppInstance, IDS_WEBSITE, g_szWebsite, ARRAYSIZE(g_szWebsite));
// Lazily search for another instance of Program Manager
// If we find one, switch focus to it and then abort.
hOldProgMgr = FindWindowEx(NULL, NULL, g_szClass, NULL);
if (hOldProgMgr != NULL)
{
SwitchToThisWindow(hOldProgMgr, FALSE);
return FALSE;
}
// Get Desktop background color // Get Desktop background color
//CreateSolidBrush(GetBackgroundColor //CreateSolidBrush(GetBackgroundColor
// Register the Frame Window // 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.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN); wc.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
wc.lpszClassName = szClass; wc.lpszClassName = g_szClass;
if (!RegisterClass(&wc)) if (!RegisterClass(&wc))
return FALSE; return FALSE;
// Load the Accelerator table // Load the Accelerator table
hAccel = LoadAccelerators(hAppInstance, MAKEINTRESOURCE(IDA_ACCELS)); hAccel = LoadAccelerators(g_hAppInstance, MAKEINTRESOURCE(IDA_ACCELS));
if (!hAccel) if (!hAccel)
return FALSE; return FALSE;
// 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);
@@ -92,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);
@@ -121,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);
} }
@@ -153,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
*/

View File

@@ -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>

View File

@@ -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,19 +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 HINSTANCE hAppInstance; extern HWND g_hWndProgMgr;
extern HWND hWndProgMgr; // Icons
extern HWND hWndMDIClient; extern HICON g_hProgMgrIcon;
extern WCHAR szAppTitle[32]; extern HICON g_hGroupIcon;
extern WCHAR szProgMgr[]; // Strings
extern WCHAR szWebsite[64]; extern WCHAR g_szAppTitle[64];
extern WCHAR g_szProgMgr[];
extern WCHAR g_szWebsite[64];
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);
@@ -50,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);

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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);

Binary file not shown.

View File

@@ -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

View File

@@ -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)
{ {

Binary file not shown.

View File

@@ -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,15 +8,19 @@
\* * * * * * * */ \* * * * * * * */
/* Headers */ /* Headers */
#include "progmgr.h" #define WIN32_LEAN_AND_MEAN
#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 */
@@ -33,73 +37,48 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE: case WM_CREATE:
{ {
RECT rc; // Play the logon sound. (But only if we're the default shell)
CLIENTCREATESTRUCT ccs; if (g_bIsDefaultShell)
PlaySound(TEXT("WindowsLogon"), NULL, SND_ALIAS | SND_ASYNC);
// Frame Window return TRUE;
hWndProgMgr = hWnd;
// MDI Client Window
ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), IDM_WINDOW);
ccs.idFirstChild = IDM_WINDOW_CHILDSTART;
GetClientRect(hWndProgMgr, &rc);
hWndMDIClient = CreateWindow(L"MDIClient", NULL,
WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL,
// rc.left - 1, rc.top - 1, rc.right + 2, rc.bottom + 2,
0, 0, 0, 0,
hWnd, (HMENU)1, hAppInstance, (LPWSTR)&ccs);
if (!hWndMDIClient) {
return -1;
}
break;
} }
case WM_SYSCOMMAND: case WM_SYSCOMMAND:
{ {
if (wParam == IDM_TASKMGR) if ((wParam >= IDM_MAIN) && (wParam <= IDM_TASKMGR))
{ {
ShellExecute(hWndProgMgr, L"open", L"TASKMGR.EXE", NULL, NULL, SW_NORMAL); if (wParam == IDM_TASKMGR)
break; {
ShellExecute(g_hWndProgMgr, TEXT("open"), TEXT("TASKMGR.EXE"), NULL, NULL, SW_NORMAL);
return 0;
}
if (CmdProc(hWnd, wParam, lParam))
return 0;
} }
if (wParam == IDM_SHUTDOWN) return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
if (wParam == IDM_FILE_EXIT)
if (wParam == IDM_FILE_RUN)
{
CmdProc(hWnd, wParam, lParam);
break;
}
goto WndProcDefault;
//return DefFrameProc(hWnd, hwndMDIClient, uiMsg, wParam, lParam);
} }
case WM_COMMAND: case WM_COMMAND:
if (CmdProc(hWnd, wParam, lParam)) if (CmdProc(hWnd, wParam, lParam))
{ return 0;
break;
} return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
goto WndProcDefault;
case WM_CLOSE: case WM_CLOSE:
case WM_ENDSESSION:
if (bSaveSettings) if (bSaveSettings)
SaveConfig(TRUE, TRUE, TRUE); SaveConfig(TRUE, TRUE, TRUE, TRUE);
if (bIsDefaultShell && (GetShellWindow() != NULL)) if (g_bIsDefaultShell && (GetShellWindow() != NULL))
SetShellWindow(0); SetShellWindow(0);
PostQuitMessage(0); PostQuitMessage(0);
break; break;
case WM_ENDSESSION:
PostQuitMessage(0);
break;
default: default:
WndProcDefault:
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam); return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
} }
return 0; return 0;
@@ -118,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;
@@ -141,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;
@@ -157,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;
} }
@@ -191,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;
@@ -204,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;
}

3
zip.cmd Normal file
View File

@@ -0,0 +1,3 @@
del /s "%~dp0\*.zip"
7z a -r "%~dp0\bin.zip" "%~dp0bin\*.exe"
pause