rename directory

This commit is contained in:
Brady McDermott
2024-10-20 21:18:56 -06:00
parent cc62e8dc38
commit 4a8ef09334
53 changed files with 0 additions and 3150 deletions

View File

@@ -1,492 +0,0 @@
/* * * * * * * *\
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;
}

View File

@@ -1,17 +0,0 @@
/* * * * * * * *\
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,677 +0,0 @@
/* * * * * * * *\
GROUP.C -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Group window and program group/item functions.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* 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 "group.h"
#include "resource.h"
#include "registry.h"
/* 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: 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: set name and 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 0;
}
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;
}
}
return 0;
}
case WM_SIZE:
{
HWND hWndListView = NULL;
RECT rcGroupWindow = { 0 };
// get the group window rect
GetClientRect(hWnd, &rcGroupWindow);
// find the listview control
hWndListView = FindWindowEx(hWnd, NULL, WC_LISTVIEW, NULL);
if (hWndListView == NULL)
break;
// resize it to fit the window
SetWindowPos(hWndListView, NULL,
rcGroupWindow.left, rcGroupWindow.top,
rcGroupWindow.right - rcGroupWindow.left,
rcGroupWindow.bottom - rcGroupWindow.top, SWP_NOZORDER);
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
default:
return DefMDIChildProc(hWnd, message, wParam, lParam);
}
return TRUE;
}

View File

@@ -1,92 +0,0 @@
/* * * * * * * *\
GROUP.H -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program group/item structures, functions and definitons
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Pragmas */
#pragma once
/* Definitions */
#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 + 1];
WCHAR szExecPath[MAX_PATH + 1]; // Path of the executable
WCHAR szWorkPath[MAX_PATH + 1]; // Working directory
// Item flags
DWORD dwFlags; // Use with ITM_FLAG_* values.
UINT uiHotkeyModifiers;
UINT uiHotkeyVirtualKey;
// Icon
WCHAR szIconPath[MAX_PATH + 1];
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 + 1];
DWORD dwFlags; // Use with GRP_FLAG_* values.
FILETIME ftLastWrite;
// Window information
RECT rcGroup;
WINDOWPLACEMENT wp;
// Icon
WCHAR szIconPath[MAX_PATH + 1];
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);

View File

@@ -1,38 +0,0 @@
/* * * * * * * *\
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.

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.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

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.

Before

Width:  |  Height:  |  Size: 766 B

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.

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: 5.3 KiB

Binary file not shown.

Before

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: 5.3 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

View File

@@ -1,93 +0,0 @@
/* * * * * * * *\
DLG_EN-US.RC -
Copyright (c) 2024 Vortesys, Brady McDermott
LANGUAGE -
English, US
CREDITS -
freedom7341
DESCRIPTION -
This file contains the language-specific dialogs
for Program Manager.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Necessary Evil */
#define APSTUDIO_HIDDEN_SYMBOLS
#include <windows.h>
#define STRICT
#include <CommCtrl.h>
#undef STRICT
#include "resource.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/* Dialogs */
// Program Group
DLG_GROUP DIALOG 0, 0, 256, 96
STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP
EXSTYLE WS_EX_WINDOWEDGE
FONT 8, "Ms Shell Dlg 2"
CAPTION "Program Group"
{
EDITTEXT IDD_NAME, 56, 19, 108, 14, WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_LEFT
AUTOCHECKBOX "Create group for all users", IDD_COMMGROUP, 14, 40, 94, 8, WS_TABSTOP | WS_DISABLED, WS_EX_LEFT
PUSHBUTTON "Change Icon...", IDD_CHICON, 185, 47, 55, 14, WS_TABSTOP, WS_EX_LEFT
PUSHBUTTON "OK", IDD_OK, 145, 75, 50, 14, WS_TABSTOP, WS_EX_LEFT
PUSHBUTTON "Cancel", IDD_CANCEL, 199, 75, 50, 14, WS_TABSTOP, WS_EX_LEFT
// The following controls shouldn't be directly interacted with.
CONTROL "", IDD_STAT_ICON, WC_STATIC, SS_ICON | SS_CENTERIMAGE, 202, 19, 21, 20, WS_EX_LEFT
LTEXT "Name:", 32, 16, 22, 22, 9, SS_LEFT, WS_EX_LEFT
GROUPBOX "Properties", 33, 7, 7, 162, 61, 0, WS_EX_LEFT
GROUPBOX "Icon", 34, 176, 7, 73, 61, 0, WS_EX_LEFT
}
// Program Item
DLG_ITEM DIALOG 0, 0, 256, 167
STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP
EXSTYLE WS_EX_WINDOWEDGE
FONT 8, "Ms Shell Dlg 2"
CAPTION "Program Item"
{
EDITTEXT IDD_NAME, 56, 19, 108, 14, WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_LEFT
EDITTEXT IDD_PATH, 16, 47, 94, 14, WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_LEFT
PUSHBUTTON "Browse...", IDD_BROWSE, 114, 47, 50, 14, WS_TABSTOP, WS_EX_LEFT
PUSHBUTTON "Change Icon...", IDD_CHICON, 185, 47, 55, 14, WS_TABSTOP, WS_EX_LEFT
AUTOCHECKBOX "Use different working directory", IDD_WORKDIR, 14, 87, 111, 8, WS_TABSTOP, WS_EX_LEFT
EDITTEXT IDD_WORKPATH, 80, 99, 106, 14, WS_TABSTOP | WS_DISABLED | ES_AUTOHSCROLL, WS_EX_LEFT
PUSHBUTTON "Browse...", IDD_BROWSE2, 190, 99, 50, 14, WS_TABSTOP | WS_DISABLED, WS_EX_LEFT
CONTROL "", IDD_HOTKEY, HOTKEY_CLASS, WS_TABSTOP, 56, 117, 184, 14, WS_EX_LEFT
PUSHBUTTON "OK", IDD_OK, 145, 146, 50, 14, WS_TABSTOP, WS_EX_LEFT
PUSHBUTTON "Cancel", IDD_CANCEL, 199, 146, 50, 14, WS_TABSTOP, WS_EX_LEFT
// The following controls shouldn't be directly interacted with.
CONTROL "", IDD_STAT_ICON, WC_STATIC, SS_ICON | SS_CENTERIMAGE, 202, 19, 21, 20, WS_EX_LEFT
LTEXT "Name:", 32, 16, 22, 22, 9, SS_LEFT, WS_EX_LEFT
LTEXT "Directory:", 34, 16, 37, 31, 9, SS_LEFT, WS_EX_LEFT
LTEXT "Hotkey:", 35, 16, 120, 26, 9, SS_LEFT, WS_EX_LEFT
LTEXT "Directory:", IDD_STAT_WORKDIR, 26, 102, 31, 9, WS_DISABLED | SS_LEFT, WS_EX_LEFT
GROUPBOX "Properties", 36, 7, 7, 162, 61, 0, WS_EX_LEFT
GROUPBOX "Icon", 37, 176, 7, 73, 61, 0, WS_EX_LEFT
GROUPBOX "Advanced", 38, 7, 75, 242, 64, 0, WS_EX_LEFT
}
// Power and Shutdown
DLG_POWER DIALOG 0, 0, 256, 167
STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_SYSMENU | WS_POPUP
EXSTYLE WS_EX_WINDOWEDGE
FONT 8, "Ms Shell Dlg 2"
CAPTION "Shut Down"
{
EDITTEXT IDD_NAME, 56, 19, 108, 14, WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_LEFT
EDITTEXT IDD_PATH, 16, 47, 94, 14, WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_LEFT
PUSHBUTTON "Browse...", IDD_BROWSE, 114, 47, 50, 14, WS_TABSTOP, WS_EX_LEFT
PUSHBUTTON "Change Icon...", IDD_CHICON, 185, 47, 55, 14, WS_TABSTOP, WS_EX_LEFT
AUTOCHECKBOX "Use different working directory", IDD_WORKDIR, 14, 87, 111, 8, WS_TABSTOP, WS_EX_LEFT
EDITTEXT IDD_WORKPATH, 80, 99, 106, 14, WS_TABSTOP | WS_DISABLED | ES_AUTOHSCROLL, WS_EX_LEFT
PUSHBUTTON "Browse...", IDD_BROWSE2, 190, 99, 50, 14, WS_TABSTOP | WS_DISABLED, WS_EX_LEFT
CONTROL "", IDD_HOTKEY, HOTKEY_CLASS, WS_TABSTOP, 56, 117, 184, 14, WS_EX_LEFT
PUSHBUTTON "OK", IDD_OK, 145, 146, 50, 14, WS_TABSTOP, WS_EX_LEFT
PUSHBUTTON "Cancel", IDD_CANCEL, 199, 146, 50, 14, WS_TABSTOP, WS_EX_LEFT
// The following controls shouldn't be directly interacted with.
CONTROL "", IDD_STAT_ICON, WC_STATIC, SS_ICON | SS_CENTERIMAGE, 202, 19, 21, 20, WS_EX_LEFT
LTEXT "Name:", 32, 16, 22, 22, 9, SS_LEFT, WS_EX_LEFT
GROUPBOX "Properties", 36, 7, 7, 162, 61, 0, WS_EX_LEFT
}

View File

@@ -1,160 +0,0 @@
/* * * * * * * *\
RES_EN-US.RC -
Copyright (c) 2024 Vortesys, Brady McDermott
LANGUAGE -
English, US
CREDITS -
freedom7341
DESCRIPTION -
This file contains the language-specific
resources for the Program Manager.
** NO DEPENDENCIES **
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Necessary Evil */
#define APSTUDIO_HIDDEN_SYMBOLS
#include <windows.h>
#include "resource.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/* Accelerator Table */
IDA_ACCELS ACCELERATORS
{
"N", IDM_FILE_NEW, VIRTKEY, CONTROL
}
/* Menus and Commands */
// Main Menu
IDM_MAIN MENU
{
POPUP "&File"
{
POPUP "&New"
{
MENUITEM "Program &Group", IDM_FILE_NEW_GROUP
MENUITEM "Program &Item", IDM_FILE_NEW_ITEM
}
MENUITEM SEPARATOR
MENUITEM "&Open", IDM_FILE_OPEN
MENUITEM "&Move", IDM_FILE_MOVE
MENUITEM "&Copy", IDM_FILE_COPY
MENUITEM "&Delete", IDM_FILE_DELETE
MENUITEM "&Properties", IDM_FILE_PROPS
MENUITEM SEPARATOR
MENUITEM "&Run...", IDM_FILE_RUN
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_FILE_EXIT
}
POPUP "&Options"
{
MENUITEM "&Auto Arrange", IDM_OPTIONS_AUTOARRANGE
MENUITEM "&Minimize on Use", IDM_OPTIONS_MINONRUN
MENUITEM "Always &on Top", IDM_OPTIONS_TOPMOST
MENUITEM "Show &Name on Titlebar", IDM_OPTIONS_SHOWUSERNAME
MENUITEM "&Save Settings on Exit", IDM_OPTIONS_SAVESETTINGS
MENUITEM SEPARATOR
MENUITEM "Save Settings &Now", IDM_OPTIONS_SAVENOW
}
POPUP "&Window"
{
MENUITEM "&Cascade", IDM_WINDOW_CASCADE
MENUITEM "&Tile Vertically", IDM_WINDOW_TILE
MENUITEM "Tile &Horizontally", IDM_WINDOW_TILEHORIZONTALLY
MENUITEM "&Arrange Icons", IDM_WINDOW_ARRANGEICONS
}
POPUP "&Help"
{
MENUITEM "&View Internet Help", IDM_HELP_INDEX
MENUITEM SEPARATOR
MENUITEM "&About Program Manager II", IDM_HELP_ABOUT
}
}
IDM_DESK MENU PRELOAD
{
POPUP "Context Menu"
{
MENUITEM "&View", IDM_DESK_VIEW
MENUITEM "S&ort by", IDM_DESK_SORT
MENUITEM "&Run Program", IDM_FILE_RUN
MENUITEM "&Task Manager", IDM_TASKMGR
MENUITEM SEPARATOR
MENUITEM "S&creen Resolution", IDM_DESK_SCREENRES
MENUITEM "Pe&rsonalize", IDM_DESK_PERSONALIZE
}
}
// Context Menus
IDM_ITEM MENU PRELOAD // Program Item
{
POPUP "Context Menu"
{
MENUITEM "&Open", IDM_FILE_OPEN
MENUITEM "&Move to", IDM_FILE_MOVE
MENUITEM "&Copy to", IDM_FILE_COPY
MENUITEM "&Delete", IDM_FILE_DELETE
MENUITEM SEPARATOR
MENUITEM "&Properties", IDM_FILE_PROPS
}
}
IDM_GROUP MENU PRELOAD // Program Group
{
POPUP "Context Menu"
{
MENUITEM "&New", IDM_FILE_NEW
// MENUITEM "&Delete", IDM_FILE_DELETE
// MENUITEM SEPARATOR
// MENUITEM "&Properties", IDM_FILE_PROPS
}
}
/* String Table */
STRINGTABLE
{
// Application
#ifndef _DEBUG
IDS_APPTITLE, "Program Manager II" // 64
#else
IDS_APPTITLE, "Program Manager II [DEBUG]" // 64
#endif
IDS_PMCLASS, "progmgr" // 16
IDS_DTCLASS, "progman" // 16
IDS_GRPCLASS, "pmgroup" // 16
IDS_WEBSITE, "https://Vortesys.github.io/progmgr/" // 64
// Menu commands
IDS_RUN "R&un..."
IDS_TASKMGR "&Task Manager"
IDS_EXIT "E&xit"
IDS_SHUTDOWN "S&hutdown..."
// Dialog strings
IDS_DLG_OK "OK"
IDS_DLG_CANCEL "Cancel"
IDS_DLG_BROWSE "Browse..."
// Icon section strings
IDS_DLG_ICON "Icon"
IDS_DLG_CHICON "Change Icon..."
// Properties section strings
IDS_DLG_PROPS "Properties"
IDS_DLG_NAME "Name:"
IDS_DLG_DIRECTORY "Directory:"
IDS_DLG_COMMGRP "Create group for all users"
// Advanced section strings
IDS_DLG_ADVANCED "Advanced"
IDS_DLG_WORKDIR "Use different working directory"
IDS_DLG_HOTKEY "Hotkey:"
// Dialog title strings
IDS_DLT_GRP_PROPS "Group Properties" // 32
IDS_DLT_GRP_NEW "New Group" // 16
IDS_DLT_ITEM_PROPS "Item Properties" // 32
IDS_DLT_ITEM_NEW "New Item" // 16
IDS_DLT_POWER "Shut Down" // [Computer Name] 16 + 16
}

View File

@@ -1,221 +0,0 @@
/* * * * * * * *\
PROGMGR.C -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's main file, now with extra wWinMain!
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Headers */
#define WIN32_LEAN_AND_MEAN
#define SECURITY_WIN32
#include <Windows.h>
#include "progmgr.h"
#include "group.h"
#include "resource.h"
#include "registry.h"
/* Variables */
// Global
#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
WCHAR g_szAppTitle[64];
WCHAR g_szProgMgr[] = TEXT("progmgr");
WCHAR g_szWebsite[64];
WCHAR g_szClass[16];
// Permissions
BOOL g_bPermAdmin; // Has Administrator permissions
BOOL g_bPermGuest; // Has Guest permissions
BOOL g_bPermPower; // Has power option permissions
/* Functions */
/* * * *\
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 -
Program Manager's entry point.
\* * * */
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
MSG msg = { 0 };
HANDLE hAccel;
HMENU hMenu;
HMENU hSystemMenu;
WNDCLASS wc = { 0 };
WCHAR szBuffer[MAX_PATH];
RECT rcRoot;
POINT ptOffset = { 0 };
// Initialize the instance
g_hAppInstance = hInstance;
// Create Strings
LoadString(g_hAppInstance, IDS_PMCLASS, g_szClass, ARRAYSIZE(g_szClass));
LoadString(g_hAppInstance, IDS_APPTITLE, g_szAppTitle, ARRAYSIZE(g_szAppTitle));
LoadString(g_hAppInstance, IDS_WEBSITE, g_szWebsite, ARRAYSIZE(g_szWebsite));
// Get Desktop background color
//CreateSolidBrush(GetBackgroundColor
// Register the Frame Window Class
wc.lpfnWndProc = WndProc;
wc.hInstance = g_hAppInstance;
wc.hIcon = g_hProgMgrIcon = LoadImage(g_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 = NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
wc.lpszClassName = g_szClass;
if (!RegisterClass(&wc))
return FALSE;
// Load the Accelerator table
hAccel = LoadAccelerators(g_hAppInstance, MAKEINTRESOURCE(IDA_ACCELS));
if (!hAccel)
return FALSE;
// Perform Registry actions, close if registry is inaccessible.
if (!InitializeRegistryKeys())
return FALSE;
g_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);
// Get the initial window offset
SystemParametersInfo(SPI_ICONHORIZONTALSPACING, 0, &ptOffset.x, 0);
SystemParametersInfo(SPI_ICONVERTICALSPACING, 0, &ptOffset.y, 0);
// Create main window with a default size
// TODO: i pulled 320x240 out of my ass, make this dynamic later
if ((g_hWndProgMgr = CreateWindowW(wc.lpszClassName, g_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, g_hAppInstance, NULL)) == NULL)
return 2;
// Set the window size from the registry, but only if the coords make sense
if ((rcMainWindow.left != rcMainWindow.right) && (rcMainWindow.top != rcMainWindow.bottom))
SetWindowPos(g_hWndProgMgr, NULL,
rcMainWindow.left, rcMainWindow.top,
rcMainWindow.right - rcMainWindow.left,
rcMainWindow.bottom - rcMainWindow.top, SWP_NOZORDER);
// Load the menus...
hMenu = GetMenu(g_hWndProgMgr);
hSystemMenu = GetSystemMenu(g_hWndProgMgr, FALSE);
// Update relevant parts of the window
UpdateChecks(bAutoArrange, IDM_OPTIONS, IDM_OPTIONS_AUTOARRANGE);
UpdateChecks(bMinOnRun, IDM_OPTIONS, IDM_OPTIONS_MINONRUN);
UpdateChecks(bTopMost, IDM_OPTIONS, IDM_OPTIONS_TOPMOST);
UpdateChecks(bShowUsername, IDM_OPTIONS, IDM_OPTIONS_SHOWUSERNAME);
UpdateChecks(bSaveSettings, IDM_OPTIONS, IDM_OPTIONS_SAVESETTINGS);
UpdateWindowTitle();
// Update settings based on their values
if (bTopMost)
SetWindowPos(g_hWndProgMgr, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
if (g_bIsDefaultShell)
{
// Modify the context menus since we're the default shell
DeleteMenu(hSystemMenu, SC_CLOSE, MF_BYCOMMAND);
LoadString(g_hAppInstance, IDS_SHUTDOWN, szBuffer, ARRAYSIZE(szBuffer));
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_SHUTDOWN, szBuffer);
ModifyMenu(hMenu, IDM_FILE_EXIT, MF_BYCOMMAND | MF_STRING, IDM_SHUTDOWN, szBuffer);
LoadString(g_hAppInstance, IDS_RUN, szBuffer, ARRAYSIZE(szBuffer));
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_FILE_RUN, szBuffer);
LoadString(g_hAppInstance, IDS_TASKMGR, szBuffer, ARRAYSIZE(szBuffer));
InsertMenu(hSystemMenu, 6, MF_BYPOSITION | MF_STRING, IDM_TASKMGR, szBuffer);
// Create the desktop window...
// CreateDesktopWindow();
}
// Create the frame window
if (!InitializeGroups())
return FALSE;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
if (!TranslateMDISysAccel(hWndMDIClient, &msg) &&
!TranslateAccelerator(g_hWndProgMgr, hAccel, &msg))
{
DispatchMessage(&msg);
}
}
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,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>

View File

@@ -1,61 +0,0 @@
/* * * * * * * *\
PROGMGR.H -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's primary header file.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Pragmas */
#pragma once
#pragma comment(lib, "ComCtl32.lib")
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Secur32.lib")
#pragma comment(lib, "UxTheme.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "Winmm.lib")
/* Macros and Defines */
#define GET_WM_COMMAND_ID(wParam, lParam) LOWORD(wParam)
// RunFileDlg flags
#define RFF_NOBROWSE 0x0001 // Removes the browse button
#define RFF_NODEFAULT 0x0002 // No default item selected
#define RFF_CALCDIRECTORY 0x0004 // Calculates the working directory from the file name
#define RFF_NOLABEL 0x0008 // Removes the edit box label
#define RFF_NOSEPARATEMEM 0x0020 // Removes the Separate Memory Space check box, NT only
// RunFileDlg notification return values
#define RF_OK 0x0000 // Allow the application to run
#define RF_CANCEL 0x0001 // Cancel the operation and close the dialog
#define RF_RETRY 0x0002 // Cancel the operation, but leave the dialog open
/* Global Variables */
extern BOOL g_bIsDefaultShell;
// Handles
extern HINSTANCE g_hAppInstance;
extern HWND g_hWndProgMgr;
// Icons
extern HICON g_hProgMgrIcon;
extern HICON g_hGroupIcon;
// Strings
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 */
BOOL UpdatePermissions(VOID);
// SYSINT.C
BOOL RunFileDlg(HWND hWndOwner, HICON hIcon, LPWSTR lpszDir, LPWSTR lpszTitle, LPWSTR lpszDesc, DWORD dwFlags);
BOOL ExitWindowsDialog(HWND hWndOwner);
BOOL SetShellWindow(HWND hWndShell);
// WNDPROC.C
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);

View File

@@ -1,201 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{b76b940d-b61a-456e-8569-72f64cf91afb}</ProjectGuid>
<RootNamespace>progmgr</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
</Link>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
</Link>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<ManifestFile>$(IntDir)$(TargetName)$(TargetExt).manifest</ManifestFile>
</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="dialog.c" />
<ClCompile Include="progmgr.c" />
<ClCompile Include="registry.c" />
<ClCompile Include="group.c" />
<ClCompile Include="sysint.c" />
<ClCompile Include="wndproc.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="lang\dlg_en-US.rc" />
<ResourceCompile Include="lang\res_en-US.rc" />
<ResourceCompile Include="resource.rc" />
</ItemGroup>
<ItemGroup>
<None Include="version.inc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="progmgr.exe.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Language Resources">
<UniqueIdentifier>{71dbbd6d-c82a-4fac-a0ff-74be88190f82}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files\en-US">
<UniqueIdentifier>{2a11d118-5a5c-4681-86dc-31de4f0251ff}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="progmgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="registry.h">
<Filter>Header Files</Filter>
</ClInclude>
<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">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="registry.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sysint.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wndproc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="group.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dialog.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
<ResourceCompile Include="lang\res_en-US.rc">
<Filter>Resource Files\en-US</Filter>
</ResourceCompile>
<ResourceCompile Include="lang\dlg_en-US.rc">
<Filter>Resource Files\en-US</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="version.inc">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Manifest Include="progmgr.exe.manifest">
<Filter>Resource Files</Filter>
</Manifest>
</ItemGroup>
</Project>

View File

@@ -1,388 +0,0 @@
/* * * * * * * *\
REGISTRY.C -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's registry and settings related functions.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Headers */
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shlwapi.h>
#include <strsafe.h>
#include "progmgr.h"
#include "group.h"
#include "registry.h"
/* Variables */
// Global HKEYs
HKEY hKeyProgramManager = NULL;
HKEY hKeyProgramGroups = NULL;
HKEY hKeySettings = NULL;
// Global Values
BOOL bSaveSettings;
BOOL bShowUsername;
BOOL bTopMost;
BOOL bMinOnRun;
BOOL bAutoArrange;
DWORD dwSettingsMask = {
PMS_SAVESETTINGS |
PMS_SHOWUSERNAME |
!PMS_TOPMOST |
!PMS_MINONRUN |
PMS_AUTOARRANGE
};
RECT rcMainWindow;
// Registry Subkeys
PWSTR pszProgramGroups = TEXT("Program Groups");
PWSTR pszSettings = TEXT("Settings");
// Settings Subkeys
PWSTR pszSettingsWindow = TEXT("Window");
PWSTR pszSettingsMask = TEXT("SettingsMask");
// Permissions (Global)
/* Functions */
/* * * *\
InitializeRegistryKeys -
Takes the relevant registry keys and turns them
into valid and usable handles.
RETURNS -
TRUE if successful, FALSE if unsuccessful.
\* * * */
BOOL InitializeRegistryKeys(VOID)
{
if (!RegCreateKeyEx(HKEY_CURRENT_USER, PROGMGR_KEY, 0, g_szProgMgr, 0,
KEY_READ | KEY_WRITE, NULL, &hKeyProgramManager, NULL))
{
// Create Program Groups and Settings keys
RegCreateKeyEx(hKeyProgramManager, pszProgramGroups, 0, g_szProgMgr, 0,
KEY_READ | KEY_WRITE, NULL, &hKeyProgramGroups, NULL);
RegCreateKeyEx(hKeyProgramManager, pszSettings, 0, g_szProgMgr, 0,
KEY_READ | KEY_WRITE, NULL, &hKeySettings, NULL);
return TRUE;
}
return FALSE;
}
/* * * *\
IsProgMgrDefaultShell -
Detects if Program Manager is the default shell.
RETURNS -
TRUE if Program Manager is the default shell,
FALSE if otherwise or an error occurs.
\* * * */
BOOL IsProgMgrDefaultShell(VOID)
{
HKEY hKeyWinlogon;
WCHAR szShell[HKEYMAXLEN] = TEXT("");
DWORD dwType;
DWORD dwBufferSize = sizeof(szShell);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINLOGON_KEY,
0, KEY_READ, &hKeyWinlogon) == ERROR_SUCCESS)
{
if (RegQueryValueEx(hKeyWinlogon, TEXT("Shell"), 0, &dwType,
(LPBYTE)szShell, &dwBufferSize) == ERROR_SUCCESS)
{
if (StrStr(szShell, g_szProgMgr))
{
// ProgMgr detected >:)
RegCloseKey(hKeyWinlogon);
return TRUE;
}
else
{
// Inferior shell detected.
RegCloseKey(hKeyWinlogon);
return FALSE;
}
}
}
else
{
// Assume that we're the shell... just incase.
RegCloseKey(hKeyWinlogon);
return TRUE;
}
// No registry access.
return FALSE;
}
/* * * *\
RegistrySaveGroup -
Saves a group structure to registry.
RETURNS -
RCE_* configuration error value
\* * * */
DWORD RegistrySaveGroup(_In_ PGROUP pg)
{
DWORD dwConfigStatus = RCE_SUCCESS;
// If the pointer is invalid then fail out
if (pg == NULL)
return RCE_FAILURE;
// Save group
UpdateGroup(pg);
if (!RegSetValueEx(hKeyProgramGroups, pg->szName, 0, REG_BINARY,
(const BYTE*)pg, sizeof(*pg)) == ERROR_SUCCESS)
dwConfigStatus = dwConfigStatus && RCE_GROUPS;
return dwConfigStatus;
}
/* * * *\
SaveConfig -
Finds and collapses all settings
and saves them to the registry.
RETURNS -
RCE_* configuration error value
\* * * */
DWORD SaveConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups, _In_ BOOL bExit)
{
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...
// TODO: do this more efficiently
dwSettingsMask =
(bAutoArrange && PMS_AUTOARRANGE) * PMS_AUTOARRANGE |
(bMinOnRun && PMS_MINONRUN) * PMS_MINONRUN |
(bTopMost && PMS_TOPMOST) * PMS_TOPMOST |
(bShowUsername && PMS_SHOWUSERNAME) * PMS_SHOWUSERNAME |
(bSaveSettings && PMS_SAVESETTINGS) * PMS_SAVESETTINGS;
if (!RegSetValueEx(hKeySettings, pszSettingsMask, 0, REG_DWORD,
(const BYTE*)&dwSettingsMask, sizeof(dwSettingsMask)) == ERROR_SUCCESS)
dwConfigStatus = dwConfigStatus && RCE_SETTINGS;
}
if (bPos)
{
WINDOWPLACEMENT wpProgMgr = { 0 };
RECT rcWindow;
// Get and save window position
wpProgMgr.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(g_hWndProgMgr, &wpProgMgr);
CopyRect(&rcWindow, &wpProgMgr.rcNormalPosition);
if (!RegSetValueEx(hKeySettings, pszSettingsWindow, 0, REG_BINARY,
(const BYTE*)&rcWindow, sizeof(rcWindow)) == ERROR_SUCCESS)
dwConfigStatus = dwConfigStatus && RCE_POSITION;
}
if (bGroups)
{
HWND hWndGroup = NULL;
EnumChildWindows(hWndMDIClient, &SaveWindowEnumProc, (LPARAM)bExit);
}
return dwConfigStatus;
}
/* * * *\
SaveWindowEnumProc() -
Procedure for enumeration
of group windows to save
or close them
NOTES -
lParam is a BOOL that determines
whether to close the group or not
RETURNS -
TRUE to continue
FALSE to stop
\* * * */
BOOL CALLBACK SaveWindowEnumProc(HWND hWndGroup, LPARAM lParam)
{
PGROUP pNewGroup = NULL;
PGROUP pGroup = NULL;
if (hWndGroup == NULL)
return FALSE;
pGroup = (PGROUP)GetWindowLongPtr(hWndGroup, GWLP_USERDATA);
if (pGroup == NULL)
return FALSE;
// lean it...
/*pNewGroup = realloc(pGroup, CalculateGroupMemory(pGroup, 1, 1));
if (pNewGroup != NULL)
{
pGroup = pNewGroup;
SetWindowLongPtr(hWndGroup, GWLP_USERDATA, (LONG_PTR)pGroup);
}*/
// save it...
if (RegistrySaveGroup(pGroup) != RCE_SUCCESS)
return FALSE;
// close it...
if ((BOOL)lParam == TRUE)
{
RemoveGroup(hWndGroup, FALSE);
return FALSE;
}
return TRUE;
}
/* * * *\
LoadConfig() -
Finds all settings and retrieves them
from the registry.
RETURNS -
RCE_* configuration error value
\* * * */
DWORD LoadConfig(_In_ BOOL bSettings, _In_ BOOL bPos, _In_ BOOL bGroups)
{
DWORD dwConfigStatus = RCE_SUCCESS;
if (bSettings)
{
DWORD dwBufferSize = sizeof(dwSettingsMask);
DWORD dwType = REG_DWORD;
// Load settings bitmask
if (!RegQueryValueEx(hKeySettings, pszSettingsMask, 0, &dwType,
(LPBYTE)&dwSettingsMask, &dwBufferSize) == ERROR_SUCCESS)
dwConfigStatus = dwConfigStatus && RCE_SETTINGS;
// 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 = MAX_TITLE_LENGTH;
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,55 +0,0 @@
/* * * * * * * *\
REGISTRY.H -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's header file for registry related functions.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Pragmas */
#pragma once
/* Defines */
#define HKEYMAXLEN 261
// Key Paths
#define WINLOGON_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
// #define PROGMAN_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager")
// #define WINDOWS_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows")
#define PROGMGR_KEY TEXT("Software\\Vortesys\\Program Manager II")
// 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
#define PMS_SHOWUSERNAME 0x00000008
#define PMS_SAVESETTINGS 0x00000010
/* Global Variables */
// HKEYs
extern HKEY hKeyProgramManager;
extern HKEY hkeyProgramGroups;
extern HKEY hKeySettings;
// Settings
extern BOOL bAutoArrange;
extern BOOL bMinOnRun;
extern BOOL bTopMost;
extern BOOL bShowUsername;
extern BOOL bSaveSettings;
extern RECT rcMainWindow;
/* Function Prototypes */
BOOL InitializeRegistryKeys(VOID);
BOOL IsProgMgrDefaultShell(VOID);
// Groups
DWORD RegistrySaveGroup(_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);

View File

@@ -1,134 +0,0 @@
/* * * * * * * *\
RESOURCE.H -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's resource collection.
** NO DEPENDENCIES **
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Pragmas */
#ifndef RC_INVOKED
#pragma once
#endif
/* Icon Library */
// Primary, 1-9
#define IDI_PROGMGR 1
#define IDI_PROGGRP 2
#define IDI_PROGITM 3
#define IDI_COMMON 4
#define IDI_PERSONAL 5
// Secondary, 10-19
// #define IDI_COMMS 10
// #define IDI_CONSOLE 11
// #define IDI_DOCUMENT 12
// #define IDI_SPREADSHEET 13
// Tertiary, 20+
// #define IDI_SUPERMAN 20
/* Menus and Commands */
// Context Menus and Accelerators
#define IDM_MAIN 100
#define IDM_ITEM 101
#define IDM_GROUP 102
#define IDA_ACCELS 103
// File, 110-119
#define IDM_FILE 110
#define IDM_FILE_NEW 111
#define IDM_FILE_NEW_GROUP 112
#define IDM_FILE_NEW_ITEM 113
#define IDM_FILE_OPEN 114
#define IDM_FILE_MOVE 115
#define IDM_FILE_COPY 116
#define IDM_FILE_DELETE 117
#define IDM_FILE_PROPS 118
#define IDM_FILE_RUN 119
#define IDM_FILE_EXIT 120
// Options, 130-149
#define IDM_OPTIONS 130
#define IDM_OPTIONS_AUTOARRANGE 131
#define IDM_OPTIONS_MINONRUN 132
#define IDM_OPTIONS_TOPMOST 133
#define IDM_OPTIONS_SHOWUSERNAME 134
#define IDM_OPTIONS_SAVESETTINGS 135
#define IDM_OPTIONS_SAVENOW 136
// Window, 150-169, 5000+
#define IDM_WINDOW 150
#define IDM_WINDOW_CASCADE 151
#define IDM_WINDOW_TILE 152
#define IDM_WINDOW_TILEHORIZONTALLY 153
#define IDM_WINDOW_ARRANGEICONS 154
#define IDM_WINDOW_CHILDSTART 5000
// Help, 170-179
#define IDM_HELP 170
#define IDM_HELP_INDEX 171
#define IDM_HELP_ABOUT 172
// Miscellaneous, 180-199
#define IDM_SHUTDOWN 180
#define IDM_TASKMGR 181
// Desktop Menus, 200-299
#define IDM_DESK 200
#define IDM_DESK_VIEW 201
#define IDM_DESK_SORT 202
#define IDM_DESK_SCREENRES 203
#define IDM_DESK_PERSONALIZE 204
/* Dialogs */
#define DLG_GROUP 1
#define DLG_ITEM 2
#define DLG_POWER 3
/* Dialog Controls */
// Buttons
#define IDD_OK 1
#define IDD_CANCEL 2
#define IDD_BROWSE 3
#define IDD_BROWSE2 4
#define IDD_CHICON 5
// Radio Buttons
#define IDD_WORKDIR 100
#define IDD_COMMGROUP 101
// Input Controls
#define IDD_NAME 200
#define IDD_PATH 201
#define IDD_WORKPATH 202
#define IDD_HOTKEY 203
// Static Controls
#define IDD_STAT_ICON 300
#define IDD_STAT_WORKDIR 301
/* String Table */
#define IDS_APPTITLE 1
#define IDS_PMCLASS 2
#define IDS_DTCLASS 3
#define IDS_GRPCLASS 4
#define IDS_WEBSITE 5
// Menu Commands
#define IDS_RUN 100
#define IDS_TASKMGR 101
#define IDS_EXIT 102
#define IDS_SHUTDOWN 103
// General Dialog
#define IDS_DLG_OK 200
#define IDS_DLG_CANCEL 201
#define IDS_DLG_BROWSE 202
// Icon Section
#define IDS_DLG_ICON 203
#define IDS_DLG_CHICON 204
// Properties Section
#define IDS_DLG_PROPS 205
#define IDS_DLG_NAME 206
#define IDS_DLG_DIRECTORY 207
#define IDS_DLG_COMMGRP 208
// Advanced Section
#define IDS_DLG_ADVANCED 209
#define IDS_DLG_WORKDIR 210
#define IDS_DLG_HOTKEY 211
// Dialog Title
#define IDS_DLT_GRP_PROPS 300
#define IDS_DLT_GRP_NEW 301
#define IDS_DLT_ITEM_PROPS 302
#define IDS_DLT_ITEM_NEW 303
#define IDS_DLT_POWER 304

View File

@@ -1,78 +0,0 @@
/* * * * * * * *\
RESOURCE.RC -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
This file contains Program Manager's resources.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Necessary Evil */
#define APSTUDIO_HIDDEN_SYMBOLS
#include <windows.h>
#include "resource.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/* Language-based Resources */
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
#ifdef NDEBUG
IDI_PROGMGR ICON icons\progmgr.ico
#else
IDI_PROGMGR ICON icons\progmgrd.ico
#endif
IDI_PROGGRP ICON icons\pmgroup.ico
IDI_PROGITM ICON icons\pmitem.ico
IDI_COMMON ICON icons\common.ico
IDI_PERSONAL ICON icons\personal.ico
// Secondary
// IDI_COMMS ICON icons\comms.ico
// IDI_CONSOLE ICON icons\console.ico
// IDI_DOCUMENT ICON icons\document.ico
// IDI_SPREADSHEET ICON icons\spsheet.ico
// Tertiary
// IDI_SUPERMAN ICON icons\misc\superman.ico
/* Manifest */
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "progmgr.exe.manifest"
/* Version Information */
#define APSTUDIO_HIDDEN_SYMBOLS
#include "version.inc"
#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
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
FILEFLAGSMASK 0x3fL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", VER_FILEDESCRIPTION_STR "\0"
VALUE "FileVersion", VER_FILEVERSION_STR "\0"
VALUE "InternalName", VER_INTERNALNAME_STR "\0"
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR "\0"
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR "\0"
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 1033, 1200
END
END

View File

@@ -1,88 +0,0 @@
/* * * * * * * *\
SYSINT.C -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's system export functions.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Headers */
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "progmgr.h"
/* Functions */
/* * * *\
RunFileDlg -
Produces a Run dialog window.
RETURNS -
True if successful, false if unsuccessful.
\* * * */
BOOL RunFileDlg(HWND hWndOwner,
HICON hIcon,
LPWSTR lpszDir,
LPWSTR lpszTitle,
LPWSTR lpszDesc,
DWORD dwFlags)
{
HMODULE hLib = LoadLibrary(TEXT("shell32.dll"));
if (hLib)
{
FARPROC fLib = GetProcAddress(hLib, MAKEINTRESOURCEA(61));
if (fLib(hWndOwner, hIcon, lpszDir, lpszTitle, lpszDesc, dwFlags))
{
FreeLibrary(hLib);
return TRUE;
}
}
return FALSE;
}
/* * * *\
ExitWindowsDialog -
Produces a Shutdown dialog window.
RETURNS -
True if successful, false if unsuccessful.
\* * * */
BOOL ExitWindowsDialog(HWND hWndOwner)
{
HMODULE hLib = LoadLibrary(TEXT("shell32.dll"));
if (hLib)
{
FARPROC fLib = GetProcAddress(hLib, (LPCSTR)60);
if (fLib(hWndOwner))
{
FreeLibrary(hLib);
return TRUE;
}
}
return FALSE;
}
/* * * *\
SetShellWindow -
Sets a window as the shell window.
RETURNS -
True if successful, false if unsuccessful.
\* * * */
BOOL SetShellWindow(HWND hWndShell)
{
HMODULE hLib = GetModuleHandle(TEXT("user32.dll"));
if (hLib)
{
FARPROC fLib = GetProcAddress(hLib, "SetShellWindow");
if (fLib(hWndShell))
{
return TRUE;
}
}
return FALSE;
}

Binary file not shown.

View File

@@ -1,243 +0,0 @@
/* * * * * * * *\
WNDPROC.C -
Copyright (c) 2024 Vortesys, Brady McDermott
DESCRIPTION -
Program Manager's window procedure.
LICENSE INFORMATION -
MIT License, see LICENSE.txt in the root folder
\* * * * * * * */
/* Headers */
#define WIN32_LEAN_AND_MEAN
#define SECURITY_WIN32
#include <Windows.h>
#include <strsafe.h>
#include <shellapi.h>
#include <Lmcons.h>
#include <security.h>
#include <Mmsystem.h>
#include "progmgr.h"
#include "dialog.h"
#include "group.h"
#include "resource.h"
#include "registry.h"
/* Functions */
/* * * *\
WndProc -
Program Manager's window procedure.
RETURNS -
Zero if nothing, otherwise returns the good stuff.
\* * * */
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
// Play the logon sound. (But only if we're the default shell)
if (g_bIsDefaultShell)
PlaySound(TEXT("WindowsLogon"), NULL, SND_ALIAS | SND_ASYNC);
return TRUE;
}
case WM_SYSCOMMAND:
{
if ((wParam >= IDM_MAIN) && (wParam <= IDM_TASKMGR))
{
if (wParam == IDM_TASKMGR)
{
ShellExecute(g_hWndProgMgr, TEXT("open"), TEXT("TASKMGR.EXE"), NULL, NULL, SW_NORMAL);
return 0;
}
if (CmdProc(hWnd, wParam, lParam))
return 0;
}
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
}
case WM_COMMAND:
if (CmdProc(hWnd, wParam, lParam))
return 0;
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
case WM_CLOSE:
case WM_ENDSESSION:
if (bSaveSettings)
SaveConfig(TRUE, TRUE, TRUE, TRUE);
if (g_bIsDefaultShell && (GetShellWindow() != NULL))
SetShellWindow(0);
PostQuitMessage(0);
break;
default:
return DefFrameProc(hWnd, hWndMDIClient, message, wParam, lParam);
}
return 0;
}
/* * * *\
CmdProc -
Program Manager's syscommand procedure.
RETURNS -
Zero if nothing, otherwise returns the good stuff.
\* * * */
LRESULT CALLBACK CmdProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDM_SHUTDOWN:
DialogBox(g_hAppInstance, MAKEINTRESOURCE(DLG_POWER), hWnd, (DLGPROC)ShutdownDlgProc);
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_RUN:
RunFileDlg(hWnd, NULL, NULL, NULL, NULL, RFF_CALCDIRECTORY);
break;
case IDM_FILE_EXIT:
PostQuitMessage(0);
break;
case IDM_OPTIONS_AUTOARRANGE:
bAutoArrange = !bAutoArrange;
UpdateChecks(bAutoArrange, IDM_OPTIONS, IDM_OPTIONS_AUTOARRANGE);
goto SaveConfig;
case IDM_OPTIONS_MINONRUN:
bMinOnRun = !bMinOnRun;
UpdateChecks(bMinOnRun, IDM_OPTIONS, IDM_OPTIONS_MINONRUN);
goto SaveConfig;
case IDM_OPTIONS_TOPMOST:
bTopMost = !bTopMost;
SetWindowPos(g_hWndProgMgr, bTopMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
UpdateChecks(bTopMost, IDM_OPTIONS, IDM_OPTIONS_TOPMOST);
goto SaveConfig;
case IDM_OPTIONS_SHOWUSERNAME:
bShowUsername = !bShowUsername;
UpdateWindowTitle();
UpdateChecks(bShowUsername, IDM_OPTIONS, IDM_OPTIONS_SHOWUSERNAME);
goto SaveConfig;
case IDM_OPTIONS_SAVESETTINGS:
bSaveSettings = !bSaveSettings;
UpdateChecks(bSaveSettings, IDM_OPTIONS, IDM_OPTIONS_SAVESETTINGS);
goto SaveConfig;
case IDM_OPTIONS_SAVENOW:
SaveConfig:
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;
case IDM_HELP_INDEX:
ShellExecute(NULL, TEXT("open"), g_szWebsite, NULL, NULL, SW_SHOWNORMAL);
break;
case IDM_HELP_ABOUT:
{
WCHAR szTitle[40];
LoadString(g_hAppInstance, IDS_APPTITLE, szTitle, ARRAYSIZE(szTitle));
ShellAbout(g_hWndProgMgr, szTitle, NULL, g_hProgMgrIcon);
break;
}
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 TRUE;
}
/* * * *\
UpdateChecks -
Updated checkmarks for a menu based on input
RETURNS -
Nothing!
\* * * */
VOID UpdateChecks(BOOL bVarMenu, UINT uSubMenu, UINT uID)
{
HMENU hMenu;
hMenu = GetMenu(g_hWndProgMgr);
CheckMenuItem(hMenu, uID, (WORD)(bVarMenu ? MF_CHECKED : MF_UNCHECKED));
return;
}
/* * * *\
UpdateWindowTitle -
Updates Window title based on settings... and
current foreground group window if applicable?
RETURNS -
Nothing!
\* * * */
VOID UpdateWindowTitle(VOID)
{
WCHAR szUsername[UNLEN + 1] = TEXT("");
DWORD dwUsernameLen = UNLEN;
WCHAR szWindowTitle[UNLEN + ARRAYSIZE(g_szAppTitle) + 4] = TEXT("");
// Get user and domain name
GetUserNameEx(NameSamCompatible, szUsername, &dwUsernameLen);
// Add username to window title if settings permit
StringCchCopy(szWindowTitle, ARRAYSIZE(g_szAppTitle), g_szAppTitle);
if (bShowUsername)
{
StringCchCat(szWindowTitle, ARRAYSIZE(szWindowTitle), TEXT(" - "));
StringCchCat(szWindowTitle, ARRAYSIZE(szWindowTitle), szUsername);
}
SetWindowText(g_hWndProgMgr, (LPCWSTR)&szWindowTitle);
return;
}