我创建了一个全局热键来通过PInvoking显示一个窗口RegisterHotKey()
.但要做到这一点,我需要那个窗口HWND
,在窗口加载之前不存在,这意味着第一次显示.但我不想在设置热键之前显示窗口.有没有办法创建一个HWND
对用户不可见的窗口?
Pat*_*lug 64
如果您的目标是.NET 4.0,则可以使用以下EnsureHandle
可用的新方法WindowInteropHelper
:
public void InitHwnd()
{
var helper = new WindowInteropHelper(this);
helper.EnsureHandle();
}
Run Code Online (Sandbox Code Playgroud)
(感谢Thomas Levesque 指出这一点.)
如果您的目标是旧版本的.NET Framework,最简单的方法是在设置一些属性时显示窗口以访问HWND,以确保窗口不可见且不会窃取焦点:
var window = new Window() //make sure the window is invisible
{
Width = 0,
Height = 0,
WindowStyle = WindowStyle.None,
ShowInTaskbar = false,
ShowActivated = false
};
window.Show();
Run Code Online (Sandbox Code Playgroud)
一旦您想要显示实际窗口,您就可以设置内容,大小并将样式更改回正常窗口.
DJP*_*DJP 17
您还可以将窗口更改为所谓的仅消息窗口.由于此窗口类型不支持图形元素,因此永远不会显示.基本上它归结为:
SetParent(hwnd, (IntPtr)HWND_MESSAGE);
Run Code Online (Sandbox Code Playgroud)
创建一个始终隐藏的专用消息窗口,或者使用真实的GUI窗口,并在想要显示它时将其更改回正常窗口.有关更完整的示例,请参阅下面的代码.
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hwnd, IntPtr hwndNewParent);
private const int HWND_MESSAGE = -3;
private IntPtr hwnd;
private IntPtr oldParent;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
hwnd = hwndSource.Handle;
oldParent = SetParent(hwnd, (IntPtr)HWND_MESSAGE);
Visibility = Visibility.Hidden;
}
}
private void OpenWindowMenuItem_Click(object sender, RoutedEventArgs e)
{
SetParent(hwnd, oldParent);
Show();
Activate();
}
Run Code Online (Sandbox Code Playgroud)
对我来说,将宽度,高度设置为零并将样式设置为无的解决方案无法解决,因为它仍然显示一个小窗口,带有恼人的阴影,似乎是围绕0x0窗口的边框(在Windows 7上测试) ).因此我提供这种替代选择.
Tho*_*que 16
这是一个肮脏的黑客,但它应该工作,并没有改变不透明度的缺点:
WindowStartupLocation
为Manual
Top
和Left
属性设置为屏幕外的某个位置ShowInTaskbar
为false,以便用户没有意识到有一个新窗口Show
和Hide
窗口您现在应该能够检索HWND
编辑:另一种选择,可能更好:设置ShowInTaskBar
为false和WindowState
to Minimized
,然后显示它:它根本不可见
Tho*_*que 11
我已经发布了这个问题的答案,但我刚刚找到了一个更好的解决方案.
如果您只需要确保创建HWND,而不实际显示窗口,则可以执行以下操作:
public void InitHwnd()
{
var helper = new WindowInteropHelper(this);
helper.EnsureHandle();
}
Run Code Online (Sandbox Code Playgroud)
(实际上,EnsureHandle
当问题发布时,该方法不可用,它是在.NET 4.0中引入的)
我从未试图做你正在做的事情,但是如果你需要显示Window来获得HWND,但又不想显示它,请将Window Opacity设置为0.这也将阻止任何命中测试的发生.然后,您可以在窗口上使用公共方法将"不透明度"更改为100,以使其可见.
归档时间: |
|
查看次数: |
24460 次 |
最近记录: |