The notification window attaches a normal form to a skin. The so-called skin is a bitmap image, which is drawn to the form surface through the onpaintbackground event of the form, before attaching a bitmap, you need to adjust the visible properties of the Form. Because the Drawing operation is for the form customer region, the customer region refers to all the areas under the Form title bar and within the form border, therefore, you need to adjust the border and appearance attribute formborderstyle of the form to none, so that the drawn image will fill the entire form.
First, we will use the region object. The region object can accurately depict the contour range of any desired shape, create a region object using a bitmap image and pass it to the region attribute of the form to display the form according to the profile defined by region. Bitmap files used as skin can be created and edited using any image editing software such as photeshop. Note that the background color of the image must be adjusted to a specific color for convenience.ProgramClear it when drawing. Here we use the pink background color. To allow the region object to create a form based on the Content border of the image, we also need to use the graphicspath class to mark the image outline according to a certain path, and then create a region object based on the path.
then, the bitmap content is displayed on the form surface through the drawing event of the form. Instead of directly using the onpaintbackground event, we reload this method, the advantage of this is that some low-layer rendering operations are still handed over.. NET Framework, we only need to consider the actual drawing operation. In the onpaintbackground method, we have enabled the dual-buffer plot technology. The so-called technology is to first display or process the image to be displayed on a canvas in the memory, after the operation is complete, place the image displayed on the canvas to the form surface. This mechanism can effectively reduce the appearance of flashes and make the image display smoother. The notification form is raised from the bottom right of the screen for a period of time and then slowly dropped back. Here, the size range of the returned screen area is used. net Framework Method screen. getworkingarea (workarearectangle) calculates the initial position before the display of the notification form using a certain algorithm . Finally, the text to be displayed is drawn to the form surface according to a certain format and the region range specified by the rectangle object. The notification form is closed by setting an area. When you click with the mouse, check whether the clicked coordinates are in the area, you can run the Code that hides the notification form in the region.
We have noticed that when the QQ and MSN notification windows are displayed, the focus of the main form is not lost, that is, the program has not shifted its focus to the displayed notification form. After testing, we can call it in any way.. NET Framework provides a form display routine such as: form. show cannot ensure that the focus of the main form is not lost. In the VC environment, we can use the showwindows function of WIN32API to complete complex form display operations,. net Framework does not provide similar methods at all, so can we pass. net Framework calls this API function to display the form? Fortunately. the Net Framework provides P/invoke Platform calls. By using the platform to call such services, managed code can call the unmanaged functions implemented in the dynamic link library and mail their parameters, we can easily display a form without getting the focus. Windows APIs and constant definitions used in the program are stored in winuser. in the H header file, the corresponding dynamic link library file is user32.dll. the dllimportattribute class provided by the net framework defines the imported function, and then it can be conveniently called in the program.
Because we have hidden the title bar of the notification form, we need to manually drag the form. This article describes how to drag a form more efficiently. Some netizens prefer to use mouse events in combination when programming a form that is not dragged by the title bar, however, frequent event response and processing reduce program performance. We will continue to use the underlying Processing Method of WIN32API to solve this problem. This means to send the message clicked on the title bar to the form and simulate the actual drag operation.
We use two timers to display, stay, and hide the form. By setting the speed variable, we can change the display speed and hide speed of the window.
Program Implementation
Start Visual Studio. NET 2005, create a C # windows form application, name the solution as taskbarform, and name the project included as taskbarform. First, create the main form form1 of the program, and add two button controls on it, one is used to display the notification form, and the other ends the program. In solution manager, right-click the project and click "Add-Windows form". we name the newly created form taskbarform.
Under the definition of the taskbarform class, we create a variable for displaying strings and their colors, define several variables of the rectangle object to place the title, prompt content, and the area where you can drag the form and the close button. Then, we need to save the height of the form when it is floating in order to calculate the new height after moving. The intervalvalue variable is used to determine the display and hiding speed of the form. During platform calling, we need to define the constant values for passing to the function in advance. The wm_nclbuttondown and ht_caption constants are used to drag the form, and their values are saved in winuser. in the H header file, the corresponding dynamic link library name is user32.dll. The WIN32API we use is sendmessage, releasecapture, and showwindow. You can use dllimportattribute to import the corresponding functions and redefine them in the program, as shown below:
[Dllimportattribute ("user32.dll")]
Public static extern int sendmessage (intptr hwnd, int MSG, int wparam, int lparam );
// Send the message // The function prototype is defined in winuser. h.
[Dllimportattribute ("user32.dll")]
Public static extern bool releasecapture (); // release the mouse to capture winuser. h
[Dllimportattribute ("user32.dll")] // winuser. h
Private Static extern Boolean showwindow (intptr hwnd, int32 ncmdshow );
Sendmessage sends a message whose title bar is pressed repeatedly to simulate the drag of the Form. showwindow is used to display the form of a specific handle. Note that the second parameter ncmdshow indicates how the form should be displayed, however, we need to display the form without getting the focus. sw_shownoactivate can meet our requirements and continue to be in winuser. search in the H file and find the corresponding value of this constant is 4, so we can call this to display the form:
Showwindow (this. Handle, 4 );
We have created a user-defined function showform to encapsulate the above showwindow to display the form. At the same time, we have passed several rectangle rectangular area objects used, and finally called the showwindows function to display the form, the code snippet is as follows:
Public void showform (string ftitletext, string fcontenttext, rectangle fregionofformtitle, rectangle comment, rectangle fregionofformcontent, rectangle comment)
{< br> titletext = ftitletext;
contenttext = fcontenttext;
workarearectangle = screen. getworkingarea (workarearectangle);
This. top = workarearectangle. height + this. height;
formborderstyle = formborderstyle. none;
windowstate = formwindowstate. normal;
This. setbounds (workarearectangle. width-this. width, workarearectangle. height-currenttop, this. width, This. height);
currentstate = 1;
timer1.enabled = true;
titlerectangle = fregionofformtitle;
titlebarrectangle = Hangzhou;
contentrectangle = fregionofformcontent;
closebtnrectangle = fregionofclosebtn;
showwindow (this. handle, 4); // # define sw_shownoactivate 4
}
The currentstate variable indicates whether the status of the form is displayed, staying, or hidden. The two timers modify the position of the form based on the status of the form. We will use setbounds to perform this operation:
This. setbounds (workarearectangle. Width-This. Width, workarearectangle. Height-currenttop, this. Width, this. Height );
When the form needs to be raised, the top attribute value of the form is continuously reduced. When the form falls back, the form that increases the top attribute value and exceeds the height of the screen disappears. Although the principle is simple, it still needs to be precisely controlled.
The setbackgroundbitmap function first saves the background image of the form to the backgroundbitmap variable, and then creates a region based on the contour and transparent color of the bitmap image. bitmaptoregion is used to convert bitmap to region, the program then pays the region value to the region attribute of the form to create an irregular form.
Public void setbackgroundbitmap (image, color transparencycolor)
{
Backgroundbitmap = new Bitmap (image );
Width = backgroundbitmap. width;
Height = backgroundbitmap. height;
Region = bitmaptoregion (backgroundbitmap, transparencycolor );
}
Public region bitmaptoregion (Bitmap bitmap, color transparencycolor)
{
If (Bitmap = NULL)
Throw new argumentnullexception ("bitmap", "bitmap cannot be null! ");
Int Height = bitmap. height;
Int width = bitmap. width;
Graphicspath Path = new graphicspath ();
For (Int J = 0; j For (INT I = 0; I <width; I ++)
{
If (bitmap. getpixel (I, j) = transparencycolor)
Continue;
Int X0 = I;
While (I <width) & (bitmap. getpixel (I, j )! = Transparencycolor ))
I ++;
Path. addrectangle (New rectangle (x0, J, I-x0, 1 ));
}
Region region = new region (PATH );
Path. Dispose ();
Return region;
}
The background and text of the notification form are drawn in the overloaded onpaintbackground method, and the dual Buffer technology is used to draw the form. The Code is as follows:
Protected override void onpaintbackground (painteventargs E)
{
Graphics grfx = E. graphics;
Grfx. pageunit = graphicsunit. pixel;
Graphics offscreengraphics;
Bitmap offscreenbitmap;
Offscreenbitmap = new Bitmap (backgroundbitmap. Width, backgroundbitmap. Height );
Offscreengraphics = graphics. fromimage (offscreenbitmap );
If (backgroundbitmap! = NULL)
{
Offscreengraphics. drawimage (backgroundbitmap, 0, 0, backgroundbitmap. Width, backgroundbitmap. Height );
}
Drawtext (offscreengraphics );
Grfx. drawimage (offscreenbitmap, 0, 0 );
}
The above code first returns the graphics on the form drawing surface and saves it in the grfx variable. Then, creates a memory graphics object offscreengraphics and the memory bitmap object offscreenbitmap, and pays the reference value of the memory bitmap object to offscreengraphics, in this way, all the drawing operations on offscreengraphics also apply to offscreenbitmap. In this case, the background image backgroundbitmap that needs to be drawn to the graphics object in the memory will be drawn, the drawtext function calls graphics based on the size and range of the text to be displayed. drawstring displays the text in a specific area of the form. Finally, Call graphics. drawimage to display the drawn images in the memory to the notification form surface.
We also need to capture the mouse operation of the form, there are three operations here, 1. Processing the drag form operation, 2. Processing the closing operation of the notification form, 3. click in the content area. All three operations need to detect the inclusion relationship between the current mouse position and each rectangle area. As long as you click in a specific area, the corresponding processing will be performed. The Code is as follows:
Private void taskbarform_mousedown (Object sender, mouseeventargs E)
{
If (E. Button = mousebuttons. Left)
{
If (titlebarrectangle. Contains (E. Location) // drag when you click the title bar
{
Releasecapture (); // release Mouse capture
Sendmessage (handle, wm_nclbuttondown, ht_caption, 0); // send the left-click message to this form (title bar)
}
If (closebtnrectangle. Contains (E. Location) // click Close to close
{
This. Hide ();
Currenttop = 1;
}
If (contentrectangle. Contains (E. Location) // click the content area
{
System. Diagnostics. process. Start ("Http://www.Rithia.com");
}
}
}
This blog code is all from the Internet for your convenience. If the author is not satisfied, leave a message and I will delete it in time.