您现在的位置是:首页 > 技术文章网站首页技术文章

[Qt]自定义窗体拉伸_分屏_移动

  • WangYe
  • 2020-11-28 18:29:48
  • 306 次阅读
Qt自定义可拉伸自动分屏移动窗体

效果:

xy-20201128-180459.gif


stdafx.h

#include <QApplication>
#include "windows.h"
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <dwmapi.h>

#ifndef GET_X_LPARAM
#define GET_X_LPARAM(lParam)    ((int)(short)LOWORD(lParam))
#endif
#ifndef GET_Y_LPARAM
#define GET_Y_LPARAM(lParam)    ((int)(short)HIWORD(lParam))
#endif

#endif

Custom_control.h

#pragma once
#include "stdafx.h"
#include <QtWidgets/QWidget>

class Custom_control: public QWidget
{
	Q_OBJECT

public:
	Custom_control(QWidget *parent = Q_NULLPTR);
	~Custom_control();
	
	void setWidgetBorderless(const QWidget *widget);	//无边界设置
	LRESULT OnTestBorder(const QPoint &pt);	//测试边界适应
	virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);	//本窗体事件

private:

};

Custom_control.cpp

#include "Custom_control.h"

Custom_control::Custom_control(QWidget *parent)
	: QWidget(parent)
{
	setObjectName("HFramer");    //设置窗体名称
	setWindowTitle("HFramer");    //设置窗体标题
	setWidgetBorderless(this);    //设置无边界窗体
}

void Custom_control::setWidgetBorderless(const QWidget *widget)	//无边界设置
{
	setWindowFlags(Qt::WindowMinimizeButtonHint | Qt::FramelessWindowHint);	//设置最小化|无边框
#ifdef Q_OS_WIN
	HWND hwnd = reinterpret_cast<HWND>(widget->winId());
	DWORD style = GetWindowLong(hwnd, GWL_STYLE);
	SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
#endif
}

bool Custom_control::nativeEvent(const QByteArray &eventType, void *message, long *result)	//本窗体事件
{
#ifdef Q_OS_WIN
	if (eventType != "windows_generic_MSG")
		return false;

	MSG* msg = static_cast<MSG*>(message);
	QWidget* widget = QWidget::find(reinterpret_cast<WId>(msg->hwnd));
	if (!widget)
		return false;

	switch (msg->message) {

	case WM_NCCALCSIZE: {
		*result = 0;
		return true;
	}

	case WM_NCHITTEST: 
	{
		int x = GET_X_LPARAM(msg->lParam);
		int y = GET_Y_LPARAM(msg->lParam);
		QPoint pt = mapFromGlobal(QPoint(x, y));
		*result = OnTestBorder(pt);
		if (*result == HTCLIENT)
		{
			QWidget* tempWidget = this->childAt(pt.x(), pt.y());
			if (tempWidget == NULL)
			{
				*result = HTCAPTION;
			}
		}
		return true;
	}

	case WM_GETMINMAXINFO: {
		if (::IsZoomed(msg->hwnd)) {

			RECT frame = { 0, 0, 0, 0 };
			AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, FALSE, 0);
			frame.left = abs(frame.left);
			frame.top = abs(frame.bottom);
			widget->setContentsMargins(frame.left, frame.top, frame.right, frame.bottom);
		}
		else {
			widget->setContentsMargins(0, 0, 0, 0);
		}

		*result = ::DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
		return true;
	}
	break;

	default:
		break;
	}

#endif

	return QWidget::nativeEvent(eventType, message, result);
}

LRESULT Custom_control::OnTestBorder(const QPoint &pt)	//测试边界适应
{
	if (::IsZoomed((HWND)this->winId()))
	{
		return HTCLIENT;
	}
	int borderSize = 4;
	int cx = this->size().width();
	int cy = this->size().height();
	QRect rectTopLeft(0, 0, borderSize, borderSize);
	if (rectTopLeft.contains(pt))
	{
		return HTTOPLEFT;
	}
	QRect rectLeft(0, borderSize, borderSize, cy - borderSize * 2);
	if (rectLeft.contains(pt))
	{
		return HTLEFT;
	}
	QRect rectTopRight(cx - borderSize, 0, borderSize, borderSize);
	if (rectTopRight.contains(pt))
	{
		return HTTOPRIGHT;
	}
	QRect rectRight(cx - borderSize, borderSize, borderSize, cy - borderSize * 2);
	if (rectRight.contains(pt))
	{
		return HTRIGHT;
	}
	QRect rectTop(borderSize, 0, cx - borderSize * 2, borderSize);
	if (rectTop.contains(pt))
	{
		return HTTOP;
	}
	QRect rectBottomLeft(0, cy - borderSize, borderSize, borderSize);
	if (rectBottomLeft.contains(pt))
	{
		return HTBOTTOMLEFT;
	}
	QRect rectBottomRight(cx - borderSize, cy - borderSize, borderSize, borderSize);
	if (rectBottomRight.contains(pt))
	{
		return HTBOTTOMRIGHT;
	}
	QRect rectBottom(borderSize, cy - borderSize, cx - borderSize * 2, borderSize);
	if (rectBottom.contains(pt))
	{
		return HTBOTTOM;
	}
	return HTCLIENT;
}


文章评论 (0)



Top