2
0
forked from Ivasoft/DSView

Optimize the operation of dragging the programsbetween two screens

This commit is contained in:
dreamsourcelabTAI
2024-02-23 14:32:32 +08:00
parent 4c66cb09b1
commit bebb913fc9
4 changed files with 105 additions and 80 deletions

View File

@@ -75,7 +75,8 @@ MainFrame::MainFrame()
_is_resize_ready = false;
_parentNativeWidget = NULL;
_mainWindow = NULL;
_is_max_status = false;
_is_max_status = false;
_move_start_screen = NULL;
AppControl::Instance()->SetTopWindow(this);
@@ -91,6 +92,8 @@ MainFrame::MainFrame()
_is_native_title = false;
#endif
// setMinimumWidth(MainWindow::Min_Width);
// setMinimumHeight(MainWindow::Min_Height);
@@ -229,7 +232,6 @@ void MainFrame::AttachNativeWindow()
setVisible(true);
if (_initWndInfo.isMaxSize){
_initWndInfo.isMaxSize = false;
showMaximized();
}
});
@@ -272,72 +274,26 @@ bool MainFrame::ParentIsMaxsized()
void MainFrame::MoveBegin()
{
// dsv_info("Move begin.");
#ifdef _WIN32
if (_parentNativeWidget != NULL)
{
POINT p;
GetCursorPos(&p);
HMONITOR hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEX inf;
inf.cbSize = sizeof(inf);
if (GetMonitorInfo(hMonitor, &inf)) {
int x = inf.rcMonitor.left;
int y = inf.rcMonitor.top;
int w = inf.rcMonitor.right - inf.rcMonitor.left;
int h = inf.rcMonitor.bottom - inf.rcMonitor.top;
_move_screen_region = QRect(x, y, w, h);
}
}
if (_parentNativeWidget != NULL){
_parentNativeWidget->SetMovingFlag(true);
_move_start_screen = _parentNativeWidget->GetPointScreen();
}
#endif
}
void MainFrame::MoveEnd()
{
// dsv_info("Move end.");
{
#ifdef _WIN32
if (_parentNativeWidget != NULL){
auto scr = _parentNativeWidget->GetPointScreen();
if (scr != _move_start_screen){
_parentNativeWidget->UpdateChildDpi();
}
POINT p;
GetCursorPos(&p);
HMONITOR hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEX inf;
inf.cbSize = sizeof(inf);
if (GetMonitorInfo(hMonitor, &inf)) {
int x = inf.rcMonitor.left;
int y = inf.rcMonitor.top;
int w = inf.rcMonitor.right - inf.rcMonitor.left;
int h = inf.rcMonitor.bottom - inf.rcMonitor.top;
// End at the same screen.
if (x == _move_screen_region.left() && w == _move_screen_region.width()){
dsv_info("Move to the same screen.");
return;
}
}
dsv_info("Move to another screen.");
QRect rc = GetFormRegion();
SetParent((HWND)winId(), NULL);
QEvent e(QEvent::EmbeddingControl);
QApplication::sendEvent(this, &e);
_parentNativeWidget->SetChildWidget(NULL);
setGeometry(rc.left(), rc.top(), rc.width(), rc.height());
this->AttachNativeWindow();
}
_parentNativeWidget->ResizeChild();
_parentNativeWidget->SetMovingFlag(false);
}
#endif
}
@@ -561,7 +517,7 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
pt.setX(p.x);
pt.setY(p.y);
#else
pt = mouse_event->globalPos();
pt = event->globalPos();
#endif
int datX = pt.x() - _clickPos.x();
int datY = pt.y() - _clickPos.y();
@@ -666,7 +622,7 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
_clickPos.setX(p.x);
_clickPos.setY(p.y);
#else
_clickPos = mouse_event->globalPos();
_clickPos = event->globalPos();
#endif
_dragStartRegion = GetFormRegion();
@@ -810,8 +766,8 @@ void MainFrame::SetFormRegion(int x, int y, int w, int h)
setGeometry(x, y, w, h);
}
QRect MainFrame::GetFormRegion()
{
QRect MainFrame::GetFormRegion()
{
QRect rc;
#ifdef _WIN32
@@ -834,7 +790,7 @@ void MainFrame::SetFormRegion(int x, int y, int w, int h)
#endif
return rc;
}
}
void MainFrame::ReadSettings()
{

View File

@@ -165,8 +165,8 @@ private:
FormRegion _normalRegion;
bool _is_max_status;
QPoint _clickPos;
QRect _dragStartRegion;
QRect _move_screen_region;
QRect _dragStartRegion;
QScreen *_move_start_screen;
};
} // namespace pv

View File

@@ -21,10 +21,12 @@
*/
#include "winnativewidget.h"
#include "WinNativeWidget.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QGuiApplication>
#include <QWindow>
#include <dwmapi.h>
#include <assert.h>
#include <QString>
@@ -40,8 +42,10 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, cons
_childWindow = nullptr;
childWidget = nullptr;
_hWnd = NULL;
_event_callback = NULL;
_is_moving = false;
HBRUSH windowBackground = CreateSolidBrush(RGB(255, 255, 255));
HBRUSH windowBackground = CreateSolidBrush(RGB(0, 0, 0));
HINSTANCE hInstance = GetModuleHandle(nullptr);
WNDCLASSEX wcx = { 0 };
@@ -146,27 +150,30 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam
case WM_SIZE:
{
if (self->_childWindow != NULL){
self->ResizeChild(false);
self->ResizeChild();
}
break;
}
case WM_DPICHANGED:
if (self->_is_moving == false){
self->UpdateChildDpi();
self->ResizeChild();
dsv_info("Dpi was changed.");
}
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void WinNativeWidget::ResizeChild(bool bManual)
void WinNativeWidget::ResizeChild()
{
if (_childWindow != NULL){
RECT rc;
GetClientRect(_hWnd, &rc);
int k = QApplication::desktop()->screen()->devicePixelRatio();
k = childWidget->window()->devicePixelRatio();
int w = rc.right;
int h = rc.bottom;
@@ -180,9 +187,8 @@ void WinNativeWidget::ResizeChild(bool bManual)
}
childWidget->adjustSize();
MoveWindow(_childWindow, 0, 0, w , h , 1 );
// dsv_info("resize child, w:%d, h:%d, k1:%d, k2:%d", w / k, h / k, k1, k2);
MoveWindow(_childWindow, 0, 0, w , h , 1);
}
}
@@ -229,4 +235,45 @@ void WinNativeWidget::ShowMin()
}
}
void WinNativeWidget::UpdateChildDpi()
{
QScreen *scr = screenFromWindow(_hWnd);
if (scr != NULL && childWidget != NULL){
childWidget->windowHandle()->setScreen(scr);
}
}
QScreen* WinNativeWidget::screenFromWindow(HWND hwnd)
{
if (hwnd == NULL)
return NULL;
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO monitor_info;
memset(&monitor_info, 0, sizeof(MONITORINFO));
monitor_info.cbSize = sizeof(MONITORINFO);
GetMonitorInfoW(monitor, &monitor_info);
QPoint top_left;
top_left.setX(monitor_info.rcMonitor.left);
top_left.setY(monitor_info.rcMonitor.top);
for (QScreen *screen : QGuiApplication::screens())
{
if (screen->geometry().topLeft() == top_left)
{
return screen;
}
}
return NULL;
}
QScreen* WinNativeWidget::GetPointScreen()
{
return screenFromWindow(_hWnd);
}
}

View File

@@ -29,8 +29,18 @@
#include <Windowsx.h>
#include <QWidget>
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
namespace pv {
class IParentNaitveEventCallback
{
public:
virtual void OnParentNativeEvent(int msg)=0;
};
class WinNativeWidget
{
public:
@@ -55,12 +65,24 @@ public:
void ShowMax();
void ShowMin();
void ResizeChild(bool bManul);
void UpdateChildDpi();
void ResizeChild();
inline void SetMovingFlag(bool bMoving){
_is_moving = bMoving;
}
QScreen* GetPointScreen();
private:
QScreen* screenFromWindow(HWND hwnd);
private:
QWidget* childWidget;
HWND _childWindow;
HWND _hWnd;
IParentNaitveEventCallback *_event_callback;
bool _is_moving;
};
}