A perfect solution for compatibility between irregular forms and the WindowsFormsHost control in WPF

Source: Internet
Author: User

 

First, let's take a look at the incompatibility between irregular forms and the WindowsFormsHost control in WPF. The solution provided on the Internet cannot meet all the conditions and has specific conditions, for example, the solution to compatibility between irregular forms and WebBrowser controls in WPF is as follows. The solution of this netizen is also ingenious. Why do you say this? After you download his program and read it carefully, you will know that his webBrowser control is placed in a Form separately, associate this Form with a Bord control in WPF for synchronous movement. However, the Movement will flash and the white points of the Movement will appear during the movement. The user experience is certainly poor.

Okay, let's just get down to the right. Why is this problem? Why is it that the control embedded in WinForm cannot be displayed after a transparent form is set in WPF. At first, I thought it was not loaded normally, and I also needed UISPY. Through this software, I captured the currently running program and found that the embedded WinForm control in WPF has been loaded, I just didn't see it. Very depressing.

Sad reminder of the program, headache ah, what is the cause of it, online query information, found the http://msdn.microsoft.com/zh-cn/library/aa970688.aspx, let me understand a lot of knowledge. Since the project needs to use a transparent form and also create a rounded corner form, it is said that the Windows Settings in WPF are not changed, that is, WindowStyle = "None" and AllowTransparent = "True" are not changed, if you want to make some settings on WindowsFormsHost, you will find that this path cannot be implemented. A lot of time is wasted.

This cannot be achieved only by changing the train of thought, so AllowTransparent = "false", then it can be displayed, haha ...... Of course, you still need to modify it. The WPF form is ugly and there is a border outside. This is also a problem. I want to use the features of WPF. It seems that there is no relevant method.

Okay, there are still some ways. Programmers are trying to solve the problem. What should they do? They can only call Windows APIs and remove the border on the outermost layer. So what do you need? The train of thought is there, right? Let's take action. google and Baidu have a lot of examples. The c ++ examples are the most comprehensive, for more information, see. Then we sorted out the need for these functions:

SetWindowLong: Set the window style.

GetWindowLong: get the window style

Setmediawrgn: Set the workspace of window

CreateRoundRectRgn: create a region with rounded corners

SetLayeredWindowAttributes sets the hierarchical form for transparency settings

Baidu and Encyclopedia have a detailed explanation of them, but the explanation of C ++ is given, so you need to convert C ++ into C, for how to call the C ++ DLL file in C #, Baidu and google have the answer you want, so I will fill it up. However, pay attention to type conversion and character conversion.

Set conversion.

Next I will post the functions I have converted to you to serve readers.

 

Public class NativeMethods

{

/// <Summary>

/// A windows style with an external border and a title

/// </Summary>

Public const long WS_CAPTION = 0X00C0000L;

 

// Public const long WS_BORDER = 0X0080000L;

 

/// <Summary>

/// Hierarchical display of window extension styles

/// </Summary>

Public const long WS_EX_LAYERED = 0x00080000L;

 

/// <Summary>

/// Style with alpha

/// </Summary>

Public const long LWA_ALPHA = 0x00000002L;

 

/// <Summary>

/// Color settings

/// </Summary>

Public const long LWA_COLORKEY = 0x00000001L;

 

/// <Summary>

/// Basic style of window

/// </Summary>

Public const int GWL_STYLE =-16;

 

/// <Summary>

/// Extended window style

/// </Summary>

Public const int GWL_EXSTYLE =-20;

 

/// <Summary>

/// Set the style of the form

/// </Summary>

/// <Param name = "handle"> handle of the operation form </param>

/// <Param name = "oldStyle"> set the style type of the Form. </param>

/// <Param name = "newStyle"> New Style </param>

[System. Runtime. InteropServices. DllImport ("User32.dll")]

Public static extern void SetWindowLong (IntPtr handle, int oldStyle, long newStyle );

 

/// <Summary>

/// Obtain the style specified by the form.

/// </Summary>

/// <Param name = "handle"> handle of the operation form </param>

/// <Param name = "style"> style to be returned </param>

/// <Returns> current window style </returns>

[System. Runtime. InteropServices. DllImport ("User32.dll")]

Public static extern long GetWindowLong (IntPtr handle, int style );

 

/// <Summary>

/// Set the work area of the form.

/// </Summary>

/// <Param name = "handle"> handle of the operation form. </param>

/// <Param name = "handleRegion"> handle of the form area. </param>

/// <Param name = "regraw"> if set to <c> true </c> [regraw]. </param>

/// <Returns> return value </returns>

[System. Runtime. InteropServices. DllImport ("User32.dll")]

Public static extern int setjavaswrgn (IntPtr handle, IntPtr handleRegion, bool regraw );

 

/// <Summary>

/// Create an area with rounded corners.

/// </Summary>

/// <Param name = "x1"> X value of the coordinate in the upper left corner. </param>

/// <Param name = "y1"> Y value of the coordinate in the upper left corner. </param>

/// <Param name = "x2"> X value of the coordinate in the lower right corner. </param>

/// <Param name = "y2"> Y value of the coordinate in the lower right corner. </param>

/// <Param name = "width"> width of the rounded corner elliptical. </param>

/// <Param name = "height"> width of the rounded corner of the elliptical corner. </param>

/// <Returns> hRgn handle </returns>

[System. Runtime. InteropServices. DllImport ("gdi32.dll")]

Public static extern IntPtr CreateRoundRectRgn (int x1, int y1, int x2, int y2, int width, int height );

 

/// <Summary>

/// Sets the layered window attributes.

/// </Summary>

/// <Param name = "handle"> handle of the window to be operated </param>

/// <Param name = "colorKey"> RGB value </param>

/// <Param name = "alpha"> Alpha value, transparency </param>

/// <Param name = "flags"> parameters </param>

/// <Returns> true or false </returns>

[System. Runtime. InteropServices. DllImport ("User32.dll")]

Public static extern bool SetLayeredWindowAttributes (IntPtr handle, ulong colorKey, byte alpha, long flags );

}

The following question is how to perform the operation. First, add a Load event to the WPF form embedded in the WinForm control and add the following code to the event:

 

// Obtain the form handle

IntPtr hwnd = new System. Windows. Interop. Unzip winterophelper (this). Handle;

 

// Obtain the style of the form

Long oldstyle = NativeMethods. GetWindowLong (hwnd, NativeMethods. GWL_STYLE );

 

// Change the form style to a borderless form

NativeMethods. SetWindowLong (hwnd, NativeMethods. GWL_STYLE, oldstyle &~ NativeMethods. WS_CAPTION );

 

// SetWindowLong (hwnd, GWL_EXSTYLE, oldstyle &~ WS_EX_LAYERED );

// 1 | 2 <8 | 3 <16 r = 1, g = 2, B = 3. For details, see winuse. h.

// Set the form to a transparent form

NativeMethods. SetLayeredWindowAttributes (hwnd, 1 | 2 <8 | 3 <16, 0, NativeMethods. LWA_ALPHA );

 

// Create the rounded corner Form 12. You can set this value based on your project.

Examples. setmediawrgn (hwnd, NativeMethods. CreateRoundRectRgn (0, 0, Convert. ToInt32 (this. ActualWidth), Convert. ToInt32 (this. ActualHeight), 12, 12), true );

 

Also, after the form size is changed, you need to re-draw the rounded corner form. Otherwise, the display effect may be unsatisfactory. Add the following Event code to reproduce the rounded corner area of the form when the form size is changed:

 

/// <Summary>

/// Handles the SizeChanged event of the specified topshell control.

/// </Summary>

/// <Param name = "sender"> The source of the event. </param>

/// <Param name = "e"> The <see cref = "System. Windows. SizeChangedEventArgs"/> instance containing the event data. </param>

Private void upload topshell_sizechanged (object sender, SizeChangedEventArgs e)

{

// Obtain the form handle

IntPtr hwnd = new System. Windows. Interop. Unzip winterophelper (this). Handle;

 

// Create a rounded corner form

Examples. setmediawrgn (hwnd, NativeMethods. CreateRoundRectRgn (0, 0, Convert. ToInt32 (this. ActualWidth), Convert. ToInt32 (this. ActualHeight), 12, 12), true );

}

 

Now all the problems have been solved. If you have any questions, you can leave a message to help you. I am very honored.

Please respect the fruits of the author's work and support reprinting. Please indicate the source of the blog. Thank you.

 

Excerpted from the column listing the statement

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.