rename directory
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
677
PROGMGR2/group.c
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
@@ -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;
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 766 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
*/
|
|
||||||
@@ -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>
|
|
||||||
@@ -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);
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||