diff --git a/progmgr/group.c b/progmgr/group.c index 0a25302..dbb5f73 100644 --- a/progmgr/group.c +++ b/progmgr/group.c @@ -14,63 +14,219 @@ #include "registry.h" // #define WIN32_LEAN_AND_MEAN #include +#include /* Variables */ WNDCLASSEX wcGrp; +WCHAR szGrpClass[16]; +PGROUPWND pgwArray[]; +HWND hWndMDIClient = NULL; /* Functions */ /* * * *\ - GroupWndProc - - Group window procedure. + InitializeGroups - + Create the MDI Client window and initialize + the group window class. RETURNS - - Zero if nothing, otherwise returns the good stuff. + TRUE if groups are successfully created. + FALSE if otherwise. \* * * */ -LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +BOOL InitializeGroups() { - switch (message) + CLIENTCREATESTRUCT ccs = { 0 }; + WNDCLASSEX wce = { 0 }; + + // Create the MDI Client Window + ccs.hWindowMenu = GetSubMenu(GetMenu(hWndProgMgr), IDM_WINDOW); + ccs.idFirstChild = IDM_WINDOW_CHILDSTART; + + if (!(hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED, L"MDIClient", + NULL, WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + hWndProgMgr, (HMENU)1, hAppInstance, (LPWSTR)&ccs))) { - case WM_CREATE: - { - break; - } - default: -// GroupProcDefault: - return DefMDIChildProc(hWnd, message, wParam, lParam); + return FALSE; } - return 0; + + // Load the group class string + LoadString(hAppInstance, IDS_GRPCLASS, szGrpClass, ARRAYSIZE(szGrpClass)); + + // Register the group window Class + wce.cbSize = sizeof(WNDCLASSEX); + wce.lpfnWndProc = GroupWndProc; + wce.cbClsExtra = 0; + wce.cbWndExtra = 0; + wce.hInstance = hAppInstance; + wce.hIcon = hGroupIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON, + 0, 0, LR_DEFAULTSIZE | LR_SHARED); + wce.hCursor = LoadCursor(NULL, IDC_ARROW); + wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wce.lpszMenuName = NULL; + wce.lpszClassName = szGrpClass; + + if (!RegisterClassEx(&wce)) + return FALSE; + + // TempCreateGroup(); + + // CreateGroupWindow(NULL); + + return TRUE; } + /* * * *\ - InitGroups - - Initialize variables for the betterment of groups forever - Make great glorious MDI Client + TempCreateGroup - + th RETURNS - - Zero if nothing, otherwise returns the good stuff. + real \* * * */ +VOID TempCreateGroup() +{ + return; +} /* * * *\ - TempCreateGroup - - th + CreateGroupWindow - + Create an MDI window from a group RETURNS - - handle to window + Group Window structure + or NULL GROUPWND on failure \* * * */ -HWND TempCreateGroup(HWND hMDIClient) +GROUPWND CreateGroupWindow(PGROUP pgGroup) { - MDICREATESTRUCT mcs; - HWND hChild; + GROUPWND gw = { NULL }; + MDICREATESTRUCT mcs = { NULL }; + HWND hGroup; + + // TODO: allocate memory from pgwArray in here + + // TODO: rethink the structure of this, when i create a group window + // i don't have a pggroup handle. or maybe i do. think about this + // just a little bit more, thanks! mcs.szClass = szGrpClass; mcs.szTitle = L""; mcs.hOwner = hAppInstance; mcs.x = mcs.y = mcs.cx = mcs.cy = CW_USEDEFAULT; mcs.style = WS_VISIBLE; + mcs.lParam = (LPARAM)pgGroup; + + hGroup = (HWND)SendMessage(hWndMDIClient, WM_MDICREATE, 0, (LPARAM)(LPTSTR)&mcs); + if (!hGroup) + return gw; + + return gw; +} + +/* * * *\ + GetGroupFlags - + Retrieve the flags of a group window. + RETURNS - + DWORD containing the flags of the group. + Otherwise 0xFFFFFFFF if failure. +\* * * */ +DWORD GetGroupFlags(PGROUPWND pgw) +{ + HWND hWndGrp; + + // Cancel if the group window doesn't exist + if (pgw == NULL) + return 0xFFFFFFFF; + + // Get the window handle + hWndGrp = pgw->hWndGroup; - hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)(LPTSTR)&mcs); - // if (!hChild) - // { - // MessageBox(hMDIClient, L"MDI Child creation failed.", L"Oh Oh...", - // MB_ICONEXCLAMATION | MB_OK); - // } - return hChild; + if (hWndGrp != NULL) + { + // NOTE: come back to this lol + // TODO: establish better what this actually does + // min/max flags are pulled from hwnd + // common/readonly flags are set upon group creation + // this means that some flags are static whereas + // others change over time, this means that we can + // either assume certain flags never change over time + // or grab them every time. + return 0xFFFFFFFF; + } + + return 0xFFFFFFFF; +} + +/* * * *\ + SaveGroup - + Saves group from a group window + into a GROUP structure. + INFO - + This function operates under the + assumption that the GROUP structure + doesn't get modified over the course + of the MDI window's life and we can't + just grab the structure directly and + expect it to be updated. + RETURNS - + Formatted GROUP structure. + Otherwise NULL if failure. +\* * * */ +GROUP SaveGroup(PGROUPWND pgw) +{ + GROUP grp = { + .dwSignature = GRP_SIGNATURE, + .wVersion = GRP_VERSION, + .wChecksum = 0, + .szGroupName = L"", + .dwFlags = 0, + .ftLastWrite = 0, + .cItems = 0, + .iItems = NULL + }; + HWND hWndGrp; + WCHAR szName[MAX_TITLE_LENGTH]; + + // Find the group and copy it + grp = *pgw->pGroup; + + // Get the window handle as well + hWndGrp = pgw->hWndGroup; + + // Set the group header information + grp.dwSignature = GRP_SIGNATURE; + grp.wVersion = GRP_VERSION; + grp.wChecksum = 0; // NOTE: implement this later lol + + // Copy group information + GetWindowText(hWndGrp, szName, MAX_TITLE_LENGTH); + StringCchCopy(grp.szGroupName, MAX_TITLE_LENGTH, szName); + + grp.dwFlags = GetGroupFlags(pgw); + + GetSystemTimeAsFileTime(&grp.ftLastWrite); + + // Save items... + grp.cItems = 0; + // TODO: iterate through listview to save items + + return grp; +} + +/* * * *\ + GroupWndProc - + Group window procedure. + RETURNS - + Zero if nothing, otherwise returns the good stuff. +\* * * */ +LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + { + break; + } + default: + // GroupProcDefault: + return DefMDIChildProc(hWnd, message, wParam, lParam); + } + return 0; } diff --git a/progmgr/group.h b/progmgr/group.h index 0acef7f..dd14580 100644 --- a/progmgr/group.h +++ b/progmgr/group.h @@ -19,6 +19,7 @@ #define MAX_TITLE_LENGTH MAX_PATH // Group Format Definitions #define GRP_SIGNATURE 0x47324D50L // PM2G +#define GRP_VERSION 1 // Increment for breaking changes // Group Flag Values (DWORD) #define GRP_FLAG_COMMON 0x00000001 #define GRP_FLAG_READONLY 0x00000002 @@ -30,12 +31,12 @@ typedef struct _ITEM { // Item executable and name WCHAR szItemName[MAX_TITLE_LENGTH]; - WCHAR szExecPath[MAX_PATH]; // Path of the item executable + WCHAR szExecPath[MAX_PATH]; // Path of the executable WCHAR szWorkPath[MAX_PATH]; // Working directory // Icon - WCHAR szIconPath[MAX_PATH]; // Path of the icon - UINT uiIconIndex; // Index of the icon + WCHAR szIconPath[MAX_PATH]; + UINT uiIconIndex; } ITEM, * PITEM; // Group format, .GRP @@ -59,12 +60,23 @@ typedef struct _GROUP { typedef struct _GROUPWND { // Window information HWND hWndGroup; - RECT rcGroup; // Window rectangle // Group information - HANDLE hGroup; // Handle to GROUP object -} GROUPINFO, * PGROUPINFO; + PGROUP pGroup; // Pointer to GROUP structure +} GROUPWND, * PGROUPWND; + +/* Global Variables */ +extern HWND hWndMDIClient; + +/* Local Variables */ /* Function Prototypes */ +BOOL InitializeGroups(); +VOID TempCreateGroup(); +// Group Window LRESULT CALLBACK GroupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -HWND TempCreateGroup(HWND hMDIClient); +GROUPWND CreateGroupWindow(PGROUP pgGroup); +// Group information +DWORD GetGroupFlags(PGROUPWND pgw); +// Import/export functions +GROUP SaveGroup(PGROUPWND pgw); diff --git a/progmgr/progmgr.c b/progmgr/progmgr.c index c91f83b..ddc9eca 100644 --- a/progmgr/progmgr.c +++ b/progmgr/progmgr.c @@ -19,18 +19,18 @@ /* Variables */ // Global BOOL bIsDefaultShell = FALSE; -// Window Related -HICON hProgMgrIcon = NULL; -HICON hGroupIcon = NULL; +// Handles HINSTANCE hAppInstance; +HANDLE hAppHeap; HWND hWndProgMgr = NULL; -HWND hWndMDIClient = NULL; +// Icons +HICON hProgMgrIcon = NULL; +HICON hGroupIcon = NULL; // Global Strings WCHAR szAppTitle[32]; WCHAR szProgMgr[] = L"progmgr"; WCHAR szWebsite[64]; WCHAR szClass[16]; -WCHAR szGrpClass[16]; /* Functions */ @@ -45,16 +45,18 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, HMENU hMenu; HMENU hSystemMenu; WNDCLASS wc = { 0 }; - WNDCLASSEX wce = { 0 }; WCHAR szBuffer[MAX_PATH]; RECT rcRoot; POINT ptOffset; + // Initialize the instance hAppInstance = hInstance; + // Create our global heap handle + hAppHeap = GetProcessHeap(); + // Create Strings LoadString(hAppInstance, IDS_PMCLASS, szClass, ARRAYSIZE(szClass)); - LoadString(hAppInstance, IDS_GRPCLASS, szGrpClass, ARRAYSIZE(szGrpClass)); LoadString(hAppInstance, IDS_APPTITLE, szAppTitle, ARRAYSIZE(szAppTitle)); LoadString(hAppInstance, IDS_WEBSITE, szWebsite, ARRAYSIZE(szWebsite)); @@ -71,22 +73,8 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, wc.hbrBackground = NULL; wc.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN); wc.lpszClassName = szClass; - if (!RegisterClass(&wc)) - return FALSE; - // Register the Group Window Class - wce.cbSize = sizeof(WNDCLASSEX); - wce.lpfnWndProc = GroupWndProc; - wce.cbClsExtra = 0; - wce.cbWndExtra = 0; - wce.hInstance = hAppInstance; - wce.hIcon = hGroupIcon = LoadImage(hAppInstance, MAKEINTRESOURCE(IDI_PROGGRP), IMAGE_ICON, - 0, 0, LR_DEFAULTSIZE | LR_SHARED); - wce.hCursor = LoadCursor(NULL, IDC_ARROW); - wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wce.lpszMenuName = NULL; - wce.lpszClassName = szGrpClass; - if (!RegisterClassEx(&wce)) + if (!RegisterClass(&wc)) return FALSE; // Load the Accelerator table @@ -95,15 +83,14 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, return FALSE; // Perform Registry actions, close if registry is inaccessible. - if (InitializeRegistryKeys()) - { - bIsDefaultShell = IsProgMgrDefaultShell(); - LoadConfig(); - } - else - { + if (!InitializeRegistryKeys()) + return FALSE; + + bIsDefaultShell = IsProgMgrDefaultShell(); + + // Load configuration, but don't load groups yet + if(LoadConfig(TRUE, TRUE, FALSE) != RCE_SUCCESS) return FALSE; - } // Get size of the root HWND GetWindowRect(GetDesktopWindow(), &rcRoot); @@ -114,10 +101,10 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, // Create main window with a default size // NOTE: i pulled 320x240 out of my ass, make this dynamic later - if (!CreateWindow(wc.lpszClassName, szAppTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, + if (!(hWndProgMgr = CreateWindowW(wc.lpszClassName, szAppTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, rcRoot.left + ptOffset.x, rcRoot.top + ptOffset.y, rcRoot.left + ptOffset.x + 320, rcRoot.top + ptOffset.y + 240, - 0, 0, hAppInstance, NULL)) + 0, 0, hAppInstance, NULL))) return 2; // Set the window size from the registry, but only if the coords make sense @@ -163,6 +150,10 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, // CreateDesktopWindow(); } + // Create the frame window + if (!InitializeGroups()) + return FALSE; + while (GetMessage(&msg, NULL, 0, 0) > 0) { if (!TranslateMDISysAccel(hWndMDIClient, &msg) && diff --git a/progmgr/progmgr.h b/progmgr/progmgr.h index b87e446..a8da82e 100644 --- a/progmgr/progmgr.h +++ b/progmgr/progmgr.h @@ -29,18 +29,19 @@ #define RF_RETRY 0x0002 // Cancel the operation, but leave the dialog open /* Global Variables */ -// PROGMGR.C extern BOOL bIsDefaultShell; -extern HICON hProgMgrIcon; -extern HICON hGroupIcon; +// Handles extern HINSTANCE hAppInstance; +extern HANDLE hAppHeap; extern HWND hWndProgMgr; -extern HWND hWndMDIClient; +// Icons +extern HICON hProgMgrIcon; +extern HICON hGroupIcon; +// Strings extern WCHAR szAppTitle[32]; extern WCHAR szProgMgr[]; extern WCHAR szWebsite[64]; extern WCHAR szClass[16]; -extern WCHAR szGrpClass[16]; /* Function Prototypes */ // DESKTOP.C diff --git a/progmgr/wndproc.c b/progmgr/wndproc.c index a25e059..152417d 100644 --- a/progmgr/wndproc.c +++ b/progmgr/wndproc.c @@ -33,28 +33,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { case WM_CREATE: { - CLIENTCREATESTRUCT ccs; - RECT rc; - - // Frame Window - hWndProgMgr = hWnd; - - // Create the MDI Client Window - ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), IDM_WINDOW); - ccs.idFirstChild = IDM_WINDOW_CHILDSTART; - - GetClientRect(hWndProgMgr, &rc); - - if (!(hWndMDIClient = CreateWindowEx(WS_EX_COMPOSITED, L"MDIClient", - NULL, WS_CLIPCHILDREN | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - hWnd, (HMENU)1, hAppInstance, (LPWSTR)&ccs))) - { - return FALSE; - } - - TempCreateGroup(hWndMDIClient); - break; }