diff options
author | George Hazan <ghazan@miranda.im> | 2017-09-26 16:24:56 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2017-09-26 16:25:03 +0300 |
commit | 2d469bf7d00fd198097fee6a1f672ee7c8cc7a9a (patch) | |
tree | 3193291755a19c006bc83ac427e02907a49ec7f3 /plugins | |
parent | b8af15fcafc9fa8b5a75fd790b93fd3f0ed5cb7e (diff) |
AsSingleWindow:
- fix for a crash on dynamic unload;
- major code cleaning
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/AsSingleWindow/src/AsSingleWindow.cpp | 84 | ||||
-rw-r--r-- | plugins/AsSingleWindow/src/Options.cpp | 164 | ||||
-rw-r--r-- | plugins/AsSingleWindow/src/WindowsManager.cpp | 731 | ||||
-rw-r--r-- | plugins/AsSingleWindow/src/WindowsManager.h | 43 | ||||
-rw-r--r-- | plugins/AsSingleWindow/src/version.h | 2 |
5 files changed, 492 insertions, 532 deletions
diff --git a/plugins/AsSingleWindow/src/AsSingleWindow.cpp b/plugins/AsSingleWindow/src/AsSingleWindow.cpp index f4fd623e24..4459f498c3 100644 --- a/plugins/AsSingleWindow/src/AsSingleWindow.cpp +++ b/plugins/AsSingleWindow/src/AsSingleWindow.cpp @@ -8,79 +8,81 @@ CLIST_INTERFACE *pcli; int hLangpack; PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), - __DESCRIPTION, - __AUTHOR, - __AUTHOREMAIL, - __COPYRIGHT, - __AUTHORWEB, - UNICODE_AWARE, - {0xF6C73B4, 0x2B2B, 0x711D, {0xFB, 0xB6, 0xBB, 0x26, 0x7D, 0xFD, 0x72, 0x08}}, // 0xF6C73B42B2B711DFBB6BB267DFD7208 + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + {0xF6C73B4, 0x2B2B, 0x711D, {0xFB, 0xB6, 0xBB, 0x26, 0x7D, 0xFD, 0x72, 0x08}}, // 0xF6C73B42B2B711DFBB6BB267DFD7208 }; sPluginVars pluginVars; bool WINAPI DllMain(HINSTANCE hInstDLL, DWORD, LPVOID) { - pluginVars.hInst = hInstDLL; - return true; + pluginVars.hInst = hInstDLL; + return true; } extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) { - return &pluginInfo; + return &pluginInfo; +} + +static int OnShutdown(WPARAM, LPARAM) +{ + for (auto itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) + mir_unsubclassWindow(itr->hWnd, wndProcSync); + return 0; } extern "C" __declspec(dllexport) int Load(void) { mir_getLP(&pluginInfo); pcli = Clist_GetInterface(); - + ::InitializeCriticalSection(&pluginVars.m_CS); - pluginVars.IsUpdateInProgress = false; - HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - HookEvent(ME_OPT_INITIALISE, InitOptions); - - return 0; + pluginVars.IsUpdateInProgress = false; + HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + HookEvent(ME_SYSTEM_SHUTDOWN, OnShutdown); + HookEvent(ME_OPT_INITIALISE, InitOptions); + return 0; } extern "C" __declspec(dllexport) int Unload(void) { - ::DeleteCriticalSection(&pluginVars.m_CS); - - return 0; + ::DeleteCriticalSection(&pluginVars.m_CS); + return 0; } int OnModulesLoaded(WPARAM, LPARAM) { - HWND hWndCListWindow = pcli->hwndContactList; - windowAdd(hWndCListWindow, true); - - HookEvent(ME_MSG_WINDOWEVENT, MsgWindowEvent); + windowAdd(pcli->hwndContactList, true); - optionsLoad(); + HookEvent(ME_MSG_WINDOWEVENT, MsgWindowEvent); - return 0; + optionsLoad(); + return 0; } - int MsgWindowEvent(WPARAM, LPARAM lParam) { - MessageWindowEventData* data = (MessageWindowEventData*) lParam; + MessageWindowEventData* data = (MessageWindowEventData*)lParam; - if (data == NULL) - return 0; + if (data == NULL) + return 0; - switch (data->uType) - { - // Здесь можно отлавливать только открытие окна, - // т.к. закрытие может быть закрытием вкладки - case MSG_WINDOW_EVT_OPEN: - windowAdd(data->hwndWindow, false); - break; - } + switch (data->uType) { + case MSG_WINDOW_EVT_OPEN: + // Здесь можно отлавливать только открытие окна, + // т.к. закрытие может быть закрытием вкладки + windowAdd(data->hwndWindow, false); + break; + } - return 0; + return 0; } diff --git a/plugins/AsSingleWindow/src/Options.cpp b/plugins/AsSingleWindow/src/Options.cpp index 9afc1a6238..1885752561 100644 --- a/plugins/AsSingleWindow/src/Options.cpp +++ b/plugins/AsSingleWindow/src/Options.cpp @@ -7,105 +7,101 @@ int InitOptions(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE Opts = { 0 }; - Opts.szTitle.a = LPGEN("AsSingleWindow"); - Opts.szGroup.a = LPGEN("Customize"); + Opts.szTitle.a = LPGEN("AsSingleWindow"); + Opts.szGroup.a = LPGEN("Customize"); - Opts.pfnDlgProc = cbOptionsDialog; - Opts.pszTemplate = MAKEINTRESOURCEA(IDD_ASW_OPTIONSPAGE); - Opts.hInstance = pluginVars.hInst; - Opts.flags = ODPF_BOLDGROUPS; + Opts.pfnDlgProc = cbOptionsDialog; + Opts.pszTemplate = MAKEINTRESOURCEA(IDD_ASW_OPTIONSPAGE); + Opts.hInstance = pluginVars.hInst; + Opts.flags = ODPF_BOLDGROUPS; Options_AddPage(wParam, &Opts); - return 0; + return 0; } INT_PTR CALLBACK cbOptionsDialog(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - switch (msg) { - case WM_INITDIALOG: - dlgProcessInit(hWnd, msg, wParam, lParam); - break; - - case WM_COMMAND: - dlgProcessCommand(hWnd, msg, wParam, lParam); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == 0) - { - switch (((LPNMHDR)lParam)->code) - { - case PSN_RESET: - optionsLoad(); - break; - - case PSN_APPLY: - optionsUpdate(hWnd); - optionsSave(); - windowReposition(hWnd); // Инициируем перерасчет координат - break; - } - } - break; - - case WM_DESTROY: - // free up resources - break; - } - - return false; + switch (msg) { + case WM_INITDIALOG: + dlgProcessInit(hWnd, msg, wParam, lParam); + break; + + case WM_COMMAND: + dlgProcessCommand(hWnd, msg, wParam, lParam); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == 0) { + switch (((LPNMHDR)lParam)->code) { + case PSN_RESET: + optionsLoad(); + break; + + case PSN_APPLY: + optionsUpdate(hWnd); + optionsSave(); + windowReposition(hWnd); // Инициируем перерасчет координат + break; + } + } + break; + + case WM_DESTROY: + // free up resources + break; + } + + return false; } void dlgProcessInit(HWND hWnd, UINT, WPARAM, LPARAM) { - TranslateDialogDefault(hWnd); + TranslateDialogDefault(hWnd); - CheckDlgButton(hWnd, IDC_RADIO_G1_RIGHTCL, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_RIGHT)); - CheckDlgButton(hWnd, IDC_RADIO_G1_LEFTCL, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_LEFT)); - CheckDlgButton(hWnd, IDC_RADIO_G1_DONTMERGEWINDOWS, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_DISABLED)); + CheckDlgButton(hWnd, IDC_RADIO_G1_RIGHTCL, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_RIGHT)); + CheckDlgButton(hWnd, IDC_RADIO_G1_LEFTCL, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_LEFT)); + CheckDlgButton(hWnd, IDC_RADIO_G1_DONTMERGEWINDOWS, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_DISABLED)); - CheckDlgButton(hWnd, IDC_RADIO_G2_MERGEALL, (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEALL)); - CheckDlgButton(hWnd, IDC_RADIO_G2_MERGEONE, (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEONE)); - CheckDlgButton(hWnd, IDC_RADIO_G2_DISABLEMERGE, (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEDISABLE)); + CheckDlgButton(hWnd, IDC_RADIO_G2_MERGEALL, (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEALL)); + CheckDlgButton(hWnd, IDC_RADIO_G2_MERGEONE, (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEONE)); + CheckDlgButton(hWnd, IDC_RADIO_G2_DISABLEMERGE, (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEDISABLE)); - dlgUpdateControls(hWnd); + dlgUpdateControls(hWnd); } void dlgProcessCommand(HWND hWnd, UINT, WPARAM wParam, LPARAM) { - WORD idCtrl = LOWORD(wParam); - WORD idNotifyCode = HIWORD(wParam); - - switch (idCtrl) - { - case IDC_RADIO_G1_LEFTCL: - case IDC_RADIO_G1_RIGHTCL: - case IDC_RADIO_G1_DONTMERGEWINDOWS: - if (idNotifyCode == BN_CLICKED) - { - dlgUpdateControls(hWnd); - SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); - } - break; - - case IDC_RADIO_G2_MERGEALL: - case IDC_RADIO_G2_MERGEONE: - case IDC_RADIO_G2_DISABLEMERGE: - if (idNotifyCode == BN_CLICKED) - SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); - break; - } + WORD idCtrl = LOWORD(wParam); + WORD idNotifyCode = HIWORD(wParam); + + switch (idCtrl) { + case IDC_RADIO_G1_LEFTCL: + case IDC_RADIO_G1_RIGHTCL: + case IDC_RADIO_G1_DONTMERGEWINDOWS: + if (idNotifyCode == BN_CLICKED) { + dlgUpdateControls(hWnd); + SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); + } + break; + + case IDC_RADIO_G2_MERGEALL: + case IDC_RADIO_G2_MERGEONE: + case IDC_RADIO_G2_DISABLEMERGE: + if (idNotifyCode == BN_CLICKED) + SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); + break; + } } void dlgUpdateControls(HWND hWnd) { - UINT idState; + UINT idState; - idState = IsDlgButtonChecked(hWnd, IDC_RADIO_G1_DONTMERGEWINDOWS); - EnableWindow(GetDlgItem(hWnd, IDC_RADIO_G2_MERGEALL), ! idState); - EnableWindow(GetDlgItem(hWnd, IDC_RADIO_G2_MERGEONE), ! idState); - EnableWindow(GetDlgItem(hWnd, IDC_RADIO_G2_DISABLEMERGE), ! idState); + idState = IsDlgButtonChecked(hWnd, IDC_RADIO_G1_DONTMERGEWINDOWS); + EnableWindow(GetDlgItem(hWnd, IDC_RADIO_G2_MERGEALL), !idState); + EnableWindow(GetDlgItem(hWnd, IDC_RADIO_G2_MERGEONE), !idState); + EnableWindow(GetDlgItem(hWnd, IDC_RADIO_G2_DISABLEMERGE), !idState); } void optionsLoad() @@ -116,15 +112,15 @@ void optionsLoad() void optionsUpdate(HWND hWnd) { - pluginVars.Options.DrivenWindowPos = - (IsDlgButtonChecked(hWnd, IDC_RADIO_G1_LEFTCL) * ASW_CLWINDOWPOS_LEFT) + - (IsDlgButtonChecked(hWnd, IDC_RADIO_G1_RIGHTCL) * ASW_CLWINDOWPOS_RIGHT) + - (IsDlgButtonChecked(hWnd, IDC_RADIO_G1_DONTMERGEWINDOWS) * ASW_CLWINDOWPOS_DISABLED); - - pluginVars.Options.WindowsMerging = - (IsDlgButtonChecked(hWnd, IDC_RADIO_G2_MERGEALL) * ASW_WINDOWS_MERGEALL) + - (IsDlgButtonChecked(hWnd, IDC_RADIO_G2_MERGEONE) * ASW_WINDOWS_MERGEONE) + - (IsDlgButtonChecked(hWnd, IDC_RADIO_G2_DISABLEMERGE) * ASW_WINDOWS_MERGEDISABLE); + pluginVars.Options.DrivenWindowPos = + (IsDlgButtonChecked(hWnd, IDC_RADIO_G1_LEFTCL) * ASW_CLWINDOWPOS_LEFT) + + (IsDlgButtonChecked(hWnd, IDC_RADIO_G1_RIGHTCL) * ASW_CLWINDOWPOS_RIGHT) + + (IsDlgButtonChecked(hWnd, IDC_RADIO_G1_DONTMERGEWINDOWS) * ASW_CLWINDOWPOS_DISABLED); + + pluginVars.Options.WindowsMerging = + (IsDlgButtonChecked(hWnd, IDC_RADIO_G2_MERGEALL) * ASW_WINDOWS_MERGEALL) + + (IsDlgButtonChecked(hWnd, IDC_RADIO_G2_MERGEONE) * ASW_WINDOWS_MERGEONE) + + (IsDlgButtonChecked(hWnd, IDC_RADIO_G2_DISABLEMERGE) * ASW_WINDOWS_MERGEDISABLE); } void optionsSave() diff --git a/plugins/AsSingleWindow/src/WindowsManager.cpp b/plugins/AsSingleWindow/src/WindowsManager.cpp index 66cf18a3ab..c741b416e7 100644 --- a/plugins/AsSingleWindow/src/WindowsManager.cpp +++ b/plugins/AsSingleWindow/src/WindowsManager.cpp @@ -4,72 +4,70 @@ void sWindowInfo::saveState() { - WINDOWPLACEMENT wndPlace; - wndPlace.length = sizeof(wndPlace); - if (! GetWindowPlacement(this->hWnd, &wndPlace)) - return; - - switch (wndPlace.showCmd) - { - case SW_HIDE: - this->eState = WINDOW_STATE_HIDDEN; - break; - - case SW_MINIMIZE: - case SW_SHOWMINIMIZED: - case SW_SHOWMINNOACTIVE: - this->eState = WINDOW_STATE_MINIMIZED; - break; - - case SW_MAXIMIZE: - case SW_RESTORE: - case SW_SHOW: - case SW_SHOWNA: - case SW_SHOWNOACTIVATE: - case SW_SHOWNORMAL: - this->eState = WINDOW_STATE_NORMAL; - break; - } + WINDOWPLACEMENT wndPlace; + wndPlace.length = sizeof(wndPlace); + if (!GetWindowPlacement(this->hWnd, &wndPlace)) + return; + + switch (wndPlace.showCmd) { + case SW_HIDE: + this->eState = WINDOW_STATE_HIDDEN; + break; + + case SW_MINIMIZE: + case SW_SHOWMINIMIZED: + case SW_SHOWMINNOACTIVE: + this->eState = WINDOW_STATE_MINIMIZED; + break; + + case SW_MAXIMIZE: + case SW_RESTORE: + case SW_SHOW: + case SW_SHOWNA: + case SW_SHOWNOACTIVATE: + case SW_SHOWNORMAL: + this->eState = WINDOW_STATE_NORMAL; + break; + } } void sWindowInfo::saveRect() { - switch (this->eState) - { - case WINDOW_STATE_HIDDEN: - case WINDOW_STATE_MINIMIZED: - WINDOWPLACEMENT wndPlace; - wndPlace.length = sizeof(wndPlace); - if (GetWindowPlacement(this->hWnd, &wndPlace)) - this->rLastSavedPosition = wndPlace.rcNormalPosition; - break; - - default: - GetWindowRect(this->hWnd, &this->rLastSavedPosition); - break; - } + switch (this->eState) { + case WINDOW_STATE_HIDDEN: + case WINDOW_STATE_MINIMIZED: + WINDOWPLACEMENT wndPlace; + wndPlace.length = sizeof(wndPlace); + if (GetWindowPlacement(this->hWnd, &wndPlace)) + this->rLastSavedPosition = wndPlace.rcNormalPosition; + break; + + default: + GetWindowRect(this->hWnd, &this->rLastSavedPosition); + break; + } } void pluginSetProgress() { - EnterCriticalSection(&pluginVars.m_CS); - pluginVars.IsUpdateInProgress = true; - LeaveCriticalSection(&pluginVars.m_CS); + EnterCriticalSection(&pluginVars.m_CS); + pluginVars.IsUpdateInProgress = true; + LeaveCriticalSection(&pluginVars.m_CS); } void pluginSetDone() { - EnterCriticalSection(&pluginVars.m_CS); - pluginVars.IsUpdateInProgress = false; - LeaveCriticalSection(&pluginVars.m_CS); + EnterCriticalSection(&pluginVars.m_CS); + pluginVars.IsUpdateInProgress = false; + LeaveCriticalSection(&pluginVars.m_CS); } bool pluginIsAlreadyRunning() { - EnterCriticalSection(&pluginVars.m_CS); - bool result = pluginVars.IsUpdateInProgress; - LeaveCriticalSection(&pluginVars.m_CS); - return result; + EnterCriticalSection(&pluginVars.m_CS); + bool result = pluginVars.IsUpdateInProgress; + LeaveCriticalSection(&pluginVars.m_CS); + return result; } /** @@ -78,12 +76,11 @@ bool pluginIsAlreadyRunning() */ sWindowInfo* windowFind(HWND hWnd) { - windowsList::iterator itr; - for (itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) - if (itr->hWnd == hWnd) - return &*itr; + for (auto itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) + if (itr->hWnd == hWnd) + return &*itr; - return NULL; + return nullptr; } /** @@ -92,12 +89,11 @@ sWindowInfo* windowFind(HWND hWnd) */ windowsList::iterator windowFindItr(HWND hWnd) { - windowsList::iterator itr; - for (itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) - if (itr->hWnd == hWnd) - return itr; + for (auto itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) + if (itr->hWnd == hWnd) + return itr; - return itr; + return pluginVars.allWindows.end(); } /** @@ -106,12 +102,11 @@ windowsList::iterator windowFindItr(HWND hWnd) */ windowsList::reverse_iterator windowFindRevItr(HWND hWnd) { - windowsList::reverse_iterator ritr; - for (ritr = pluginVars.allWindows.rbegin(); ritr != pluginVars.allWindows.rend(); ++ritr) - if (ritr->hWnd == hWnd) - return ritr; + for (auto ritr = pluginVars.allWindows.rbegin(); ritr != pluginVars.allWindows.rend(); ++ritr) + if (ritr->hWnd == hWnd) + return ritr; - return ritr; + return pluginVars.allWindows.rend(); } /** @@ -120,28 +115,27 @@ windowsList::reverse_iterator windowFindRevItr(HWND hWnd) */ void windowAdd(HWND hWnd, bool IsMain) { - sWindowInfo thisWindowInfo; - - hWnd = windowGetRoot(hWnd); + sWindowInfo thisWindowInfo; - // Если окно уже есть в списке (могло быть спрятано) - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - wndInfo->eState = WINDOW_STATE_NORMAL; // если окно пряталось ранее - windowReposition(hWnd); - return; - } + hWnd = windowGetRoot(hWnd); - thisWindowInfo.hWnd = hWnd; - thisWindowInfo.eState = WINDOW_STATE_NORMAL; - thisWindowInfo.pPrevWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)wndProcSync); + // Если окно уже есть в списке (могло быть спрятано) + if (sWindowInfo* wndInfo = windowFind(hWnd)) { + wndInfo->eState = WINDOW_STATE_NORMAL; // если окно пряталось ранее + windowReposition(hWnd); + return; + } - pluginVars.allWindows.push_back(thisWindowInfo); + thisWindowInfo.hWnd = hWnd; + thisWindowInfo.eState = WINDOW_STATE_NORMAL; + mir_subclassWindow(hWnd, wndProcSync); - if (IsMain) - pluginVars.contactListHWND = hWnd; + pluginVars.allWindows.push_back(thisWindowInfo); - windowReposition(hWnd); + if (IsMain) + pluginVars.contactListHWND = hWnd; + + windowReposition(hWnd); } /** @@ -149,35 +143,34 @@ void windowAdd(HWND hWnd, bool IsMain) */ HWND windowGetRoot(HWND hWnd) { - HWND hWndParent = GetParent(hWnd); - while (IsWindow(hWndParent) && (hWndParent != GetDesktopWindow())) // IsWindowVisible() ? - { - hWnd = hWndParent; - hWndParent = GetParent(hWnd); - } - return hWnd; + HWND hWndParent = GetParent(hWnd); + while (IsWindow(hWndParent) && (hWndParent != GetDesktopWindow())) // IsWindowVisible() ? + { + hWnd = hWndParent; + hWndParent = GetParent(hWnd); + } + return hWnd; } void windowListUpdate() { - bool isRemoved = false; - windowsList::iterator itr = pluginVars.allWindows.begin(); - while (itr != pluginVars.allWindows.end()) - // Не удаляем КЛ в принципе, нет необходимости - if (!IsWindow(itr->hWnd) && itr->hWnd != pluginVars.contactListHWND) - { - if (itr->hWnd == pluginVars.contactListHWND) - pluginVars.contactListHWND = 0; - itr = pluginVars.allWindows.erase(itr); - isRemoved = true; - } - else - ++itr; - - if (isRemoved) - if (!pluginVars.allWindows.empty()) - // TODO: разобраться, почему после этого КЛ пропадает в трей - allWindowsMoveAndSize(pluginVars.contactListHWND); + bool isRemoved = false; + windowsList::iterator itr = pluginVars.allWindows.begin(); + while (itr != pluginVars.allWindows.end()) + // Не удаляем КЛ в принципе, нет необходимости + if (!IsWindow(itr->hWnd) && itr->hWnd != pluginVars.contactListHWND) { + if (itr->hWnd == pluginVars.contactListHWND) + pluginVars.contactListHWND = 0; + itr = pluginVars.allWindows.erase(itr); + isRemoved = true; + } + else + ++itr; + + if (isRemoved) + if (!pluginVars.allWindows.empty()) + // TODO: разобраться, почему после этого КЛ пропадает в трей + allWindowsMoveAndSize(pluginVars.contactListHWND); } /** @@ -186,28 +179,25 @@ void windowListUpdate() */ void windowReposition(HWND hWnd) { - // TODO: Подумать, нужен ли тут hWnd вообще - RECT prevWindowPos; - - hWnd = windowGetRoot(hWnd); - - // TODO: Проверить, возможно нужен выход из цикла - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - for (windowsList::iterator itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) - if (itr->hWnd != hWnd) // TODO: очень странная логика - if (GetWindowRect(itr->hWnd, &prevWindowPos)) - { - SendMessage(itr->hWnd, WM_MOVE, 0, MAKELPARAM(prevWindowPos.left, prevWindowPos.top)); - break; - } - } - else if (!pluginVars.allWindows.empty()) - { - windowsList::iterator itr = pluginVars.allWindows.begin(); - if (GetWindowRect(itr->hWnd, &prevWindowPos)) - SendMessage(itr->hWnd, WM_MOVE, 0, MAKELPARAM(prevWindowPos.left, prevWindowPos.top)); - } + // TODO: Подумать, нужен ли тут hWnd вообще + RECT prevWindowPos; + + hWnd = windowGetRoot(hWnd); + + // TODO: Проверить, возможно нужен выход из цикла + if (sWindowInfo* wndInfo = windowFind(hWnd)) { + for (auto itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) + if (itr->hWnd != hWnd) // TODO: очень странная логика + if (GetWindowRect(itr->hWnd, &prevWindowPos)) { + SendMessage(itr->hWnd, WM_MOVE, 0, MAKELPARAM(prevWindowPos.left, prevWindowPos.top)); + break; + } + } + else if (!pluginVars.allWindows.empty()) { + auto itr = pluginVars.allWindows.begin(); + if (GetWindowRect(itr->hWnd, &prevWindowPos)) + SendMessage(itr->hWnd, WM_MOVE, 0, MAKELPARAM(prevWindowPos.left, prevWindowPos.top)); + } } /** @@ -216,286 +206,259 @@ void windowReposition(HWND hWnd) */ void allWindowsMoveAndSize(HWND hWnd) { - // Если склеивание отключено - if (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_DISABLED) - return; - - // Окно должно быть в списке и иметь нормальное состояние - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - if (wndInfo->eState != WINDOW_STATE_NORMAL) - return; - } - else - return; - - // Отключаем связь, если окон больше двух и выбрана соотв. опция - if (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEDISABLE) - if (pluginVars.allWindows.size() > 2) - return; - - // Просмотр окон от текущего до конца - windowsList::iterator itrC = windowFindItr(hWnd); - if (itrC != pluginVars.allWindows.end()) - { - windowsList::iterator itrN = ++windowFindItr(hWnd); - for (; itrC != pluginVars.allWindows.end(), itrN != pluginVars.allWindows.end(); ++itrC, ++itrN) - { - // Режим только двух окон - if (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEONE) - if ((itrC->hWnd != pluginVars.contactListHWND) && (itrN->hWnd != pluginVars.contactListHWND)) - continue; - - // itrC проверяется в начале функции - UINT incCount = 0; - bool isItrInList = true; - while (itrN->eState != WINDOW_STATE_NORMAL) - { - ++itrN; - ++incCount; - if (itrN == pluginVars.allWindows.end()) - { - isItrInList = false; - break; - } - } - if (! isItrInList) - break; - - sWndCoords wndCoord; - if (calcNewWindowPosition(itrC->hWnd, itrN->hWnd, &wndCoord, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_RIGHT) ? WINDOW_POSITION_RIGHT : WINDOW_POSITION_LEFT)) - SetWindowPos(itrN->hWnd, itrC->hWnd, wndCoord.x, wndCoord.y, wndCoord.width, wndCoord.height, SWP_NOACTIVATE); - - itrN->saveRect(); - - for (; incCount != 0; incCount--) - ++itrC; - } - } - - // Просмотр окон от текущего до начала - windowsList::reverse_iterator ritrC = windowFindRevItr(hWnd); - if (ritrC != pluginVars.allWindows.rend()) - { - windowsList::reverse_iterator ritrN = ++windowFindRevItr(hWnd); - for (; ritrC != pluginVars.allWindows.rend(), ritrN != pluginVars.allWindows.rend(); ++ritrC, ++ritrN) - { - // Режим только двух окон - if (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEONE) - if ((ritrC->hWnd != pluginVars.contactListHWND) && (ritrN->hWnd != pluginVars.contactListHWND)) - continue; - - UINT incCount = 0; - bool isItrInList = true; - while (ritrN->eState != WINDOW_STATE_NORMAL) - { - ++ritrN; - ++incCount; - if (ritrN == pluginVars.allWindows.rend()) - { - isItrInList = false; - break; - } - } - if (! isItrInList) - break; - - sWndCoords wndCoord; - if (calcNewWindowPosition(ritrC->hWnd, ritrN->hWnd, &wndCoord, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_RIGHT) ? WINDOW_POSITION_LEFT : WINDOW_POSITION_RIGHT)) - SetWindowPos(ritrN->hWnd, ritrC->hWnd, wndCoord.x, wndCoord.y, wndCoord.width, wndCoord.height, SWP_NOACTIVATE); - - ritrN->saveRect(); - - for (; incCount != 0; incCount--) - ++ritrC; - } - } - - if (sWindowInfo* wndInfo = windowFind(hWnd)) - wndInfo->saveRect(); + // Если склеивание отключено + if (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_DISABLED) + return; + + // Окно должно быть в списке и иметь нормальное состояние + if (sWindowInfo* wndInfo = windowFind(hWnd)) { + if (wndInfo->eState != WINDOW_STATE_NORMAL) + return; + } + else + return; + + // Отключаем связь, если окон больше двух и выбрана соотв. опция + if (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEDISABLE) + if (pluginVars.allWindows.size() > 2) + return; + + // Просмотр окон от текущего до конца + windowsList::iterator itrC = windowFindItr(hWnd); + if (itrC != pluginVars.allWindows.end()) { + windowsList::iterator itrN = ++windowFindItr(hWnd); + for (; itrC != pluginVars.allWindows.end(), itrN != pluginVars.allWindows.end(); ++itrC, ++itrN) { + // Режим только двух окон + if (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEONE) + if ((itrC->hWnd != pluginVars.contactListHWND) && (itrN->hWnd != pluginVars.contactListHWND)) + continue; + + // itrC проверяется в начале функции + UINT incCount = 0; + bool isItrInList = true; + while (itrN->eState != WINDOW_STATE_NORMAL) { + ++itrN; + ++incCount; + if (itrN == pluginVars.allWindows.end()) { + isItrInList = false; + break; + } + } + if (!isItrInList) + break; + + sWndCoords wndCoord; + if (calcNewWindowPosition(itrC->hWnd, itrN->hWnd, &wndCoord, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_RIGHT) ? WINDOW_POSITION_RIGHT : WINDOW_POSITION_LEFT)) + SetWindowPos(itrN->hWnd, itrC->hWnd, wndCoord.x, wndCoord.y, wndCoord.width, wndCoord.height, SWP_NOACTIVATE); + + itrN->saveRect(); + + for (; incCount != 0; incCount--) + ++itrC; + } + } + + // Просмотр окон от текущего до начала + windowsList::reverse_iterator ritrC = windowFindRevItr(hWnd); + if (ritrC != pluginVars.allWindows.rend()) { + windowsList::reverse_iterator ritrN = ++windowFindRevItr(hWnd); + for (; ritrC != pluginVars.allWindows.rend(), ritrN != pluginVars.allWindows.rend(); ++ritrC, ++ritrN) { + // Режим только двух окон + if (pluginVars.Options.WindowsMerging == ASW_WINDOWS_MERGEONE) + if ((ritrC->hWnd != pluginVars.contactListHWND) && (ritrN->hWnd != pluginVars.contactListHWND)) + continue; + + UINT incCount = 0; + bool isItrInList = true; + while (ritrN->eState != WINDOW_STATE_NORMAL) { + ++ritrN; + ++incCount; + if (ritrN == pluginVars.allWindows.rend()) { + isItrInList = false; + break; + } + } + if (!isItrInList) + break; + + sWndCoords wndCoord; + if (calcNewWindowPosition(ritrC->hWnd, ritrN->hWnd, &wndCoord, (pluginVars.Options.DrivenWindowPos == ASW_CLWINDOWPOS_RIGHT) ? WINDOW_POSITION_LEFT : WINDOW_POSITION_RIGHT)) + SetWindowPos(ritrN->hWnd, ritrC->hWnd, wndCoord.x, wndCoord.y, wndCoord.width, wndCoord.height, SWP_NOACTIVATE); + + ritrN->saveRect(); + + for (; incCount != 0; incCount--) + ++ritrC; + } + } + + if (sWindowInfo* wndInfo = windowFind(hWnd)) + wndInfo->saveRect(); } void allWindowsActivation(HWND hWnd) { - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - WindowState wndState = wndInfo->eState; - for (windowsList::iterator itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) - { - if (itr->hWnd == hWnd) - continue; - - switch (wndState) - { - // Восстанавливаем все окна и выстраиваем на переднем плане - case WINDOW_STATE_NORMAL: - ShowWindow(itr->hWnd, SW_SHOWNA); - ShowWindow(itr->hWnd, SW_RESTORE); - SetWindowPos(itr->hWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE); - itr->eState = WINDOW_STATE_NORMAL; - break; - - // Прячем окна диалогов, окно КЛ - скрываем - case WINDOW_STATE_MINIMIZED: - if (itr->hWnd != pluginVars.contactListHWND) - ShowWindow(itr->hWnd, SW_MINIMIZE); - else - ShowWindow(itr->hWnd, SW_HIDE); - itr->eState = WINDOW_STATE_MINIMIZED; - break; - - // Прячем все окна - case WINDOW_STATE_HIDDEN: - case WINDOW_STATE_CLOSED: - ShowWindow(itr->hWnd, SW_HIDE); - itr->eState = WINDOW_STATE_HIDDEN; - break; - } - } - } + if (sWindowInfo* wndInfo = windowFind(hWnd)) { + WindowState wndState = wndInfo->eState; + for (auto itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) { + if (itr->hWnd == hWnd) + continue; + + switch (wndState) { + // Восстанавливаем все окна и выстраиваем на переднем плане + case WINDOW_STATE_NORMAL: + ShowWindow(itr->hWnd, SW_SHOWNA); + ShowWindow(itr->hWnd, SW_RESTORE); + SetWindowPos(itr->hWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE); + itr->eState = WINDOW_STATE_NORMAL; + break; + + // Прячем окна диалогов, окно КЛ - скрываем + case WINDOW_STATE_MINIMIZED: + if (itr->hWnd != pluginVars.contactListHWND) + ShowWindow(itr->hWnd, SW_MINIMIZE); + else + ShowWindow(itr->hWnd, SW_HIDE); + itr->eState = WINDOW_STATE_MINIMIZED; + break; + + // Прячем все окна + case WINDOW_STATE_HIDDEN: + case WINDOW_STATE_CLOSED: + ShowWindow(itr->hWnd, SW_HIDE); + itr->eState = WINDOW_STATE_HIDDEN; + break; + } + } + } } void windowChangeState(HWND hWnd, WPARAM cmd, LPARAM) { - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - switch (cmd) - { - case SC_CLOSE: - wndInfo->eState = WINDOW_STATE_CLOSED; - windowReposition(hWnd); - break; - - case SC_MAXIMIZE: - wndInfo->eState = WINDOW_STATE_MAXIMIZED; - windowReposition(hWnd); - break; - - case SC_MINIMIZE: - wndInfo->eState = WINDOW_STATE_MINIMIZED; - allWindowsActivation(hWnd); - break; - - case SC_RESTORE: - case SC_MOVE: - case SC_SIZE: - wndInfo->eState = WINDOW_STATE_NORMAL; - allWindowsActivation(hWnd); - windowReposition(hWnd); - break; - } - } + if (sWindowInfo* wndInfo = windowFind(hWnd)) { + switch (cmd) { + case SC_CLOSE: + wndInfo->eState = WINDOW_STATE_CLOSED; + windowReposition(hWnd); + break; + + case SC_MAXIMIZE: + wndInfo->eState = WINDOW_STATE_MAXIMIZED; + windowReposition(hWnd); + break; + + case SC_MINIMIZE: + wndInfo->eState = WINDOW_STATE_MINIMIZED; + allWindowsActivation(hWnd); + break; + + case SC_RESTORE: + case SC_MOVE: + case SC_SIZE: + wndInfo->eState = WINDOW_STATE_NORMAL; + allWindowsActivation(hWnd); + windowReposition(hWnd); + break; + } + } } void windowChangeState(HWND hWnd, WindowState newState) { - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - wndInfo->eState = newState; - switch (newState) - { - case WINDOW_STATE_NORMAL: - case WINDOW_STATE_HIDDEN: - allWindowsActivation(hWnd); - break; - } - } + if (sWindowInfo* wndInfo = windowFind(hWnd)) { + wndInfo->eState = newState; + switch (newState) { + case WINDOW_STATE_NORMAL: + case WINDOW_STATE_HIDDEN: + allWindowsActivation(hWnd); + break; + } + } } void windowActivation(HWND hWnd, HWND prevhWnd) { - // Не активируем окно, если предыдущим активным было уже привязанное окно - if (sWindowInfo* wndInfo = windowFind(prevhWnd)) - return; - - // Почему-то этот код приводит к скукоживанию КЛа / двойному восстановлению - /* - hWnd = windowGetRoot(hWnd); - if (sWindowInfo* wndInfo = windowFind(hWnd)) - { - if (wndInfo->eState == WINDOW_STATE_MINIMIZED) - ShowWindow(wndInfo->hWnd, SW_RESTORE); - if (wndInfo->eState == WINDOW_STATE_HIDDEN) - ShowWindow(wndInfo->hWnd, SW_SHOW); - wndInfo->eState = WINDOW_STATE_NORMAL; - - allWindowsActivation(hWnd); - } - */ - - for (windowsList::iterator itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) - if (itr->hWnd != hWnd) - { - if (itr->eState == WINDOW_STATE_MINIMIZED) - { - ShowWindow(itr->hWnd, SW_RESTORE); - // itr->eState = WINDOW_STATE_NORMAL; - ведет к глюкам - } - SetWindowPos(itr->hWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } + // Не активируем окно, если предыдущим активным было уже привязанное окно + if (sWindowInfo* wndInfo = windowFind(prevhWnd)) + return; + + // Почему-то этот код приводит к скукоживанию КЛа / двойному восстановлению + /* + hWnd = windowGetRoot(hWnd); + if (sWindowInfo* wndInfo = windowFind(hWnd)) + { + if (wndInfo->eState == WINDOW_STATE_MINIMIZED) + ShowWindow(wndInfo->hWnd, SW_RESTORE); + if (wndInfo->eState == WINDOW_STATE_HIDDEN) + ShowWindow(wndInfo->hWnd, SW_SHOW); + wndInfo->eState = WINDOW_STATE_NORMAL; + + allWindowsActivation(hWnd); + } + */ + + for (auto itr = pluginVars.allWindows.begin(); itr != pluginVars.allWindows.end(); ++itr) { + if (itr->hWnd != hWnd) { + if (itr->eState == WINDOW_STATE_MINIMIZED) { + ShowWindow(itr->hWnd, SW_RESTORE); + // itr->eState = WINDOW_STATE_NORMAL; - ведет к глюкам + } + SetWindowPos(itr->hWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + } } LRESULT CALLBACK wndProcSync(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (! pluginIsAlreadyRunning()) - { - pluginSetProgress(); - - windowListUpdate(); - - switch (msg) - { - case WM_SYSCOMMAND: - windowChangeState(hWnd, wParam, lParam); - break; - - case WM_SIZE: - allWindowsMoveAndSize(hWnd); - break; - - case WM_MOVE: - allWindowsMoveAndSize(hWnd); - break; - - case WM_SHOWWINDOW: - windowChangeState(hWnd, wParam ? WINDOW_STATE_NORMAL : WINDOW_STATE_HIDDEN); - allWindowsMoveAndSize(hWnd); - break; - - case WM_ACTIVATE: - if (wParam) - windowActivation(hWnd, (HWND)lParam); - break; - - //case WM_ACTIVATEAPP: - // if (! wParam) - // windowActivation(hWnd, 0); - // break; - } - - pluginSetDone(); - } - - if (sWindowInfo* wndInfo = windowFind(hWnd)) - return CallWindowProc(wndInfo->pPrevWndProc, hWnd, msg, wParam, lParam); - else - return 0; + if (!pluginIsAlreadyRunning()) { + pluginSetProgress(); + + windowListUpdate(); + + switch (msg) { + case WM_SYSCOMMAND: + windowChangeState(hWnd, wParam, lParam); + break; + + case WM_SIZE: + allWindowsMoveAndSize(hWnd); + break; + + case WM_MOVE: + allWindowsMoveAndSize(hWnd); + break; + + case WM_SHOWWINDOW: + windowChangeState(hWnd, wParam ? WINDOW_STATE_NORMAL : WINDOW_STATE_HIDDEN); + allWindowsMoveAndSize(hWnd); + break; + + case WM_ACTIVATE: + if (wParam) + windowActivation(hWnd, (HWND)lParam); + break; + } + + pluginSetDone(); + } + + return mir_callNextSubclass(hWnd, wndProcSync, msg, wParam, lParam); } bool calcNewWindowPosition(HWND hWndLeading, HWND hWndDriven, sWndCoords* wndCoord, eWindowPosition wndPos) { - RECT rWndLeading, rWndDriven; + RECT rWndLeading, rWndDriven; - if (! GetWindowRect(hWndLeading, &rWndLeading) || ! GetWindowRect(hWndDriven, &rWndDriven)) - return false; + if (!GetWindowRect(hWndLeading, &rWndLeading) || !GetWindowRect(hWndDriven, &rWndDriven)) + return false; - wndCoord->width = rWndDriven.right - rWndDriven.left; - wndCoord->height = rWndLeading.bottom - rWndLeading.top; - wndCoord->y = rWndLeading.top; - if (wndPos == WINDOW_POSITION_RIGHT) - wndCoord->x = rWndLeading.left - wndCoord->width; - else if (wndPos == WINDOW_POSITION_LEFT) - wndCoord->x = rWndLeading.right; + wndCoord->width = rWndDriven.right - rWndDriven.left; + wndCoord->height = rWndLeading.bottom - rWndLeading.top; + wndCoord->y = rWndLeading.top; + if (wndPos == WINDOW_POSITION_RIGHT) + wndCoord->x = rWndLeading.left - wndCoord->width; + else if (wndPos == WINDOW_POSITION_LEFT) + wndCoord->x = rWndLeading.right; - return true; + return true; } diff --git a/plugins/AsSingleWindow/src/WindowsManager.h b/plugins/AsSingleWindow/src/WindowsManager.h index a93f33678c..b3e7e5297f 100644 --- a/plugins/AsSingleWindow/src/WindowsManager.h +++ b/plugins/AsSingleWindow/src/WindowsManager.h @@ -2,32 +2,34 @@ #include "stdafx.h" -enum WindowState { - WINDOW_STATE_NORMAL, - WINDOW_STATE_MINIMIZED, - WINDOW_STATE_MAXIMIZED, - WINDOW_STATE_HIDDEN, - WINDOW_STATE_CLOSED, // not used ? +enum WindowState +{ + WINDOW_STATE_NORMAL, + WINDOW_STATE_MINIMIZED, + WINDOW_STATE_MAXIMIZED, + WINDOW_STATE_HIDDEN, + WINDOW_STATE_CLOSED, // not used ? }; -enum eWindowPosition { - WINDOW_POSITION_LEFT = 1, - WINDOW_POSITION_RIGHT = 2, +enum eWindowPosition +{ + WINDOW_POSITION_LEFT = 1, + WINDOW_POSITION_RIGHT = 2, }; -struct sWndCoords { - LONG x, y, width, height; +struct sWndCoords +{ + LONG x, y, width, height; }; -struct sWindowInfo { - HWND hWnd; - WindowState eState; - WNDPROC pPrevWndProc; - RECT rLastSavedPosition; +struct sWindowInfo +{ + HWND hWnd; + WindowState eState; + RECT rLastSavedPosition; - void saveState(); - void saveRect(); - //void restoreRect(); + void saveState(); + void saveRect(); }; // critical section tools @@ -37,10 +39,7 @@ bool pluginIsAlreadyRunning(); // system sWindowInfo* windowFind(HWND); -//windowsList::iterator windowFindItr(HWND); -//windowsList::reverse_iterator windowFindRevItr(HWND); void windowAdd(HWND, bool); -//void windowRemove(HWND); HWND windowGetRoot(HWND); void windowListUpdate(); void windowReposition(HWND); diff --git a/plugins/AsSingleWindow/src/version.h b/plugins/AsSingleWindow/src/version.h index 8c6f564fd0..4c03112884 100644 --- a/plugins/AsSingleWindow/src/version.h +++ b/plugins/AsSingleWindow/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 2 -#define __BUILD_NUM 1 +#define __BUILD_NUM 2 #include <stdver.h> |