From 8a95c1ac464676b9c7f2ab1383cc48175158e41d Mon Sep 17 00:00:00 2001 From: Randy Edmunds Date: Sat, 28 Jul 2012 16:19:58 -0700 Subject: [PATCH 1/5] implement restoring window size on windows --- appshell/cefclient_win.cpp | 183 +++++++++++++++++++++++++++++++++---- 1 file changed, 166 insertions(+), 17 deletions(-) diff --git a/appshell/cefclient_win.cpp b/appshell/cefclient_win.cpp index deb927b26..7b185c33e 100644 --- a/appshell/cefclient_win.cpp +++ b/appshell/cefclient_win.cpp @@ -54,6 +54,23 @@ extern CefRefPtr g_handler; #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") // NOLINT(whitespace/line_length) #endif +// Registry access functions +bool GetRegistryInt(LPCWSTR pEntry, int* pDefault, int& ret); +bool GetRegistryString(LPCWSTR pEntry, LPBYTE pDefault, LPBYTE pRet); +bool WriteRegistryInt (LPCWSTR pEntry, int val); +bool WriteRegistryString(LPCWSTR pEntry, LPBYTE pValue, int len); + +// Registry key strings +#define PREF_BRACKETS_BASE L"Software\\Brackets\\" +#define PREF_WINPOS_LEFT L"Window Position Left" +#define PREF_WINPOS_TOP L"Window Position Top" +#define PREF_WINPOS_WIDTH L"Window Position Width" +#define PREF_WINPOS_HEIGHT L"Window Position Height" + +// Window state functions +void SaveWindowRect(); +void RestoreWindowRect(int& left, int& top, int& width, int& height); + // Program entry point function. int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -93,18 +110,12 @@ int APIENTRY wWinMain(HINSTANCE hInstance, LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_CEFCLIENT, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); - - HKEY hKey; - DWORD lResult; - #define PREF_NAME L"Software\\Brackets\\InitialURL" + + #define PREF_INITIAL_URL L"InitialURL" // Don't read the prefs if the shift key is down if (GetAsyncKeyState(VK_SHIFT) == 0) { - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, PREF_NAME, 0, KEY_READ, &hKey)) { - DWORD length = MAX_PATH; - RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)szInitialUrl, &length); - RegCloseKey(hKey); - } + GetRegistryString(PREF_INITIAL_URL, (LPBYTE)NULL, (LPBYTE)szInitialUrl); } if (!wcslen(szInitialUrl)) { @@ -116,11 +127,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_EXPLORER; if (GetOpenFileName(&ofn)) { - lResult = RegCreateKeyEx(HKEY_CURRENT_USER, PREF_NAME, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL); - if (lResult == ERROR_SUCCESS) { - RegSetValueEx(hKey, NULL, 0, REG_SZ, (LPBYTE)szInitialUrl, (wcslen(szInitialUrl) + 1) * 2); - RegCloseKey(hKey); - } + WriteRegistryString(PREF_INITIAL_URL, (LPBYTE)szInitialUrl, (wcslen(szInitialUrl) + 1) * 2); } } @@ -156,6 +163,137 @@ int APIENTRY wWinMain(HINSTANCE hInstance, return result; } +// get integer value from registry key +// caller can either use return value to determine success/fail, or pass a default to be used on fail +bool GetRegistryInt(LPCWSTR pEntry, int* pDefault, int& ret) +{ + HKEY hKey; + bool result = false; + + std::wstring key = PREF_BRACKETS_BASE; + key += pEntry; + + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, KEY_READ, &hKey)) + { + DWORD dwValue = 0; + DWORD dwType = 0; + DWORD dwCount = sizeof(DWORD); + if (ERROR_SUCCESS == RegQueryValueEx(hKey, (LPCWSTR)key.c_str(), NULL, &dwType, (LPBYTE)&dwValue, &dwCount)) + { + result = true; + ASSERT(dwType == REG_DWORD); + ASSERT(dwCount == sizeof(dwValue)); + ret = (int)dwValue; + } + RegCloseKey(hKey); + } + + if (!result) + { + // couldn't read value, so use default, if specified + if (pDefault) + ret = *pDefault; + } + + return result; +} + +// get string value from registry key +// caller can either use return value to determine success/fail, or pass a default to be used on fail +bool GetRegistryString(LPCWSTR pEntry, LPBYTE pDefault, LPBYTE pRet) +{ + // return value buffer is required + if (!pRet) + return false; + + std::wstring key = PREF_BRACKETS_BASE; + key += pEntry; + + HKEY hKey; + bool result = false; + + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, KEY_READ, &hKey)) + { + result = true; + DWORD length = MAX_PATH; + RegQueryValueEx(hKey, NULL, NULL, NULL, pRet, &length); + RegCloseKey(hKey); + } + else + { + // couldn't read value, so use default, if specified + if (pDefault) + *pRet = *pDefault; + } + + return result; +} + +// write integer value to registry key +bool WriteRegistryInt (LPCWSTR pEntry, int val) +{ + HKEY hKey; + bool result = false; + + std::wstring key = PREF_BRACKETS_BASE; + key += pEntry; + + if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) + { + DWORD dwCount = sizeof(int); + if (ERROR_SUCCESS == RegSetValueEx(hKey, (LPCWSTR)key.c_str(), 0, REG_DWORD, (LPBYTE)&val, dwCount)) + result = true; + RegCloseKey(hKey); + } + + return result; +} + +// write string value to registry key +bool WriteRegistryString(LPCWSTR pEntry, LPBYTE pValue, int len) +{ + HKEY hKey; + bool result = false; + + std::wstring key = PREF_BRACKETS_BASE; + key += pEntry; + + if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) + { + result = true; + RegSetValueEx(hKey, NULL, 0, REG_SZ, pValue, len); + RegCloseKey(hKey); + } + + return result; +} + +void SaveWindowRect() +{ + // Save position of active window + HWND hWnd = GetActiveWindow(); + if (hWnd) + { + RECT rect; + if (GetWindowRect(hWnd, &rect)) + { + WriteRegistryInt(PREF_WINPOS_LEFT, rect.left); + WriteRegistryInt(PREF_WINPOS_TOP, rect.top); + WriteRegistryInt(PREF_WINPOS_WIDTH, rect.right - rect.left); + WriteRegistryInt(PREF_WINPOS_HEIGHT, rect.bottom - rect.top); + } + } +} + +void RestoreWindowRect(int& left, int& top, int& width, int& height) +{ + GetRegistryInt(PREF_WINPOS_LEFT, NULL, left); + GetRegistryInt(PREF_WINPOS_TOP, NULL, top); + GetRegistryInt(PREF_WINPOS_WIDTH, NULL, width); + GetRegistryInt(PREF_WINPOS_HEIGHT, NULL, height); +} + + // // FUNCTION: MyRegisterClass() // @@ -204,9 +342,17 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // Store instance handle in our global variable - hWnd = CreateWindow(szWindowClass, szTitle, - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, 0, - CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); + // TODO: test this cases: + // - window in secondary monitor when shutdown, disconnect secondary monitor, restart + + int left = CW_USEDEFAULT; + int top = 0; + int width = CW_USEDEFAULT; + int height = 0; + RestoreWindowRect(left, top, width, height); + + hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + left, top, width, height, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; @@ -471,6 +617,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, case WM_CLOSE: if (g_handler.get()) { + + SaveWindowRect(); + // If we already initiated the browser closing, then let default window proc handle it. HWND browserHwnd = g_handler->GetBrowser()->GetHost()->GetWindowHandle(); HANDLE closing = GetProp(browserHwnd, CLOSING_PROP); From 6a3b1824b7e48b30e6656d1756aa8143fbb15505 Mon Sep 17 00:00:00 2001 From: Randy Edmunds Date: Tue, 2 Oct 2012 21:14:06 -0700 Subject: [PATCH 2/5] fix registry keys --- appshell/cefclient_win.cpp | 91 +++++++++----------------------------- 1 file changed, 21 insertions(+), 70 deletions(-) diff --git a/appshell/cefclient_win.cpp b/appshell/cefclient_win.cpp index 27f33763d..f1339e4e3 100644 --- a/appshell/cefclient_win.cpp +++ b/appshell/cefclient_win.cpp @@ -56,17 +56,16 @@ extern CefRefPtr g_handler; #endif // Registry access functions -bool GetRegistryInt(LPCWSTR pEntry, int* pDefault, int& ret); -bool GetRegistryString(LPCWSTR pEntry, LPBYTE pDefault, LPBYTE pRet); -bool WriteRegistryInt (LPCWSTR pEntry, int val); -bool WriteRegistryString(LPCWSTR pEntry, LPBYTE pValue, int len); +bool GetRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int* pDefault, int& ret); +bool WriteRegistryInt (LPCWSTR pFolder, LPCWSTR pEntry, int val); // Registry key strings #define PREF_BRACKETS_BASE L"Software\\Brackets\\" -#define PREF_WINPOS_LEFT L"Window Position Left" -#define PREF_WINPOS_TOP L"Window Position Top" -#define PREF_WINPOS_WIDTH L"Window Position Width" -#define PREF_WINPOS_HEIGHT L"Window Position Height" +#define PREF_WINPOS_FOLDER L"Window Position" +#define PREF_LEFT L"Left" +#define PREF_TOP L"Top" +#define PREF_WIDTH L"Width" +#define PREF_HEIGHT L"Height" // Window state functions void SaveWindowRect(); @@ -209,19 +208,20 @@ int APIENTRY wWinMain(HINSTANCE hInstance, // get integer value from registry key // caller can either use return value to determine success/fail, or pass a default to be used on fail -bool GetRegistryInt(LPCWSTR pEntry, int* pDefault, int& ret) +bool GetRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int* pDefault, int& ret) { HKEY hKey; bool result = false; std::wstring key = PREF_BRACKETS_BASE; - key += pEntry; + key += pFolder; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, KEY_READ, &hKey)) { DWORD dwValue = 0; DWORD dwType = 0; DWORD dwCount = sizeof(DWORD); + key = pEntry; if (ERROR_SUCCESS == RegQueryValueEx(hKey, (LPCWSTR)key.c_str(), NULL, &dwType, (LPBYTE)&dwValue, &dwCount)) { result = true; @@ -242,49 +242,19 @@ bool GetRegistryInt(LPCWSTR pEntry, int* pDefault, int& ret) return result; } -// get string value from registry key -// caller can either use return value to determine success/fail, or pass a default to be used on fail -bool GetRegistryString(LPCWSTR pEntry, LPBYTE pDefault, LPBYTE pRet) -{ - // return value buffer is required - if (!pRet) - return false; - - std::wstring key = PREF_BRACKETS_BASE; - key += pEntry; - - HKEY hKey; - bool result = false; - - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, KEY_READ, &hKey)) - { - result = true; - DWORD length = MAX_PATH; - RegQueryValueEx(hKey, NULL, NULL, NULL, pRet, &length); - RegCloseKey(hKey); - } - else - { - // couldn't read value, so use default, if specified - if (pDefault) - *pRet = *pDefault; - } - - return result; -} - // write integer value to registry key -bool WriteRegistryInt (LPCWSTR pEntry, int val) +bool WriteRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int val) { HKEY hKey; bool result = false; std::wstring key = PREF_BRACKETS_BASE; - key += pEntry; + key += pFolder; if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) { DWORD dwCount = sizeof(int); + key = pEntry; if (ERROR_SUCCESS == RegSetValueEx(hKey, (LPCWSTR)key.c_str(), 0, REG_DWORD, (LPBYTE)&val, dwCount)) result = true; RegCloseKey(hKey); @@ -293,25 +263,6 @@ bool WriteRegistryInt (LPCWSTR pEntry, int val) return result; } -// write string value to registry key -bool WriteRegistryString(LPCWSTR pEntry, LPBYTE pValue, int len) -{ - HKEY hKey; - bool result = false; - - std::wstring key = PREF_BRACKETS_BASE; - key += pEntry; - - if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) - { - result = true; - RegSetValueEx(hKey, NULL, 0, REG_SZ, pValue, len); - RegCloseKey(hKey); - } - - return result; -} - void SaveWindowRect() { // Save position of active window @@ -321,20 +272,20 @@ void SaveWindowRect() RECT rect; if (GetWindowRect(hWnd, &rect)) { - WriteRegistryInt(PREF_WINPOS_LEFT, rect.left); - WriteRegistryInt(PREF_WINPOS_TOP, rect.top); - WriteRegistryInt(PREF_WINPOS_WIDTH, rect.right - rect.left); - WriteRegistryInt(PREF_WINPOS_HEIGHT, rect.bottom - rect.top); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_LEFT, rect.left); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_TOP, rect.top); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_WIDTH, rect.right - rect.left); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_HEIGHT, rect.bottom - rect.top); } } } void RestoreWindowRect(int& left, int& top, int& width, int& height) { - GetRegistryInt(PREF_WINPOS_LEFT, NULL, left); - GetRegistryInt(PREF_WINPOS_TOP, NULL, top); - GetRegistryInt(PREF_WINPOS_WIDTH, NULL, width); - GetRegistryInt(PREF_WINPOS_HEIGHT, NULL, height); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_LEFT, NULL, left); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_TOP, NULL, top); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_WIDTH, NULL, width); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_HEIGHT, NULL, height); } From 9eb8a2d4d18c3e01effe2140a22979766ebedf66 Mon Sep 17 00:00:00 2001 From: Randy Edmunds Date: Wed, 3 Oct 2012 09:33:35 -0700 Subject: [PATCH 3/5] parameterize registry key --- appshell/cefclient_win.cpp | 53 ++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/appshell/cefclient_win.cpp b/appshell/cefclient_win.cpp index f1339e4e3..078689a2d 100644 --- a/appshell/cefclient_win.cpp +++ b/appshell/cefclient_win.cpp @@ -56,11 +56,12 @@ extern CefRefPtr g_handler; #endif // Registry access functions +void GetKey(LPCWSTR pBase, LPCWSTR pGroup, LPCWSTR pApp, LPCWSTR pFolder, LPWSTR pRet); bool GetRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int* pDefault, int& ret); bool WriteRegistryInt (LPCWSTR pFolder, LPCWSTR pEntry, int val); // Registry key strings -#define PREF_BRACKETS_BASE L"Software\\Brackets\\" +#define PREF_APPSHELL_BASE L"Software" #define PREF_WINPOS_FOLDER L"Window Position" #define PREF_LEFT L"Left" #define PREF_TOP L"Top" @@ -206,6 +207,36 @@ int APIENTRY wWinMain(HINSTANCE hInstance, return result; } +// Helper method to build Registry Key string +void GetKey(LPCWSTR pBase, LPCWSTR pGroup, LPCWSTR pApp, LPCWSTR pFolder, LPWSTR pRet) +{ + // Check for required params + ASSERT(pBase && pApp && pRet); + if (!pBase || !pApp || !pRet) + return; + + // Base + wcscpy(pRet, pBase); + + // Group (optional) + if (pGroup && (pGroup[0] != '\0')) + { + wcscat(pRet, L"\\"); + wcscat(pRet, pGroup); + } + + // App name + wcscat(pRet, L"\\"); + wcscat(pRet, pApp); + + // Folder (optional) + if (pFolder && (pFolder[0] != '\0')) + { + wcscat(pRet, L"\\"); + wcscat(pRet, pFolder); + } +} + // get integer value from registry key // caller can either use return value to determine success/fail, or pass a default to be used on fail bool GetRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int* pDefault, int& ret) @@ -213,16 +244,16 @@ bool GetRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int* pDefault, int& ret) HKEY hKey; bool result = false; - std::wstring key = PREF_BRACKETS_BASE; - key += pFolder; + wchar_t key[MAX_PATH]; + key[0] = '\0'; + GetKey(PREF_APPSHELL_BASE, GROUP_NAME, APP_NAME, pFolder, (LPWSTR)&key); - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, KEY_READ, &hKey)) + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key, 0, KEY_READ, &hKey)) { DWORD dwValue = 0; DWORD dwType = 0; DWORD dwCount = sizeof(DWORD); - key = pEntry; - if (ERROR_SUCCESS == RegQueryValueEx(hKey, (LPCWSTR)key.c_str(), NULL, &dwType, (LPBYTE)&dwValue, &dwCount)) + if (ERROR_SUCCESS == RegQueryValueEx(hKey, pEntry, NULL, &dwType, (LPBYTE)&dwValue, &dwCount)) { result = true; ASSERT(dwType == REG_DWORD); @@ -248,14 +279,14 @@ bool WriteRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int val) HKEY hKey; bool result = false; - std::wstring key = PREF_BRACKETS_BASE; - key += pFolder; + wchar_t key[MAX_PATH]; + key[0] = '\0'; + GetKey(PREF_APPSHELL_BASE, GROUP_NAME, APP_NAME, pFolder, (LPWSTR)&key); - if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) + if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, (LPCWSTR)key, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) { DWORD dwCount = sizeof(int); - key = pEntry; - if (ERROR_SUCCESS == RegSetValueEx(hKey, (LPCWSTR)key.c_str(), 0, REG_DWORD, (LPBYTE)&val, dwCount)) + if (ERROR_SUCCESS == RegSetValueEx(hKey, pEntry, 0, REG_DWORD, (LPBYTE)&val, dwCount)) result = true; RegCloseKey(hKey); } From 16a750cb51b27ab4e031a4293b3de255b44aa7c4 Mon Sep 17 00:00:00 2001 From: Randy Edmunds Date: Wed, 10 Oct 2012 17:01:24 -0700 Subject: [PATCH 4/5] handle path parts both with and without trailing separators --- appshell/cefclient_win.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/appshell/cefclient_win.cpp b/appshell/cefclient_win.cpp index 078689a2d..56858d2a1 100644 --- a/appshell/cefclient_win.cpp +++ b/appshell/cefclient_win.cpp @@ -56,6 +56,7 @@ extern CefRefPtr g_handler; #endif // Registry access functions +void EnsureTrailingSeparator(LPWSTR pRet); void GetKey(LPCWSTR pBase, LPCWSTR pGroup, LPCWSTR pApp, LPCWSTR pFolder, LPWSTR pRet); bool GetRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int* pDefault, int& ret); bool WriteRegistryInt (LPCWSTR pFolder, LPCWSTR pEntry, int val); @@ -207,6 +208,19 @@ int APIENTRY wWinMain(HINSTANCE hInstance, return result; } +// Add trailing separator, if necessary +void EnsureTrailingSeparator(LPWSTR pRet) +{ + if (!pRet) + return; + + int len = wcslen(pRet); + if (len > 0 && wcscmp(&(pRet[len-1]), L"\\") != 0) + { + wcscat(pRet, L"\\"); + } +} + // Helper method to build Registry Key string void GetKey(LPCWSTR pBase, LPCWSTR pGroup, LPCWSTR pApp, LPCWSTR pFolder, LPWSTR pRet) { @@ -221,18 +235,18 @@ void GetKey(LPCWSTR pBase, LPCWSTR pGroup, LPCWSTR pApp, LPCWSTR pFolder, LPWSTR // Group (optional) if (pGroup && (pGroup[0] != '\0')) { - wcscat(pRet, L"\\"); + EnsureTrailingSeparator(pRet); wcscat(pRet, pGroup); } // App name - wcscat(pRet, L"\\"); + EnsureTrailingSeparator(pRet); wcscat(pRet, pApp); // Folder (optional) if (pFolder && (pFolder[0] != '\0')) { - wcscat(pRet, L"\\"); + EnsureTrailingSeparator(pRet); wcscat(pRet, pFolder); } } From d4bd936d473805a26d06dce71a5e2b6db02af304 Mon Sep 17 00:00:00 2001 From: Randy Edmunds Date: Thu, 11 Oct 2012 14:59:58 -0700 Subject: [PATCH 5/5] handle maximized and minimized window states --- appshell/cefclient_win.cpp | 118 +++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 23 deletions(-) diff --git a/appshell/cefclient_win.cpp b/appshell/cefclient_win.cpp index 56858d2a1..b2572fa9f 100644 --- a/appshell/cefclient_win.cpp +++ b/appshell/cefclient_win.cpp @@ -68,10 +68,16 @@ bool WriteRegistryInt (LPCWSTR pFolder, LPCWSTR pEntry, int val); #define PREF_TOP L"Top" #define PREF_WIDTH L"Width" #define PREF_HEIGHT L"Height" +#define PREF_RESTORE_LEFT L"Restore Left" +#define PREF_RESTORE_TOP L"Restore Top" +#define PREF_RESTORE_RIGHT L"Restore Right" +#define PREF_RESTORE_BOTTOM L"Restore Bottom" +#define PREF_SHOWSTATE L"Show State" // Window state functions -void SaveWindowRect(); -void RestoreWindowRect(int& left, int& top, int& width, int& height); +void SaveWindowRect(HWND hWnd); +void RestoreWindowRect(int& left, int& top, int& width, int& height, int& showCmd); +void RestoreWindowPlacement(HWND hWnd, int showCmd); // Program entry point function. int APIENTRY wWinMain(HINSTANCE hInstance, @@ -308,29 +314,90 @@ bool WriteRegistryInt(LPCWSTR pFolder, LPCWSTR pEntry, int val) return result; } -void SaveWindowRect() +void SaveWindowRect(HWND hWnd) { // Save position of active window - HWND hWnd = GetActiveWindow(); - if (hWnd) + if (!hWnd) + return; + + WINDOWPLACEMENT wp; + memset(&wp, 0, sizeof(WINDOWPLACEMENT)); + wp.length = sizeof(WINDOWPLACEMENT); + + if (GetWindowPlacement(hWnd, &wp)) { - RECT rect; - if (GetWindowRect(hWnd, &rect)) + // Only save window positions for "restored" and "maximized" states. + // If window is closed while "minimized", we don't want it to open minimized + // for next session, so don't update registry so it opens in previous state. + if (wp.showCmd == SW_SHOWNORMAL || wp.showCmd == SW_SHOW || wp.showCmd == SW_MAXIMIZE) { - WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_LEFT, rect.left); - WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_TOP, rect.top); - WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_WIDTH, rect.right - rect.left); - WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_HEIGHT, rect.bottom - rect.top); + RECT rect; + if (GetWindowRect(hWnd, &rect)) + { + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_LEFT, rect.left); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_TOP, rect.top); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_WIDTH, rect.right - rect.left); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_HEIGHT, rect.bottom - rect.top); + } + + if (wp.showCmd == SW_MAXIMIZE) + { + // When window is maximized, we also store the "restore" size + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_LEFT, wp.rcNormalPosition.left); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_TOP, wp.rcNormalPosition.top); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_RIGHT, wp.rcNormalPosition.right); + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_BOTTOM, wp.rcNormalPosition.bottom); + } + + // Maximize is the only special case we handle + WriteRegistryInt(PREF_WINPOS_FOLDER, PREF_SHOWSTATE, + (wp.showCmd == SW_MAXIMIZE) ? SW_MAXIMIZE : SW_SHOW); } } } -void RestoreWindowRect(int& left, int& top, int& width, int& height) +void RestoreWindowRect(int& left, int& top, int& width, int& height, int& showCmd) +{ + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_LEFT, NULL, left); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_TOP, NULL, top); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_WIDTH, NULL, width); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_HEIGHT, NULL, height); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_SHOWSTATE, NULL, showCmd); +} + +void RestoreWindowPlacement(HWND hWnd, int showCmd) { - GetRegistryInt(PREF_WINPOS_FOLDER, PREF_LEFT, NULL, left); - GetRegistryInt(PREF_WINPOS_FOLDER, PREF_TOP, NULL, top); - GetRegistryInt(PREF_WINPOS_FOLDER, PREF_WIDTH, NULL, width); - GetRegistryInt(PREF_WINPOS_FOLDER, PREF_HEIGHT, NULL, height); + if (!hWnd) + return; + + // If window is maximized, set the "restore" window position + if (showCmd == SW_MAXIMIZE) + { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + + wp.flags = 0; + wp.showCmd = SW_MAXIMIZE; + wp.ptMinPosition.x = -1; + wp.ptMinPosition.y = -1; + wp.ptMaxPosition.x = -1; + wp.ptMaxPosition.y = -1; + + wp.rcNormalPosition.left = CW_USEDEFAULT; + wp.rcNormalPosition.top = CW_USEDEFAULT; + wp.rcNormalPosition.right = CW_USEDEFAULT; + wp.rcNormalPosition.bottom = CW_USEDEFAULT; + + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_LEFT, NULL, (int&)wp.rcNormalPosition.left); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_TOP, NULL, (int&)wp.rcNormalPosition.top); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_RIGHT, NULL, (int&)wp.rcNormalPosition.right); + GetRegistryInt(PREF_WINPOS_FOLDER, PREF_RESTORE_BOTTOM, NULL, (int&)wp.rcNormalPosition.bottom); + + // This returns an error code, but not sure what we could do on an error + SetWindowPlacement(hWnd, &wp); + } + + ShowWindow(hWnd, showCmd); } @@ -395,18 +462,22 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { // - window in secondary monitor when shutdown, disconnect secondary monitor, restart int left = CW_USEDEFAULT; - int top = 0; + int top = CW_USEDEFAULT; int width = CW_USEDEFAULT; - int height = 0; - RestoreWindowRect(left, top, width, height); - - hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + int height = CW_USEDEFAULT; + int showCmd = SW_SHOW; + RestoreWindowRect(left, top, width, height, showCmd); + + DWORD styles = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; + if (showCmd == SW_MAXIMIZE) + styles |= WS_MAXIMIZE; + hWnd = CreateWindow(szWindowClass, szTitle, styles, left, top, width, height, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; - ShowWindow(hWnd, nCmdShow); + RestoreWindowPlacement(hWnd, showCmd); UpdateWindow(hWnd); return TRUE; @@ -662,7 +733,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, case WM_CLOSE: if (g_handler.get()) { - SaveWindowRect(); + HWND hWnd = GetActiveWindow(); + SaveWindowRect(hWnd); // If we already initiated the browser closing, then let default window proc handle it. HWND browserHwnd = g_handler->GetBrowser()->GetHost()->GetWindowHandle();