void ConEmuAbout::OnInfo_ThrowTrapException(bool bMainThread) { if (bMainThread) { if (MsgBox(L"Are you sure?\nApplication will terminates after that!\nThrow exception in ConEmu's main thread?", MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2)==IDYES) { //#ifdef _DEBUG //MyAssertTrap(); //#else //DebugBreak(); //#endif // -- trigger division by 0 RaiseTestException(); } } else { if (MsgBox(L"Are you sure?\nApplication will terminates after that!\nThrow exception in ConEmu's monitor thread?", MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2)==IDYES) { CVConGuard VCon; if ((gpConEmu->GetActiveVCon(&VCon) >= 0) && VCon->RCon()) VCon->RCon()->MonitorAssertTrap(); } } }
void CConEmuCtrl::ChooseTabFromMenu(BOOL abFirstTabOnly, POINT pt, DWORD Align /*= TPM_CENTERALIGN|TPM_VCENTERALIGN*/) { HMENU hPopup = gpConEmu->mp_Menu->CreateVConListPopupMenu(NULL, abFirstTabOnly); if (!Align) Align = TPM_LEFTALIGN|TPM_TOPALIGN; int nTab = gpConEmu->mp_Menu->trackPopupMenu(tmp_TabsList, hPopup, Align|TPM_RETURNCMD, pt.x, pt.y, ghWnd); if (nTab >= IDM_VCON_FIRST && nTab <= IDM_VCON_LAST) { int nNewV = ((int)HIWORD(nTab))-1; int nNewR = ((int)LOWORD(nTab))-1; CVConGuard VCon; if (CVConGroup::GetVCon(nNewV, &VCon)) { CRealConsole* pRCon = VCon->RCon(); if (pRCon) { CTab tab(__FILE__,__LINE__); if (pRCon->GetTab(nNewR, tab)) pRCon->ActivateFarWindow(tab->Info.nFarWindowID); } if (!VCon->isActive(false)) gpConEmu->Activate(VCon.VCon()); } } DestroyMenu(hPopup); }
int CTabBarClass::CountActiveTabs(int nMax /*= 0*/) { int nTabs = 0; bool bHideInactiveConsoleTabs = gpSet->bHideInactiveConsoleTabs; for (int V = 0; V < MAX_CONSOLE_COUNT; V++) { CVConGuard guard; if (!CVConGroup::GetVCon(V, &guard)) continue; CVirtualConsole* pVCon = guard.VCon(); if (bHideInactiveConsoleTabs) { if (!pVCon->isVisible()) continue; } nTabs += pVCon->RCon()->GetTabCount(TRUE); if ((nMax > 0) && (nTabs >= nMax)) break; } return nTabs; }
void CEFindDlg::FindTextDialog() { if (mh_FindDlg && IsWindow(mh_FindDlg)) { SetForegroundWindow(mh_FindDlg); return; } CVConGuard VCon; CRealConsole* pRCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon() : NULL; // Создаем диалог поиска только для консольных приложений if (!pRCon || (pRCon->GuiWnd() && !pRCon->isBufferHeight()) || !pRCon->GetView()) { //DisplayLastError(L"No RealConsole, nothing to find"); return; } gpConEmu->SkipOneAppsRelease(true); mh_FindDlg = CreateDialogParam((HINSTANCE)GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_FIND), ghWnd, findTextProc, 0/*Param*/); if (!mh_FindDlg) { DisplayLastError(L"Can't create Find text dialog", GetLastError()); } }
bool CTabBarClass::GetVConFromTab(int nTabIdx, CVConGuard* rpVCon, DWORD* rpWndIndex) { bool lbRc = false; CTab tab(__FILE__,__LINE__); CVConGuard VCon; DWORD wndIndex = 0; if (m_Tabs.GetTabByIndex(nTabIdx, tab)) { wndIndex = tab->Info.nFarWindowID; if (!gpConEmu->isValid((CVirtualConsole*)tab->Info.pVCon)) { RequestPostUpdate(); } else { VCon = (CVirtualConsole*)tab->Info.pVCon; lbRc = true; } } if (rpVCon) rpVCon->Attach(VCon.VCon()); if (rpWndIndex) *rpWndIndex = lbRc ? wndIndex : 0; return lbRc; }
// This function is called throughout the duration of the panning/inertia gesture bool CGestures::ProcessMove(HWND hWnd, const LONG ldx, const LONG ldy) { bool lbSent = false; if (ldy) { CVConGuard VCon; CRealConsole* pRCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon() : NULL; if (pRCon) { TODO("Если можно будет задавать разный шрифт для разных консолей - заменить gpSet->FontSizeY"); // Соотнести Pan с высотой шрифта int dy = ((ldy < 0) ? -ldy : ldy) / gpSet->FontSizeY; if (dy > 0) { short Delta = ((ldy < 0) ? -120 : 120) * dy; #ifdef _DEBUG wchar_t szDbg[128]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L" ProcessMove(%i,%i), WheelDelta=%i\n", ldx, ldy, (int)Delta); DEBUGSTRPAN(szDbg); #endif POINT pt = _ptBegin; if (hWnd != VCon->GetView()) MapWindowPoints(hWnd, VCon->GetView(), &pt, 1); pRCon->OnMouse(WM_MOUSEWHEEL, MAKELPARAM(0,Delta), pt.x, pt.y, true, true); lbSent = true; // Запомнить обработанную координату } } } return lbSent; }
// Общая для key_WinWidthDec/key_WinWidthInc/key_WinHeightDec/key_WinHeightInc // pRCon may be NULL bool CConEmuCtrl::key_WinSize(BYTE vk) { if (gpConEmu->isFullScreen() || gpConEmu->isZoomed() || gpConEmu->isIconic()) { // ничего не делать } else { CVConGuard VCon; CVirtualConsole* pVCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon.VCon() : NULL; RECT rcWindow = {}; if (GetWindowRect(ghWnd, &rcWindow)) { RECT rcMon = gpConEmu->CalcRect(CER_MONITOR, rcWindow, CER_MONITOR, pVCon); int nX = gpSetCls->FontWidth(); int nY = gpSetCls->FontHeight(); if (vk == VK_LEFT) { rcWindow.right = rcWindow.right - nX; } else if (vk == VK_RIGHT) { if ((rcWindow.right + nX) < rcMon.right) rcWindow.right = rcWindow.right + nX; } else if (vk == VK_UP) { rcWindow.bottom = rcWindow.bottom - nY; } else if (vk == VK_DOWN) { if ((rcWindow.bottom + nY) < rcMon.bottom) rcWindow.bottom = rcWindow.bottom + nY; } if (rcWindow.right > rcWindow.left && rcWindow.bottom > rcWindow.top) { MoveWindowRect(ghWnd, rcWindow, TRUE); } } // //CRealConsole* pRCon = pVCon ? pVCon->RCon() : NULL; //if (pRCon) //{ // // //if (!pRCon->GuiWnd()) // //{ // // // //} // //else // //{ // // // Ресайз в ГУИ режиме // //} //} } return true; }
void CConEmuInside::InsideUpdateDir() { CVConGuard VCon; if (mh_InsideParentPath && IsWindow(mh_InsideParentPath) && (gpConEmu->GetActiveVCon(&VCon) >= 0) && VCon->RCon()) { wchar_t szCurText[512] = {}; DWORD_PTR lRc = 0; if (SendMessageTimeout(mh_InsideParentPath, WM_GETTEXT, countof(szCurText), (LPARAM)szCurText, SMTO_ABORTIFHUNG|SMTO_NORMAL, 300, &lRc)) { if (gnOsVer < 0x600) { // Если в заголовке нет полного пути if (wcschr(szCurText, L'\\') == NULL) { // Сразу выходим return; } } LPCWSTR pszPath = NULL; // Если тут уже путь - то префикс не отрезать if ((szCurText[0] == L'\\' && szCurText[1] == L'\\' && szCurText[2]) // сетевой путь || (szCurText[0] && szCurText[1] == L':' && szCurText[2] == L'\\' /*&& szCurText[3]*/)) // Путь через букву диска { pszPath = szCurText; } else { // Иначе - отрезать префикс. На английской винде это "Address: D:\dir1\dir2" pszPath = wcschr(szCurText, L':'); if (pszPath) pszPath = SkipNonPrintable(pszPath+1); } // Если успешно - сравниваем с ms_InsideParentPath if (pszPath && *pszPath && (lstrcmpi(ms_InsideParentPath, pszPath) != 0)) { int nLen = lstrlen(pszPath); if (nLen >= (int)countof(ms_InsideParentPath)) { _ASSERTE((nLen<countof(ms_InsideParentPath)) && "Too long path?"); } else //if (VCon->RCon()) { // Запомнить для сравнения lstrcpyn(ms_InsideParentPath, pszPath, countof(ms_InsideParentPath)); // Подготовить команду для выполнения в Shell VCon->RCon()->PostPromptCmd(true, pszPath); } } } } }
void CConEmuCtrl::DoEndFindText(CRealConsole* pRCon /*= NULL*/) { CVConGuard VCon; if (!pRCon) { pRCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon() : NULL; if (!pRCon) return; } pRCon->DoEndFindText(); }
bool CConEmuCtrl::key_ChildSystemMenu(const ConEmuChord& VkState, bool TestOnly, const ConEmuHotKey* hk, CRealConsole* pRCon) { if (TestOnly) return true; // Должно обрабатываться через WM_HOTKEY CVConGuard VCon; if (gpConEmu->GetActiveVCon(&VCon) >= 0) { VCon->RCon()->ChildSystemMenu(); } return true; }
bool CTabBarClass::CanActivateTab(int nTabIdx) { CVConGuard VCon; DWORD wndIndex = 0; if (!GetVConFromTab(nTabIdx, &VCon, &wndIndex)) return false; if (!VCon->RCon()->CanActivateFarWindow(wndIndex)) return false; return true; }
void CGestures::SendRClick(HWND hWnd, const LONG ldx, const LONG ldy) { CVConGuard VCon; CRealConsole* pRCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon() : NULL; if (pRCon) { POINT pt = {ldx, ldy}; if (hWnd != VCon->GetView()) MapWindowPoints(hWnd, VCon->GetView(), &pt, 1); pRCon->OnMouse(WM_RBUTTONDOWN, MK_RBUTTON, pt.x, pt.y); pRCon->OnMouse(WM_RBUTTONUP, 0, pt.x, pt.y); } }
void CSetPgInfo::OnPostLocalize(HWND hDlg) { CVirtualConsole* pVCon = NULL; CVConGuard VCon; if (CVConGroup::GetActiveVCon(&VCon) >= 0) pVCon = VCon.VCon(); // Performance gpSetCls->Performance(gbPerformance, TRUE); if (pVCon) { FillConsoleMode(hDlg, pVCon->RCon()); } }
size_t CConEmuCtrl::GetOpenedPanels(wchar_t*& pszDirs, int& iCount, int& iCurrent) { CmdArg szActiveDir, szPassive; CVConGuard VCon; MArray<wchar_t*> Dirs; size_t cchAllLen = 1; iCount = iCurrent = 0; for (int V = 0; CVConGroup::GetVCon(V, &VCon, true); V++) { VCon->RCon()->GetPanelDirs(szActiveDir, szPassive); if (VCon->isActive(false)) iCurrent = iCount; LPCWSTR psz[] = {szActiveDir.ms_Arg, szPassive.ms_Arg}; for (int i = 0; i <= 1; i++) { if (psz[i] && psz[i][0]) { int iLen = lstrlen(psz[i]); cchAllLen += (iLen+1); Dirs.push_back(lstrdup(psz[i])); iCount++; } } } _ASSERTE(pszDirs == NULL); pszDirs = (wchar_t*)malloc(cchAllLen*sizeof(*pszDirs)); if (!pszDirs) return 0; wchar_t* psz = pszDirs; for (int i = 0; i < Dirs.size(); i++) { wchar_t* p = Dirs[i]; _wcscpy_c(psz, cchAllLen, p); psz += lstrlen(psz)+1; free(p); } return cchAllLen; }
INT_PTR CSetDlgColors::ColorCtlStatic(HWND hWnd2, WORD c, HWND hItem) { if (GetDlgItem(hWnd2, c) == hItem) { if (mh_CtlColorBrush) DeleteObject(mh_CtlColorBrush); COLORREF cr = 0; if (c >= c32 && c <= c34) { ThumbColor *ptc = NULL; if (c == c32) ptc = &gpSet->ThSet.crBackground; else if (c == c33) ptc = &gpSet->ThSet.crPreviewFrame; else ptc = &gpSet->ThSet.crSelectFrame; // if (ptc->UseIndex) { if (ptc->ColorIdx >= 0 && ptc->ColorIdx <= 15) { cr = gpSet->Colors[ptc->ColorIdx]; } else { CVConGuard VCon; const CEFAR_INFO_MAPPING *pfi = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon()->GetFarInfo() : NULL; if (pfi && pfi->cbSize>=sizeof(CEFAR_INFO_MAPPING)) { cr = gpSet->Colors[(pfi->nFarColors[col_PanelText] & 0xF0)>>4]; } else { cr = gpSet->Colors[1]; } } }
void CEFindDlg::FindTextDialog() { if (mh_FindDlg && IsWindow(mh_FindDlg)) { SetForegroundWindow(mh_FindDlg); return; } CVConGuard VCon; CRealConsole* pRCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon() : NULL; // Создаем диалог поиска только для консольных приложений if (!pRCon || (pRCon->GuiWnd() && !pRCon->isBufferHeight()) || !pRCon->GetView()) { //DisplayLastError(L"No RealConsole, nothing to find"); return; } if (gpConEmu->mp_TabBar && gpConEmu->mp_TabBar->ActivateSearchPane(true)) { // Контрол поиска встроен и показан в панели инструментов return; } gpConEmu->SkipOneAppsRelease(true); if (!mp_DpiAware) mp_DpiAware = new CDpiForDialog(); // (CreateDialog) mp_Dlg = CDynDialog::ShowDialog(IDD_FIND, ghWnd, findTextProc, 0/*Param*/); mh_FindDlg = mp_Dlg ? mp_Dlg->mh_Dlg : NULL; if (!mh_FindDlg) { DisplayLastError(L"Can't create Find text dialog", GetLastError()); } }
LRESULT CSetPgInfo::OnInitDialog(HWND hDlg, bool abInitial) { CVirtualConsole* pVCon = NULL; CVConGuard VCon; if (CVConGroup::GetActiveVCon(&VCon) >= 0) pVCon = VCon.VCon(); SetDlgItemText(hDlg, tCurCmdLine, GetCommandLine()); gpConEmu->UpdateProcessDisplay(TRUE); gpConEmu->UpdateSizes(); if (pVCon) { ConsoleInfoArg cursorInfo = {}; pVCon->RCon()->GetConsoleInfo(&cursorInfo); FillCursorInfo(hDlg, &cursorInfo); } FillFontInfo(hDlg); return 0; }
void CTabBarClass::Update(BOOL abPosted/*=FALSE*/) { #ifdef _DEBUG if (this != gpConEmu->mp_TabBar) { _ASSERTE(this == gpConEmu->mp_TabBar); } #endif MCHKHEAP /*if (!_active) { return; }*/ // Теперь - ВСЕГДА! т.к. сами управляем мультиконсолью if (mb_DisableRedraw) { _ASSERTE(FALSE && "mb_DisableRedraw?"); // Надо? return; } if (!isMainThread()) { RequestPostUpdate(); return; } gpConEmu->mp_Status->UpdateStatusBar(); mb_PostUpdateCalled = FALSE; #ifdef _DEBUG _ASSERTE(mn_InUpdate >= 0); if (mn_InUpdate > 0) { _ASSERTE(mn_InUpdate == 0); } #endif mn_InUpdate ++; MCHKHEAP int V, I, tabIdx = 0, nCurTab = -1; BOOL bShowFarWindows = gpSet->bShowFarWindows; // Выполняться должно только в основной нити, так что CriticalSection не нужна #ifdef _DEBUG if (this != gpConEmu->mp_TabBar) { _ASSERTE(this == gpConEmu->mp_TabBar); } #endif TODO("Обработка gpSet->bHideInactiveConsoleTabs для новых табов"); MCHKHEAP // Check if we need to AutoSHOW or AutoHIDE tab bar if (!IsTabsActive() && gpSet->isTabs) { int nTabs = CountActiveTabs(2); if (nTabs > 1) { Activate(); } } else if (IsTabsActive() && gpSet->isTabs==2) { int nTabs = CountActiveTabs(2); if (nTabs <= 1) { Deactivate(); } } // Validation? #ifdef _DEBUG if (this != gpConEmu->mp_TabBar) { _ASSERTE(this == gpConEmu->mp_TabBar); } #endif MCHKHEAP HANDLE hUpdate = m_Tabs.UpdateBegin(); _ASSERTE(hUpdate!=NULL); bool bStackChanged = false; /* ********************* */ /* Go */ /* ********************* */ { MMap<CVConGroup*,CVirtualConsole*> Groups; Groups.Init(MAX_CONSOLE_COUNT, true); for (V = 0; V < MAX_CONSOLE_COUNT; V++) { //if (!(pVCon = gpConEmu->GetVCon(V))) continue; CVConGuard guard; if (!CVConGroup::GetVCon(V, &guard)) continue; CVirtualConsole* pVCon = guard.VCon(); BOOL lbActive = pVCon->isActive(false); if (gpSet->bHideInactiveConsoleTabs && !lbActive) continue; if (gpSet->isOneTabPerGroup) { CVConGroup *pGr; CVConGuard VGrActive; if (CVConGroup::isGroup(pVCon, &pGr, &VGrActive)) { CVirtualConsole* pGrVCon; if (Groups.Get(pGr, &pGrVCon)) continue; // эта группа уже есть pGrVCon = VGrActive.VCon(); Groups.Set(pGr, pGrVCon); // И показывать таб нужно от "активной" консоли, а не от первой в группе if (pVCon != pGrVCon) { guard = pGrVCon; pVCon = pGrVCon; } if (!lbActive) { lbActive = pVCon->isActive(true); } // Показывать редакторы из всех групп? if (gpSet->bShowFarWindows) { MArray<CVConGuard*> Panes; int nPanes = pGr->GetGroupPanes(&Panes); // Только если в группе более одного таба - тогда нужно дополниетльная логика населения... if (nPanes > 1) { // Первым табом - показать текущую панель, либо МОДАЛЬНЫЙ редактор/вьювер // Редакторы из "far /e ..." здесь НЕ добавлять! if (!pVCon->RCon()->isFarPanelAllowed() || !UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged, pVCon, uat_PanelsOrModalsOnly)) { // Если есть - добавить ОДНУ панель, чтобы табы сплита не прыгали туда-сюда for (int K = 0; K < nPanes; K++) { if (Panes[K]->VCon()->RCon()->isFarPanelAllowed()) { if (UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged, Panes[K]->VCon(), uat_PanelsOnly) > 0) break; } } } // Потом - все оставшиеся редакторы/вьюверы (в том числе и "far /e ...") for (int K = 0; K < nPanes; K++) { UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged, Panes[K]->VCon(), uat_NonModals|uat_NonPanels); } // Release CVConGroup::FreePanesArray(Panes); // Already processed, next VCon continue; } } } } UpdateAddTab(hUpdate, tabIdx, nCurTab, bStackChanged, pVCon, uat_AnyTab); } Groups.Release(); } MCHKHEAP // Must be at least one tab ("ConEmu -Detached" for example) if (tabIdx == 0) { m_Tabs.UpdateAppend(hUpdate, mp_DummyTab, FALSE); // Физически (WinAPI) добавляет закладку, или меняет (при необходимости) заголовок существующей mp_Rebar->AddTabInt(gpConEmu->GetDefaultTabLabel(), tabIdx, gpConEmu->mb_IsUacAdmin, -1); nCurTab = tabIdx; tabIdx++; } m_Tabs.UpdateEnd(hUpdate, 0); // Проверим стек последних выбранных if (CheckStack()) bStackChanged = true; #ifdef PRINT_RECENT_STACK PrintRecentStack(); #endif #ifdef _DEBUG static int nPrevVisible, nPrevStacked; { wchar_t szDbg[100]; int nNewVisible = m_Tabs.GetCount(); int nNewStacked = m_TabStack.size(); _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"*** Tab list updated. Visible:%u, Stacked:%u, StackChanged:%s\n", nNewVisible, nNewStacked, bStackChanged ? L"Yes" : L"No"); DEBUGSTRCOUNT(szDbg); nPrevVisible = nNewVisible; nPrevStacked = nNewStacked; } #endif // удалить лишние закладки (визуально) int nCurCount = GetItemCount(); #ifdef _DEBUG wchar_t szDbg[128]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"CTabBarClass::Update. ItemCount=%i, PrevItemCount=%i\n", tabIdx, nCurCount); DEBUGSTRTABS(szDbg); #endif if (mp_Rebar->IsTabbarCreated()) { for (I = tabIdx; I < nCurCount; I++) { #ifdef _DEBUG _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L" Deleting tab=%i\n", I+1); DEBUGSTRTABS(szDbg); #endif DeleteItem(tabIdx); } } MCHKHEAP if (mb_InKeySwitching) { if (mn_CurSelTab >= nCurCount) // Если выбранный таб вылез за границы mb_InKeySwitching = false; } if (!mb_InKeySwitching && nCurTab != -1) { SelectTab(nCurTab); } UpdateToolConsoles(); //if (gpSet->isTabsInCaption) //{ // SendMessage(ghWnd, WM_NCPAINT, 0, 0); //} mn_InUpdate --; if (mb_PostUpdateRequested) { mb_PostUpdateCalled = FALSE; mb_PostUpdateRequested = FALSE; RequestPostUpdate(); } MCHKHEAP return; // Just for clearness }
size_t CConEmuCtrl::GetOpenedTabs(CESERVER_REQ_GETALLTABS::TabInfo*& pTabs) { _ASSERTE(pTabs==NULL); int nConCount = gpConEmu->GetConCount(); int nActiveCon = gpConEmu->ActiveConNum(); size_t cchMax = nConCount*16; size_t cchCount = 0; CVConGuard VCon; pTabs = (CESERVER_REQ_GETALLTABS::TabInfo*)calloc(cchMax, sizeof(*pTabs)); for (int V = 0; CVConGroup::GetVCon(V, &VCon, true); V++) { if (!pTabs) { _ASSERTE(pTabs!=NULL); break; } CRealConsole* pRCon = VCon->RCon(); if (!pRCon) continue; CTab tab(__FILE__,__LINE__); wchar_t szMark[6]; for (int t = 0; pRCon->GetTab(t, tab); t++) { int T = t; //tab->Info.nFarWindowID; -- В Far3 номер из nFarWindowID стал бесполезным для пользователя if (cchCount >= cchMax) { pTabs = (CESERVER_REQ_GETALLTABS::TabInfo*)realloc(pTabs, (cchMax+32)*sizeof(*pTabs)); if (!pTabs) { _ASSERTE(pTabs!=NULL); break; } cchMax += 32; _ASSERTE(cchCount<cchMax); } pTabs[cchCount].ActiveConsole = (V == nActiveCon); pTabs[cchCount].ActiveTab = ((tab->Flags() & fwt_CurrentFarWnd) == fwt_CurrentFarWnd); pTabs[cchCount].Disabled = ((tab->Flags() & fwt_Disabled) == fwt_Disabled); pTabs[cchCount].ConsoleIdx = V; pTabs[cchCount].TabNo = T; pTabs[cchCount].FarWindow = tab->Info.nFarWindowID; // Text //wcscpy_c(szMark, tab.Modified ? L" * " : L" "); switch (tab->Type()) { case fwt_Editor: wcscpy_c(szMark, (tab->Flags() & fwt_ModifiedFarWnd) ? L" * " : L" E "); break; case fwt_Viewer: wcscpy_c(szMark, L" V "); break; default: wcscpy_c(szMark, L" "); } if ((V == nActiveCon) && (T <= 9)) _wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/&%i]%s", V+1, T, szMark); else _wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/%i]%s", V+1, T, szMark); #ifdef _DEBUG if (pRCon->IsFarLua()) _wsprintf(pTabs[cchCount].Title+lstrlen(pTabs[cchCount].Title), SKIPLEN(30) L"{%i} ", tab->Info.nFarWindowID); #endif int nCurLen = lstrlen(pTabs[cchCount].Title); lstrcpyn(pTabs[cchCount].Title+nCurLen, pRCon->GetTabTitle(tab), countof(pTabs[cchCount].Title)-nCurLen); cchCount++; } } return cchCount; }
LRESULT CConEmuChild::ChildWndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam) { LRESULT result = 0; // Logger MSG msgStr = {hWnd, messg, wParam, lParam}; ConEmuMsgLogger::Log(msgStr, ConEmuMsgLogger::msgCanvas); if (gpSetCls->isAdvLogging >= 4) { gpConEmu->LogMessage(hWnd, messg, wParam, lParam); } CVConGuard guard; CVirtualConsole* pVCon = NULL; if (messg == WM_CREATE || messg == WM_NCCREATE) { LPCREATESTRUCT lp = (LPCREATESTRUCT)lParam; guard = (CVirtualConsole*)lp->lpCreateParams; pVCon = guard.VCon(); if (pVCon) { gVConDcMap.Set(hWnd, pVCon); pVCon->m_TAutoCopy.Init(hWnd, TIMER_AUTOCOPY, TIMER_AUTOCOPY_DELAY); pVCon->m_TScrollShow.Init(hWnd, TIMER_SCROLL_SHOW, TIMER_SCROLL_SHOW_DELAY); pVCon->m_TScrollHide.Init(hWnd, TIMER_SCROLL_HIDE, TIMER_SCROLL_HIDE_DELAY); #ifndef SKIP_HIDE_TIMER pVCon->m_TScrollCheck.Init(hWnd, TIMER_SCROLL_CHECK, TIMER_SCROLL_CHECK_DELAY); #endif } } else if (hWnd != ghDcInDestroing) { if (!gVConDcMap.Get(hWnd, &pVCon) || !guard.Attach(pVCon)) pVCon = NULL; } if (messg == WM_SYSCHAR) { _ASSERTE(FALSE); // по идее, фокуса тут быть не должно // Чтобы не пищало result = TRUE; goto wrap; } if (!pVCon) { _ASSERTE(pVCon!=NULL || hWnd==ghDcInDestroing); result = DefWindowProc(hWnd, messg, wParam, lParam); goto wrap; } switch (messg) { case WM_SHOWWINDOW: { #ifdef _DEBUG HWND hGui = pVCon->GuiWnd(); if (hGui) { _ASSERTE(((wParam==0) || pVCon->RCon()->isGuiForceConView()) && "Show DC while GuiWnd exists"); } #endif result = DefWindowProc(hWnd, messg, wParam, lParam); break; } case WM_SETFOCUS: // Если в консоли работает "GUI" окно (GUI режим), то фокус нужно отдать туда. { // Фокус должен быть в главном окне! За исключением случая работы в GUI режиме. pVCon->setFocus(); } return 0; case WM_ERASEBKGND: result = 0; break; case WM_PAINT: result = pVCon->OnPaint(); break; case WM_PRINTCLIENT: if (wParam && (lParam & PRF_CLIENT)) { pVCon->PrintClient((HDC)wParam, false, NULL); } break; case WM_SIZE: #ifdef _DEBUG { RECT rc; GetClientRect(hWnd, &rc); short cx = LOWORD(lParam); rc.left = rc.left; } #endif result = pVCon->OnSize(wParam, lParam); break; case WM_MOVE: result = pVCon->OnMove(wParam, lParam); break; case WM_CREATE: break; case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_MOUSEWHEEL: case WM_ACTIVATE: case WM_ACTIVATEAPP: //case WM_MOUSEACTIVATE: case WM_KILLFOCUS: //case WM_SETFOCUS: case WM_MOUSEMOVE: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_XBUTTONUP: case WM_XBUTTONDBLCLK: case WM_VSCROLL: // Вся обработка в родителе { switch (messg) { case WM_VSCROLL: switch (LOWORD(wParam)) { case SB_THUMBTRACK: case SB_THUMBPOSITION: pVCon->mb_VTracking = TRUE; break; case SB_ENDSCROLL: pVCon->mb_VTracking = FALSE; break; } pVCon->RCon()->OnSetScrollPos(wParam); break; case WM_LBUTTONUP: pVCon->mb_VTracking = FALSE; break; } TODO("Обработка ghWndWork"); HWND hParent = ghWnd; static bool bInFixStyle = false; if (!bInFixStyle) { hParent = GetParent(hWnd); if (hParent != ghWnd) { // Неправомерные действия плагинов фара? bInFixStyle = true; _ASSERTE(GetParent(hWnd)==ghWnd); SetParent(hWnd, ghWnd); bInFixStyle = false; hParent = ghWnd; } DWORD curStyle = GetWindowLong(hWnd, GWL_STYLE); if ((curStyle & CRITICAL_DCWND_STYLES) != (pVCon->mn_WndDCStyle & CRITICAL_DCWND_STYLES)) { // DC window styles was changed externally! bInFixStyle = true; _ASSERTEX(((curStyle & CRITICAL_DCWND_STYLES) != (pVCon->mn_WndDCStyle & CRITICAL_DCWND_STYLES))); SetWindowLongPtr(hWnd, GWL_STYLE, (LONG_PTR)(DWORD_PTR)pVCon->mn_WndDCStyle); bInFixStyle = false; } } if (messg >= WM_MOUSEFIRST && messg <= WM_MOUSELAST) { POINT pt = {LOWORD(lParam),HIWORD(lParam)}; MapWindowPoints(hWnd, hParent, &pt, 1); lParam = MAKELONG(pt.x,pt.y); } result = gpConEmu->WndProc(hParent, messg, wParam, lParam); } break; case WM_IME_NOTIFY: break; case WM_INPUTLANGCHANGE: case WM_INPUTLANGCHANGEREQUEST: { #ifdef _DEBUG if (IsDebuggerPresent()) { WCHAR szMsg[128]; _wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"InChild %s(CP:%i, HKL:0x%08X)\n", (messg == WM_INPUTLANGCHANGE) ? L"WM_INPUTLANGCHANGE" : L"WM_INPUTLANGCHANGEREQUEST", (DWORD)wParam, (DWORD)lParam); DEBUGSTRLANG(szMsg); } #endif result = DefWindowProc(hWnd, messg, wParam, lParam); } break; #ifdef _DEBUG case WM_WINDOWPOSCHANGING: { WINDOWPOS* pwp = (WINDOWPOS*)lParam; result = DefWindowProc(hWnd, messg, wParam, lParam); } return result; case WM_WINDOWPOSCHANGED: { WINDOWPOS* pwp = (WINDOWPOS*)lParam; result = DefWindowProc(hWnd, messg, wParam, lParam); } break; #endif case WM_SETCURSOR: { gpConEmu->WndProc(hWnd, messg, wParam, lParam); //if (!result) // result = DefWindowProc(hWnd, messg, wParam, lParam); } // If an application processes this message, it should return TRUE to halt further processing or FALSE to continue. break; case WM_SYSCOMMAND: // -- лишние ограничения, похоже result = DefWindowProc(hWnd, messg, wParam, lParam); //if (wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP/*0xF180*/) //{ // // Изменение размеров/максимизация/и т.п. окна консоли - запрещена // _ASSERTE(!(wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP)); //} //else //{ // // По идее, сюда ничего приходить больше не должно // _ASSERTE(FALSE); //} break; case WM_TIMER: { switch(wParam) { #ifndef SKIP_HIDE_TIMER // Не будем прятать по таймеру - только по движению мышки case TIMER_SCROLL_CHECK: if (pVCon->mb_Scroll2Visible) { if (!pVCon->CheckMouseOverScroll()) { pVCon->HideScroll(FALSE/*abImmediate*/); } } break; #endif case TIMER_SCROLL_SHOW: if (pVCon->CheckMouseOverScroll() || pVCon->CheckScrollAutoPopup()) pVCon->ShowScroll(TRUE/*abImmediate*/); else pVCon->mb_Scroll2Visible = FALSE; if (pVCon->m_TScrollShow.IsStarted()) pVCon->m_TScrollShow.Stop(); break; case TIMER_SCROLL_HIDE: if (!pVCon->CheckMouseOverScroll()) pVCon->HideScroll(TRUE/*abImmediate*/); else pVCon->mb_Scroll2Visible = TRUE; if (pVCon->m_TScrollHide.IsStarted()) pVCon->m_TScrollHide.Stop(); break; case TIMER_AUTOCOPY: pVCon->SetAutoCopyTimer(false); if (!isPressed(VK_LBUTTON)) { pVCon->RCon()->AutoCopyTimer(); } break; } break; } // case WM_TIMER: case WM_GESTURENOTIFY: case WM_GESTURE: { gpConEmu->ProcessGestureMessage(hWnd, messg, wParam, lParam, result); break; } // case WM_GESTURE, WM_GESTURENOTIFY default: // Сообщение приходит из ConEmuPlugin if (messg == pVCon->mn_MsgTabChanged) { if (gpSet->isTabs) { //изменились табы, их нужно перечитать #ifdef MSGLOGGER WCHAR szDbg[128]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"Tabs:Notified(%i)\n", (DWORD)wParam); DEBUGSTRTABS(szDbg); #endif TODO("здесь хорошо бы вместо OnTimer реально обновить mn_TopProcessID") // иначе во время запуска PID фара еще может быть не известен... //gpConEmu->OnTimer(0,0); не получилось. индекс конмана не менялся, из-за этого индекс активного фара так и остался 0 WARNING("gpConEmu->mp_TabBar->Retrieve() ничего уже не делает вообще"); _ASSERTE(FALSE); gpConEmu->mp_TabBar->Retrieve(); } } else if (messg == pVCon->mn_MsgPostFullPaint) { pVCon->Redraw(); } else if (messg == pVCon->mn_MsgSavePaneSnapshoot) { pVCon->SavePaneSnapshoot(); } else if (messg == pVCon->mn_MsgDetachPosted) { pVCon->RCon()->Detach(true, (lParam == 1)); } else if (messg == gn_MsgVConTerminated) { CVirtualConsole* pVCon = (CVirtualConsole*)lParam; #ifdef _DEBUG int i = -100; wchar_t szDbg[200]; { lstrcpy(szDbg, L"gn_MsgVConTerminated"); i = CVConGroup::GetVConIndex(pVCon); if (i >= 1) { ConEmuTab tab = {0}; pVCon->RCon()->GetTab(0, &tab); tab.Name[128] = 0; // чтобы не вылезло из szDbg wsprintf(szDbg+_tcslen(szDbg), L": #%i: %s", i, tab.Name); } lstrcat(szDbg, L"\n"); DEBUGSTRCONS(szDbg); } #endif // Do not "Guard" lParam here, validation will be made in ProcessVConClosed CConEmuChild::ProcessVConClosed(pVCon, TRUE); return 0; } #ifdef _DEBUG else if (messg == pVCon->mn_MsgCreateDbgDlg) { pVCon->CreateDbgDlg(); } #endif else if (messg) { result = DefWindowProc(hWnd, messg, wParam, lParam); } } wrap: return result; }
//// Эта функция пайп не закрывает! //void CGuiServer::GuiServerThreadCommand(HANDLE hPipe) BOOL CGuiServer::GuiServerCommand(LPVOID pInst, CESERVER_REQ* pIn, CESERVER_REQ* &ppReply, DWORD &pcbReplySize, DWORD &pcbMaxReplySize, LPARAM lParam) { BOOL lbRc = FALSE; CGuiServer* pGSrv = (CGuiServer*)lParam; if (!pGSrv) { _ASSERTE(((CGuiServer*)lParam)!=NULL); pGSrv = &gpConEmu->m_GuiServer; } if (pIn->hdr.bAsync) pGSrv->mp_GuiServer->BreakConnection(pInst); gpSetCls->debugLogCommand(pIn, TRUE, timeGetTime(), 0, pGSrv ? pGSrv->ms_ServerPipe : NULL); #ifdef _DEBUG UINT nDataSize = pIn->hdr.cbSize - sizeof(CESERVER_REQ_HDR); #endif // Все данные из пайпа получены, обрабатываем команду и возвращаем (если нужно) результат #ifdef ALLOW_WINE_MSG if (gbIsWine) { wchar_t szMsg[128]; msprintf(szMsg, countof(szMsg), L"CGuiServer::GuiServerCommand.\nGUI TID=%u\nSrcPID=%u, SrcTID=%u, Cmd=%u", GetCurrentThreadId(), pIn->hdr.nSrcPID, pIn->hdr.nSrcThreadId, pIn->hdr.nCmd); MessageBox(szMsg, MB_ICONINFORMATION); } #endif switch (pIn->hdr.nCmd) { case CECMD_NEWCMD: { // Приходит из другой копии ConEmu.exe, когда она запущена с ключом /single, /showhide, /showhideTSA DEBUGSTR(L"GUI recieved CECMD_NEWCMD\n"); if (gpSetCls->isAdvLogging) { size_t cchAll = 120 + _tcslen(pIn->NewCmd.szConEmu) + _tcslen(pIn->NewCmd.szCurDir) + _tcslen(pIn->NewCmd.szCommand); wchar_t* pszInfo = (wchar_t*)malloc(cchAll*sizeof(*pszInfo)); if (pszInfo) { _wsprintf(pszInfo, SKIPLEN(cchAll) L"CECMD_NEWCMD: Wnd=x%08X, Act=%u, ConEmu=%s, Dir=%s, Cmd=%s", (DWORD)(DWORD_PTR)pIn->NewCmd.hFromConWnd, pIn->NewCmd.ShowHide, pIn->NewCmd.szConEmu, pIn->NewCmd.szCurDir, pIn->NewCmd.szCommand); gpConEmu->LogString(pszInfo); free(pszInfo); } } BOOL bAccepted = FALSE; if (pIn->NewCmd.szConEmu[0]) { bAccepted = (lstrcmpi(gpConEmu->ms_ConEmuExeDir, pIn->NewCmd.szConEmu) == 0); } else { bAccepted = TRUE; } if (bAccepted) { bool bCreateTab = (pIn->NewCmd.ShowHide == sih_None || pIn->NewCmd.ShowHide == sih_StartDetached); gpConEmu->OnMinimizeRestore(bCreateTab ? sih_SetForeground : pIn->NewCmd.ShowHide); // Может быть пусто if (bCreateTab && pIn->NewCmd.szCommand[0]) { RConStartArgs *pArgs = new RConStartArgs; pArgs->bDetached = (pIn->NewCmd.ShowHide == sih_StartDetached); pArgs->pszSpecialCmd = lstrdup(pIn->NewCmd.szCommand); if (pIn->NewCmd.szCurDir[0] == 0) { _ASSERTE(pIn->NewCmd.szCurDir[0] != 0); } else { pArgs->pszStartupDir = lstrdup(pIn->NewCmd.szCurDir); } if (gpSet->isMulti || CVConGroup::isDetached()) { gpConEmu->PostCreateCon(pArgs); } else { // Если хотят в одном окне - только одну консоль gpConEmu->CreateWnd(pArgs); SafeDelete(pArgs); } } else { _ASSERTE(pIn->NewCmd.ShowHide==sih_ShowMinimize || pIn->NewCmd.ShowHide==sih_ShowHideTSA || pIn->NewCmd.ShowHide==sih_Show); } } pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(BYTE); lbRc = ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize); if (lbRc) { ppReply->Data[0] = bAccepted; } break; } //CECMD_NEWCMD case CECMD_TABSCMD: { // 0: спрятать/показать табы, 1: перейти на следующую, 2: перейти на предыдущую, 3: commit switch DEBUGSTR(L"GUI recieved CECMD_TABSCMD\n"); _ASSERTE(nDataSize>=1); DWORD nTabCmd = pIn->Data[0]; gpConEmu->TabCommand((ConEmuTabCommand)nTabCmd); pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(BYTE); if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { lbRc = TRUE; ppReply->Data[0] = TRUE; } break; } // CECMD_TABSCMD #if 0 case CECMD_GETALLTABS: { int nConCount = gpConEmu->GetConCount(); int nActiveCon = gpConEmu->ActiveConNum(); size_t cchMax = nConCount*16; size_t cchCount = 0; CVirtualConsole* pVCon; CESERVER_REQ_GETALLTABS::TabInfo* pTabs = (CESERVER_REQ_GETALLTABS::TabInfo*)calloc(cchMax, sizeof(*pTabs)); for (int V = 0; (pVCon = gpConEmu->GetVCon(V)) != NULL; V++) { if (!pTabs) { _ASSERTE(pTabs!=NULL); break; } CRealConsole* pRCon = pVCon->RCon(); if (!pRCon) continue; ConEmuTab tab; wchar_t szModified[4]; for (int T = 0; pRCon->GetTab(T, &tab); T++) { if (cchCount >= cchMax) { pTabs = (CESERVER_REQ_GETALLTABS::TabInfo*)realloc(pTabs, (cchMax+32)*sizeof(*pTabs)); if (!pTabs) { _ASSERTE(pTabs!=NULL); break; } cchMax += 32; _ASSERTE(cchCount<cchMax); } pTabs[cchCount].ActiveConsole == (V == nActiveCon); pTabs[cchCount].ActiveTab == (tab.Current != 0); pTabs[cchCount].Disabled = ((tab.Type & fwt_Disabled) == fwt_Disabled); pTabs[cchCount].ConsoleIdx = V; pTabs[cchCount].TabIdx = T; // Text wcscpy_c(szModified, tab.Modified ? L" * " : L" "); if (V == nActiveCon) { if (T < 9) _wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/&%i]%s", V+1, T+1, szModified); else if (T == 9) _wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/1&0]%s", V+1, szModified); else _wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/%i]%s", V+1, T+1, szModified); } else { _wsprintf(pTabs[cchCount].Title, SKIPLEN(countof(pTabs[cchCount].Title)) L"[%i/%i]%s", V+1, T+1, szModified); } cchCount++; } } if (cchCount && pTabs) { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_GETALLTABS)+((cchCount-1)*sizeof(CESERVER_REQ_GETALLTABS::TabInfo)); if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { lbRc = TRUE; ppReply->GetAllTabs.Count = cchCount; memmove(ppReply->GetAllTabs.Tabs, pTabs, cchCount*sizeof(*pTabs)); } } SafeFree(pTabs); break; } // CECMD_GETALLTABS case CECMD_ACTIVATETAB: { BOOL lbTabOk = FALSE; CVirtualConsole *pVCon = gpConEmu->GetVCon(pIn->dwData[0]); if (pVCon && pVCon->RCon()) { lbTabOk = pVCon->RCon()->ActivateFarWindow(pIn->dwData[1]); } pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(DWORD); if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { lbRc = TRUE; ppReply->dwData[0] = lbTabOk; } break; } // CECMD_ACTIVATETAB #endif case CECMD_ATTACH2GUI: { // Получен запрос на Attach из сервера pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_STARTSTOPRET); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; //CESERVER_REQ* pOut = ExecuteNewCmd(CECMD_ATTACH2GUI, sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_STARTSTOPRET)); gpConEmu->AttachRequested(pIn->StartStop.hWnd, &(pIn->StartStop), &(ppReply->StartStopRet)); _ASSERTE((ppReply->StartStopRet.nBufferHeight == 0) || ((int)ppReply->StartStopRet.nBufferHeight > pIn->StartStop.sbi.dwSize.X)); lbRc = TRUE; //ExecuteFreeResult(pOut); break; } // CECMD_ATTACH2GUI case CECMD_SRVSTARTSTOP: { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_STARTSTOPRET); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; if (pIn->SrvStartStop.Started == srv_Started) { // Запущен процесс сервера HWND hConWnd = (HWND)pIn->dwData[1]; _ASSERTE(hConWnd && IsWindow(hConWnd)); DWORD nStartTick = timeGetTime(); //LRESULT l = 0; //DWORD_PTR dwRc = 0; //2010-05-21 Поскольку это критично - лучше ждать до упора, хотя может быть DeadLock? //l = SendMessageTimeout(ghWnd, gpConEmu->mn_MsgSrvStarted, (WPARAM)hConWnd, pIn->hdr.nSrcPID, // SMTO_BLOCK, 5000, &dwRc); //111002 - вернуть должен HWND окна отрисовки (дочернее окно ConEmu) MsgSrvStartedArg arg = {hConWnd, pIn->hdr.nSrcPID, pIn->SrvStartStop.dwKeybLayout, nStartTick}; SendMessage(ghWnd, gpConEmu->mn_MsgSrvStarted, 0, (LPARAM)&arg); HWND hWndDC = arg.hWndDc; HWND hWndBack = arg.hWndBack; _ASSERTE(hWndDC!=NULL); #ifdef _DEBUG DWORD dwErr = GetLastError(), nEndTick = timeGetTime(), nDelta = nEndTick - nStartTick; if (hWndDC && nDelta >= EXECUTE_CMD_WARN_TIMEOUT) { if (!IsDebuggerPresent()) { //_ASSERTE(nDelta <= EXECUTE_CMD_WARN_TIMEOUT || (pIn->hdr.nCmd == CECMD_CMDSTARTSTOP && nDelta <= EXECUTE_CMD_WARN_TIMEOUT2)); _ASSERTEX(nDelta <= EXECUTE_CMD_WARN_TIMEOUT); } } #endif //pIn->dwData[0] = (DWORD)ghWnd; //-V205 //pIn->dwData[1] = (DWORD)dwRc; //-V205 //pIn->dwData[0] = (l == 0) ? 0 : 1; ppReply->StartStopRet.hWnd = ghWnd; ppReply->StartStopRet.hWndDc = hWndDC; ppReply->StartStopRet.hWndBack = hWndBack; ppReply->StartStopRet.dwPID = GetCurrentProcessId(); } else if (pIn->SrvStartStop.Started == srv_Stopped) { // Процесс сервера завершается CRealConsole* pRCon = NULL; CVConGuard VCon; for (size_t i = 0;; i++) { if (!CVConGroup::GetVCon(i, &VCon)) break; pRCon = VCon->RCon(); if (pRCon && (pRCon->GetServerPID(true) == pIn->hdr.nSrcPID || pRCon->GetServerPID(false) == pIn->hdr.nSrcPID)) { break; } pRCon = NULL; } if (pRCon) pRCon->OnServerClosing(pIn->hdr.nSrcPID); //pIn->dwData[0] = 1; } else { _ASSERTE((pIn->dwData[0] == 1) || (pIn->dwData[0] == 101)); } lbRc = TRUE; //// Отправляем //fSuccess = WriteFile( // hPipe, // handle to pipe // pOut, // buffer to write from // pOut->hdr.cbSize, // number of bytes to write // &cbWritten, // number of bytes written // NULL); // not overlapped I/O //ExecuteFreeResult(pOut); break; } // CECMD_SRVSTARTSTOP case CECMD_ASSERT: { DWORD nBtn = MessageBox(NULL, pIn->AssertInfo.szDebugInfo, pIn->AssertInfo.szTitle, pIn->AssertInfo.nBtns); pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(DWORD); if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { lbRc = TRUE; ppReply->dwData[0] = nBtn; } //ExecutePrepareCmd(&pIn->hdr, CECMD_ASSERT, sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)); //pIn->dwData[0] = nBtn; //// Отправляем //fSuccess = WriteFile( // hPipe, // handle to pipe // pIn, // buffer to write from // pIn->hdr.cbSize, // number of bytes to write // &cbWritten, // number of bytes written // NULL); // not overlapped I/O break; } // CECMD_ASSERT case CECMD_ATTACHGUIAPP: { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_ATTACHGUIAPP); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; ppReply->AttachGuiApp = pIn->AttachGuiApp; //CESERVER_REQ Out; //ExecutePrepareCmd(&Out.hdr, CECMD_ATTACHGUIAPP, sizeof(CESERVER_REQ_HDR)+sizeof(Out.AttachGuiApp)); //Out.AttachGuiApp = pIn->AttachGuiApp; #ifdef SHOW_GUIATTACH_START if (pIn->AttachGuiApp.hWindow == NULL) { wchar_t szDbg[1024]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"AttachGuiApp requested from:\n%s\nPID=%u", pIn->AttachGuiApp.sAppFileName, pIn->AttachGuiApp.nPID); //MBoxA(szDbg); MessageBox(NULL, szDbg, L"ConEmu", MB_SYSTEMMODAL); } #endif // Уведомить ожидающую вкладку CRealConsole* pRCon = gpConEmu->AttachRequestedGui(pIn->AttachGuiApp.sAppFileName, pIn->AttachGuiApp.nPID); if (pRCon) { CVConGuard VCon(pRCon->VCon()); RECT rcPrev = ppReply->AttachGuiApp.rcWindow; HWND hBack = pRCon->VCon()->GetBack(); //// Размер должен быть независим от возможности наличия прокрутки в VCon //GetWindowRect(hBack, &ppReply->AttachGuiApp.rcWindow); //ppReply->AttachGuiApp.rcWindow.right -= ppReply->AttachGuiApp.rcWindow.left; //ppReply->AttachGuiApp.rcWindow.bottom -= ppReply->AttachGuiApp.rcWindow.top; //ppReply->AttachGuiApp.rcWindow.left = ppReply->AttachGuiApp.rcWindow.top = 0; ////MapWindowPoints(NULL, hBack, (LPPOINT)&ppReply->AttachGuiApp.rcWindow, 2); //pRCon->CorrectGuiChildRect(ppReply->AttachGuiApp.nStyle, ppReply->AttachGuiApp.nStyleEx, ppReply->AttachGuiApp.rcWindow); // Уведомить RCon и ConEmuC, что гуй подцепился // Вызывается два раза. Первый (при запуске exe) ahGuiWnd==NULL, второй - после фактического создания окна pRCon->SetGuiMode(pIn->AttachGuiApp.nFlags, pIn->AttachGuiApp.hAppWindow, pIn->AttachGuiApp.Styles.nStyle, pIn->AttachGuiApp.Styles.nStyleEx, pIn->AttachGuiApp.sAppFileName, pIn->AttachGuiApp.nPID, rcPrev); ppReply->AttachGuiApp.nFlags = agaf_Success | (pRCon->isActive(false) ? 0 : agaf_Inactive); ppReply->AttachGuiApp.nPID = pRCon->GetServerPID(); ppReply->AttachGuiApp.hConEmuDc = pRCon->GetView(); ppReply->AttachGuiApp.hConEmuBack = hBack; ppReply->AttachGuiApp.hConEmuWnd = ghWnd; ppReply->AttachGuiApp.hAppWindow = pIn->AttachGuiApp.hAppWindow; ppReply->AttachGuiApp.hSrvConWnd = pRCon->ConWnd(); ppReply->AttachGuiApp.hkl = (DWORD)(LONG)(LONG_PTR)GetKeyboardLayout(gpConEmu->mn_MainThreadId); ZeroStruct(ppReply->AttachGuiApp.Styles.Shifts); CRealConsole::CorrectGuiChildRect(pIn->AttachGuiApp.Styles.nStyle, pIn->AttachGuiApp.Styles.nStyleEx, ppReply->AttachGuiApp.Styles.Shifts); } else { ppReply->AttachGuiApp.nFlags = agaf_Fail; } lbRc = TRUE; //// Отправляем //fSuccess = WriteFile( // hPipe, // handle to pipe // &Out, // buffer to write from // Out.hdr.cbSize, // number of bytes to write // &cbWritten, // number of bytes written // NULL); // not overlapped I/O break; } // CECMD_ATTACHGUIAPP case CECMD_GUICLIENTSHIFT: { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(GuiStylesAndShifts); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; ppReply->GuiAppShifts = pIn->GuiAppShifts; ZeroStruct(ppReply->GuiAppShifts.Shifts); CRealConsole::CorrectGuiChildRect(pIn->GuiAppShifts.nStyle, pIn->GuiAppShifts.nStyleEx, ppReply->GuiAppShifts.Shifts); lbRc = TRUE; break; } // CECMD_GUICLIENTSHIFT } //// Освободить память //if (pIn && (LPVOID)pIn != (LPVOID)&in) //{ // free(pIn); pIn = NULL; //} wrap: return lbRc; }
LRESULT CConEmuChild::BackWndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam) { LRESULT result = 0; // Logger MSG msgStr = {hWnd, messg, wParam, lParam}; ConEmuMsgLogger::Log(msgStr, ConEmuMsgLogger::msgBack); if (gpSetCls->isAdvLogging >= 4) { gpConEmu->LogMessage(hWnd, messg, wParam, lParam); } CVConGuard guard; CVirtualConsole* pVCon = NULL; if (messg == WM_CREATE || messg == WM_NCCREATE) { LPCREATESTRUCT lp = (LPCREATESTRUCT)lParam; guard = (CVirtualConsole*)lp->lpCreateParams; pVCon = guard.VCon(); if (pVCon) gVConBkMap.Set(hWnd, pVCon); } else if (hWnd != ghBkInDestroing) { if (!gVConBkMap.Get(hWnd, &pVCon) || !guard.Attach(pVCon)) pVCon = NULL; } if (messg == WM_SYSCHAR) { _ASSERTE(FALSE); // по идее, фокуса тут быть не должно // Чтобы не пищало result = TRUE; goto wrap; } if (!pVCon) { _ASSERTE(pVCon!=NULL || hWnd==ghBkInDestroing); result = DefWindowProc(hWnd, messg, wParam, lParam); goto wrap; } switch (messg) { case WM_SHOWWINDOW: if (wParam) { HWND hView = pVCon->GetView(); SetWindowPos(hView, HWND_TOP, 0, 0, 0,0, SWP_NOSIZE|SWP_NOMOVE); SetWindowPos(hWnd, hView, 0, 0, 0,0, SWP_NOSIZE|SWP_NOMOVE); } break; // DefaultProc case WM_SETFOCUS: // Если в консоли работает "GUI" окно (GUI режим), то фокус нужно отдать туда. { // Фокус должен быть в главном окне! За исключением случая работы в GUI режиме. pVCon->setFocus(); } return 0; case WM_ERASEBKGND: result = 0; break; case WM_PAINT: _ASSERTE(hWnd == pVCon->mh_WndBack); pVCon->OnPaintGaps(); break; case WM_KEYDOWN: case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_MOUSEWHEEL: case WM_ACTIVATE: case WM_ACTIVATEAPP: //case WM_MOUSEACTIVATE: case WM_KILLFOCUS: //case WM_SETFOCUS: case WM_MOUSEMOVE: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_XBUTTONUP: case WM_XBUTTONDBLCLK: case WM_VSCROLL: // Вся обработка в родителе { switch (messg) { case WM_VSCROLL: switch (LOWORD(wParam)) { case SB_THUMBTRACK: case SB_THUMBPOSITION: pVCon->mb_VTracking = TRUE; break; case SB_ENDSCROLL: pVCon->mb_VTracking = FALSE; break; } pVCon->RCon()->OnSetScrollPos(wParam); break; case WM_LBUTTONUP: pVCon->mb_VTracking = FALSE; break; } TODO("Обработка ghWndWork"); HWND hParent = ghWnd; _ASSERTE(GetParent(hWnd)==ghWnd); if (messg >= WM_MOUSEFIRST && messg <= WM_MOUSELAST) { POINT pt = {LOWORD(lParam),HIWORD(lParam)}; MapWindowPoints(hWnd, hParent, &pt, 1); lParam = MAKELONG(pt.x,pt.y); } result = gpConEmu->WndProc(hParent, messg, wParam, lParam); } break; case WM_IME_NOTIFY: break; case WM_INPUTLANGCHANGE: case WM_INPUTLANGCHANGEREQUEST: { #ifdef _DEBUG if (IsDebuggerPresent()) { WCHAR szMsg[128]; _wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"InChild %s(CP:%i, HKL:0x%08X)\n", (messg == WM_INPUTLANGCHANGE) ? L"WM_INPUTLANGCHANGE" : L"WM_INPUTLANGCHANGEREQUEST", (DWORD)wParam, (DWORD)lParam); DEBUGSTRLANG(szMsg); } #endif result = DefWindowProc(hWnd, messg, wParam, lParam); } break; #ifdef _DEBUG case WM_WINDOWPOSCHANGING: { WINDOWPOS* pwp = (WINDOWPOS*)lParam; result = DefWindowProc(hWnd, messg, wParam, lParam); } return result; case WM_WINDOWPOSCHANGED: { WINDOWPOS* pwp = (WINDOWPOS*)lParam; result = DefWindowProc(hWnd, messg, wParam, lParam); } break; #endif case WM_SETCURSOR: { gpConEmu->WndProc(hWnd, messg, wParam, lParam); //if (!result) // result = DefWindowProc(hWnd, messg, wParam, lParam); } // If an application processes this message, it should return TRUE to halt further processing or FALSE to continue. break; case WM_SYSCOMMAND: // -- лишние ограничения, похоже result = DefWindowProc(hWnd, messg, wParam, lParam); //if (wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP/*0xF180*/) //{ // // Изменение размеров/максимизация/и т.п. окна консоли - запрещена // _ASSERTE(!(wParam >= SC_SIZE && wParam <= SC_CONTEXTHELP)); //} //else //{ // // По идее, сюда ничего приходить больше не должно // _ASSERTE(FALSE); //} break; case WM_GESTURENOTIFY: case WM_GESTURE: { gpConEmu->ProcessGestureMessage(hWnd, messg, wParam, lParam, result); break; } // case WM_GESTURE, WM_GESTURENOTIFY default: if (pVCon && (messg == pVCon->mn_MsgRestoreChildFocus)) { if (!gpConEmu->CanSetChildFocus()) { // Клик по иконке открывает системное меню //_ASSERTE(FALSE && "Must not get here?"); } else { CRealConsole* pRCon = pVCon->RCon(); if (gpConEmu->isActive(pVCon, false)) { pRCon->GuiWndFocusRestore(); } if (pRCon->GuiWnd()) { pRCon->StoreGuiChildRect(NULL); } } } else { result = DefWindowProc(hWnd, messg, wParam, lParam); } } wrap: return result; }
int CTabBarClass::ActiveTabByName(int anType, LPCWSTR asName, CVConGuard* rpVCon) { int nTab = -1; if (rpVCon) rpVCon->Release(); TODO("TabBarClass::ActiveTabByName - найти таб по имени"); INT_PTR V, I; int tabIdx = 0; CVConGuard VCon; for (V = 0; (nTab == -1) && CVConGroup::GetVCon(V, &VCon, true); V++) { #ifdef _DEBUG bool lbActive = VCon->isActive(false); #endif //111120 - Эту опцию игнорируем. Если редактор открыт в другой консоли - активируем ее потом //if (gpSet->bHideInactiveConsoleTabs) //{ // if (!lbActive) continue; //} CRealConsole *pRCon = VCon->RCon(); for (I = 0; TRUE; I++) { CTab tab(__FILE__,__LINE__); if (!pRCon->GetTab(I, tab)) break; if (tab->Type() == (anType & fwt_TypeMask)) { // Тут GetName() использовать нельзя, т.к. оно может возвращать "переименованное пользователем" // А здесь ищется конкретный редактор-вьювер фара (то есть нужно правильное полное имя-путь к файлу) LPCWSTR pszNamePtr = tab->Name.Ptr(); // If asName (searched file) has been specified with path, we need to compare with tab full path LPCWSTR pszCompareTab = wcspbrk(asName, L"\\/") ? pszNamePtr : PointToName(pszNamePtr); if (pszNamePtr && ((lstrcmpi(pszCompareTab, asName) == 0))) { nTab = tabIdx; break; } } tabIdx++; } } if (nTab >= 0) { if (!CanActivateTab(nTab)) { nTab = -2; } else { if (!mp_Rebar->FarSendChangeTab(nTab, &VCon)) nTab = -2; } } if (rpVCon) rpVCon->Attach(VCon.VCon()); return nTab; }
bool CTabBarClass::OnNotify(LPNMHDR nmhdr, LRESULT& lResult) { if (!this) return false; if (!_active) return false; lResult = 0; if (mp_Rebar->OnNotifyInt(nmhdr, lResult)) return true; if (nmhdr->code == TBN_GETINFOTIP && mp_Rebar->IsToolbarNotify(nmhdr)) { if (!gpSet->isMultiShowButtons) return false; LPNMTBGETINFOTIP pDisp = (LPNMTBGETINFOTIP)nmhdr; //if (pDisp->iItem>=1 && pDisp->iItem<=MAX_CONSOLE_COUNT) if (pDisp->iItem == TID_ACTIVE_NUMBER) { if (!pDisp->pszText || !pDisp->cchTextMax) return true; CVConGuard VCon; CVirtualConsole* pVCon = (gpConEmu->GetActiveVCon(&VCon) >= 0) ? VCon.VCon() : NULL; LPCWSTR pszTitle = pVCon ? pVCon->RCon()->GetTitle() : NULL; if (pszTitle) { lstrcpyn(pDisp->pszText, pszTitle, pDisp->cchTextMax); } else { pDisp->pszText[0] = 0; } } else if (pDisp->iItem == TID_CREATE_CON) { lstrcpyn(pDisp->pszText, _T("Create new console"), pDisp->cchTextMax); } else if (pDisp->iItem == TID_ALTERNATIVE) { bool lbChecked = mp_Rebar->GetToolBtnChecked(TID_ALTERNATIVE); lstrcpyn(pDisp->pszText, lbChecked ? L"Alternative mode is ON (console freezed)" : L"Alternative mode is off", pDisp->cchTextMax); } else if (pDisp->iItem == TID_SCROLL) { bool lbChecked = mp_Rebar->GetToolBtnChecked(TID_SCROLL); lstrcpyn(pDisp->pszText, lbChecked ? L"BufferHeight mode is ON (scrolling enabled)" : L"BufferHeight mode is off", pDisp->cchTextMax); } else if (pDisp->iItem == TID_MINIMIZE) { lstrcpyn(pDisp->pszText, _T("Minimize window"), pDisp->cchTextMax); } else if (pDisp->iItem == TID_MAXIMIZE) { lstrcpyn(pDisp->pszText, _T("Maximize window"), pDisp->cchTextMax); } else if (pDisp->iItem == TID_APPCLOSE) { lstrcpyn(pDisp->pszText, _T("Close ALL consoles"), pDisp->cchTextMax); } //else if (pDisp->iItem == TID_COPYING) //{ // lstrcpyn(pDisp->pszText, _T("Show copying queue"), pDisp->cchTextMax); //} else if (pDisp->iItem == TID_SYSMENU) { lstrcpyn(pDisp->pszText, _T("Show system menu (RClick for Settings)"), pDisp->cchTextMax); } else { _ASSERTE(FALSE && "Tooltip was not processed"); } return true; } if (nmhdr->code == TBN_DROPDOWN && mp_Rebar->IsToolbarNotify(nmhdr)) { LPNMTOOLBAR pBtn = (LPNMTOOLBAR)nmhdr; switch (pBtn->iItem) { case TID_ACTIVE_NUMBER: OnChooseTabPopup(); break; case TID_CREATE_CON: gpConEmu->mp_Menu->OnNewConPopupMenu(NULL, 0, isPressed(VK_SHIFT)); break; #ifdef _DEBUG default: _ASSERTE(FALSE && "DropDown was not processed"); #endif } lResult = TBDDRET_DEFAULT; return true; } if (nmhdr->code == TTN_GETDISPINFO && mp_Rebar->IsTabbarNotify(nmhdr)) { LPNMTTDISPINFO pDisp = (LPNMTTDISPINFO)nmhdr; DWORD wndIndex = 0; pDisp->hinst = NULL; pDisp->szText[0] = 0; pDisp->lpszText = NULL; POINT ptScr = {}; GetCursorPos(&ptScr); int iPage = mp_Rebar->GetTabFromPoint(ptScr); if (iPage >= 0) { // Если в табе нет "…" - тип не нужен if (!mp_Rebar->GetTabText(iPage, ms_TmpTabText, countof(ms_TmpTabText))) return true; if (!wcschr(ms_TmpTabText, L'\x2026' /*"…"*/)) return true; CVConGuard VCon; if (!GetVConFromTab(iPage, &VCon, &wndIndex)) return true; CTab tab(__FILE__,__LINE__); if (!VCon->RCon()->GetTab(wndIndex, tab)) return true; lstrcpyn(ms_TmpTabText, VCon->RCon()->GetTabTitle(tab), countof(ms_TmpTabText)); pDisp->lpszText = ms_TmpTabText; } return true; } return false; }
void CTabBarClass::OnCommand(WPARAM wParam, LPARAM lParam) { if (!this) return; if (!mp_Rebar->IsToolbarCommand(wParam, lParam)) return; if (!gpSet->isMultiShowButtons) { _ASSERTE(gpSet->isMultiShowButtons); return; } if (wParam == TID_ACTIVE_NUMBER) { //gpConEmu->ConActivate(wParam-1); OnChooseTabPopup(); } else if (wParam == TID_CREATE_CON) { if (gpConEmu->IsGesturesEnabled()) gpConEmu->mp_Menu->OnNewConPopupMenu(NULL, 0, isPressed(VK_SHIFT)); else gpConEmu->RecreateAction(gpSetCls->GetDefaultCreateAction(), gpSet->isMultiNewConfirm || isPressed(VK_SHIFT)); } else if (wParam == TID_ALTERNATIVE) { CVConGuard VCon; CVirtualConsole* pVCon = (gpConEmu->GetActiveVCon(&VCon) >= 0) ? VCon.VCon() : NULL; // Вернуть на тулбар _текущее_ состояние режима mp_Rebar->SetToolBtnChecked(TID_ALTERNATIVE, pVCon ? pVCon->RCon()->isAlternative() : false); // И собственно Action gpConEmu->AskChangeAlternative(); } else if (wParam == TID_SCROLL) { CVConGuard VCon; CVirtualConsole* pVCon = (gpConEmu->GetActiveVCon(&VCon) >= 0) ? VCon.VCon() : NULL; // Вернуть на тулбар _текущее_ состояние режима mp_Rebar->SetToolBtnChecked(TID_SCROLL, pVCon ? pVCon->RCon()->isBufferHeight() : false); // И собственно Action gpConEmu->AskChangeBufferHeight(); } else if (wParam == TID_MINIMIZE) { PostMessage(ghWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); } else if (wParam == TID_MAXIMIZE) { // Чтобы клик случайно не провалился в консоль gpConEmu->mouse.state |= MOUSE_SIZING_DBLCKL; // Аналог AltF9 gpConEmu->DoMaximizeRestore(); } else if (wParam == TID_APPCLOSE) { gpConEmu->PostScClose(); } //else if (wParam == TID_COPYING) //{ // gpConEmu->OnCopyingState(); //} else if (wParam == TID_SYSMENU) { RECT rcBtnRect = {0}; mp_Rebar->GetToolBtnRect(TID_SYSMENU, &rcBtnRect); DWORD nAddFlags = ((gpSet->nTabsLocation == 1) ? TPM_BOTTOMALIGN : 0) | TPM_RIGHTALIGN; LogString(L"ShowSysmenu called from (ToolBar)"); gpConEmu->mp_Menu->ShowSysmenu(rcBtnRect.right,rcBtnRect.bottom, nAddFlags); } else { _ASSERTE(FALSE && "Toolbar click was not processed"); } }
void CRecreateDlg::InitVars() { if (mpsz_DefCmd || mpsz_CurCmd || mpsz_SysCmd || mpsz_DefDir || !ms_RConStartDir.IsEmpty() || !ms_RConCurDir.IsEmpty()) { _ASSERTE(!(mpsz_DefCmd || mpsz_CurCmd || mpsz_SysCmd || mpsz_DefDir || !ms_RConStartDir.IsEmpty() || !ms_RConCurDir.IsEmpty())); FreeVars(); } CVConGuard VCon; CVirtualConsole* pVCon = (gpConEmu->GetActiveVCon(&VCon) >= 0) ? VCon.VCon() : NULL; CRealConsole* pRCon = pVCon ? pVCon->RCon() : NULL; if (pRCon) { ms_RConStartDir.Set(pRCon->GetStartupDir()); pRCon->GetConsoleCurDir(ms_RConCurDir); } // Если уже передана команда через параметры - из текущей консоли не извлекать if (!mp_Args || mp_Args->pszSpecialCmd) { _ASSERTE(mp_Args!=NULL); return; } // AutoStartTaskName - не возвращаем никогда. // Если он выбран при старте - то либо текущая консоль, либо первая команда из AutoStartTaskName, либо команда по умолчанию // Диалог может быть вызван в следующих случаях // * Recreate // * Свободный выбор = cra_EditTab (добавление новой команды в task или выбор шелла при обломе на старте) // * Ни одной консоли нет (предложить то что запускается при старте - Task, команда) // * Консоли есть (пусть наверное будет то что запускается при старте - Task, команда) wchar_t* pszBuf = NULL; _ASSERTE(pRCon || (mp_Args->aRecreate == cra_CreateTab || mp_Args->aRecreate == cra_EditTab)); LPCWSTR pszCmd = pRCon ? pRCon->GetCmd() : NULL; if (pszCmd && *pszCmd) mpsz_CurCmd = lstrdup(pszCmd); LPCWSTR pszSystem = gpSetCls->GetCmd(); if (pszSystem && *pszSystem && (lstrcmpi(pszSystem, AutoStartTaskName) != 0)) mpsz_SysCmd = lstrdup(pszSystem); bool bDirFromRCon = false; if (mp_Args->aRecreate == cra_RecreateTab) { // When recreate - always show active console command line _ASSERTE(pRCon); mpsz_DefCmd = lstrdup(pszCmd); bDirFromRCon = true; } else { // В диалоге запуска новой консоли - нечего делать автостартующему таску? if (lstrcmpi(pszSystem, AutoStartTaskName) == 0) { // Раз активной консоли нет - попробовать взять первую команду из AutoStartTaskName if (!pszCmd) { pszBuf = gpConEmu->LoadConsoleBatch(AutoStartTaskName); wchar_t* pszLine = wcschr(pszBuf, L'\n'); if (pszLine > pszBuf && *(pszLine-1) == L'\r') pszLine--; if (pszLine) *pszLine = 0; bool lbRunAdmin = (mp_Args->RunAsAdministrator == crb_On); pszCmd = gpConEmu->ParseScriptLineOptions(pszBuf, &lbRunAdmin, NULL); if (lbRunAdmin) mp_Args->RunAsAdministrator = crb_On; } else { bDirFromRCon = true; } } else if (pszSystem && *pszSystem) { pszCmd = pszSystem; } else { bDirFromRCon = true; } mpsz_DefCmd = lstrdup(pszCmd); //mpsz_DefDir = lstrdup(mp_Args->pszStartupDir ? mp_Args->pszStartupDir : L""); } if (bDirFromRCon) { TODO("May be try to retrieve current directory of the shell?"); mpsz_DefDir = lstrdup(ms_RConCurDir); } SafeFree(pszBuf); }
INT_PTR CRecreateDlg::OnInitDialog(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { LRESULT lbRc = FALSE; gpConEmu->OnOurDialogOpened(); // Visual SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); // Set password style (avoid "bars" on some OS) SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); // Add menu items HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED, ID_RESETCMDHISTORY, L"Clear history..."); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | (gpSet->isSaveCmdHistory ? MF_CHECKED : 0), ID_STORECMDHISTORY, L"Store history"); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif RConStartArgs* pArgs = mp_Args; _ASSERTE(pArgs); // Fill command and task drop down SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); // Set text in command and folder fields SetDlgItemText(hDlg, IDC_RESTART_CMD, mpsz_DefCmd ? mpsz_DefCmd : pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : L""); // Current directory, startup directory, ConEmu startup directory, and may be startup directory history in the future AddDirectoryList(mpsz_DefDir ? mpsz_DefDir : pArgs->pszStartupDir); AddDirectoryList(ms_RConCurDir); AddDirectoryList(ms_RConStartDir); AddDirectoryList(gpConEmu->WorkDir()); LPCWSTR pszShowDir; if ((pArgs->aRecreate == cra_RecreateTab) && !ms_RConCurDir.IsEmpty()) pszShowDir = ms_RConCurDir; else pszShowDir = mpsz_DefDir ? mpsz_DefDir : pArgs->pszStartupDir ? pArgs->pszStartupDir : gpConEmu->WorkDir(); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszShowDir); // Split controls if (pArgs->aRecreate == cra_RecreateTab) { // Hide Split's ShowWindow(GetDlgItem(hDlg, gbRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplitNone), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Right), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Bottom), SW_HIDE); ShowWindow(GetDlgItem(hDlg, stRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, tRecreateSplit), SW_HIDE); } else { // Fill splits SetDlgItemInt(hDlg, tRecreateSplit, (1000-pArgs->nSplitValue)/10, FALSE); CheckRadioButton(hDlg, rbRecreateSplitNone, rbRecreateSplit2Bottom, rbRecreateSplitNone+pArgs->eSplit); EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); } // Спрятать флажок "New window" bool bRunInNewWindow_Hidden = (pArgs->aRecreate == cra_EditTab || pArgs->aRecreate == cra_RecreateTab); ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), bRunInNewWindow_Hidden ? SW_HIDE : SW_SHOWNORMAL); const wchar_t *pszUser = pArgs->pszUserName; const wchar_t *pszDomain = pArgs->pszDomain; bool bResticted = (pArgs->RunAsRestricted == crb_On); int nChecked = rbCurrentUser; DWORD nUserNameLen = countof(ms_CurUser); if (!GetUserName(ms_CurUser, &nUserNameLen)) ms_CurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szOtherUser, pszUser, MAX_PATH); wcscat_c(szOtherUser, L"@"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szOtherUser, pszDomain, MAX_PATH); wcscat_c(szOtherUser, L"\\"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszUser, MAX_PATH); } } else { lstrcpyn(szOtherUser, pszUser, countof(szOtherUser)); } SetDlgItemText(hDlg, tRunAsPassword, pArgs->szUserPassword); } } SetDlgItemText(hDlg, tRunAsUser, (nChecked == rbAnotherUser) ? szOtherUser : L""); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && (pArgs->RunAsAdministrator == crb_On))) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else //if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to restart console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); // Если ВЫКЛЮЧЕН "Multi consoles in one window" // - Check & Disable "New window" checkbox CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow || !gpSetCls->IsMulti()) ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hDlg, cbRunInNewWindow), gpSetCls->IsMulti()); // SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, (pArgs->aRecreate == cra_EditTab) ? L"&Save" : L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); } // Correct cbRunInNewWindow position if (!bRunInNewWindow_Hidden) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } // Dpi aware processing at the end of sequence // because we done some manual control reposition if (mp_DpiAware) { mp_DpiAware->Attach(hDlg, ghWnd); } // Ensure, it will be "on screen" RECT rect; GetWindowRect(hDlg, &rect); RECT rcCenter = CenterInParent(rect, mh_Parent); MoveWindow(hDlg, rcCenter.left, rcCenter.top, rect.right - rect.left, rect.bottom - rect.top, false); // Была отключена обработка CConEmuMain::OnFocus (лишние телодвижения) PostMessage(hDlg, (WM_APP+1), 0,0); // Default focus control if (pArgs->aRecreate == cra_RecreateTab) SetFocus(GetDlgItem(hDlg, IDC_START)); // Win+~ (Recreate tab), Focus on "Restart" button" else if ((pArgs->pszUserName && *pArgs->pszUserName) && !*pArgs->szUserPassword) SetFocus(GetDlgItem(hDlg, tRunAsPassword)); // We need password, all other fields are ready else SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); // Set focus in command-line field return lbRc; }
INT_PTR CEFindDlg::findTextProc(HWND hWnd2, UINT messg, WPARAM wParam, LPARAM lParam) { switch (messg) { case WM_INITDIALOG: { gpConEmu->OnOurDialogOpened(); gpConEmu->mp_Find->mh_FindDlg = hWnd2; SendMessage(hWnd2, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hWnd2, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); CDynDialog::LocalizeDialog(hWnd2); if (gpConEmu->mp_Find->mp_DpiAware) { gpConEmu->mp_Find->mp_DpiAware->Attach(hWnd2, ghWnd, gpConEmu->mp_Find->mp_Dlg); } #if 0 //if (IsDebuggerPresent()) if (!gpSet->isAlwaysOnTop) SetWindowPos(hWnd2, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); #endif CVConGuard VCon; CRealConsole* pRCon = (CVConGroup::GetActiveVCon(&VCon) >= 0) ? VCon->RCon() : NULL; RECT rcWnd = {}; GetWindowRect(pRCon->GetView(), &rcWnd); RECT rcDlg = {}; GetWindowRect(hWnd2, &rcDlg); int nShift = max(gpFontMgr->FontWidth(),gpFontMgr->FontHeight()); int nWidth = rcDlg.right - rcDlg.left; SetWindowPos(hWnd2, gpSet->isAlwaysOnTop ? HWND_TOPMOST : HWND_TOP, max(rcWnd.left,(rcWnd.right-nShift-nWidth)), (rcWnd.top+nShift), 0,0, SWP_NOSIZE); gpConEmu->mp_Find->UpdateFindDlgAlpha(true); SetTimer(hWnd2, 101, 1000, NULL); SetClassLongPtr(hWnd2, GCLP_HICON, (LONG_PTR)hClassIcon); SetDlgItemText(hWnd2, tFindText, gpSet->FindOptions.pszText ? gpSet->FindOptions.pszText : L""); CDlgItemHelper::checkDlgButton(hWnd2, cbFindMatchCase, gpSet->FindOptions.bMatchCase); CDlgItemHelper::checkDlgButton(hWnd2, cbFindWholeWords, gpSet->FindOptions.bMatchWholeWords); CDlgItemHelper::checkDlgButton(hWnd2, cbFindFreezeConsole, gpSet->FindOptions.bFreezeConsole); #if 0 CDlgItemHelper::checkDlgButton(hWnd2, cbFindHighlightAll, gpSet->FindOptions.bHighlightAll); #endif CDlgItemHelper::checkDlgButton(hWnd2, cbFindTransparent, gpSet->FindOptions.bTransparent); if (gpSet->FindOptions.pszText && *gpSet->FindOptions.pszText) SendDlgItemMessage(hWnd2, tFindText, EM_SETSEL, 0, lstrlen(gpSet->FindOptions.pszText)); // Зовем всегда, чтобы инициализировать буфер для поиска как минимум gpConEmu->DoFindText(0); break; } //case WM_SYSCOMMAND: // if (LOWORD(wParam) == ID_ALWAYSONTOP) // { // BOOL lbOnTopNow = GetWindowLong(ghOpWnd, GWL_EXSTYLE) & WS_EX_TOPMOST; // SetWindowPos(ghOpWnd, lbOnTopNow ? HWND_NOTOPMOST : HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); // CheckMenuItem(GetSystemMenu(ghOpWnd, FALSE), ID_ALWAYSONTOP, MF_BYCOMMAND | // (lbOnTopNow ? MF_UNCHECKED : MF_CHECKED)); // SetWindowLongPtr(hWnd2, DWLP_MSGRESULT, 0); // return 1; // } // break; case WM_MOUSEMOVE: case WM_NCMOUSEMOVE: case WM_TIMER: gpConEmu->mp_Find->UpdateFindDlgAlpha(); break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { int nDirection = 0; switch (LOWORD(wParam)) { case IDCLOSE: case IDCANCEL: DestroyWindow(hWnd2); return 0; case cbFindMatchCase: gpSet->FindOptions.bMatchCase = CDlgItemHelper::isChecked2(hWnd2, cbFindMatchCase); break; case cbFindWholeWords: gpSet->FindOptions.bMatchWholeWords = CDlgItemHelper::isChecked2(hWnd2, cbFindWholeWords); break; case cbFindFreezeConsole: gpSet->FindOptions.bFreezeConsole = CDlgItemHelper::isChecked2(hWnd2, cbFindFreezeConsole); break; case cbFindHighlightAll: gpSet->FindOptions.bHighlightAll = CDlgItemHelper::isChecked2(hWnd2, cbFindHighlightAll); break; case cbFindTransparent: gpSet->FindOptions.bTransparent = CDlgItemHelper::isChecked2(hWnd2, cbFindTransparent); gpConEmu->mp_Find->UpdateFindDlgAlpha(true); return 0; case cbFindNext: nDirection = 1; break; case cbFindPrev: nDirection = -1; break; default: return 0; } if (gpSet->FindOptions.pszText && *gpSet->FindOptions.pszText) gpConEmu->DoFindText(nDirection); } else if (HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == CBN_EDITCHANGE || HIWORD(wParam) == CBN_SELCHANGE) { MyGetDlgItemText(hWnd2, tFindText, gpSet->FindOptions.cchTextMax, gpSet->FindOptions.pszText); if (gpSet->FindOptions.pszText && *gpSet->FindOptions.pszText) gpConEmu->DoFindText(0); } break; case WM_CLOSE: gpConEmu->OnOurDialogClosed(); DestroyWindow(hWnd2); break; case WM_DESTROY: KillTimer(hWnd2, 101); gpConEmu->mp_Find->mh_FindDlg = NULL; gpSet->SaveFindOptions(); gpConEmu->SkipOneAppsRelease(false); gpConEmu->DoEndFindText(); if (gpConEmu->mp_Find->mp_DpiAware) gpConEmu->mp_Find->mp_DpiAware->Detach(); SafeDelete(gpConEmu->mp_Find->mp_Dlg); break; default: if (gpConEmu->mp_Find->mp_DpiAware && gpConEmu->mp_Find->mp_DpiAware->ProcessDpiMessages(hWnd2, messg, wParam, lParam)) { return TRUE; } } return 0; }
// IDYES - Close All consoles // IDNO - Close active console only // IDCANCEL - As is int ConfirmCloseConsoles(const ConfirmCloseParam& Parm) { DontEnable de; wchar_t szText[512], *pszText; int nBtn = IDCANCEL; static LONG lCounter = 0; LONG l = InterlockedIncrement(&lCounter); if (l > 1) { if (l == 2) { _ASSERTE(FALSE && "Confirm stack overflow!"); } goto wrap; } if (Parm.rpLeaveConEmuOpened) *Parm.rpLeaveConEmuOpened = false; // Use TaskDialog? if (gOSVer.dwMajorVersion >= 6) { // must be already initialized: CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); wchar_t szMessage[128]; if (Parm.asSingleConsole) lstrcpyn(szMessage, Parm.asSingleConsole, countof(szMessage)); else if (Parm.bForceKill) wcscpy_c(szMessage, L"Confirm killing?"); else if (Parm.bGroup) wcscpy_c(szMessage, L"Confirm closing group?"); else wcscpy_c(szMessage, L"Confirm closing?"); wchar_t szWWW[MAX_PATH]; _wsprintf(szWWW, SKIPLEN(countof(szWWW)) L"<a href=\"%s\">%s</a>", gsHomePage, gsHomePage); wchar_t szCloseAll[MAX_PATH*2]; wchar_t *pszText; if (Parm.asSingleConsole) { wcscpy_c(szCloseAll, L"Yes\n"); pszText = szCloseAll + _tcslen(szCloseAll); lstrcpyn(pszText, Parm.asSingleTitle, min(MAX_PATH,(countof(szCloseAll)-(pszText-szCloseAll)))); pszText += _tcslen(pszText); } else { _wsprintf(szCloseAll, SKIPLEN(countof(szCloseAll)) (Parm.bGroup && (Parm.nConsoles>1)) ? ((Parm.bGroup == ConfirmCloseParam::eGroup) ? L"Close group (%u consoles)" : L"Close (%u consoles)") : (Parm.nConsoles>1) ? L"Close all %u consoles." : L"Close %u console.", Parm.nConsoles); pszText = szCloseAll + _tcslen(szCloseAll); } if ((Parm.asSingleConsole == NULL) || (Parm.nOperations || Parm.nUnsavedEditors)) { //if (nOperations) { _wsprintf(pszText, SKIPLEN(countof(szCloseAll)-(pszText-szCloseAll)) L"\nIncomplete operations: %i", Parm.nOperations); pszText += _tcslen(pszText); } //if (nUnsavedEditors) { _wsprintf(pszText, SKIPLEN(countof(szCloseAll)-(pszText-szCloseAll)) L"\nUnsaved editor windows: %i", Parm.nUnsavedEditors); pszText += _tcslen(pszText); } } wchar_t szCloseOne[MAX_PATH]; wcscpy_c(szCloseOne, L"Close active console only"); if (Parm.nConsoles > 1) { CVConGuard VCon; int iCon = gpConEmu->GetActiveVCon(&VCon); if (iCon >= 0) { pszText = szCloseOne + _tcslen(szCloseOne); _wsprintf(pszText, SKIPLEN(countof(szCloseOne)-(pszText-szCloseOne)) L"\n#%u: ", (iCon+1)); pszText += _tcslen(pszText); lstrcpyn(pszText, VCon->RCon()->GetTitle(true), countof(szCloseOne)-(pszText-szCloseOne)); } } const wchar_t* szCancel = L"Cancel\nDon't close anything"; int nButtonPressed = 0; TASKDIALOGCONFIG config = {sizeof(config)}; TASKDIALOG_BUTTON buttons[] = { { IDYES, szCloseAll }, { IDNO, szCloseOne }, { IDCANCEL, szCancel }, }; config.cButtons = countof(buttons); if (Parm.nConsoles <= 1) { buttons[1] = buttons[2]; config.cButtons--; } config.hwndParent = ghWnd; config.hInstance = NULL /*g_hInstance*/; config.dwFlags = TDF_USE_HICON_MAIN|TDF_USE_COMMAND_LINKS|TDF_ALLOW_DIALOG_CANCELLATION |TDF_ENABLE_HYPERLINKS; //|TDIF_SIZE_TO_CONTENT|TDF_CAN_BE_MINIMIZED; //config.pszMainIcon = MAKEINTRESOURCE(IDI_ICON1); config.hMainIcon = hClassIcon; config.pszWindowTitle = gpConEmu->GetDefaultTitle(); config.pszMainInstruction = szMessage; //config.pszContent = L"..."; config.pButtons = buttons; config.nDefaultButton = IDYES; config.pszFooter = szWWW; //{ // config.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED; // config.pszVerificationText = L"Text on checkbox"; //} HRESULT hr = TaskDialog(&config, &nButtonPressed, NULL, NULL); if (hr == S_OK) { switch (nButtonPressed) { case IDCANCEL: // user cancelled the dialog case IDYES: case IDNO: nBtn = nButtonPressed; goto wrap; default: _ASSERTE(nButtonPressed==IDCANCEL||nButtonPressed==IDYES||nButtonPressed==IDNO); break; // should never happen } } } // Иначе - через стандартный MessageBox if (Parm.asSingleConsole) { lstrcpyn(szText, Parm.asSingleConsole ? Parm.asSingleConsole : Parm.bForceKill ? L"Confirm killing?" : L"Confirm closing?", min(128,countof(szText))); wcscat_c(szText, L"\r\n\r\n"); int nLen = lstrlen(szText); lstrcpyn(szText+nLen, Parm.asSingleTitle, countof(szText)-nLen); } else { _wsprintf(szText, SKIPLEN(countof(szText)) L"About to close %u console%s.\r\n", Parm.nConsoles, (Parm.nConsoles>1)?L"s":L""); } pszText = szText+_tcslen(szText); if (Parm.nOperations || Parm.nUnsavedEditors) { *(pszText++) = L'\r'; *(pszText++) = L'\n'; *(pszText) = 0; if (Parm.nOperations) { _wsprintf(pszText, SKIPLEN(countof(szText)-(pszText-szText)) L"Incomplete operations: %i\r\n", Parm.nOperations); pszText += _tcslen(pszText); } if (Parm.nUnsavedEditors) { _wsprintf(pszText, SKIPLEN(countof(szText)-(pszText-szText)) L"Unsaved editor windows: %i\r\n", Parm.nUnsavedEditors); pszText += _tcslen(pszText); } } if (Parm.nConsoles > 1) { wcscat_c(szText, L"\r\nPress button <No> to close active console only\r\n" L"\r\nProceed with close ConEmu?"); } nBtn = MsgBox(szText, (/*rpPanes ? MB_OKCANCEL :*/ (Parm.nConsoles>1) ? MB_YESNOCANCEL : MB_OKCANCEL)|MB_ICONEXCLAMATION, gpConEmu->GetDefaultTitle(), ghWnd); if (nBtn == IDOK) { nBtn = IDYES; // для однозначности } wrap: InterlockedDecrement(&lCounter); return nBtn; }
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { #define UM_USER_CONTROLS (WM_USER+121) #define UM_FILL_CMDLIST (WM_USER+122) CRecreateDlg* pDlg = NULL; if (messg == WM_INITDIALOG) { pDlg = (CRecreateDlg*)lParam; pDlg->mh_Dlg = hDlg; SetWindowLongPtr(hDlg, DWLP_USER, lParam); } else { pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER); } if (!pDlg) { return FALSE; } PatchMsgBoxIcon(hDlg, messg, wParam, lParam); switch (messg) { case WM_INITDIALOG: { LRESULT lbRc = FALSE; // Visual SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); // Set password style (avoid "bars" on some OS) SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); // Add menu items HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED, ID_RESETCMDHISTORY, L"Clear history..."); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | (gpSet->isSaveCmdHistory ? MF_CHECKED : 0), ID_STORECMDHISTORY, L"Store history"); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); // Fill command and task drop down SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); // Set text in command and folder fields SetDlgItemText(hDlg, IDC_RESTART_CMD, pDlg->mpsz_DefCmd ? pDlg->mpsz_DefCmd : pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : L""); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pDlg->mpsz_DefDir ? pDlg->mpsz_DefDir : pArgs->pszStartupDir ? pArgs->pszStartupDir : gpConEmu->WorkDir()); // Split controls if (pArgs->aRecreate == cra_RecreateTab) { // Hide Split's ShowWindow(GetDlgItem(hDlg, gbRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplitNone), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Right), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Bottom), SW_HIDE); ShowWindow(GetDlgItem(hDlg, stRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, tRecreateSplit), SW_HIDE); } else { // Fill splits SetDlgItemInt(hDlg, tRecreateSplit, (1000-pArgs->nSplitValue)/10, FALSE); CheckRadioButton(hDlg, rbRecreateSplitNone, rbRecreateSplit2Bottom, rbRecreateSplitNone+pArgs->eSplit); EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); } // Спрятать флажок "New window" bool bRunInNewWindow_Hidden = (pArgs->aRecreate == cra_EditTab || pArgs->aRecreate == cra_RecreateTab); ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), bRunInNewWindow_Hidden ? SW_HIDE : SW_SHOWNORMAL); const wchar_t *pszUser = pArgs->pszUserName; const wchar_t *pszDomain = pArgs->pszDomain; bool bResticted = (pArgs->RunAsRestricted == crb_On); int nChecked = rbCurrentUser; DWORD nUserNameLen = countof(pDlg->ms_CurUser); if (!GetUserName(pDlg->ms_CurUser, &nUserNameLen)) pDlg->ms_CurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szOtherUser, pszUser, MAX_PATH); wcscat_c(szOtherUser, L"@"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szOtherUser, pszDomain, MAX_PATH); wcscat_c(szOtherUser, L"\\"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszUser, MAX_PATH); } } else { lstrcpyn(szOtherUser, pszUser, countof(szOtherUser)); } SetDlgItemText(hDlg, tRunAsPassword, pArgs->szUserPassword); } } SetDlgItemText(hDlg, tRunAsUser, (nChecked == rbAnotherUser) ? szOtherUser : L""); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && (pArgs->RunAsAdministrator == crb_On))) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to restart console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); // Если ВЫКЛЮЧЕН "Multi consoles in one window" // - Check & Disable "New window" checkbox CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow || !gpSetCls->IsMulti()) ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hDlg, cbRunInNewWindow), gpSetCls->IsMulti()); // SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, (pArgs->aRecreate == cra_EditTab) ? L"&Save" : L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); } // Correct cbRunInNewWindow position if (!bRunInNewWindow_Hidden) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } // Ensure, it will be "on screen" RECT rect; GetWindowRect(hDlg, &rect); RECT rcCenter = CenterInParent(rect, pDlg->mh_Parent); MoveWindow(hDlg, rcCenter.left, rcCenter.top, rect.right - rect.left, rect.bottom - rect.top, false); // Была отключена обработка CConEmuMain::OnFocus (лишние телодвижения) PostMessage(hDlg, (WM_APP+1), 0,0); // Default focus control if (pArgs->aRecreate == cra_RecreateTab) SetFocus(GetDlgItem(hDlg, IDC_START)); // Win+~ (Recreate tab), Focus on "Restart" button" else if ((pArgs->pszUserName && *pArgs->pszUserName) && !*pArgs->szUserPassword) SetFocus(GetDlgItem(hDlg, tRunAsPassword)); // We need password, all other fields are ready else SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); // Set focus in command-line field return lbRc; } case (WM_APP+1): //TODO: Не совсем корректно, не учитывается предыдущее значение флажка gpConEmu->SetSkipOnFocus(false); return FALSE; case WM_CTLCOLORSTATIC: if (GetDlgItem(hDlg, IDC_WARNING) == (HWND)lParam) { SetTextColor((HDC)wParam, 255); HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE); SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)hBrush; } break; //case WM_GETICON: // if (wParam==ICON_BIG) // { // /*SetWindowLong(hWnd2, DWL_MSGRESULT, (LRESULT)hClassIcon); // return 1;*/ // } // else // { // SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LRESULT)hClassIconSm); // return 1; // } // return 0; case UM_FILL_CMDLIST: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); pDlg->AddCommandList(pArgs->pszSpecialCmd); pDlg->AddCommandList(pDlg->mpsz_SysCmd, pArgs->pszSpecialCmd ? -1 : 0); pDlg->AddCommandList(pDlg->mpsz_CurCmd); pDlg->AddCommandList(pDlg->mpsz_DefCmd); // Может быть позван после очистки истории из меню, тогда нет смысла и дергаться if (wParam) { LPCWSTR pszHistory = gpSet->HistoryGet(); if (pszHistory) { while (*pszHistory) { pDlg->AddCommandList(pszHistory); pszHistory += _tcslen(pszHistory)+1; } } } // Tasks int nGroup = 0; const Settings::CommandTasks* pGrp = NULL; while ((pGrp = gpSet->CmdTaskGet(nGroup++))) { pDlg->AddCommandList(pGrp->pszName); } } return 0; case UM_USER_CONTROLS: { if (SendDlgItemMessage(hDlg, rbCurrentUser, BM_GETCHECK, 0, 0)) { EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), TRUE); //BOOL lbText = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) == 0; EnableWindow(GetDlgItem(hDlg, tRunAsUser), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), FALSE); } else { if (SendDlgItemMessage(hDlg, tRunAsUser, CB_GETCOUNT, 0, 0) == 0) { DWORD dwLevel = 3, dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0; NET_API_STATUS nStatus; USER_INFO_3 *info = NULL; nStatus = ::NetUserEnum(NULL, dwLevel, FILTER_NORMAL_ACCOUNT, (PBYTE*) & info, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nStatus == NERR_Success) { wchar_t *pszAdmin = NULL, *pszLikeAdmin = NULL, *pszOtherUser = NULL; for (DWORD i = 0; i < dwEntriesRead; ++i) { // usri3_logon_server "\\*" wchar_t * if (!(info[i].usri3_flags & UF_ACCOUNTDISABLE) && info[i].usri3_name && *info[i].usri3_name) { SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)info[i].usri3_name); if (info[i].usri3_priv == 2/*USER_PRIV_ADMIN*/) { if (!pszAdmin && (info[i].usri3_user_id == 500)) pszAdmin = lstrdup(info[i].usri3_name); else if (!pszLikeAdmin && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0)) pszLikeAdmin = lstrdup(info[i].usri3_name); } else if (!pszOtherUser && (info[i].usri3_priv == 1/*USER_PRIV_USER*/) && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0)) { pszOtherUser = lstrdup(info[i].usri3_name); } } } if (GetWindowTextLength(GetDlgItem(hDlg, tRunAsUser)) == 0) { // Try to suggest "Administrator" account SetDlgItemText(hDlg, tRunAsUser, pszAdmin ? pszAdmin : pszLikeAdmin ? pszLikeAdmin : pszOtherUser ? pszOtherUser : pDlg->ms_CurUser); } ::NetApiBufferFree(info); SafeFree(pszAdmin); SafeFree(pszLikeAdmin); } else { // Добавить хотя бы текущего SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)pDlg->ms_CurUser); } } EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsUser), TRUE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), TRUE); } if (wParam == rbAnotherUser) SetFocus(GetDlgItem(hDlg, tRunAsUser)); } return 0; case WM_SYSCOMMAND: switch (LOWORD(wParam)) { case ID_RESETCMDHISTORY: // Подтверждение спросит ResetCmdHistory if (gpSetCls->ResetCmdHistory(hDlg)) { wchar_t* pszCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_RESETCONTENT, 0,0); SendMessage(hDlg, UM_FILL_CMDLIST, FALSE, 0); if (pszCmd) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); free(pszCmd); } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; case ID_STORECMDHISTORY: if (MsgBox(gpSet->isSaveCmdHistory ? L"Do you want to disable history?" : L"Do you want to enable history?", MB_YESNO|MB_ICONQUESTION, NULL, hDlg) == IDYES) { gpSetCls->SetSaveCmdHistory(!gpSet->isSaveCmdHistory); HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); CheckMenuItem(hSysMenu, ID_STORECMDHISTORY, MF_BYCOMMAND|(gpSet->isSaveCmdHistory ? MF_CHECKED : 0)); } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_CHOOSE: { wchar_t *pszFilePath = SelectFile(L"Choose program to run", NULL, hDlg, L"Executables (*.exe)\0*.exe\0All files (*.*)\0*.*\0\0", true, false, false); if (pszFilePath) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszFilePath); SafeFree(pszFilePath); } return 1; } case IDC_CHOOSE_DIR: { wchar_t* pszDefFolder = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszFolder = SelectFolder(L"Choose startup directory", pszDefFolder, hDlg, false, false); if (pszFolder) { SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszFolder); SafeFree(pszFolder); } SafeFree(pszDefFolder); return 1; } case cbRunAsAdmin: { // BCM_SETSHIELD = 5644 BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (gOSVer.dwMajorVersion >= 6) { SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs && (pDlg->mp_Args->aRecreate != cra_EditTab)); } if (bRunAs) { CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser); CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); } return 1; } case rbCurrentUser: case rbAnotherUser: case cbRunAsRestricted: { RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0); return 1; } case rbRecreateSplitNone: case rbRecreateSplit2Right: case rbRecreateSplit2Bottom: { RConStartArgs* pArgs = pDlg->mp_Args; switch (LOWORD(wParam)) { case rbRecreateSplitNone: pArgs->eSplit = RConStartArgs::eSplitNone; break; case rbRecreateSplit2Right: pArgs->eSplit = RConStartArgs::eSplitHorz; break; case rbRecreateSplit2Bottom: pArgs->eSplit = RConStartArgs::eSplitVert; break; } EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); if (pArgs->eSplit != pArgs->eSplitNone) SetFocus(GetDlgItem(hDlg, tRecreateSplit)); return 1; } case IDC_START: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); SafeFree(pArgs->pszUserName); SafeFree(pArgs->pszDomain); //SafeFree(pArgs->pszUserPassword); if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0)) { pArgs->RunAsRestricted = crb_Off; pArgs->pszUserName = GetDlgItemText(hDlg, tRunAsUser); if (pArgs->pszUserName) { //pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword); // Попытаться проверить правильность введенного пароля и возможность запуска bool bCheckPwd = pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword)); DWORD nErr = bCheckPwd ? 0 : GetLastError(); if (!bCheckPwd) { DisplayLastError(L"Invalid user name or password was specified!", nErr, MB_ICONSTOP, NULL, hDlg); return 1; } } } else { pArgs->RunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; } // Vista+ (As Admin...) pArgs->RunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; // StartupDir (may be specified as argument) wchar_t* pszDir = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL; LPCWSTR pszDirResult = pszExpand ? pszExpand : pszDir; // Another user? We may fail with access denied. Check only for "current user" account if (!pArgs->pszUserName && pszDirResult && *pszDirResult && !DirectoryExists(pszDirResult)) { wchar_t* pszErrInfo = lstrmerge(L"Specified directory does not exists!\n", pszDirResult, L"\n" L"Do you want to choose another directory?\n\n"); DWORD nErr = GetLastError(); int iDirBtn = DisplayLastError(pszErrInfo, nErr, MB_ICONEXCLAMATION|MB_YESNO, NULL, hDlg); if (iDirBtn == IDYES) { SafeFree(pszDir); SafeFree(pszExpand); SafeFree(pszErrInfo); return 1; } // User want to run "as is". Most likely it will fail, but who knows... } SafeFree(pArgs->pszStartupDir); pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir; if (pszExpand) { SafeFree(pszDir) } // Command // pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода SafeFree(pArgs->pszSpecialCmd); // GetDlgItemText выделяет память через calloc pArgs->pszSpecialCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); if (pArgs->pszSpecialCmd) gpSet->HistoryAdd(pArgs->pszSpecialCmd); if ((pArgs->aRecreate != cra_RecreateTab) && (pArgs->aRecreate != cra_EditTab)) { if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0)) pArgs->aRecreate = cra_CreateWindow; else pArgs->aRecreate = cra_CreateTab; } if (((pArgs->aRecreate == cra_CreateTab) || (pArgs->aRecreate == cra_EditTab)) && (pArgs->eSplit != RConStartArgs::eSplitNone)) { BOOL bOk = FALSE; int nPercent = GetDlgItemInt(hDlg, tRecreateSplit, &bOk, FALSE); if (bOk && (nPercent >= 1) && (nPercent <= 99)) { pArgs->nSplitValue = (100-nPercent) * 10; } //pArgs->nSplitPane = 0; Сбрасывать не будем? } pDlg->mn_DlgRc = IDC_START; EndDialog(hDlg, IDC_START); return 1; } case IDC_TERMINATE: pDlg->mn_DlgRc = IDC_TERMINATE; EndDialog(hDlg, IDC_TERMINATE); return 1; case IDCANCEL: pDlg->mn_DlgRc = IDCANCEL; EndDialog(hDlg, IDCANCEL); return 1; } } else if ((HIWORD(wParam) == EN_SETFOCUS) && lParam) { switch (LOWORD(wParam)) { case tRecreateSplit: case tRunAsPassword: PostMessage((HWND)lParam, EM_SETSEL, 0, SendMessage((HWND)lParam, WM_GETTEXTLENGTH, 0,0)); break; } } break; default: return 0; }