From b40b190dfdb50acd2cbb2108e92c3d4b0d7f3bfe Mon Sep 17 00:00:00 2001 From: RadAd Date: Tue, 16 Jul 2019 12:05:52 +1000 Subject: Support multiple profiles --- RadTerminal.cpp | 15 +++++++------- RadTerminal.rc | Bin 7202 -> 7322 bytes RadTerminalFrame.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++---- WinUtils.h | 42 +++++++++++++++++++++++++++++++++++++++ resource.h | Bin 2648 -> 3458 bytes 5 files changed, 100 insertions(+), 11 deletions(-) diff --git a/RadTerminal.cpp b/RadTerminal.cpp index be590a9..7121dfc 100644 --- a/RadTerminal.cpp +++ b/RadTerminal.cpp @@ -68,7 +68,7 @@ void ShowError(HWND hWnd, LPCTSTR msg, HRESULT hr) HWND CreateRadTerminalFrame(HINSTANCE hInstance); LRESULT CALLBACK RadTerminalWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -HWND ActionNewWindow(HWND hWnd, bool bParseCmdLine); +HWND ActionNewWindow(HWND hWnd, bool bParseCmdLine, const std::tstring& profile); ATOM RegisterRadTerminal(HINSTANCE hInstance) { @@ -154,9 +154,10 @@ void ParseCommandLine(RadTerminalCreate& rtc) } } -RadTerminalCreate GetDefaultTerminalCreate(bool bParseCmdLine) +RadTerminalCreate GetTerminalCreate(bool bParseCmdLine, std::tstring profile) { - std::tstring profile = RegGetString(HKEY_CURRENT_USER, _T("Software\\RadSoft\\" PROJ_CODE), _T("Profile"), _T("Cmd")); + if (profile.empty()) + profile = RegGetString(HKEY_CURRENT_USER, _T("Software\\RadSoft\\" PROJ_CODE), _T("Profile"), _T("Cmd")); RadTerminalCreate rtc = {}; rtc.iFontHeight = 16; @@ -194,7 +195,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, PTSTR pCmdLine, int nCmdSho hWndMDIClient = GetMDIClient(hWnd); hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); - HWND hChildWnd = ActionNewWindow(hWnd, true); + HWND hChildWnd = ActionNewWindow(hWnd, true, TEXT("")); if (true && hChildWnd != NULL) { @@ -208,7 +209,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, PTSTR pCmdLine, int nCmdSho } else { - RadTerminalCreate rtc = GetDefaultTerminalCreate(true); + RadTerminalCreate rtc = GetTerminalCreate(true, TEXT("")); hWnd = CreateWindowEx( WS_EX_ACCEPTFILES, @@ -683,14 +684,14 @@ int ActionScrollbackDown(HWND hWnd) return 0; } -HWND ActionNewWindow(HWND hWnd, bool bParseCmdLine) +HWND ActionNewWindow(HWND hWnd, bool bParseCmdLine, const std::tstring& profile) { const HINSTANCE hInstance = GetWindowInstance(hWnd); const HWND hWndMDIClient = GetMDIClient(hWnd); BOOL bMaximized = FALSE; GetMDIActive(hWndMDIClient, &bMaximized); - const RadTerminalCreate rtc = GetDefaultTerminalCreate(bParseCmdLine); + const RadTerminalCreate rtc = GetTerminalCreate(bParseCmdLine, profile); HWND hChildWnd = CreateMDIWindow( MAKEINTATOM(GetRadTerminalAtom(hInstance)), diff --git a/RadTerminal.rc b/RadTerminal.rc index f13d6d3..4b6b09a 100644 Binary files a/RadTerminal.rc and b/RadTerminal.rc differ diff --git a/RadTerminalFrame.cpp b/RadTerminalFrame.cpp index 1d2aeff..84a0789 100644 --- a/RadTerminalFrame.cpp +++ b/RadTerminalFrame.cpp @@ -1,11 +1,13 @@ #include #include +#include #include "WinUtils.h" #include "resource.h" #define PROJ_NAME TEXT("RadTerminal") +#define PROJ_CODE TEXT("RadTerminal") -HWND ActionNewWindow(HWND hWnd, bool bParseCmdLine); +HWND ActionNewWindow(HWND hWnd, bool bParseCmdLine, const std::tstring& profile); LRESULT CALLBACK RadTerminalMDIFrameProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); HWND CreateRadTerminalFrame(HINSTANCE hInstance) @@ -44,16 +46,52 @@ inline LRESULT MyDefFrameWindowProc(_In_ HWND hWnd, _In_ UINT Msg, _In_ WPARAM w return DefFrameProc(hWnd, GetMDIClient(hWnd), Msg, wParam, lParam); } +struct RadTerminalFrameData +{ + std::vector profiles; +}; + BOOL RadTerminalFrameOnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) { FORWARD_WM_CREATE(hWnd, lpCreateStruct, MyDefFrameWindowProc); - HINSTANCE hInst = GetWindowInstance(hWnd); + const HINSTANCE hInst = GetWindowInstance(hWnd); + + RadTerminalFrameData* const data = new RadTerminalFrameData; + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data); CLIENTCREATESTRUCT ccs = {}; HMENU hMenu = GetMenu(hWnd); ccs.hWindowMenu = GetSubMenu(hMenu, GetMenuItemCount(hMenu) - 1); ccs.idFirstChild = IDM_WINDOWCHILD; + { + HKEY hMainKey = NULL; + if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\RadSoft\\" PROJ_CODE "\\Profiles"), &hMainKey) == ERROR_SUCCESS) + { + const std::tstring strDefault = RegGetString(HKEY_CURRENT_USER, TEXT("Software\\RadSoft\\" PROJ_CODE), TEXT("Profile"), TEXT("Cmd")); + DWORD i = 0; + std::tstring strName; + for (int i = 0; RegEnumKeyEx(hMainKey, i, strName); ++i) + { + data->profiles.push_back(strName); + if (strName != TEXT("Default")) + { + MENUITEMINFO mii = {}; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE; + mii.fType = MFT_STRING; + if (strName == strDefault) + mii.fState |= MFS_DEFAULT; + mii.wID = ID_NEW_PROFILE_1 + i; + mii.dwTypeData = (LPTSTR) strName.c_str(); + InsertMenuItem(hMenu, ID_NEW_PLACEHOLDER, FALSE, &mii); + } + } + DeleteMenu(hMenu, ID_NEW_PLACEHOLDER, MF_BYCOMMAND); + RegCloseKey(hMainKey); + } + } + HWND hWndMDIClient = CreateWindow(TEXT("MDICLIENT"), (LPCTSTR) NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL, 0, 0, 0, 0, hWnd, (HMENU) 0, hInst, (LPSTR) &ccs); @@ -68,7 +106,10 @@ BOOL RadTerminalFrameOnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) void RadTerminalFrameOnDestroy(HWND hWnd) { FORWARD_WM_DESTROY(hWnd, MyDefFrameWindowProc); + const RadTerminalFrameData* const data = (RadTerminalFrameData*) GetWindowLongPtr(hWnd, GWLP_USERDATA); PostQuitMessage(0); + delete data; + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) nullptr); } void RadTerminalFrameOnSizing(HWND hWnd, UINT edge, LPRECT prRect) @@ -87,11 +128,16 @@ void RadTerminalFrameOnSizing(HWND hWnd, UINT edge, LPRECT prRect) void RadTerminalFrameOnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) { - HWND hWndMDIClient = GetMDIClient(hWnd); + const HWND hWndMDIClient = GetMDIClient(hWnd); + const RadTerminalFrameData* const data = (RadTerminalFrameData*) GetWindowLongPtr(hWnd, GWLP_USERDATA); switch (id) { - case ID_FILE_NEW: ActionNewWindow(hWnd, false); break; + case ID_FILE_NEW: ActionNewWindow(hWnd, false, TEXT("")); break; + case ID_NEW_PROFILE_1: case ID_NEW_PROFILE_2: case ID_NEW_PROFILE_3: + case ID_NEW_PROFILE_4: case ID_NEW_PROFILE_5: case ID_NEW_PROFILE_6: + case ID_NEW_PROFILE_7: case ID_NEW_PROFILE_8: case ID_NEW_PROFILE_9: + ActionNewWindow(hWnd, false, data->profiles[id - ID_NEW_PROFILE_1]); break; case ID_FILE_EXIT: PostMessage(hWnd, WM_CLOSE, 0, 0); break; case ID_WINDOW_CASCADE: CascadeWindows(hWndMDIClient, 0, nullptr, 0, nullptr); break; case ID_WINDOW_TILEHORIZONTALLY: TileWindows(hWndMDIClient, MDITILE_HORIZONTAL, nullptr, 0, nullptr); break; diff --git a/WinUtils.h b/WinUtils.h index ffd3929..da1a652 100644 --- a/WinUtils.h +++ b/WinUtils.h @@ -138,6 +138,19 @@ inline DWORD RegGetDWORD(HKEY hKey, LPCTSTR sSubKey, LPCTSTR sValue, DWORD dwDef return dwDef; } +inline bool RegEnumKeyEx(_In_ HKEY hKey, _In_ DWORD dwIndex, std::tstring& strName) +{ + TCHAR name[256]; + DWORD len = ARRAYSIZE(name); + if (RegEnumKeyEx(hKey, dwIndex, name, &len, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS) + { + strName = name; + return true; + } + else + return false; +} + inline HWND GetMDIClient(HWND hWnd) { return FindWindowEx(hWnd, NULL, TEXT("MDICLIENT"), nullptr); @@ -160,3 +173,32 @@ inline HWND MyGetActiveWnd(HWND hWnd) hActive = GetMDIActive(GetParent(hWnd)); return hActive; } + +inline bool FindMenuPos(HMENU hBaseMenu, UINT myID, HMENU* pMenu, int* mpos) +{ + if (hBaseMenu == NULL) + { + *pMenu = NULL; + *mpos = -1; + return true; + } + + for (int myPos = 0; myPos < GetMenuItemCount(hBaseMenu); ++myPos) + { + if (GetMenuItemID(hBaseMenu, myPos) == myID) + { + *pMenu = hBaseMenu; + *mpos = myPos; + return true; + } + + HMENU hNewMenu = GetSubMenu(hBaseMenu, myPos); + if (hNewMenu != NULL) + { + if (FindMenuPos(hNewMenu, myID, pMenu, mpos)) + return true; + } + } + + return false; +} diff --git a/resource.h b/resource.h index faf024e..89b4d50 100644 Binary files a/resource.h and b/resource.h differ -- cgit v1.2.3