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; }
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; }