Reputation: 3
Please help me figure out the problem. There is a form on WinForms. I ask her the parent:
SetParent(guestHandle, hostHandle); SetWindowLongPtr(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
The form is moved to the parent window.
Everything stops working when I set a transparent background for the form. The form becomes a child, but it is not visible.
I tried installing transparency via user32, I tried to do the same with the wpf. There is no result. How to achieve a working window with transparency in the parent application?
P.s. The child window is embedded in a third-party application.
Sample code:
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
namespace Demo
{
public partial class MainWindow : Window
{
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
public const int GWL_EXSTYLE = -20;
public const int WS_EX_LAYERED = 0x80000;
public const int LWA_ALPHA = 0x2;
public const int LWA_COLORKEY = 0x1;
public static int GWL_STYLE = -16;
public static int WS_CHILD = 0x40000000;
public HwndSource hwnd;
public MainWindow()
{
InitializeComponent();
}
public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, int dwNewLong)
{
if (Environment.Is64BitOperatingSystem)
return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong));
else
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
}
private void Window_ContentRendered(object sender, EventArgs e)
{
this.hwnd = PresentationSource.FromVisual(this) as HwndSource;
if (this.hwnd != null)
{
Process hostProcess = Process.GetProcessesByName("POWERPNT").FirstOrDefault();
if (hostProcess != null)
{
IntPtr hostHandle = hostProcess.MainWindowHandle;
IntPtr guestHandle = this.hwnd.Handle;
SetParent(guestHandle, hostHandle);
SetWindowLongPtr(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
}
}
}
}
}
Upvotes: -1
Views: 128
Reputation: 557
Here it worked like this in a WPF project
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
public partial class MainWindow : Window
{
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
private static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
public const int GWL_EXSTYLE = -20;
public const int WS_EX_LAYERED = 0x80000;
public const int WS_EX_TRANSPARENT = 0x20;
public const int LWA_ALPHA = 0x2;
public const int LWA_COLORKEY = 0x1;
public HwndSource hwnd;
public MainWindow()
{
InitializeComponent();
}
public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, int dwNewLong)
{
if (Environment.Is64BitOperatingSystem)
return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong));
else
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
}
private void Window_ContentRendered(object sender, EventArgs e)
{
this.hwnd = PresentationSource.FromVisual(this) as HwndSource;
if (this.hwnd != null)
{
Process hostProcess = Process.GetProcessesByName("WindowsFormsApp5").FirstOrDefault();
if (hostProcess != null)
{
IntPtr hostHandle = hostProcess.MainWindowHandle;
IntPtr guestHandle = this.hwnd.Handle;
SetWindowLong(hostHandle, GWL_EXSTYLE, (IntPtr)(GetWindowLong(hostHandle, GWL_EXSTYLE) ^ WS_EX_LAYERED));
SetLayeredWindowAttributes(hostHandle, 0, 200, LWA_ALPHA);
SetParent(guestHandle, hostHandle);
}
}
}
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
Window_ContentRendered(sender, e);
}
}
Upvotes: 0