Click through window with image (WPF) issues (HTTRANSPARENT isn't working)
-
Monday, October 26, 2009 3:02 PM
Hi
I've had a look on a number of forums about using HTTRANSPARENT on a WPF window to allow mouse clicks to be registered by anything
under the window in question (a click through/ glass like window).
The problem is that handling windows messages doesn't seem to work (the code get's called but has not effect).
I've also tried setting the IsHitTestVisible to false (just in case) but this also doesn't work.
I've added the relevant code below:
(XML stuff, note the background color is only there so that I can see the window for testing)
<Window x:Class="MyNewWPF.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="768" Width="1024" WindowStyle="None" Topmost="True" AllowsTransparency="True" Background="Blue" Opacity="0.2" xmlns:effect="clr-namespace:MyNewWPF"> <Grid x:Name="imageGrid" > <Grid.ColumnDefinitions> <ColumnDefinition Width="43*" /> <ColumnDefinition Width="181*" /> <ColumnDefinition Width="254*" /> </Grid.ColumnDefinitions> </Grid> </Window>
(Form code that tries to make it click through/ glass like)
public const Int32 WM_NCHITTEST = 0x84; public const Int32 HTTRANSPARENT = -1; void Window1_Loaded(object sender, RoutedEventArgs e) { HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); source.AddHook(new HwndSourceHook(WndProc)); } IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == (int)WM_NCHITTEST) { handled = true; return (IntPtr)HTTRANSPARENT; } return IntPtr.Zero; }
Any ideas why this isn't working??? Is it because WPF windows don't allow for this type of access?
Thanks
All Replies
-
Monday, October 26, 2009 11:29 PMModerator
HTTRANSPARENT only works to pass on the message to a window that's owned by the *same thread*. That precludes "anything under the window".
A WPF Window is transparent to mouse clicks if you set its AllowTransparency to true and set the Background to Transparent. Ask more questions about this in the WPF forum.
Hans Passant.- Marked As Answer by CrazyMagic Tuesday, October 27, 2009 9:30 AM
-
Tuesday, October 27, 2009 9:31 AMCool ok will do.
The issue is that I also have a image that's needs to be click through as well.
I'll ask this over on the WPF forum then
Thanks -
Thursday, September 09, 2010 6:57 PM
HittestVisible works for controls inside that window, which are unaware of OS and are entirely drawn by WPF. But the Window is different. It is OS object so you have to deal with WM_ and WS_ and PInvokes
I've done this in WinForms, I've tried what youv'e written here, but it doesn't work . But fortunantly it is simple ones you know where to tweak.
heres a winForms examlple
http://social.msdn.microsoft.com/forums/en-US/winforms/thread/50dc4a18-853e-447f-8477-776e857d8330/?prof=required
I plan to write the same thing in WPF
Here's how I solved problem:
I used the WS_EX_TRANSPARENT flag. It took me days to find it. Nobody provided me with a ready example to invesatigate. U can see it if u google for [tsadigov ghost window]. But I was lucky and one day when my comp was overloaded and I was dragging a file the icon of dragged file stayed on screen and I could click through it. That was what I wanted. I also used Spy++ to realize how it was done. I hadnt enough time to finish that project. But project that I uploaded is a working example.
also I've found an answer for how doing this in WPF on the NET
heres source code
class MyWindow:Window{ //... //... protected override void OnSourceInitialized(EventArgs e) { // Get this window's handle IntPtr hwnd = new WindowInteropHelper(this).Handle; // Change the extended window style to include WS_EX_TRANSPARENT int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE); SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT); base.OnSourceInitialized(e); } public const int WS_EX_TRANSPARENT = 0x00000020; public const int GWL_EXSTYLE = (-20); [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hwnd, int index); [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); }
.NET guy- Proposed As Answer by tsadigov Thursday, September 09, 2010 6:58 PM

