42 Commits

Author SHA1 Message Date
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
25 changed files with 766 additions and 111 deletions

1
.gitignore vendored
View File

@@ -57,3 +57,4 @@ dkms.conf
/bin/
/misc/supermiumman.png
/bin.7z
*.zip

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -111,7 +111,7 @@ LRESULT CALLBACK DeskWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
hWndDesktop = hWnd;
// Set the window position to shell
SetShellWindow(hWndDesktop);
// SetShellWindow(hWndDesktop);
ShowWindow(hWndDesktop, SW_MAXIMIZE);
// Strip the border from the desktop window
@@ -173,11 +173,12 @@ HWND CreateListView(HWND hWndParent, RECT rc)
{
HWND hWndListView;
LVITEM lviTestItem;
//WCHAR szTestItem[] = L"Test Item\0";
WCHAR szTestItem[] = L"Test Item";
// Create the ListView
hWndListView = CreateWindowEx(WS_EX_LEFT, WC_LISTVIEW, L"",
WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_ICON | LVS_SINGLESEL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
LVS_ICON | LVS_SINGLESEL,
rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
hWndParent, (HMENU)ID_LISTVIEW, hAppInstance,
NULL);
@@ -192,11 +193,11 @@ HWND CreateListView(HWND hWndParent, RECT rc)
lviTestItem.iSubItem = 0;
lviTestItem.state = 0;
lviTestItem.stateMask = 0;
//lviTestItem.pszText = &szTestItem;
lviTestItem.pszText = (LPWSTR)&szTestItem;
lviTestItem.cchTextMax = MAXTITLELEN;
// lviTestItem.iImage = 1;
ListView_InsertItem(hWndListView, &lviTestItem);
return hWndListView;
}
}

201
progmgr/dialog.c Normal file
View File

@@ -0,0 +1,201 @@
/* * * * * * * *\
DIALOG.C -
Copyright (c) 2023 freedom7341, Vortesys
DESCRIPTION -
Program Manager's dialogs and related
common functions.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Headers */
#include "progmgr.h"
#include "dialog.h"
#include "group.h"
#include "resource.h"
// #define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Shlobj.h>
#include <strsafe.h>
/* 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)
{
GROUP grp = {
.dwSignature = GRP_SIGNATURE,
.wVersion = GRP_VERSION,
.wChecksum = 0,
.szName = L"",
.dwFlags = 0,
.ftLastWrite = 0,
.cItems = 0,
.iItems = NULL
};
BOOL bOKEnabled = FALSE;
WCHAR szBuffer[MAX_TITLE_LENGTH] = { L"\0" };
HICON hIconDef = NULL;
HICON hIconDlg = NULL;
WCHAR szIconPath[MAX_PATH] = { L"\0" };
INT iIconIndex = 0;
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
// Populate the icon with the default path and index.
GetModuleFileName(NULL, (LPWSTR)&szIconPath, MAX_PATH);
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(hAppInstance, (LPWSTR)&szIconPath, 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);
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)&szIconPath, ARRAYSIZE(szIconPath), &iIconIndex) == TRUE)
{
// Since we've got the new icon...
hIconDlg = ExtractIcon(hAppInstance, (LPWSTR)&szIconPath, iIconIndex);
SendDlgItemMessage(hWndDlg, IDD_STAT_ICON, STM_SETICON, (WPARAM)hIconDlg, 0);
}
break;
case IDD_OK:
// Check that all the applicable fields are filled out
bOKEnabled = GetDlgItemText(hWndDlg, IDD_NAME, (LPWSTR)&szBuffer, ARRAYSIZE(szBuffer));
// If not, set the focus to the offending field
if (!bOKEnabled)
SendDlgItemMessage(hWndDlg, IDD_NAME, EM_TAKEFOCUS, 0, 0);
// 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;
// TODO: set FILETIME
// Set the rectangle of the group to be CW_USEDEFAULT
grp.rcGroup.left = grp.rcGroup.top = grp.rcGroup.right = grp.rcGroup.bottom = CW_USEDEFAULT;
// Set icon properties
StringCchCopy(grp.szIconPath, ARRAYSIZE(szIconPath), szIconPath);
grp.iIconIndex = iIconIndex;
// Group's ready!
if (CreateGroupWindow(&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)
{
switch (message)
{
case WM_INITDIALOG:
// Place message cases here.
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDD_CANCEL:
EndDialog(hWndDlg, FALSE);
break;
default:
break;
}
default:
return FALSE;
}
return TRUE;
}

16
progmgr/dialog.h Normal file
View File

@@ -0,0 +1,16 @@
/* * * * * * * *\
DIALOG.H -
Copyright (c) 2023 freedom7341, Vortesys
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);

View File

@@ -2,7 +2,7 @@
GROUP.C -
Copyright (c) 2023 freedom7341, Vortesys
DESCRIPTION -
Group window and program item functions.
Group window and program group/item functions.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
@@ -14,5 +14,236 @@
#include "registry.h"
// #define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <strsafe.h>
/* Functions */
/* Variables */
WNDCLASSEX wcGrp;
WCHAR szGrpClass[16];
PGROUPWND pgwArray[];
HWND hWndMDIClient = 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()
{
CLIENTCREATESTRUCT ccs = { 0 };
WNDCLASSEX wce = { 0 };
RECT rcFrame;
// Create the MDI Client Window
ccs.hWindowMenu = GetSubMenu(GetMenu(hWndProgMgr), IDM_WINDOW);
ccs.idFirstChild = IDM_WINDOW_CHILDSTART;
GetClientRect(hWndProgMgr, &rcFrame);
if (!(hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED, L"MDIClient",
NULL, WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
rcFrame.left, rcFrame.top, rcFrame.right, rcFrame.bottom,
hWndProgMgr, (HMENU)1, hAppInstance, (LPWSTR)&ccs)))
{
return FALSE;
}
// Load the group class string
LoadString(hAppInstance, IDS_GRPCLASS, szGrpClass, ARRAYSIZE(szGrpClass));
// Register the group window Class
wce.cbSize = sizeof(WNDCLASSEX);
wce.lpfnWndProc = GroupWndProc;
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hInstance = hAppInstance;
wce.hIcon = hGroupIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON,
0, 0, LR_DEFAULTSIZE | LR_SHARED);
wce.hCursor = LoadCursor(NULL, IDC_ARROW);
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wce.lpszMenuName = NULL;
wce.lpszClassName = szGrpClass;
if (!RegisterClassEx(&wce))
return FALSE;
// CreateGroupWindow(NULL);
return TRUE;
}
/* * * *\
CreateGroupWindow -
Create an MDI window from a group structure
RETURNS -
Pointer to a group window structure
or NULL on failure
\* * * */
PGROUPWND CreateGroupWindow(PGROUP pgGroup)
{
GROUPWND gw = { NULL };
MDICREATESTRUCT mcs = { NULL };
HICON hIconBig = NULL;
HICON hIconSmall = NULL;
// Copy group structure to our group window
gw.grp = *pgGroup;
// TODO: allocate memory from pgwArray in here
// TODO: Automatically add itself to the array of
// PGW pointers?
// Get group minimized/maximized flags
mcs.szClass = szGrpClass;
mcs.szTitle = gw.grp.szName;
mcs.hOwner = hAppInstance;
if ((gw.grp.rcGroup.left == CW_USEDEFAULT) & (gw.grp.rcGroup.right == CW_USEDEFAULT))
{
mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT;
}
else
{
mcs.x = gw.grp.rcGroup.left;
mcs.y = gw.grp.rcGroup.top;
mcs.cx = gw.grp.rcGroup.right - gw.grp.rcGroup.left;
mcs.cy = gw.grp.rcGroup.bottom - gw.grp.rcGroup.top;
}
mcs.style = WS_VISIBLE;
mcs.lParam = (LPARAM)pgGroup;
if (!(gw.hWndGroup = (HWND)SendMessage(hWndMDIClient, WM_MDICREATE, 0, (LPARAM)(LPTSTR)&mcs)))
return NULL;
// Load the group icon
ExtractIconEx(gw.grp.szIconPath, gw.grp.iIconIndex, &hIconBig, &hIconSmall, 0);
SendMessage(gw.hWndGroup, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall);
SendMessage(gw.hWndGroup, WM_SETICON, ICON_BIG, (LPARAM)hIconBig);
// TODO: make sure the groups delete their icons upon destruction!
return &gw;
}
/* * * *\
SetGroupFlags -
Retrieve the flags of a group window.
RETURNS -
TRUE if the flag mask is applied
FALSE if the flags aren't set
\* * * */
BOOL SetGroupFlags(PGROUPWND pgw, DWORD dwFlags)
{
return FALSE;
}
/* * * *\
GetGroupFlags -
Retrieve the flags of a group window.
RETURNS -
TRUE if the flag mask is applied
FALSE if the flags aren't set
\* * * */
BOOL GetGroupFlags(PGROUPWND pgw, DWORD dwFlags)
{
HWND hWndGrp;
// Cancel if the group window doesn't exist
if (pgw == NULL)
return 0xFFFFFFFF;
// Get the window handle
hWndGrp = pgw->hWndGroup;
if (hWndGrp != NULL)
{
// NOTE: come back to this lol
// TODO: establish better what this actually does
// min/max flags are pulled from hwnd
// common/readonly flags are set upon group creation
// this means that some flags are static whereas
// others change over time, this means that we can
// either assume certain flags never change over time
// or grab them every time.
return 0xFFFFFFFF;
}
return 0xFFFFFFFF;
}
/* * * *\
SaveGroup -
Saves group from a group window
into a GROUP structure.
ABSTRACT -
This function will extract all of the
necessary information from a group window
in order to produce a group structure.
RETURNS -
Formatted GROUP structure.
Upon failure, wChecksum will be 0.
\* * * */
GROUP SaveGroup(PGROUPWND pgw)
{
GROUP grp = {
.dwSignature = GRP_SIGNATURE,
.wVersion = GRP_VERSION,
.wChecksum = 0,
.szName = L"",
.dwFlags = 0,
.ftLastWrite = 0,
.cItems = 0,
.iItems = NULL
};
HWND hWndGrp;
WCHAR szGroupName[MAX_TITLE_LENGTH];
// Find the group and copy it
grp = pgw->grp;
// Get the window handle as well
hWndGrp = pgw->hWndGroup;
// Set the group checksum
grp.wChecksum = 1; // NOTE: implement this for real later lol
// Copy group information
GetWindowText(hWndGrp, szGroupName, MAX_TITLE_LENGTH);
StringCchCopy(grp.szName, MAX_TITLE_LENGTH, szGroupName);
grp.dwFlags = GRP_FLAG_MAXIMIZED;// GetGroupFlags(pgw);
GetSystemTimeAsFileTime(&grp.ftLastWrite);
// Save items...
grp.cItems = 0;
// TODO: iterate through listview to save items
return grp;
}
/* * * *\
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:
{
break;
}
default:
// GroupProcDefault:
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
return 0;
}

View File

@@ -2,7 +2,7 @@
GROUP.H -
Copyright (c) 2023 freedom7341, Vortesys
DESCRIPTION -
Program group and item structures and... stuff.
Program group/item structures, functions and definitons
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
@@ -10,6 +10,79 @@
/* Pragmas */
#pragma once
/* Includes */
#include <wtypes.h>
/* Definitions */
#define MAX_GROUPS 512
#define MAX_ITEMS 512
#define MAX_TITLE_LENGTH MAX_PATH
// Group Format Definitions
#define GRP_SIGNATURE 0x47324D50L // PM2G
#define GRP_VERSION 1 // Increment for breaking changes
// 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_MINIMIZED 0x00000001
#define ITM_FLAG_MAXIMIZED 0x00000002
/* 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;
// Icon
WCHAR szIconPath[MAX_PATH];
INT iIconIndex;
// Items
WORD cItems; // Number of items
PITEM iItems; // Array of items
} GROUP, * PGROUP;
// Group window information
typedef struct _GROUPWND {
// Windows
HWND hWndGroup;
HWND hWndListView;
// Group
GROUP grp; // Pointer to GROUP structure
} GROUPWND, * PGROUPWND;
/* Global Variables */
extern HWND hWndMDIClient;
/* Local Variables */
/* Function Prototypes */
BOOL InitializeGroups();
// Group Window
LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
PGROUPWND CreateGroupWindow(PGROUP pgGroup);
// Group information
BOOL SetGroupFlags(PGROUPWND pgw, DWORD dwFlags);
BOOL GetGroupFlags(PGROUPWND pgw, DWORD dwFlags);
// Import/export functions
GROUP SaveGroup(PGROUPWND pgw);

38
progmgr/grpupdat.h Normal file
View File

@@ -0,0 +1,38 @@
/* * * * * * * *\
GRPUPDAT.H -
Copyright (c) 2023 freedom7341, Vortesys
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: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

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.

Binary file not shown.

View File

@@ -9,6 +9,7 @@
/* Headers */
#include "progmgr.h"
#include "group.h"
#include "resource.h"
#include "registry.h"
// #define WIN32_LEAN_AND_MEAN
@@ -18,15 +19,18 @@
/* Variables */
// Global
BOOL bIsDefaultShell = FALSE;
// Handles
HINSTANCE hAppInstance;
HANDLE hAppHeap;
HWND hWndProgMgr = NULL;
// Icons
HICON hProgMgrIcon = NULL;
HICON hGroupIcon = NULL;
// Global Strings
WCHAR szAppTitle[32];
WCHAR szProgMgr[] = L"progmgr";
WCHAR szWebsite[64];
// Window Related
HICON hProgMgrIcon = NULL;
HINSTANCE hAppInstance;
HWND hWndProgMgr = NULL;
HWND hWndMDIClient = NULL;
WCHAR szClass[16];
/* Functions */
@@ -42,12 +46,15 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
HMENU hSystemMenu;
WNDCLASS wc = { 0 };
WCHAR szBuffer[MAX_PATH];
WCHAR szClass[16];
RECT rcRoot;
POINT ptOffset;
// Initialize the instance
hAppInstance = hInstance;
// Create our global heap handle
hAppHeap = GetProcessHeap();
// Create Strings
LoadString(hAppInstance, IDS_PMCLASS, szClass, ARRAYSIZE(szClass));
LoadString(hAppInstance, IDS_APPTITLE, szAppTitle, ARRAYSIZE(szAppTitle));
@@ -56,15 +63,17 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
// Get Desktop background color
//CreateSolidBrush(GetBackgroundColor
// Register the Frame Window
// Register the Frame Window Class
wc.lpfnWndProc = WndProc;
wc.hInstance = hAppInstance;
wc.hIcon = hProgMgrIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGMGR), IMAGE_ICON,
0, 0, LR_DEFAULTSIZE | LR_SHARED);
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.lpszClassName = szClass;
if (!RegisterClass(&wc))
return FALSE;
@@ -74,15 +83,14 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
return FALSE;
// Perform Registry actions, close if registry is inaccessible.
if (InitializeRegistryKeys())
{
bIsDefaultShell = IsProgMgrDefaultShell();
LoadConfig();
}
else
{
if (!InitializeRegistryKeys())
return FALSE;
bIsDefaultShell = IsProgMgrDefaultShell();
// Load configuration, but don't load groups yet
if(LoadConfig(TRUE, TRUE, FALSE) != RCE_SUCCESS)
return FALSE;
}
// Get size of the root HWND
GetWindowRect(GetDesktopWindow(), &rcRoot);
@@ -92,11 +100,11 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
SystemParametersInfo(SPI_ICONVERTICALSPACING, 0, &ptOffset.y, 0);
// Create main window with a default size
// NOTE: i pulled 320x240 out of my ass, make this dynamic later
if (!CreateWindow(wc.lpszClassName, szAppTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
// TODO: i pulled 320x240 out of my ass, make this dynamic later
if (!(hWndProgMgr = CreateWindowW(wc.lpszClassName, szAppTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
rcRoot.left + ptOffset.x, rcRoot.top + ptOffset.y,
rcRoot.left + ptOffset.x + 320, rcRoot.top + ptOffset.y + 240,
0, 0, hAppInstance, NULL))
0, 0, hAppInstance, NULL)))
return 2;
// Set the window size from the registry, but only if the coords make sense
@@ -142,6 +150,10 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
// CreateDesktopWindow();
}
// Create the frame window
if (!InitializeGroups())
return FALSE;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
if (!TranslateMDISysAccel(hWndMDIClient, &msg) &&

View File

@@ -29,15 +29,19 @@
#define RF_RETRY 0x0002 // Cancel the operation, but leave the dialog open
/* Global Variables */
// PROGMGR.C
extern BOOL bIsDefaultShell;
extern HICON hProgMgrIcon;
// Handles
extern HINSTANCE hAppInstance;
extern HANDLE hAppHeap;
extern HWND hWndProgMgr;
extern HWND hWndMDIClient;
// Icons
extern HICON hProgMgrIcon;
extern HICON hGroupIcon;
// Strings
extern WCHAR szAppTitle[32];
extern WCHAR szProgMgr[];
extern WCHAR szWebsite[64];
extern WCHAR szClass[16];
/* Function Prototypes */
// DESKTOP.C
@@ -50,4 +54,4 @@ BOOL SetShellWindow(HWND hWndShell);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam);
VOID UpdateChecks(BOOL bVarMenu, UINT uSubMenu, UINT uID);
VOID UpdateWindowTitle();
VOID UpdateWindowTitle();

View File

@@ -159,13 +159,16 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="dialog.h" />
<ClInclude Include="group.h" />
<ClInclude Include="grpupdat.h" />
<ClInclude Include="progmgr.h" />
<ClInclude Include="registry.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="desktop.c" />
<ClCompile Include="dialog.c" />
<ClCompile Include="progmgr.c" />
<ClCompile Include="registry.c" />
<ClCompile Include="group.c" />

View File

@@ -30,6 +30,12 @@
<ClInclude Include="group.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="grpupdat.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dialog.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="progmgr.c">
@@ -50,6 +56,9 @@
<ClCompile Include="group.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dialog.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">

View File

@@ -9,6 +9,7 @@
/* Headers */
#include "progmgr.h"
#include "group.h"
#include "registry.h"
// #define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -110,24 +111,67 @@ BOOL IsProgMgrDefaultShell()
return FALSE;
}
/* * * *\
SaveGroupToRegistry -
Saves a group structure to registry.
RETURNS -
RCE_* configuration error value
\* * * */
DWORD SaveGroupToRegistry(_In_ PGROUP pg)
{
DWORD dwConfigStatus = RCE_SUCCESS;
// If the pointer is invalid then fail out
if (pg == NULL)
return RCE_FAILURE;
// Save group
if (!RegSetValueEx(hKeyProgramGroups, pg->szName, 0, REG_BINARY,
(const BYTE*)pg, (sizeof(*pg) + sizeof(ITEM) * pg->cItems)) == ERROR_SUCCESS)
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
return dwConfigStatus;
}
/* * * *\
LoadGroupFromRegistry -
Loads a group structure from the registry.
RETURNS -
RCE_* configuration error value
\* * * */
DWORD LoadGroupFromRegistry(_Inout_ PGROUP pg, _Out_ DWORD dwBufferSize)
{
DWORD dwConfigStatus = RCE_SUCCESS;
DWORD dwType = REG_BINARY;
// If the pointer is invalid then fail out
if (pg == NULL)
return RCE_FAILURE;
// Load group
if (!RegQueryValueEx(hKeyProgramGroups, pg->szName, 0, &dwType,
(LPBYTE)pg, &dwBufferSize) == ERROR_SUCCESS)
dwConfigStatus = dwConfigStatus && RCE_POSITION;
return dwConfigStatus;
}
/* * * *\
SaveConfig -
Finds and collapses all settings
and saves them to the registry.
RETURNS -
TRUE if successful, FALSE if unsuccessful.
RCE_* configuration error value
\* * * */
BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups)
DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
{
BOOL bConfigStatus = TRUE;
WINDOWPLACEMENT wpProgMgr;
RECT rcWindow;
DWORD dwConfigStatus = RCE_SUCCESS;
if (bSettings)
{
// Shrink the settings into the bitmask and save it
// There's definitely a better way to do this but...
// I'll get to it later :)
// TODO: do this more efficiently
dwSettingsMask =
(bAutoArrange && PMS_AUTOARRANGE) * PMS_AUTOARRANGE |
(bMinOnRun && PMS_MINONRUN) * PMS_MINONRUN |
@@ -137,11 +181,14 @@ BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups)
if (!RegSetValueEx(hKeySettings, pszSettingsMask, 0, REG_DWORD,
(const BYTE*)&dwSettingsMask, sizeof(dwSettingsMask)) == ERROR_SUCCESS)
bConfigStatus = FALSE;
dwConfigStatus = dwConfigStatus && RCE_SETTINGS;
}
if (bPos)
{
WINDOWPLACEMENT wpProgMgr;
RECT rcWindow;
// Get and save window position
wpProgMgr.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hWndProgMgr, &wpProgMgr);
@@ -149,42 +196,65 @@ BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups)
if (!RegSetValueEx(hKeySettings, pszSettingsWindow, 0, REG_BINARY,
(const BYTE*)&rcWindow, sizeof(rcWindow)) == ERROR_SUCCESS)
bConfigStatus = FALSE;
dwConfigStatus = dwConfigStatus && RCE_POSITION;
}
return bConfigStatus;
if (bGroups)
{
// TODO: Get list of groups, iterate through,
// save each one as an individual subkey based
// on the name of the group
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
}
return dwConfigStatus;
}
/* * * *\
BOOL LoadConfig() -
LoadConfig() -
Finds all settings and retrieves them
from the registry.
RETURNS -
TRUE if successful, FALSE if unsuccessful.
RCE_* configuration error value
\* * * */
BOOL LoadConfig()
DWORD LoadConfig(BOOL bSettings, BOOL bPos, BOOL bGroups)
{
BOOL bConfigStatus = TRUE;
DWORD dwType;
DWORD dwBufferSize = sizeof(dwSettingsMask);
DWORD dwRectBufferSize = sizeof(rcMainWindow);
DWORD dwConfigStatus = RCE_SUCCESS;
// Load settings bitmask
if (!RegQueryValueEx(hKeySettings, pszSettingsMask, 0, &dwType,
(LPBYTE)&dwSettingsMask, &dwBufferSize) == ERROR_SUCCESS)
bConfigStatus = FALSE;
// 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 (bSettings)
{
DWORD dwBufferSize = sizeof(dwSettingsMask);
DWORD dwType = REG_DWORD;
// Load window position... and apply it!
if (!RegQueryValueEx(hKeySettings, pszSettingsWindow, 0, &dwType,
(LPBYTE)&rcMainWindow, &dwRectBufferSize) == ERROR_SUCCESS)
bConfigStatus = FALSE;
// Load settings bitmask
if (!RegQueryValueEx(hKeySettings, pszSettingsMask, 0, &dwType,
(LPBYTE)&dwSettingsMask, &dwBufferSize) == ERROR_SUCCESS)
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)
{
// TODO: this is unbearable
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
}
return dwConfigStatus;
}

View File

@@ -20,7 +20,13 @@
// #define PROGMAN_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager"
// #define WINDOWS_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
#define PROGMGR_KEY L"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_MINONRUN 0x00000002
#define PMS_TOPMOST 0x00000004
@@ -43,5 +49,9 @@ extern RECT rcMainWindow;
/* Function Prototypes */
BOOL InitializeRegistryKeys(VOID);
BOOL IsProgMgrDefaultShell(VOID);
BOOL LoadConfig(VOID);
BOOL SaveConfig(BOOL bPos, BOOL bSettings, BOOL bGroups);
// Groups
DWORD SaveGroupToRegistry(_In_ PGROUP pg);
DWORD LoadGroupFromRegistry(_Inout_ PGROUP pg, _Out_ DWORD dwBufferSize);
// Settings
DWORD SaveConfig(BOOL bSettings, BOOL bPos, BOOL bGroups);
DWORD LoadConfig(BOOL bSettings, BOOL bPos, BOOL bGroups);

Binary file not shown.

View File

@@ -17,6 +17,7 @@
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(65001) // UTF-8
#include "lang\res_en-US.rc" // English (US)
#include "lang\dlg_en-US.rc" // English (US)
/* Icon Library */
// Primary

Binary file not shown.

View File

@@ -9,6 +9,8 @@
/* Headers */
#include "progmgr.h"
#include "dialog.h"
#include "group.h"
#include "resource.h"
#include "registry.h"
// #define WIN32_LEAN_AND_MEAN
@@ -33,55 +35,30 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE:
{
RECT rc;
CLIENTCREATESTRUCT ccs;
// Frame Window
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:
{
if (wParam == IDM_TASKMGR)
if ((wParam >= IDM_MAIN) && (wParam <= IDM_TASKMGR))
{
ShellExecute(hWndProgMgr, L"open", L"TASKMGR.EXE", NULL, NULL, SW_NORMAL);
break;
}
if (wParam == IDM_TASKMGR)
{
ShellExecute(hWndProgMgr, L"open", L"TASKMGR.EXE", NULL, NULL, SW_NORMAL);
return 0;
}
if (wParam == IDM_SHUTDOWN)
if (wParam == IDM_FILE_EXIT)
if (wParam == IDM_FILE_RUN)
{
CmdProc(hWnd, wParam, lParam);
break;
if (CmdProc(hWnd, wParam, lParam))
return 0;
}
goto WndProcDefault;
//return DefFrameProc(hWnd, hwndMDIClient, uiMsg, wParam, lParam);
}
case WM_COMMAND:
if (CmdProc(hWnd, wParam, lParam))
{
break;
}
return 0;
goto WndProcDefault;
case WM_CLOSE:
@@ -99,7 +76,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
default:
WndProcDefault:
WndProcDefault:
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
}
return 0;
@@ -120,7 +97,15 @@ LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
case IDM_SHUTDOWN:
ExitWindowsDialog(hWnd);
break;
case IDM_FILE_NEW_GROUP:
DialogBox(hAppInstance, MAKEINTRESOURCE(DLG_GROUP), hWnd, (DLGPROC)NewGroupDlgProc);
break;
case IDM_FILE_NEW_ITEM:
DialogBox(hAppInstance, MAKEINTRESOURCE(DLG_ITEM), hWnd, (DLGPROC)NewItemDlgProc);
break;
case IDM_FILE_RUN:
RunFileDlg(hWnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
break;
@@ -157,7 +142,7 @@ LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
goto SaveConfig;
case IDM_OPTIONS_SAVENOW:
SaveConfig:
SaveConfig:
SaveConfig(TRUE, TRUE, TRUE);
break;
@@ -236,4 +221,4 @@ VOID UpdateWindowTitle()
LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return FALSE;
}
}

3
zipbuild.bat Normal file
View File

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