This commit is contained in:
朱子楚\zhuzi 2023-12-18 21:29:38 +08:00
parent ecd0f29d30
commit 1bf992ed69
3 changed files with 166 additions and 111 deletions

View File

@ -12,6 +12,23 @@ static inline QByteArray qtNativeEventType()
} }
#endif #endif
static inline bool isCompositionEnabled(){
typedef HRESULT (WINAPI* DwmIsCompositionEnabledPtr)(BOOL *pfEnabled);
HMODULE module = LoadLibraryW(L"dwmapi.dll");
if (module)
{
BOOL composition_enabled = false;
DwmIsCompositionEnabledPtr dwm_is_composition_enabled;
dwm_is_composition_enabled= reinterpret_cast<DwmIsCompositionEnabledPtr>(GetProcAddress(module, "DwmIsCompositionEnabled"));
if (dwm_is_composition_enabled)
{
dwm_is_composition_enabled(&composition_enabled);
}
return composition_enabled;
}
return false;
}
FramelessEventFilter::FramelessEventFilter(QQuickWindow* window){ FramelessEventFilter::FramelessEventFilter(QQuickWindow* window){
_window = window; _window = window;
_current = window->winId(); _current = window->winId();
@ -23,25 +40,27 @@ bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *
return false; return false;
} }
const auto msg = static_cast<const MSG *>(message); const auto msg = static_cast<const MSG *>(message);
const HWND hWnd = msg->hwnd; const HWND hwnd = msg->hwnd;
if (!hWnd) { if (!hwnd) {
return false; return false;
} }
const qint64 wid = reinterpret_cast<qint64>(hWnd); const qint64 wid = reinterpret_cast<qint64>(hwnd);
if(wid != _current){ if(wid != _current){
return false; return false;
} }
const UINT uMsg = msg->message; const UINT uMsg = msg->message;
if (!msg || !msg->hwnd) const WPARAM wParam = msg->wParam;
const LPARAM lParam = msg->lParam;
if (!msg || !hwnd)
{ {
return false; return false;
} }
if(uMsg == WM_WINDOWPOSCHANGING){ if(uMsg == WM_WINDOWPOSCHANGING){
WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(msg->lParam); WINDOWPOS* wp = reinterpret_cast<WINDOWPOS*>(lParam);
if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0) if (wp != nullptr && (wp->flags & SWP_NOSIZE) == 0)
{ {
wp->flags |= SWP_NOCOPYBITS; wp->flags |= SWP_NOCOPYBITS;
*result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam); *result = DefWindowProc(hwnd, uMsg, wParam, lParam);
return true; return true;
} }
return false; return false;
@ -49,8 +68,22 @@ bool FramelessEventFilter::nativeEventFilter(const QByteArray &eventType, void *
*result = WVR_REDRAW; *result = WVR_REDRAW;
return true; return true;
}else if(uMsg == WM_NCPAINT){ }else if(uMsg == WM_NCPAINT){
*result = WVR_REDRAW; if(!isCompositionEnabled()){
*result = WVR_REDRAW;
return true;
}
return false; return false;
}else if(uMsg == WM_NCACTIVATE){
if(isCompositionEnabled()){
*result = DefWindowProc(hwnd, uMsg, wParam, -1);
}else{
if (wParam == FALSE) {
*result = TRUE;
} else {
*result = FALSE;
}
}
return true;
} }
return false; return false;
#endif #endif
@ -90,7 +123,7 @@ void FluFrameless::updateCursor(int edges){
} }
bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){ bool FluFrameless::eventFilter(QObject *obj, QEvent *ev){
if (!_window.isNull() && _window->flags()& Qt::FramelessWindowHint) { if (!_window.isNull()) {
static int edges = 0; static int edges = 0;
const int margin = 8; const int margin = 8;
@ -156,25 +189,29 @@ void FluFrameless::componentComplete(){
o = o->parent(); o = o->parent();
} }
if(!_window.isNull()){ if(!_window.isNull()){
_window->setFlag(Qt::FramelessWindowHint,true);
_window->installEventFilter(this);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
_nativeEvent =new FramelessEventFilter(_window); _nativeEvent =new FramelessEventFilter(_window);
qApp->installNativeEventFilter(_nativeEvent); qApp->installNativeEventFilter(_nativeEvent);
HWND hwnd = reinterpret_cast<HWND>(_window->winId()); HWND hwnd = reinterpret_cast<HWND>(_window->winId());
ULONG_PTR cNewStyle = GetClassLongPtr(hwnd, GCL_STYLE) | CS_DROPSHADOW; ULONG_PTR cNewStyle = GetClassLongPtr(hwnd, GCL_STYLE) | CS_DROPSHADOW;
SetClassLongPtr(hwnd, GCL_STYLE, cNewStyle); SetClassLongPtr(hwnd, GCL_STYLE, cNewStyle);
DWORD style = GetWindowLongPtr(hwnd,GWL_STYLE);
SetWindowLongPtr(hwnd,GWL_STYLE,style &~ WS_SYSMENU);
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |SWP_FRAMECHANGED); SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |SWP_FRAMECHANGED);
#else
_window->setFlag(Qt::FramelessWindowHint,true);
#endif #endif
_window->installEventFilter(this);
} }
} }
FluFrameless::~FluFrameless(){ FluFrameless::~FluFrameless(){
if (!_window.isNull()) { if (!_window.isNull()) {
_window->setFlag(Qt::FramelessWindowHint,false);
_window->removeEventFilter(this); _window->removeEventFilter(this);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
qApp->removeNativeEventFilter(_nativeEvent); qApp->removeNativeEventFilter(_nativeEvent);
#else
_window->setFlag(Qt::FramelessWindowHint,false);
#endif #endif
} }
} }

View File

@ -197,60 +197,69 @@ Window {
FluLoader{ FluLoader{
id:loader_frameless id:loader_frameless
} }
onWidthChanged: {
window.appBar.width = width
}
FluLoader{
id:loader_app_bar
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: {
if(window.useSystemAppBar){
return 0
}
return window.fitsAppBarWindows ? 0 : window.appBar.height
}
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
}
Item{ Item{
id:container
anchors{
top: loader_app_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
FluLoader{
property string loadingText: "加载中..."
property bool cancel: false
id:loader_loading
anchors.fill: container
}
FluInfoBar{
id:infoBar
root: window
}
WindowLifecycle{
id:lifecycle
}
Rectangle{
anchors.fill: parent anchors.fill: parent
color:"transparent" anchors.margins: {
border.width: window.resizeBorderWidth if(FluTools.isWin() && !window.useSystemAppBar){
border.color: window.resizeBorderColor return window.visibility === Window.Maximized ? 8 : 0
visible: {
if(window.useSystemAppBar){
return false
} }
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){ return 0
return false }
onWidthChanged: {
window.appBar.width = width
}
FluLoader{
id:loader_app_bar
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: {
if(window.useSystemAppBar){
return 0
}
return window.fitsAppBarWindows ? 0 : window.appBar.height
}
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
}
Item{
id:container
anchors{
top: loader_app_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
FluLoader{
property string loadingText: "加载中..."
property bool cancel: false
id:loader_loading
anchors.fill: container
}
FluInfoBar{
id:infoBar
root: window
}
WindowLifecycle{
id:lifecycle
}
Rectangle{
anchors.fill: parent
color:"transparent"
border.width: window.resizeBorderWidth
border.color: window.resizeBorderColor
visible: {
if(window.useSystemAppBar){
return false
}
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){
return false
}
return true
} }
return true
} }
} }
function destoryOnClose(){ function destoryOnClose(){

View File

@ -196,60 +196,69 @@ Window {
FluLoader{ FluLoader{
id:loader_frameless id:loader_frameless
} }
onWidthChanged: {
window.appBar.width = width
}
FluLoader{
id:loader_app_bar
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: {
if(window.useSystemAppBar){
return 0
}
return window.fitsAppBarWindows ? 0 : window.appBar.height
}
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
}
Item{ Item{
id:container
anchors{
top: loader_app_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
FluLoader{
property string loadingText: "加载中..."
property bool cancel: false
id:loader_loading
anchors.fill: container
}
FluInfoBar{
id:infoBar
root: window
}
WindowLifecycle{
id:lifecycle
}
Rectangle{
anchors.fill: parent anchors.fill: parent
color:"transparent" anchors.margins: {
border.width: window.resizeBorderWidth if(FluTools.isWin() && !window.useSystemAppBar){
border.color: window.resizeBorderColor return window.visibility === Window.Maximized ? 8 : 0
visible: {
if(window.useSystemAppBar){
return false
} }
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){ return 0
return false }
onWidthChanged: {
window.appBar.width = width
}
FluLoader{
id:loader_app_bar
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: {
if(window.useSystemAppBar){
return 0
}
return window.fitsAppBarWindows ? 0 : window.appBar.height
}
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
}
Item{
id:container
anchors{
top: loader_app_bar.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}
clip: true
}
FluLoader{
property string loadingText: "加载中..."
property bool cancel: false
id:loader_loading
anchors.fill: container
}
FluInfoBar{
id:infoBar
root: window
}
WindowLifecycle{
id:lifecycle
}
Rectangle{
anchors.fill: parent
color:"transparent"
border.width: window.resizeBorderWidth
border.color: window.resizeBorderColor
visible: {
if(window.useSystemAppBar){
return false
}
if(window.visibility == Window.Maximized || window.visibility == Window.FullScreen){
return false
}
return true
} }
return true
} }
} }
function destoryOnClose(){ function destoryOnClose(){