This commit is contained in:
朱子楚\zhuzi 2023-12-29 23:09:46 +08:00
parent 42f0987e73
commit 6221eb4178
8 changed files with 141 additions and 56 deletions

View File

@ -9,7 +9,7 @@ FluWindow {
id:window
title:"关于"
width: 600
height: 600
height: 580
fixSize: true
launchMode: FluWindowType.SingleTask

View File

@ -10,7 +10,7 @@ FluWindow {
id:window
title:"关于"
width: 600
height: 600
height: 580
fixSize: true
launchMode: FluWindowType.SingleTask

View File

@ -23,6 +23,24 @@ static inline bool isTaskbarAutoHide() {
return lParam & ABS_AUTOHIDE;
}
static inline QColor getAccentColor(){
typedef HRESULT (WINAPI* DwmGetColorizationColorPtr)(DWORD* pcrColorization,BOOL* pfOpaqueBlend);
HMODULE module = LoadLibraryW(L"dwmapi.dll");
if (module)
{
DwmGetColorizationColorPtr dwm_get_colorization_color;
dwm_get_colorization_color= reinterpret_cast<DwmGetColorizationColorPtr>(GetProcAddress(module, "DwmGetColorizationColor"));
DWORD color = 0;
BOOL bOpaque = FALSE;
if (dwm_get_colorization_color)
{
dwm_get_colorization_color(&color,&bOpaque);
}
return QColor(color);
}
return QColor();
}
static inline bool isCompositionEnabled(){
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
HMODULE module = LoadLibraryW(L"dwmapi.dll");
@ -41,22 +59,17 @@ static inline bool isCompositionEnabled(){
}
static inline void showShadow(HWND hwnd){
if(isCompositionEnabled()){
const MARGINS shadow = { 0, 0, 1, 0 };
typedef HRESULT (WINAPI* DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset);
HMODULE module = LoadLibraryW(L"dwmapi.dll");
if (module)
const MARGINS shadow = { 0, 0, 1, 0 };
typedef HRESULT (WINAPI* DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset);
HMODULE module = LoadLibraryW(L"dwmapi.dll");
if (module)
{
DwmExtendFrameIntoClientAreaPtr dwm_extendframe_into_client_area_;
dwm_extendframe_into_client_area_= reinterpret_cast<DwmExtendFrameIntoClientAreaPtr>(GetProcAddress(module, "DwmExtendFrameIntoClientArea"));
if (dwm_extendframe_into_client_area_)
{
DwmExtendFrameIntoClientAreaPtr dwm_extendframe_into_client_area_;
dwm_extendframe_into_client_area_= reinterpret_cast<DwmExtendFrameIntoClientAreaPtr>(GetProcAddress(module, "DwmExtendFrameIntoClientArea"));
if (dwm_extendframe_into_client_area_)
{
dwm_extendframe_into_client_area_(hwnd, &shadow);
}
dwm_extendframe_into_client_area_(hwnd, &shadow);
}
}else{
ULONG_PTR cNewStyle = GetClassLongPtr(hwnd, GCL_STYLE) | CS_DROPSHADOW;
SetClassLongPtr(hwnd, GCL_STYLE, cNewStyle);
}
}
@ -108,25 +121,16 @@ bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *
}
if(IsZoomed(hwnd)){
_helper->setOriginalPos(QPoint(originalLeft,originalTop));
if(isTaskbarAutoHide()){
clientRect->bottom -= 1;
}
}else{
_helper->setOriginalPos({});
}
clientRect->top = originalTop;
*result = WVR_REDRAW;
return true;
}else if(uMsg == WM_NCPAINT){
if(!isCompositionEnabled()){
*result = WVR_REDRAW;
return true;
}
return false;
}else if(uMsg == WM_NCACTIVATE){
if(!isCompositionEnabled()){
*result = 1;
return true;
}
return false;
}else if(uMsg == WM_NCHITTEST){
}if(uMsg == WM_NCHITTEST){
if(FluTools::getInstance()->isWindows11OrGreater() && _helper->hoverMaxBtn() && _helper->resizeable()){
if (*result == HTNOWHERE) {
*result = HTZOOM;
@ -256,24 +260,34 @@ void FluFramelessHelper::componentComplete(){
o = o->parent();
}
if(!window.isNull()){
_stayTop = QQmlProperty(window,"stayTop");
_screen = QQmlProperty(window,"screen");
_fixSize = QQmlProperty(window,"fixSize");
_originalPos = QQmlProperty(window,"_originalPos");
_accentColor = QQmlProperty(window,"_accentColor");
#ifdef Q_OS_WIN
// window->setFlags(window->flags() | Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
_nativeEvent =new FramelessEventFilter(this);
qApp->installNativeEventFilter(_nativeEvent);
HWND hwnd = reinterpret_cast<HWND>(window->winId());
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
if(resizeable()){
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
if(isCompositionEnabled()){
_accentColor.write(getAccentColor());
_nativeEvent =new FramelessEventFilter(this);
qApp->installNativeEventFilter(_nativeEvent);
HWND hwnd = reinterpret_cast<HWND>(window->winId());
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
if(resizeable()){
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
}else{
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);
}
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
if(_fixSize.read().toBool()){
window->setMaximumSize(window->size());
window->setMinimumSize(window->size());
}
}else{
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION);
window->setFlags((window->flags() & (~Qt::WindowMinMaxButtonsHint) & (~Qt::Dialog)) | Qt::FramelessWindowHint | Qt::Window);
}
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
#else
window->setFlags((window->flags() & (~Qt::WindowMinMaxButtonsHint) & (~Qt::Dialog)) | Qt::FramelessWindowHint | Qt::Window);
#endif
_stayTop = QQmlProperty(window,"stayTop");
_screen = QQmlProperty(window,"screen");
_originalPos = QQmlProperty(window,"_originalPos");
_onStayTopChange();
_stayTop.connectNotifySignal(this,SLOT(_onStayTopChange()));
_screen.connectNotifySignal(this,SLOT(_onScreenChanged()));
@ -334,8 +348,10 @@ FluFramelessHelper::~FluFramelessHelper(){
if (!window.isNull()) {
window->setFlags(Qt::Window);
#ifdef Q_OS_WIN
qApp->removeNativeEventFilter(_nativeEvent);
delete _nativeEvent;
if(isCompositionEnabled()){
qApp->removeNativeEventFilter(_nativeEvent);
delete _nativeEvent;
}
#endif
window->removeEventFilter(this);
}

View File

@ -56,6 +56,8 @@ private:
QQmlProperty _stayTop;
QQmlProperty _screen;
QQmlProperty _originalPos;
QQmlProperty _fixSize;
QQmlProperty _accentColor;
};
#endif // FLUFRAMELESSHELPER_H

View File

@ -196,17 +196,42 @@ int FluTools::cursorScreenIndex(){
return screenIndex;
}
int FluTools::windowBuildNumber(){
#if defined(Q_OS_WIN)
QSettings regKey {QString::fromUtf8("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), QSettings::NativeFormat};
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
return buildNumber;
}
#endif
return -1;
}
bool FluTools::isWindows11OrGreater(){
static QVariant var;
if(var.isNull()){
#if defined(Q_OS_WIN)
QSettings regKey {QString::fromUtf8("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), QSettings::NativeFormat};
if (regKey.contains(QString::fromUtf8("CurrentBuildNumber"))) {
auto buildNumber = regKey.value(QString::fromUtf8("CurrentBuildNumber")).toInt();
if(buildNumber>=22000){
var = QVariant::fromValue(true);
return true;
}
auto buildNumber = windowBuildNumber();
if(buildNumber>=22000){
var = QVariant::fromValue(true);
return true;
}
#endif
var = QVariant::fromValue(false);
return false;
}else{
return var.toBool();
}
}
bool FluTools::isWindows10OrGreater(){
static QVariant var;
if(var.isNull()){
#if defined(Q_OS_WIN)
auto buildNumber = windowBuildNumber();
if(buildNumber>=10240){
var = QVariant::fromValue(true);
return true;
}
#endif
var = QVariant::fromValue(false);

View File

@ -51,7 +51,9 @@ public:
Q_INVOKABLE QPoint cursorPos();
Q_INVOKABLE QIcon windowIcon();
Q_INVOKABLE int cursorScreenIndex();
Q_INVOKABLE int windowBuildNumber();
Q_INVOKABLE bool isWindows11OrGreater();
Q_INVOKABLE bool isWindows10OrGreater();
};
#endif // FLUTOOLS_H

View File

@ -40,7 +40,12 @@ Window {
property bool showStayTop: true
property bool autoMaximize: false
property bool useSystemAppBar
property color resizeBorderColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
property color resizeBorderColor: {
if(window.active){
return _accentColor
}
return FluTheme.dark ? "#3D3D3E" : "#A7A7A7"
}
property int resizeBorderWidth: 1
property var closeListener: function(event){
if(closeDestory){
@ -55,6 +60,7 @@ Window {
signal firstVisible()
property point _offsetXY : Qt.point(0,0)
property var _originalPos
property color _accentColor : FluTheme.dark ? "#333333" : "#6E6E6E"
id:window
color:"transparent"
Component.onCompleted: {
@ -192,7 +198,7 @@ Window {
id:layout_container
anchors{
fill:parent
topMargin: _offsetXY.x
topMargin: _offsetXY.y
}
onWidthChanged: {
window.appBar.width = width
@ -245,7 +251,21 @@ Window {
border.width: window.resizeBorderWidth
border.color: window.resizeBorderColor
visible: {
if(window.useSystemAppBar){
if(window.useSystemAppBar || FluTools.isWindows10OrGreater()){
return false
}
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){
return false
}
return true
}
}
Rectangle{
height: 1
width: parent.width
color: window.resizeBorderColor
visible: {
if(window.useSystemAppBar || !FluTools.isWin()){
return false
}
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){

View File

@ -39,7 +39,12 @@ Window {
property bool showStayTop: true
property bool autoMaximize: false
property bool useSystemAppBar
property color resizeBorderColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
property color resizeBorderColor: {
if(window.active){
return _accentColor
}
return FluTheme.dark ? "#3D3D3E" : "#A7A7A7"
}
property int resizeBorderWidth: 1
property var closeListener: function(event){
if(closeDestory){
@ -54,6 +59,7 @@ Window {
signal firstVisible()
property point _offsetXY : Qt.point(0,0)
property var _originalPos
property color _accentColor : FluTheme.dark ? "#333333" : "#6E6E6E"
id:window
color:"transparent"
Component.onCompleted: {
@ -191,7 +197,7 @@ Window {
id:layout_container
anchors{
fill:parent
topMargin: _offsetXY.x
topMargin: _offsetXY.y
}
onWidthChanged: {
window.appBar.width = width
@ -244,7 +250,21 @@ Window {
border.width: window.resizeBorderWidth
border.color: window.resizeBorderColor
visible: {
if(window.useSystemAppBar){
if(window.useSystemAppBar || FluTools.isWindows10OrGreater()){
return false
}
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){
return false
}
return true
}
}
Rectangle{
height: 1
width: parent.width
color: window.resizeBorderColor
visible: {
if(window.useSystemAppBar || !FluTools.isWin()){
return false
}
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){