static void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) { MSG msg; ScreenToWindow(hwnd, &pt); SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt ); do { if (!GetMessageW( &msg, 0, 0, 0 )) break; if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue; if (msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE || (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER)) { pt.x = GET_X_LPARAM(msg.lParam); pt.y = GET_Y_LPARAM(msg.lParam); ClientToScreen(hwnd, &pt); ScreenToWindow(hwnd, &pt); SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt ); } else { TranslateMessage( &msg ); DispatchMessageW( &msg ); } if (!IsWindow( hwnd )) { ReleaseCapture(); break; } } while (msg.message != WM_LBUTTONUP && GetCapture() == hwnd); }
/*********************************************************************** * NC_HandleNCRButtonDown * * Handle a WM_NCRBUTTONDOWN message. Called from DefWindowProc(). */ LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) { MSG msg; INT hittest = wParam; switch (hittest) { case HTCAPTION: case HTSYSMENU: if (!GetSystemMenu( hwnd, FALSE )) break; SetCapture( hwnd ); for (;;) { if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break; if (CallMsgFilterW( &msg, MSGF_MAX )) continue; if (msg.message == WM_RBUTTONUP) { hittest = DefWndNCHitTest( hwnd, msg.pt ); break; } if (hwnd != GetCapture()) return 0; } ReleaseCapture(); if (hittest == HTCAPTION || hittest == HTSYSMENU) { ERR("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg.pt.x,msg.pt.y),msg.lParam,lParam); SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, msg.lParam ); } break; } return 0; }
/*********************************************************************** * ScrollTrackScrollBar * * Track a mouse button press on a scroll-bar. * pt is in screen-coordinates for non-client scroll bars. */ VOID FASTCALL ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt) { MSG Msg; UINT XOffset = 0, YOffset = 0; if (SBType != SB_CTL) { // Used with CMD mouse tracking. PWND pwnd = ValidateHwnd(Wnd); if (!pwnd) return; XOffset = pwnd->rcClient.left - pwnd->rcWindow.left; YOffset = pwnd->rcClient.top - pwnd->rcWindow.top; // RECT rect; // WIN_GetRectangles( Wnd, COORDS_CLIENT, &rect, NULL ); ScreenToClient(Wnd, &Pt); // Pt.x -= rect.left; // Pt.y -= rect.top; Pt.x += XOffset; Pt.y += YOffset; } IntScrollHandleScrollEvent(Wnd, SBType, WM_LBUTTONDOWN, Pt); do { if (!GetMessageW(&Msg, 0, 0, 0)) break; if (CallMsgFilterW(&Msg, MSGF_SCROLLBAR)) continue; if ( Msg.message == WM_LBUTTONUP || Msg.message == WM_MOUSEMOVE || (Msg.message == WM_SYSTIMER && Msg.wParam == SCROLL_TIMER)) { Pt.x = LOWORD(Msg.lParam) + XOffset; Pt.y = HIWORD(Msg.lParam) + YOffset; IntScrollHandleScrollEvent(Wnd, SBType, Msg.message, Pt); } else { TranslateMessage(&Msg); DispatchMessageW(&Msg); } if (!IsWindow(Wnd)) { ReleaseCapture(); break; } } while (Msg.message != WM_LBUTTONUP && GetCapture() == Wnd); }
VOID DefWndDoButton(HWND hWnd, WPARAM wParam) { MSG Msg; HDC WindowDC; BOOL Pressed = TRUE, OldState; WPARAM SCMsg; HMENU hSysMenu; ULONG ButtonType; DWORD Style; UINT MenuState; Style = GetWindowLongPtrW(hWnd, GWL_STYLE); switch (wParam) { case HTCLOSE: hSysMenu = GetSystemMenu(hWnd, FALSE); MenuState = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */ if (!(Style & WS_SYSMENU) || (MenuState & (MF_GRAYED|MF_DISABLED)) || (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_NOCLOSE)) return; ButtonType = DFCS_CAPTIONCLOSE; SCMsg = SC_CLOSE; break; case HTMINBUTTON: if (!(Style & WS_MINIMIZEBOX)) return; ButtonType = DFCS_CAPTIONMIN; SCMsg = ((Style & WS_MINIMIZE) ? SC_RESTORE : SC_MINIMIZE); break; case HTMAXBUTTON: if (!(Style & WS_MAXIMIZEBOX)) return; ButtonType = DFCS_CAPTIONMAX; SCMsg = ((Style & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE); break; default: ASSERT(FALSE); return; } /* * FIXME: Not sure where to do this, but we must flush the pending * window updates when someone clicks on the close button and at * the same time the window is overlapped with another one. This * looks like a good place for now... */ UpdateWindow(hWnd); WindowDC = GetWindowDC(hWnd); UserDrawCaptionButtonWnd(hWnd, WindowDC, TRUE, ButtonType); SetCapture(hWnd); for (;;) { if (GetMessageW(&Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST) <= 0) break; if (CallMsgFilterW( &Msg, MSGF_MAX )) continue; if (Msg.message == WM_LBUTTONUP) break; if (Msg.message != WM_MOUSEMOVE) continue; OldState = Pressed; Pressed = (DefWndNCHitTest(hWnd, Msg.pt) == wParam); if (Pressed != OldState) UserDrawCaptionButtonWnd(hWnd, WindowDC, Pressed, ButtonType); } if (Pressed) UserDrawCaptionButtonWnd(hWnd, WindowDC, FALSE, ButtonType); ReleaseCapture(); ReleaseDC(hWnd, WindowDC); if (Pressed) SendMessageW(hWnd, WM_SYSCOMMAND, SCMsg, MAKELONG(Msg.pt.x,Msg.pt.y)); }
LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam ) { HWND hwnd, hwndActive; MSG msg; BOOL Esc = FALSE; INT Count = 0; WCHAR Text[1024]; // Already in the loop. if (switchdialog) return 0; hwndActive = GetActiveWindow(); // Nothing is active so exit. if (!hwndActive) return 0; // Capture current active window. SetCapture( hwndActive ); switch (lParam) { case VK_TAB: if( !CreateSwitcherWindow(User32Instance) ) goto Exit; if( !GetDialogFont() ) goto Exit; ProcessHotKey(); break; case VK_ESCAPE: windowCount = 0; Count = 0; EnumWindowsZOrder(EnumerateCallback, 0); if (windowCount < 2) goto Exit; if (wParam == SC_NEXTWINDOW) Count = 1; else { if (windowCount == 2) Count = 0; else Count = windowCount - 1; } TRACE("DoAppSwitch VK_ESCAPE 1 Count %d windowCount %d\n",Count,windowCount); hwnd = windowList[Count]; GetWindowTextW(hwnd, Text, 1023); TRACE("[ATbot] Switching to 0x%08x (%ls)\n", hwnd, Text); MakeWindowActive(hwnd); Esc = TRUE; break; default: goto Exit; } // Main message loop: while (1) { for (;;) { if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE )) { if (!CallMsgFilterW( &msg, MSGF_NEXTWINDOW )) break; /* remove the message from the queue */ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); } else WaitMessage(); } switch (msg.message) { case WM_KEYUP: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (msg.wParam == VK_MENU) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_RETURN) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_ESCAPE) { TRACE("DoAppSwitch VK_ESCAPE 2\n"); CompleteSwitch(FALSE); } goto Exit; //break; } case WM_SYSKEYDOWN: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (HIWORD(msg.lParam) & KF_ALTDOWN) { INT Shift; if ( msg.wParam == VK_TAB ) { if (Esc) break; Shift = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW; if (Shift == SC_NEXTWINDOW) { selectedWindow = (selectedWindow + 1)%windowCount; } else { selectedWindow = selectedWindow - 1; if (selectedWindow < 0) selectedWindow = windowCount - 1; } InvalidateRect(switchdialog, NULL, TRUE); } else if ( msg.wParam == VK_ESCAPE ) { if (!Esc) break; if (windowCount < 2) goto Exit; if (wParam == SC_NEXTWINDOW) { Count = (Count + 1)%windowCount; } else { Count--; if (Count < 0) Count = windowCount - 1; } hwnd = windowList[Count]; GetWindowTextW(hwnd, Text, 1023); MakeWindowActive(hwnd); } } break; } case WM_LBUTTONUP: PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); ProcessMouseMessage(msg.message, msg.lParam); goto Exit; default: if (PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE )) { TranslateMessage(&msg); DispatchMessageW(&msg); } break; } } Exit: ReleaseCapture(); if (switchdialog) DestroyWindow(switchdialog); switchdialog = NULL; selectedWindow = 0; windowCount = 0; return 0; }
LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam ) { HWND hwndActive; MSG msg; // FIXME: Is loading timing OK? LoadCoolSwitchSettings(); if (!CoolSwitch) return 0; // Already in the loop. if (switchdialog || Esc) return 0; hwndActive = GetActiveWindow(); // Nothing is active so exit. if (!hwndActive) return 0; if (lParam == VK_ESCAPE) { Esc = TRUE; windowCount = 0; EnumWindowsZOrder(EnumerateCallback, 0); if (windowCount < 2) return 0; RotateTasks(GetAsyncKeyState(VK_SHIFT) < 0); hwndActive = GetActiveWindow(); if (hwndActive == NULL) { Esc = FALSE; return 0; } } // Capture current active window. SetCapture( hwndActive ); switch (lParam) { case VK_TAB: if( !CreateSwitcherWindow(User32Instance) ) goto Exit; if( !GetDialogFont() ) goto Exit; if( !ProcessHotKey() ) goto Exit; break; case VK_ESCAPE: break; default: goto Exit; } // Main message loop: while (1) { for (;;) { if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE )) { if (!CallMsgFilterW( &msg, MSGF_NEXTWINDOW )) break; /* remove the message from the queue */ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); } else WaitMessage(); } switch (msg.message) { case WM_KEYUP: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (msg.wParam == VK_MENU) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_RETURN) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_ESCAPE) { TRACE("DoAppSwitch VK_ESCAPE 2\n"); CompleteSwitch(FALSE); } goto Exit; //break; } case WM_SYSKEYDOWN: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (HIWORD(msg.lParam) & KF_ALTDOWN) { if ( msg.wParam == VK_TAB ) { if (Esc) break; if (GetKeyState(VK_SHIFT) < 0) { MoveLeft(); } else { MoveRight(); } } else if ( msg.wParam == VK_ESCAPE ) { if (!Esc) break; RotateTasks(GetKeyState(VK_SHIFT) < 0); } else if ( msg.wParam == VK_LEFT ) { MoveLeft(); } else if ( msg.wParam == VK_RIGHT ) { MoveRight(); } else if ( msg.wParam == VK_UP ) { MoveUp(); } else if ( msg.wParam == VK_DOWN ) { MoveDown(); } } break; } case WM_LBUTTONUP: PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); ProcessMouseMessage(msg.message, msg.lParam); goto Exit; default: if (PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE )) { TranslateMessage(&msg); DispatchMessageW(&msg); } break; } } Exit: ReleaseCapture(); if (switchdialog) DestroyWindow(switchdialog); if (Esc) DestroyAppWindows(); switchdialog = NULL; selectedWindow = 0; windowCount = 0; Esc = FALSE; return 0; }