forked from Ivasoft/DSView
Optimize the operation of dragging the programsbetween two screens
This commit is contained in:
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user