none
WPF Control as child window under Win32 Window with transparent background (help and question) RRS feed

  • Question

  • I created WPF Control and add it on Win32 Windows. It work ok, but when my WPF control have transparent background, background is black inside Win32 Windows.

    From this documentation it looks like it is possible with Regions, but I lost whole day without any success.

    I don't know how to use or set Regions, it is not clear from documentation what means regions.

    Question is how to create HwndSource transparent under Win32 WIndow? I need it working under Windows 7 up to recent Win version.

    Here is code what I have:

    // this is inside WndProc()

    wpfHwnd = GetHwnd(hWnd , 0 , 0 , rect.right, rect.bottom);

    HRGN rgn = CreateRectRgn(0, 0, rect.right, rect.bottom);
    SetWindowRgn(wpfHwnd, rgn, TRUE); // this doesnt help

    // ... HWND GetHwnd(HWND parent, int x, int y, int width, int height) { System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters( "my window" // NAME ); sourceParams->PositionX = x; sourceParams->PositionY = y; sourceParams->Height = height; sourceParams->Width = width; sourceParams->ParentWindow = IntPtr(parent); sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; sourceParams->UsesPerPixelOpacity = true; System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams); Page1 ^myPage = gcnew Page1(); source->RootVisual = myPage; HWND wnd = (HWND)source->Handle.ToPointer(); return wnd; }


    Tuesday, September 10, 2019 10:01 PM

Answers

  • It is originally for Winforms, but can be used in C++/Win32.

    For example, a rotated button (in a canvas as child of ElementHost) :

    System::Windows::Controls::Canvas^ canvas = gcnew System::Windows::Controls::Canvas();
    System::Windows::Controls::Button^ btn1 = gcnew System::Windows::Controls::Button();
    btn1->Content = "Test Button";
    btn1->SetValue(System::Windows::Controls::Canvas::LeftProperty, 50.0);
    btn1->Width = 200;
    btn1->Height = 40;
    canvas->Children->Add(btn1);
    
    System::Windows::Media::RotateTransform^ rotateTransform1 = gcnew System::Windows::Media::RotateTransform(45);
    btn1->RenderTransform = rotateTransform1;
    
    System::Windows::Forms::Integration::ElementHost^ eh = gcnew System::Windows::Forms::Integration::ElementHost();
    eh->Child = canvas;
    eh->Location = System::Drawing::Point(10, 10);
    eh->Size = System::Drawing::Size(300, 300);
    eh->BackgroundImage = gcnew System::Drawing::Bitmap("e:\\blue-floral-background-flower-vector-3286564.jpg");
    
    HWND hWndWrapper = (HWND)eh->Handle.ToPointer();
    SetParent(hWndWrapper, hWnd);

    • Marked as answer by Striebrovlas Wednesday, September 11, 2019 12:36 PM
    Wednesday, September 11, 2019 12:14 PM
  • Thanks. It is working!

    The only strange thing is, when I use Page it is not working (show nothing) but when I use UserControl as Child, it show UserControl with transparent background.

    myHost->Child = myPage1; // myPage must be UserControl from WPF


    • Edited by Striebrovlas Wednesday, September 11, 2019 12:36 PM
    • Marked as answer by Striebrovlas Wednesday, September 11, 2019 12:36 PM
    Wednesday, September 11, 2019 12:35 PM

All replies

  • Hi,

    Thank you for posting here.

    >>how to create HwndSource transparent under Win32 WIndow?

    When you create the HwndSource, you could set the UsesPerPixelOpacity property via HwndSourceParameters.UsesPerPixelOpacity. Setting it to true creates a transparent window. But this property only works if the HwndSource is a top-level window which means it must have the WS_POPUP instead of WS_CHILD.

    If you want to make the WPF control transparent and be a child of the Win32 window. I'm afraid of that there is no way to do it.

    Best Regards,

    Jeanine Zhang

    Wednesday, September 11, 2019 7:23 AM
    Moderator
  • Thanks, before I mark it as answer I'll wait some time if someone have solution.

    Wednesday, September 11, 2019 10:06 AM
  • You can use ElementHost like in Winforms

    For example, an ElementHost with a BackgroundImage (light blue flowers) and
    a FlowDocumentScrollViewer with a png (Hulk, drawn transparent) and a jpg (not transparent) :


    The control can also be layered with a Manifest (OS >= Windows 8) :

    • Edited by Castorix31 Wednesday, September 11, 2019 11:22 AM
    Wednesday, September 11, 2019 10:59 AM
  • But isn't ElementHost for WinForms? If I understand instead 

    Page1 ^myPage = gcnew Page1();
    	source->RootVisual = myPage;

    I 'll use

    ElementHost ^myHost = gcnew ElementHost();
    myHost->Child = myPage1;
    source->RootVisual = myHost;

    ?

    Wednesday, September 11, 2019 11:36 AM
  • It is originally for Winforms, but can be used in C++/Win32.

    For example, a rotated button (in a canvas as child of ElementHost) :

    System::Windows::Controls::Canvas^ canvas = gcnew System::Windows::Controls::Canvas();
    System::Windows::Controls::Button^ btn1 = gcnew System::Windows::Controls::Button();
    btn1->Content = "Test Button";
    btn1->SetValue(System::Windows::Controls::Canvas::LeftProperty, 50.0);
    btn1->Width = 200;
    btn1->Height = 40;
    canvas->Children->Add(btn1);
    
    System::Windows::Media::RotateTransform^ rotateTransform1 = gcnew System::Windows::Media::RotateTransform(45);
    btn1->RenderTransform = rotateTransform1;
    
    System::Windows::Forms::Integration::ElementHost^ eh = gcnew System::Windows::Forms::Integration::ElementHost();
    eh->Child = canvas;
    eh->Location = System::Drawing::Point(10, 10);
    eh->Size = System::Drawing::Size(300, 300);
    eh->BackgroundImage = gcnew System::Drawing::Bitmap("e:\\blue-floral-background-flower-vector-3286564.jpg");
    
    HWND hWndWrapper = (HWND)eh->Handle.ToPointer();
    SetParent(hWndWrapper, hWnd);

    • Marked as answer by Striebrovlas Wednesday, September 11, 2019 12:36 PM
    Wednesday, September 11, 2019 12:14 PM
  • Thanks. It is working!

    The only strange thing is, when I use Page it is not working (show nothing) but when I use UserControl as Child, it show UserControl with transparent background.

    myHost->Child = myPage1; // myPage must be UserControl from WPF


    • Edited by Striebrovlas Wednesday, September 11, 2019 12:36 PM
    • Marked as answer by Striebrovlas Wednesday, September 11, 2019 12:36 PM
    Wednesday, September 11, 2019 12:35 PM