void wf_resize_window(wfContext* wfc) { if (wfc->fullscreen) { if(wfc->instance->settings->UseMultimon) { int x = GetSystemMetrics(SM_XVIRTUALSCREEN); int y = GetSystemMetrics(SM_YVIRTUALSCREEN); int w = GetSystemMetrics(SM_CXVIRTUALSCREEN); int h = GetSystemMetrics(SM_CYVIRTUALSCREEN); SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP); SetWindowPos(wfc->hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED); } else { SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP); SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED); } } else if (!wfc->instance->settings->Decorations) { SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CHILD); /* Now resize to get full canvas size and room for caption and borders */ SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, wfc->width, wfc->height, SWP_FRAMECHANGED); wf_update_canvas_diff(wfc); SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, wfc->width + wfc->diff.x, wfc->height + wfc->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); } else { SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX); if (!wfc->client_height) wfc->client_height = wfc->height; if (!wfc->client_width) wfc->client_width = wfc->width; if (!wfc->client_x) wfc->client_x = 10; if (!wfc->client_y) wfc->client_y = 10; wf_update_canvas_diff(wfc); /* Now resize to get full canvas size and room for caption and borders */ SetWindowPos(wfc->hwnd, HWND_TOP, wfc->client_x, wfc->client_y, wfc->client_width + wfc->diff.x, wfc->client_height + wfc->diff.y, 0 /*SWP_FRAMECHANGED*/); //wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height); } wf_update_offset(wfc); }
void wf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e) { RECT rect; HMENU hMenu; wfContext* wfc = (wfContext*) context; // specific processing here switch (e->id) { case FreeRDP_SmartSizing: fprintf(stderr, "SmartSizing changed.\n"); if (!context->settings->SmartSizing && (wfc->client_width > context->settings->DesktopWidth || wfc->client_height > context->settings->DesktopHeight)) { GetWindowRect(wfc->hwnd, &rect); SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, MIN(wfc->client_width + wfc->offset_x, rect.right - rect.left), MIN(wfc->client_height + wfc->offset_y, rect.bottom - rect.top), SWP_NOMOVE | SWP_FRAMECHANGED); wf_update_canvas_diff(wfc); } hMenu = GetSystemMenu(wfc->hwnd, FALSE); CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, context->settings->SmartSizing); wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height); GetClientRect(wfc->hwnd, &rect); InvalidateRect(wfc->hwnd, &rect, TRUE); break; case FreeRDP_ConnectionType: fprintf(stderr, "ConnectionType changed.\n"); freerdp_set_connection_type(wfc->instance->settings, wfc->instance->settings->ConnectionType); break; } }
void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, UINT32 client_height) { if (wfc->disablewindowtracking) return; // prevent infinite message loop wfc->disablewindowtracking = TRUE; if (wfc->instance->settings->SmartSizing) { wfc->xCurrentScroll = 0; wfc->yCurrentScroll = 0; if (wfc->xScrollVisible || wfc->yScrollVisible) { if (ShowScrollBar(wfc->hwnd, SB_BOTH, FALSE)) { wfc->xScrollVisible = FALSE; wfc->yScrollVisible = FALSE; } } } else { SCROLLINFO si; BOOL horiz = wfc->xScrollVisible; BOOL vert = wfc->yScrollVisible;; if (!horiz && client_width < wfc->instance->settings->DesktopWidth) { horiz = TRUE; } else if (horiz && client_width >= wfc->instance->settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/) { horiz = FALSE; } if (!vert && client_height < wfc->instance->settings->DesktopHeight) { vert = TRUE; } else if (vert && client_height >= wfc->instance->settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/) { vert = FALSE; } if (horiz == vert && (horiz != wfc->xScrollVisible && vert != wfc->yScrollVisible)) { if (ShowScrollBar(wfc->hwnd, SB_BOTH, horiz)) { wfc->xScrollVisible = horiz; wfc->yScrollVisible = vert; } } if (horiz != wfc->xScrollVisible) { if (ShowScrollBar(wfc->hwnd, SB_HORZ, horiz)) { wfc->xScrollVisible = horiz; } } if (vert != wfc->yScrollVisible) { if (ShowScrollBar(wfc->hwnd, SB_VERT, vert)) { wfc->yScrollVisible = vert; } } if (horiz) { // The horizontal scrolling range is defined by // (bitmap_width) - (client_width). The current horizontal // scroll value remains within the horizontal scrolling range. wfc->xMaxScroll = MAX(wfc->instance->settings->DesktopWidth - client_width, 0); wfc->xCurrentScroll = MIN(wfc->xCurrentScroll, wfc->xMaxScroll); si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMin = wfc->xMinScroll; si.nMax = wfc->instance->settings->DesktopWidth; si.nPage = client_width; si.nPos = wfc->xCurrentScroll; SetScrollInfo(wfc->hwnd, SB_HORZ, &si, TRUE); } if (vert) { // The vertical scrolling range is defined by // (bitmap_height) - (client_height). The current vertical // scroll value remains within the vertical scrolling range. wfc->yMaxScroll = MAX(wfc->instance->settings->DesktopHeight - client_height, 0); wfc->yCurrentScroll = MIN(wfc->yCurrentScroll, wfc->yMaxScroll); si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; si.nMin = wfc->yMinScroll; si.nMax = wfc->instance->settings->DesktopHeight; si.nPage = client_height; si.nPos = wfc->yCurrentScroll; SetScrollInfo(wfc->hwnd, SB_VERT, &si, TRUE); } } wfc->disablewindowtracking = FALSE; wf_update_canvas_diff(wfc); }
LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC hdc; LONG ptr; wfContext* wfc; int x, y, w, h; PAINTSTRUCT ps; rdpInput* input; BOOL processed; RECT windowRect; RECT clientRect; MINMAXINFO* minmax; SCROLLINFO si; processed = TRUE; ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA); wfc = (wfContext*) ptr; if (wfc != NULL) { input = wfc->instance->input; switch (Msg) { case WM_MOVE: if (!wfc->disablewindowtracking) { int x = (int)(short) LOWORD(lParam); int y = (int)(short) HIWORD(lParam); wfc->client_x = x; wfc->client_y = y; } break; case WM_GETMINMAXINFO: if (wfc->instance->settings->SmartSizing) { processed = FALSE; } else { // Set maximum window size for resizing minmax = (MINMAXINFO*) lParam; wf_update_canvas_diff(wfc); if (!wfc->fullscreen) { // add window decoration minmax->ptMaxTrackSize.x = wfc->width + wfc->diff.x; minmax->ptMaxTrackSize.y = wfc->height + wfc->diff.y; } } break; case WM_SIZING: wf_sizing(wfc, lParam, wParam); break; case WM_SIZE: GetWindowRect(wfc->hwnd, &windowRect); if (!wfc->fullscreen) { wfc->client_width = LOWORD(lParam); wfc->client_height = HIWORD(lParam); wfc->client_x = windowRect.left; wfc->client_y = windowRect.top; } wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam)); // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect. if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen) SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); break; case WM_EXITSIZEMOVE: wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height); break; case WM_ERASEBKGND: /* Say we handled it - prevents flickering */ return (LRESULT) 1; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); x = ps.rcPaint.left; y = ps.rcPaint.top; w = ps.rcPaint.right - ps.rcPaint.left + 1; h = ps.rcPaint.bottom - ps.rcPaint.top + 1; wf_scale_blt(wfc, hdc, x, y, w, h, wfc->primary->hdc, x - wfc->offset_x + wfc->xCurrentScroll, y - wfc->offset_y + wfc->yCurrentScroll, SRCCOPY); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN: wf_scale_mouse_event(wfc, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_LBUTTONUP: wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_RBUTTONDOWN: wf_scale_mouse_event(wfc, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_RBUTTONUP: wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_MOUSEMOVE: wf_scale_mouse_event(wfc, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_MOUSEWHEEL: wf_event_process_WM_MOUSEWHEEL(wfc, hWnd, Msg, wParam, lParam); break; case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT) SetCursor(wfc->cursor); else DefWindowProc(hWnd, Msg, wParam, lParam); break; case WM_HSCROLL: { int xDelta; // xDelta = new_pos - current_pos int xNewPos; // new position int yDelta = 0; switch (LOWORD(wParam)) { // User clicked the scroll bar shaft left of the scroll box. case SB_PAGEUP: xNewPos = wfc->xCurrentScroll - 50; break; // User clicked the scroll bar shaft right of the scroll box. case SB_PAGEDOWN: xNewPos = wfc->xCurrentScroll + 50; break; // User clicked the left arrow. case SB_LINEUP: xNewPos = wfc->xCurrentScroll - 5; break; // User clicked the right arrow. case SB_LINEDOWN: xNewPos = wfc->xCurrentScroll + 5; break; // User dragged the scroll box. case SB_THUMBPOSITION: xNewPos = HIWORD(wParam); // user is dragging the scrollbar case SB_THUMBTRACK : xNewPos = HIWORD(wParam); break; default: xNewPos = wfc->xCurrentScroll; } // New position must be between 0 and the screen width. xNewPos = MAX(0, xNewPos); xNewPos = MIN(wfc->xMaxScroll, xNewPos); // If the current position does not change, do not scroll. if (xNewPos == wfc->xCurrentScroll) break; // Determine the amount scrolled (in pixels). xDelta = xNewPos - wfc->xCurrentScroll; // Reset the current scroll position. wfc->xCurrentScroll = xNewPos; // Scroll the window. (The system repaints most of the // client area when ScrollWindowEx is called; however, it is // necessary to call UpdateWindow in order to repaint the // rectangle of pixels that were invalidated.) ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL, SW_INVALIDATE); UpdateWindow(wfc->hwnd); // Reset the scroll bar. si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = wfc->xCurrentScroll; SetScrollInfo(wfc->hwnd, SB_HORZ, &si, TRUE); } break; case WM_VSCROLL: { int xDelta = 0; int yDelta; // yDelta = new_pos - current_pos int yNewPos; // new position switch (LOWORD(wParam)) { // User clicked the scroll bar shaft above the scroll box. case SB_PAGEUP: yNewPos = wfc->yCurrentScroll - 50; break; // User clicked the scroll bar shaft below the scroll box. case SB_PAGEDOWN: yNewPos = wfc->yCurrentScroll + 50; break; // User clicked the top arrow. case SB_LINEUP: yNewPos = wfc->yCurrentScroll - 5; break; // User clicked the bottom arrow. case SB_LINEDOWN: yNewPos = wfc->yCurrentScroll + 5; break; // User dragged the scroll box. case SB_THUMBPOSITION: yNewPos = HIWORD(wParam); break; // user is dragging the scrollbar case SB_THUMBTRACK : yNewPos = HIWORD(wParam); break; default: yNewPos = wfc->yCurrentScroll; } // New position must be between 0 and the screen height. yNewPos = MAX(0, yNewPos); yNewPos = MIN(wfc->yMaxScroll, yNewPos); // If the current position does not change, do not scroll. if (yNewPos == wfc->yCurrentScroll) break; // Determine the amount scrolled (in pixels). yDelta = yNewPos - wfc->yCurrentScroll; // Reset the current scroll position. wfc->yCurrentScroll = yNewPos; // Scroll the window. (The system repaints most of the // client area when ScrollWindowEx is called; however, it is // necessary to call UpdateWindow in order to repaint the // rectangle of pixels that were invalidated.) ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL, SW_INVALIDATE); UpdateWindow(wfc->hwnd); // Reset the scroll bar. si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = wfc->yCurrentScroll; SetScrollInfo(wfc->hwnd, SB_VERT, &si, TRUE); } break; case WM_SYSCOMMAND: { if (wParam == SYSCOMMAND_ID_SMARTSIZING) { HMENU hMenu = GetSystemMenu(wfc->hwnd, FALSE); freerdp_set_param_bool(wfc->instance->settings, FreeRDP_SmartSizing, !wfc->instance->settings->SmartSizing); CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfc->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED); } else { processed = FALSE; } } break; default: processed = FALSE; break; } } else { processed = FALSE; } if (processed) return 0; switch (Msg) { case WM_DESTROY: PostQuitMessage(WM_QUIT); break; case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT) SetCursor(wfc->hDefaultCursor); else DefWindowProc(hWnd, Msg, wParam, lParam); break; case WM_SETFOCUS: DEBUG_KBD("getting focus %X", hWnd); g_focus_hWnd = hWnd; break; case WM_KILLFOCUS: if (g_focus_hWnd == hWnd && wfc && !wfc->fullscreen) { DEBUG_KBD("loosing focus %X", hWnd); g_focus_hWnd = NULL; } break; case WM_ACTIVATE: { int activate = (int)(short) LOWORD(wParam); if (activate != WA_INACTIVE) { g_focus_hWnd = hWnd; } else { g_focus_hWnd = NULL; } } default: return DefWindowProc(hWnd, Msg, wParam, lParam); break; } return 0; }