walterlv / BlogComments

3 stars 0 forks source link

post/wpf-simulate-native-window-style-using-window-chrome #4

Open utterances-bot opened 5 years ago

utterances-bot commented 5 years ago

WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome) - walterlv

WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)

https://blog.walterlv.com/post/wpf-simulate-native-window-style-using-window-chrome.html

ehnap commented 5 years ago

其实Chrome定制了背景色可能只是在 UI 层面参考了原生,而开发层面上,是完全自己做的…… 业内很多都是如法炮制……

walterlv commented 5 years ago

@ehnap 我看到了微软的一些应用如 WinDbg,其 UI 也都是完全自己做的(拆解了 UI),只不过也跟原生 UI 一样。这一点非常感谢你的提醒,按照原生路线,很容易改出问题来,我也打算自己仿照 WinDbg 来做了。

wangwenx190 commented 4 years ago

博主,最近我在研究无边框窗口,在WM_NCHITTEST里实现了窗口的resize功能,但遇到了这篇博文中提到的问题,就是我自己做的resize是在窗口内部的,而系统默认的resize是在外部的,您知道应该怎么解决吗?

walterlv commented 4 years ago

@wangwenx190 在处理 WM_NCHITTEST 时返回 HT_LEFT 等做调整大小功能的时候,只能支持调节当前你处理消息的那个窗口。如果你的这个窗口和外面那个窗口是同一个线程的,那么可以通过返回 HT_TRANSPARENT 让调节大小在外面的窗口。

刚好在你问这个问题的前几天,我写了一篇博客来说明这个问题如何解决:

抱歉我回复晚了……

wangwenx190 commented 4 years ago

您的回答多少有点答非所问了,我不是要调整一个被挡住的窗口的大小,而是要让resize的判定范围在窗口外部(你可以打开记事本或文件管理器试一下,原生Win32窗口,resize都是在窗口的外部触发的,但如果搞这种无边框窗口,resize的触发区域就跑到窗口内部了),现在我已经有了解决方案了,我可以将我的窗口嵌入一个完全透明的大一号的窗口来实现这个功能,虽然这个做法很丑陋,但没有更好的办法了。

具体原因我也已经弄明白了,只是一直不能很好的解决。WS_THICKFRAME这个窗口样式会在窗口的左边、右边和底边添加三个透明区域用来做resize,在100%缩放时宽度均为8像素,它们处于非客户区,因此如果在WM_NCCALCSIZE中将边框去掉,它们也会变成客户区的一部分,所以就变不透明了,所以resize时看起来是在窗口内部,实际上还是在外部的。我研究了很久也没有找到把它们再次变透明的方法,我得到的结论是如果要保留这三个透明区域,只能在WM_NCCALCSIZE中保留这三边,但这样做在Win7上又会特别难看(因为Win7上边框宽度是8像素,如果保留下来,会十分醒目),而且顶边的问题很难解决(没法只去掉标题栏,保留顶边,要留只能一起留,要去只能一起去掉),所以这个方案不可行。

TonyDragonlake commented 2 years ago

博主您好,看了许多您的博文,感觉对我的WPF学习非常有帮助。在此想和您探讨一个最近遇到的奇怪问题。

最近我用sharpdx在wpf中做些渲染时发现,当我鼠标长按在wpf窗口的非客户区时,渲染出现卡滞; 随后我创建了一些测试,包括一个动画(非常简单的doubleanimation)和一个自定义控件的渲染,发现这种现象依然存在; 并且当我长按在wpf窗口的非客户区时,自定义控件的OnRender方法中写下debug输出也卡滞了一下才继续;

关于这个问题您是否有时间探讨?

walterlv commented 2 years ago

博主您好,看了许多您的博文,感觉对我的WPF学习非常有帮助。在此想和您探讨一个最近遇到的奇怪问题。

最近我用sharpdx在wpf中做些渲染时发现,当我鼠标长按在wpf窗口的非客户区时,渲染出现卡滞; 随后我创建了一些测试,包括一个动画(非常简单的doubleanimation)和一个自定义控件的渲染,发现这种现象依然存在; 并且当我长按在wpf窗口的非客户区时,自定义控件的OnRender方法中写下debug输出也卡滞了一下才继续;

关于这个问题您是否有时间探讨?

@TonyDragonlake 您好,我也发现了这个问题。而且不止是 WPF,其他一些程序(并不是所有)也有相同的现象。

QQ 450711383

TonyDragonlake commented 2 years ago

博主您好,看了许多您的博文,感觉对我的WPF学习非常有帮助。在此想和您探讨一个最近遇到的奇怪问题。 最近我用sharpdx在wpf中做些渲染时发现,当我鼠标长按在wpf窗口的非客户区时,渲染出现卡滞; 随后我创建了一些测试,包括一个动画(非常简单的doubleanimation)和一个自定义控件的渲染,发现这种现象依然存在; 并且当我长按在wpf窗口的非客户区时,自定义控件的OnRender方法中写下debug输出也卡滞了一下才继续; 关于这个问题您是否有时间探讨?

@TonyDragonlake 您好,我也发现了这个问题。而且不止是 WPF,其他一些程序(并不是所有)也有相同的现象。

QQ 450711383

非常感谢您的关注,我目前做的测试有: 测试环境:仅在win10 20H2 和 虚拟机 win11正式版中测试。 测试方法:渲染循环测试帧率并在Debug窗口中输出语句;长按或缓慢拖拽 非客户区(窗口可拖动区域)

  1. WPF 基于SharpDXD3DImage的渲染 (使用DispatcherSynchronizationContext.Post 提交给D3DImage) .NET Framework 4.5
  2. WPF 基于SharpDXD3DImage的渲染 (使用DispatcherSynchronizationContext.Send 提交给D3DImage) .NET Framework 4.5
  3. WPF 基于SharpDXD3DImage的渲染 (使用DispatcherTimer.Tick事件做同步渲染) .NET Framework4.5
  4. WPF 自定义FrameworkElement使用DrawingVisual渲染 (使用DispatcherSynchronizationContext.Post 提交UIElement.InvalidateVisual) .NET Framework 4.5
  5. WPF DoubleAnimation 控制Rectangle旋转 .NET Framework 4.5
  6. WPF DoubleAnimation 控制Rectangle旋转 .NET Core 3.1

测试下来 均存在 长按非客户区时渲染卡滞的现象; 我后续测试了winform 结果也是有类似的问题;

  1. Winform 使用 Samples【下载地址】 of WinFormAnimation

所以如此看来,是否可能与.NET Framework和.NET Core对窗口程序的支持有关?

lfmissonb commented 1 year ago

您好,请问如何在标题栏上创建一个可以点击的按钮?我成功在标题栏上添加了按钮,但是按钮无法被点击,感觉像是被一个透明的东西挡住了一样,请问您有办法解决吗 我希望实现office2010和windows10中资源管理器的那种效果(在系统原生标题栏上添加按钮)

walterlv commented 1 year ago

@lfmissonb 需要设置 WindowChrome.IsHitTestVisibleInChrome 属性

lfmissonb commented 12 months ago

您好,我还有一个问题,我发现这样做出来的窗口虽然可以在阴影处进行缩放,但是资源管理器在阴影处的拖放区域貌似比这个窗口要大