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; _is_resize_ready = false;
_parentNativeWidget = NULL; _parentNativeWidget = NULL;
_mainWindow = NULL; _mainWindow = NULL;
_is_max_status = false; _is_max_status = false;
_move_start_screen = NULL;
AppControl::Instance()->SetTopWindow(this); AppControl::Instance()->SetTopWindow(this);
@@ -91,6 +92,8 @@ MainFrame::MainFrame()
_is_native_title = false; _is_native_title = false;
#endif #endif
// setMinimumWidth(MainWindow::Min_Width); // setMinimumWidth(MainWindow::Min_Width);
// setMinimumHeight(MainWindow::Min_Height); // setMinimumHeight(MainWindow::Min_Height);
@@ -229,7 +232,6 @@ void MainFrame::AttachNativeWindow()
setVisible(true); setVisible(true);
if (_initWndInfo.isMaxSize){ if (_initWndInfo.isMaxSize){
_initWndInfo.isMaxSize = false;
showMaximized(); showMaximized();
} }
}); });
@@ -272,72 +274,26 @@ bool MainFrame::ParentIsMaxsized()
void MainFrame::MoveBegin() void MainFrame::MoveBegin()
{ {
// dsv_info("Move begin.");
#ifdef _WIN32 #ifdef _WIN32
if (_parentNativeWidget != NULL) if (_parentNativeWidget != NULL){
{ _parentNativeWidget->SetMovingFlag(true);
POINT p; _move_start_screen = _parentNativeWidget->GetPointScreen();
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);
}
}
#endif #endif
} }
void MainFrame::MoveEnd() void MainFrame::MoveEnd()
{ {
// dsv_info("Move end.");
#ifdef _WIN32 #ifdef _WIN32
if (_parentNativeWidget != NULL){ if (_parentNativeWidget != NULL){
auto scr = _parentNativeWidget->GetPointScreen();
if (scr != _move_start_screen){
_parentNativeWidget->UpdateChildDpi();
}
POINT p; _parentNativeWidget->ResizeChild();
GetCursorPos(&p); _parentNativeWidget->SetMovingFlag(false);
}
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();
}
#endif #endif
} }
@@ -561,7 +517,7 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
pt.setX(p.x); pt.setX(p.x);
pt.setY(p.y); pt.setY(p.y);
#else #else
pt = mouse_event->globalPos(); pt = event->globalPos();
#endif #endif
int datX = pt.x() - _clickPos.x(); int datX = pt.x() - _clickPos.x();
int datY = pt.y() - _clickPos.y(); int datY = pt.y() - _clickPos.y();
@@ -666,7 +622,7 @@ bool MainFrame::eventFilter(QObject *object, QEvent *event)
_clickPos.setX(p.x); _clickPos.setX(p.x);
_clickPos.setY(p.y); _clickPos.setY(p.y);
#else #else
_clickPos = mouse_event->globalPos(); _clickPos = event->globalPos();
#endif #endif
_dragStartRegion = GetFormRegion(); _dragStartRegion = GetFormRegion();
@@ -810,8 +766,8 @@ void MainFrame::SetFormRegion(int x, int y, int w, int h)
setGeometry(x, y, w, h); setGeometry(x, y, w, h);
} }
QRect MainFrame::GetFormRegion() QRect MainFrame::GetFormRegion()
{ {
QRect rc; QRect rc;
#ifdef _WIN32 #ifdef _WIN32
@@ -834,7 +790,7 @@ void MainFrame::SetFormRegion(int x, int y, int w, int h)
#endif #endif
return rc; return rc;
} }
void MainFrame::ReadSettings() void MainFrame::ReadSettings()
{ {

View File

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

View File

@@ -21,10 +21,12 @@
*/ */
#include "winnativewidget.h" #include "WinNativeWidget.h"
#include <QApplication> #include <QApplication>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QScreen> #include <QScreen>
#include <QGuiApplication>
#include <QWindow>
#include <dwmapi.h> #include <dwmapi.h>
#include <assert.h> #include <assert.h>
#include <QString> #include <QString>
@@ -40,8 +42,10 @@ WinNativeWidget::WinNativeWidget(const int x, const int y, const int width, cons
_childWindow = nullptr; _childWindow = nullptr;
childWidget = nullptr; childWidget = nullptr;
_hWnd = NULL; _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); HINSTANCE hInstance = GetModuleHandle(nullptr);
WNDCLASSEX wcx = { 0 }; WNDCLASSEX wcx = { 0 };
@@ -146,27 +150,30 @@ LRESULT CALLBACK WinNativeWidget::WndProc(HWND hWnd, UINT message, WPARAM wParam
case WM_SIZE: case WM_SIZE:
{ {
if (self->_childWindow != NULL){ if (self->_childWindow != NULL){
self->ResizeChild(false); self->ResizeChild();
} }
break; 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); return DefWindowProc(hWnd, message, wParam, lParam);
} }
void WinNativeWidget::ResizeChild(bool bManual) void WinNativeWidget::ResizeChild()
{ {
if (_childWindow != NULL){ if (_childWindow != NULL){
RECT rc; RECT rc;
GetClientRect(_hWnd, &rc); GetClientRect(_hWnd, &rc);
int k = QApplication::desktop()->screen()->devicePixelRatio();
k = childWidget->window()->devicePixelRatio();
int w = rc.right; int w = rc.right;
int h = rc.bottom; int h = rc.bottom;
@@ -180,9 +187,8 @@ void WinNativeWidget::ResizeChild(bool bManual)
} }
childWidget->adjustSize(); childWidget->adjustSize();
MoveWindow(_childWindow, 0, 0, w , h , 1 ); 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);
} }
} }
@@ -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 <Windowsx.h>
#include <QWidget> #include <QWidget>
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
namespace pv { namespace pv {
class IParentNaitveEventCallback
{
public:
virtual void OnParentNativeEvent(int msg)=0;
};
class WinNativeWidget class WinNativeWidget
{ {
public: public:
@@ -55,12 +65,24 @@ public:
void ShowMax(); void ShowMax();
void ShowMin(); 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: private:
QWidget* childWidget; QWidget* childWidget;
HWND _childWindow; HWND _childWindow;
HWND _hWnd; HWND _hWnd;
IParentNaitveEventCallback *_event_callback;
bool _is_moving;
}; };
} }