static INT_PTR WLoadWindows(MArray<WindowInfo>& wCurrent, int windowCount) { WindowInfo WInfo; wCurrent.clear(); // Load window list for (int i = 0; i < windowCount; i++) { ZeroStruct(WInfo); WInfo.StructSize = sizeof(WInfo); WInfo.Pos = i; if (!InfoW2800->AdvControl(&guid_ConEmu, ACTL_GETWINDOWINFO, 0, &WInfo)) continue; if (WInfo.Type != WTYPE_EDITOR && WInfo.Type != WTYPE_VIEWER && WInfo.Type != WTYPE_PANELS) continue; if (WInfo.Type == WTYPE_PANELS) { if ((wCurrent.size() > 0) && (wCurrent[0].Type == WTYPE_PANELS)) wCurrent[0] = WInfo; else wCurrent.insert(0, WInfo); } else { wCurrent.push_back(WInfo); } } return wCurrent.size(); }
bool CPluginW2800::UpdateConEmuTabsApi(int windowCount) { if (!InfoW2800 || !InfoW2800->AdvControl || gbIgnoreUpdateTabs) return false; bool lbCh = false, lbDummy = false; WindowInfo WInfo = {sizeof(WindowInfo)}; wchar_t szWNameBuffer[CONEMUTABMAX]; int tabCount = 0; bool lbActiveFound = false; _ASSERTE(GetCurrentThreadId() == gnMainThreadId); WindowInfo WActive = {sizeof(WActive)}; WActive.Pos = -1; bool bActiveInfo = InfoW2800->AdvControl(&guid_ConEmu, ACTL_GETWINDOWINFO, 0, &WActive)!=0; // Если фар запущен с ключом "/e" (как standalone редактор) - будет ассерт при первой попытке // считать информацию об окне (редактор еще не создан?, а панелей вообще нет) _ASSERTE(bActiveInfo && (WActive.Flags & WIF_CURRENT)); static WindowInfo WLastActive; if (!pwList) pwList = new MArray<WindowInfo>(); // Another weird Far API breaking change. How more?.. MArray<WindowInfo> wCurrent; // Load window list for (int i = 0; i < windowCount; i++) { ZeroStruct(WInfo); WInfo.StructSize = sizeof(WInfo); WInfo.Pos = i; if (!InfoW2800->AdvControl(&guid_ConEmu, ACTL_GETWINDOWINFO, 0, &WInfo)) continue; if (WInfo.Type != WTYPE_EDITOR && WInfo.Type != WTYPE_VIEWER && WInfo.Type != WTYPE_PANELS) continue; if (WInfo.Type == WTYPE_PANELS) { if ((wCurrent.size() > 0) && (wCurrent[0].Type == WTYPE_PANELS)) wCurrent[0] = WInfo; else wCurrent.insert(0, WInfo); } else { wCurrent.push_back(WInfo); } } // Clear closed windows for (INT_PTR i = 0; i < pwList->size();) { const WindowInfo& L = (*pwList)[i]; INT_PTR iFound = WExists(L, wCurrent); if (iFound < 0) pwList->erase(i); else i++; } // Add new windows for (INT_PTR i = 0; i < wCurrent.size(); i++) { const WindowInfo& C = wCurrent[i]; INT_PTR iFound = WExists(C, *pwList); if (iFound >= 0) { (*pwList)[iFound] = C; } else { if (C.Type == WTYPE_PANELS) { if ((pwList->size() > 0) && ((*pwList)[0].Type == WTYPE_PANELS)) (*pwList)[0] = C; else pwList->insert(0, C); } else { pwList->push_back(C); } } } // And check the count windowCount = pwList->size(); // Проверить, есть ли активный редактор/вьювер/панель if (bActiveInfo && (WActive.Type == WTYPE_EDITOR || WActive.Type == WTYPE_VIEWER || WActive.Type == WTYPE_PANELS)) { if (!(WActive.Flags & WIF_MODAL)) WLastActive = WActive; } else { int nTabs = 0, nModalTabs = 0; bool bFound = false; WindowInfo WModal, WFirst; // Поскольку в табах диалоги не отображаются - надо подменить "активное" окно // т.е. предпочитаем тот таб, который был активен ранее for (int i = 0; i < windowCount; i++) { WInfo = (*pwList)[i]; _ASSERTE(WInfo.Type == WTYPE_EDITOR || WInfo.Type == WTYPE_VIEWER || WInfo.Type == WTYPE_PANELS); if (!nTabs) WFirst = WInfo; nTabs++; if (WInfo.Flags & WIF_MODAL) { nModalTabs++; WModal = WInfo; } if (WLastActive.StructSize && (WInfo.Type == WLastActive.Type) && (WInfo.Id == WLastActive.Id)) { bActiveInfo = bFound = true; WActive = WInfo; } } if (!bFound) { if (nModalTabs) { bActiveInfo = true; WActive = WModal; } else if (nTabs) { bActiveInfo = true; WActive = WFirst; } } } for (int i = 0; i < windowCount; i++) { WInfo = (*pwList)[i]; if (WInfo.Type == WTYPE_EDITOR || WInfo.Type == WTYPE_VIEWER || WInfo.Type == WTYPE_PANELS) { WInfo.Name = szWNameBuffer; WInfo.NameSize = CONEMUTABMAX; InfoW2800->AdvControl(&guid_ConEmu, ACTL_GETWINDOWINFO, 0, &WInfo); WARNING("Для получения имени нужно пользовать ECTL_GETFILENAME"); //// Проверить, чего там... //_ASSERTE((WInfo.Flags & WIF_MODAL) == 0); if (WInfo.Type == WTYPE_EDITOR || WInfo.Type == WTYPE_VIEWER || WInfo.Type == WTYPE_PANELS) { if ((WInfo.Flags & WIF_CURRENT)) { lbActiveFound = true; } else if (bActiveInfo && (WInfo.Type == WActive.Type) && (WInfo.Id == WActive.Id)) { WInfo.Flags |= WIF_CURRENT; lbActiveFound = true; } TODO("Определение ИД редактора/вьювера"); lbCh |= AddTab(tabCount, WInfo.Pos, false/*losingFocus*/, false/*editorSave*/, WInfo.Type, WInfo.Name, /*editorSave ? ei.FileName :*/ NULL, (WInfo.Flags & WIF_CURRENT), (WInfo.Flags & WIF_MODIFIED), (WInfo.Flags & WIF_MODAL), WInfo.Id); } } } bool bHasPanels = this->CheckPanelExist(); if (!lbActiveFound) { // Порядок инициализации поменялся, при запуске "far /e ..." редактора сначала вообще "нет". _ASSERTE((!bHasPanels && windowCount==0 && bActiveInfo && WActive.Type == WTYPE_DESKTOP) && "Active window must be detected already!"); if (tabCount == 0) { // Добавить в табы хоть что-то lbCh |= AddTab(tabCount, 0, false/*losingFocus*/, false/*editorSave*/, WTYPE_PANELS, L"far", /*editorSave ? ei.FileName :*/ NULL, 1/*Current*/, 0/*Modified*/, 1/*Modal*/, 0); } if (tabCount > 0) { gpTabs->Tabs.CurrentType = gnCurrentWindowType = gpTabs->Tabs.tabs[tabCount-1].Type; } else { _ASSERTE(tabCount>0); } } // 101224 - сразу запомнить количество! gpTabs->Tabs.nTabCount = tabCount; return lbCh; }