Windmix
Windmix

Reputation: 3

Set the parent window for the winform form with a transparent background C#

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

Answers (1)

Anderson Constantino
Anderson Constantino

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

Related Questions