C # GDI + programming (v)

Source: Internet
Author: User
Call API function to draw in window non-client area

GDI + 's Graphics class has a FROMHDC function that can create a graphics object based on the window device context (DC), in VC + +, the window client area and the non-client area of the drawing is nothing more than the GETWINDOWDC and GETDC functions of the different calls. The former obtains the entire window DC, which obtains the window client area DC.

Then we can call the GETWINDOWDC function in C # to get the entire window DC and then load it through FROMHDC so that we can draw on the entire window.

How does C # invoke the Windows API, or how to invoke a function in a dynamic-link library (DLL).

Similar to VC + +, first import the dynamic link library, and then declare the API function, as follows:

[System.Runtime.InteropServices.DllImport ("User32.dll")]
private static extern IntPtr GETWINDOWDC (INTPTR hwnd);

Of course, the above is the simplest, there are some details did not say, first of all, will be the basic use of the line, the details of the problem later explained in detail.

In C #, we find that the parameter types of API functions are different, such as the handle Hdc,hwnd in VC + +. There is no way to use IntPtr instead when declaring here, because C # does not have the concept of pointers, and we find that by checking HDC, and the HWND type definition, they are all pointer types.

So in C #, these "handle" types are replaced with IntPtr, including the area handle Hrgn,hicon icon, Hfont font handle, and so on.

Look at an example, (then the previous chapter)

public partial class Form1:form
{
Import the dynamic link library, declare the function, this function is declared in the Form1 class.
[System.Runtime.InteropServices.DllImport ("User32.dll")]
private static extern IntPtr GETWINDOWDC (INTPTR hwnd);
Path to store PNG opaque portions
Private GraphicsPath Path = new GraphicsPath ();
Loading PNG pictures
Bitmap bmp = New Bitmap ("D:\\image\\win.png");
Public Form1 ()
{
InitializeComponent ();
Determine the color value of each pixel to get the display area of the picture
for (int y = 0; y < bmp. Height; y++)
for (int x = 0; x < BMP. Width; X + +)
{
Color cor = BMP. GetPixel (x, y);
int ARGB = Cor. ToArgb ();
byte[] Bargb = bitconverter.getbytes (ARGB);
Pixel color values are not transparent
if (bargb[3]! = 0)
{
Add this pixel area to the path.
Path. AddRectangle (New Rectangle (x, Y, 1, 1));
}
}
Setting the window display area, creating a region from a path
This. Region = new Region (path);
This. Paint + = Formpaint;

}
private void Formpaint (object sender, PaintEventArgs e)
{

OnPaintBackground (e);
Handle is a window handle, which is a IntPtr type
INTPTR hdc = GETWINDOWDC (this. Handle);
To create a Graphics object from a window DC
Graphics gr = GRAPHICS.FROMHDC (HDC);
Drawing pictures
Gr. DrawImage (BMP, New Rectangle (0, 0, BMP). Width, BMP. Height));
}
protected override void OnPaintBackground (PaintEventArgs e)
{
Transparent paint brush Fill
Base. OnPaintBackground (e);
E.graphics.fillrectangle (Brushes.transparent, this. ClientRectangle);
}

}

How, the effect is good, but a drag window on the true colors, notice the shadow under the apple, is to achieve this effect will bring some problems, or say a lot of trouble. I'm just not going to solve it. Moving the window, or maximizing the window, does not completely refresh the entire window, causing the problem to occur. This problem will be solved later,

Friends who are interested can also solve this problem.

In addition, I fill the window with a transparent brush only client area, if you want to fill the entire window (including the title bar), the method with the entire window drawing, get WINDOWDC, and then

Creates a graphics object and draws the window background.

(digression: In VC + +, customer area and non-client area has different redraw message, WM_PAINT and Wm_ncpaint, this point to note, in the refresh of the non-client area, do not redraw the customer area, although there will be no problem, but the impact of the efficiency is always bad, can avoid to avoid)

Self-Painted window non-client area (including title bar, Max, minimize, Close button)

Overriding the message handler function WndProc

public partial class Form1:form
{
Public Form1 ()
{
InitializeComponent ();
}
protected override void WndProc (ref Message m)
{
if (m.msg = = 0xa3)//WM_NCLBUTTONDBLCLK Double-click Header message
MessageBox.Show ("You double-clicked the title bar");
Default Message Handling
Base. WndProc (ref m);
}

}

This will give you a hint when you double-click the title bar, and then the default processing.

Check the value of the message corresponding to VC + + compiler to check, such as Wm_lbuttondown and then right-click, choose to go to the definition can be viewed.

The M.hwnd Store has window handles, m.LParam and M.wparam are included with the message, and can be explained in wparam and lparam parameters in the CreateWindow function.

Self-painted non-client area workload is too big, here I only give a general idea, direction, and later to do it.

The premise of course is to calculate the various data, such as the window has no border, if any, get the border width, height, and then calculate the four border rectangle area.

Finally, the judging window has no maximum, the maximum small attribute, and then obtains three button area.

The SystemInformation class stores this data, such as Systeminformation.captionbuttonsize store the size of the title bar button, get the size, you can

The area of the button is determined, because the three buttons are all in the upper-right corner of the window, removing the high-width of the border.

While Systeminformation.captionheight stores the height of the title bar, the high-width of the border is stored in systeminformation.bordersize or Systeminformation.border3dsize, which is based on the window's for Mborderstyle decided. Whether the window is maximized can be judged by MaximizeBox, which is true maximized.

Get the above data in response to various messages in the non-client area, such as the left mouse button message Wm_nclbuttondown and Wm_nclbuttonup.

The mouse moves the message wm_ncmousemove, and then begins to paint itself.

Another rectangle class of contains function, you can determine whether a point in a rectangular region.


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.