提问人:elmor6942 提问时间:11/12/2023 更新时间:11/14/2023 访问量:78
如何使用可点击控件创建半透明叠加层
How to create a semi transparent overlay with clickable controls
问:
我想创建一个带有一些控件的半透明窗口(黑色,带有一些不透明度)(可能是一个 + 和 - 来增加/减少不透明度)。我正在使用 WPF,并查看了以下 stackoverflow 答案
如何制作一个“覆盖”窗口,允许鼠标单击传递到其下方的窗口,但仍允许单击某些控件?
只有当窗口完全透明时,这才有效,添加一些不透明度会破坏叠加行为
使用这种方法时,我丢失了控件的单击功能。
如何将这两者结合起来?我可以更改为其他框架,例如 winforms、winui,如果这会让事情变得更容易
答:
0赞
MIHOW
11/14/2023
#1
WS_EX_TRANSPARENT使您的事件(如鼠标点击)落入您的窗口等。不透明度是一个单独的概念,它指示窗口管理器在绘制表单时应用 alphablending。
所以,如果我理解你的问题是正确的,你希望有一个允许单击它下面的对象,但该窗口上也有可点击的控件。Transparent Window
为此,您需要找到折衷方案。
因为当您应用它时,它不再可点击,因此为了返回正常窗口,您需要以某种方式触发重置方法。WS_EX_TRANSPARENT
WS_EX_TRANSPARENT
我在 中创建了一个示例。NET6 和 WPF,我在其中切换 ,在事件上。
当然,有必要在尝试重置此示例时将 Window 集中注意力。WS_EX_TRANSPARENT
PreviewKeyDown
WS_EX_TRANSPARENT
XAML
<Window x:Class="WpfApp8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp8"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="300"
Height="300"
WindowStyle="None"
AllowsTransparency="True"
Topmost="True"
BorderThickness="5"
BorderBrush="LimeGreen"
Background="Transparent"
PreviewKeyDown="Window_PreviewKeyDown"
mc:Ignorable="d">
<DockPanel>
<Border Height="40"
DockPanel.Dock="Top"
Background="Blue"
MouseDown="Border_MouseDown"/>
<Button x:Name="button"
Grid.Row="2"
Width="75"
Height="50"
Margin="10"
DockPanel.Dock="Bottom"
Content="Button"
Click="button_Click"/>
<Border Background="Black" Opacity="0.5"/>
</DockPanel>
</Window>
代码隐藏
namespace WpfApp8
{
public partial class MainWindow : Window
{
private bool _borderClicked;
private IntPtr _handle;
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
_handle = new WindowInteropHelper(this).Handle;
WindowsServices.SetWindowExNormal(_handle);
}
private void button_Click(object sender, RoutedEventArgs e)
{
this.BorderBrush = !_borderClicked ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.LimeGreen);
_borderClicked = !_borderClicked;
}
private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.D1 && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
WindowsServices.SetWindowExNormal(_handle);
}
else if (e.Key == Key.D2 && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
WindowsServices.SetWindowExTransparent(_handle);
}
}
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
// Drag window
this.DragMove();
}
}
public static class WindowsServices
{
const int WS_EX_TRANSPARENT = 0x00000020;
const int GWL_EXSTYLE = (-20);
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
public static void SetWindowExTransparent(IntPtr hwnd)
{
var extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
}
public static void SetWindowExNormal(IntPtr hwnd)
{
int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle & ~WS_EX_TRANSPARENT);
}
}
}
评论