Delphi technique to transform the output mode of hint

Source: Internet
Author: User

The use of hints in Delphi is as simple as setting the controls you want to use hint as follows:
Showhint: = True;

Hint: = ' hint message ';

It's quite handy not to write a line of code.

But sometimes we want to customize the effect of the hint, so that it looks more beautiful and more personal features, no matter, Delphi has a way to let you write your favorite hint effect.

Delphi's hint function is categorized in the application class, so we can see several properties of hint in the application class, which can set the color of the hint window, dwell time, occurrence time, etc., set these properties, will affect the hint function of the whole project. The benefit of this, of course, is to unify the hint style, and let the other classes ignore the hint implementation.

We can build a simple project, put a button, set the button's Showhint to True, and set a value for hint. Run the program and a prompt window appears when the cursor is pointing to the button.

But if we write in the creation event of the main window:

Procedure Tform1.formcreate (Sender:tobject);

Begin

Application.showhint: = False;

End

These re-run the program, there is no longer a hint, it can be seen application Showhint control the entire project hint whether the display.

If you are bored with the color of the hint window that you normally see, you can set application Hintcolor as other colors. However, there is a problem, if the hintcolor is set to black, the prompt font is also black, you can not see the prompt message. To do this, we need to understand another global object, in fact, when the program runs, it creates three global objects: Application,screen,mouse, the responsibilities of the three objects are obvious. Screen closes the state of the running project on the display, it has a Hintfont property that allows you to set the font of the cue information.
We can write the following code:

Procedure Tform1.button1click (Sender:tobject);

Begin

Application.hintcolor: = Clblack;

Screen.HintFont.Color: = Clwindow;

Screen.HintFont.Size: = 14;

End

Run the program to see the effect, prompting the font to become white and become larger.

In addition application has these three attributes:

Hinthidepause,hintpause,hintshortpause, control the time of the display of the cue window and so on. Hinthidepause specifies the time, in milliseconds, that the prompt window will appear on the screen. Hintpause Specifies how long the prompt window, in milliseconds, will appear when you move the cursor over a control that is prompted. And Hintshortpause, when you move the cursor over a set of hint controls, displays the hint interval. For example, there are two control buttons with hint, and when your cursor moves quickly from BTN1 to BTN2, hint is displayed after hintshortpause milliseconds.

There is a special property in application hint, we can not help but wonder, hint specified is the hint of that control. In fact, one of the great uses of the hint attribute is to give the controls a chance to appear directly in the hint window, so that they can be prompted in other ways. Like the menu, we have no way to make the menu appear hint window, but we can make the menu hint appear on the status bar.

We add a status bar to the main project window above and add a menu control, set several menu items, and set some strings for each menu's recommended hint property.

Then write down:

Procedure Tform1.formcreate (Sender:tobject);

Begin

Application.onhint: = Whenhint;

End

Procedure Tform1.whenhint (Sender:tobject);

Begin

Statusbar1.simpletext: = Application.hint;

End

Run the program, when you point to the menu item, look, the status bar appears on the prompt.

As you can see, with some simple code, you can make the hints unique. But people will never be satisfied, they always want to be able to do a better hint, even to the hint of the window style to ask. Delphi's engineers thought of this, and they set a hint window's parent class through the inheritance of the class, which is the hint window we see, and we can write our own cue window by inheriting it and overwriting the virtual method it provides.

To read the source of Hintwindow, you just cover a few virtual methods, you can make very beautiful hints come out.

Delphi's hint, though simple to use, is not flexible enough because it provides a unified style, so you can't specify a hint as an error indication, and a hint is a warning prompt. About this, we have to use the API to achieve, in the Internet to find a comic hint, there are many articles available. No longer mentioned here.

An example of a custom hint window is given below. This custom hint window has a good effect, with a glass border and a shaded effect.
But before we do, we have to introduce a custom, hint parent class for Thintwindow, defined in the controls unit. Let's look at a few virtual methods, createparams the style of the window, and we'll overwrite it so that it doesn't have a border. Ncpaint draw the border of the window, we also want to overwrite it, because we do not need a border. Paint is more important for painting Hint window client area content, of course to be covered. But the most important thing is activatehint, it will set the window size, and show it, we are here to customize the window effect of a class glass. The implementation of this class is given below:
Unit Wdhintwnd;

Interface

Uses

Windows, Classes, Controls, Graphics, Forms, Sysutils, Extctrls;

Type

Twdhintwnd = Class (Thintwindow)

Private

Fwndbmp:tbitmap; Window bitmap

Fhintbmp:tbitmap; Hint Information bitmap

Protected

Procedure CreateParams (var params:tcreateparams); Override

Procedure Paint; Override

Procedure Ncpaint (DC:HDC); Override

{Draw Hint's image}

Procedure Drawhintimg (Bmp:tbitmap; ahint:string);

{Get the image of the desktop area corresponding to the prompt window}

Procedure Getdesktopimg (Bmp:tbitmap; R:trect);

{The desktop area image is processed so that it looks like a piece of glass with a little shadow}

Procedure Effecthandle (wndbmp, Hintbmp:tbitmap);

Public

Constructor Create (aowner:tcomponent); Override

destructor Destroy; Override

Procedure Activatehint (rect:trect; const ahint:string); Override

End


Implementation

{Twdhintwnd}

Procedure Twdhintwnd.activatehint (rect:trect; const ahint:string);

Var

P:tpoint;

Begin

Here to get a proper size display text

Fhintbmp.width: = Rect.right-rect.left;

Fhintbmp.height: = Rect.bottom-rect.top + 4;

Drawhintimg (Fhintbmp, ahint);

Fwndbmp.width: = Rect.right-rect.left + 23;

Fwndbmp.height: = Rect.bottom-rect.top + 27;

INC (Rect.right, 23);

INC (Rect.bottom, 27);

Boundsrect: = Rect;

If left < Screen.desktopleft then

Left: = Screen.desktopleft;

If Top < screen.desktoptop Then

Top: = Screen.desktoptop;

If left + Width > Screen.desktopwidth Then

Left: = Screen.desktopwidth-width;

If Top + Height > Screen.desktopheight Then

Top: = Screen.desktopheight-height;

Getdesktopimg (Fwndbmp, boundsrect);

Effecthandle (Fwndbmp, fhintbmp);

P: = ClientToScreen (Point (0, 0));

SetWindowPos (Handle, Hwnd_topmost, p.x, p.y, 0, 0,

Swp_showwindow or Swp_noactivate or swp_nosize);

End


Constructor Twdhintwnd.create (aowner:tcomponent);

Begin

inherited;

Fwndbmp: = tbitmap.create;

Fwndbmp.pixelformat: = Pf24bit;

Fhintbmp: = tbitmap.create;

End


Procedure Twdhintwnd.createparams (var params:tcreateparams);

Begin

inherited;

Remove window border

Params.style: = Params.style and not ws_border;

End


destructor Twdhintwnd.destroy;

Begin

Fwndbmp.free;

Fhintbmp.free;

inherited;

End


Procedure Twdhintwnd.getdesktopimg (Bmp:tbitmap; R:trect);

Var

C:tcanvas;

Begin

C:= tcanvas.create;

Try

C.handle: = GetDC (0);

Bmp.Canvas.CopyRect (Rect (0, 0, Bmp.width, bmp.height), C, R);

Finally

C.free;

End

End


Procedure Twdhintwnd.effecthandle (wndbmp, Hintbmp:tbitmap);

Var

R:trect;

I, J:integer;

P:pbytearray;

Transt, Transtangle:integer;

Begin

R: = Rect (0, 0, wndbmp.width-4, wndbmp.height-4);

Frame3d (Wndbmp.canvas, R, Clmedgray, Clbtnshadow, 1);

Shadow effect at the bottom of the window

Transt: = 60;

For j:= wndbmp.height-4 to Wndbmp.height-1 do

Begin

P: = Wndbmp.scanline[j];

Transtangle: = Transt;

For i:= 3 to Wndbmp.width-1 do

Begin

If you are in the lower right corner

If i > wndbmp.width-5 then

Begin

P[3*i]: = p[3*i] * transtangle DIV 100;

P[3*i + 1]: = p[3*i + 1] * transtangle DIV 100;

P[3*i + 2]: = P[3*i + 2] * transtangle DIV 100;

Transtangle: = Transtangle + 10;

If Transtangle > Transtangle: = 90;

End

ELSE begin

P[3*i]: = p[3*i] * transt DIV 100;

P[3*i + 1]: = p[3*i + 1] * transt DIV 100;

P[3*i + 2]: = P[3*i + 2] * transt DIV 100;

End

End

Transt: = Transt + 10;

End

Shadow effect on the right side of the window

For J: = 3 to Wndbmp.height-5 do

Begin

P: = Wndbmp.scanline[j];

Transt: = 60;

For i:= wndbmp.width-4 to Wndbmp.width-1 do

Begin

P[3*i]: = p[3*i] * transt DIV 100;

P[3*i + 1]: = p[3*i + 1] * transt DIV 100;

P[3*i + 2]: = P[3*i + 2] * transt DIV 100;

Transt: = Transt + 10;

End

End

WndBmp.Canvas.Draw (ten, hintbmp);

End


Procedure Twdhintwnd.ncpaint;

Begin

Overloading does not let the picture border

End


Procedure Twdhintwnd.paint;

Begin

Canvas.copyrect (Clientrect, Fwndbmp.canvas, Clientrect);

End


Procedure Twdhintwnd.drawhintimg (Bmp:tbitmap; ahint:string);

Var

R:trect;

Begin

Bmp.Canvas.Brush.Color: = Application.hintcolor;

Bmp.Canvas.Pen.Color: = Application.hintcolor;

Bmp.Canvas.Rectangle (0, 0, bmp.width, bmp.height);

Bmp.Canvas.Font.Color: = Screen.HintFont.Color;

R: = Rect (0, 0, bmp.width, bmp.height);

INC (R.left, 2);

INC (R.top, 2);

DrawText (Bmp.Canvas.Handle, PChar (Ahint),-1, R, dt_left or Dt_noprefix or

Dt_wordbreak or drawtextbidimodeflagsreadingonly);

End


Initialization

Application.showhint: = False;

Hintwindowclass: = Twdhintwnd;

Application.showhint: = True;

End.
Just add the unit to your project, then run the program, you can see the effect, try it, pretty.

The important part of the program has been commented, here is only a few important places, the first is the initialization part, here will application Showhint set to False, look at the VCL source code, Know that application has destroyed a Hintwindow, and hintwindowclass is defined as follows:

Thintwindowclass = Class of Thintwindow;

It is a class reference for Thintwindow, which is initialized to Thintwindow in the forms cell:

Hintwindowclass:thintwindowclass = Thintwindow;

Here we replace it with Twdhintwnd, and finally set Showhint to True,application to create a hint window with Hintwindowclass, and we created our custom class. The subsequent prompt window will be displayed in the window above us.

In the Activatehint method, we will make the effect of processing, the principle is to get the hint window on the desktop location corresponding to the bitmap, and then draw to the prompt window, and then the location of the hint information to copy to the center of the prompt window, so that there is a transparent effect. Next, draw the edge of the glass, and then make a shadow effect on the right and bottom of the window.

About the shadow effect of the implementation, using the image of the Alpha technology, you can find on the Internet, there is not much to say, just give the image transparency formula:

dst.red = src.red * Alpha + (1-alpha) * dst.red;

Dst.green = Src.green * Alpha + (1-alpha) * dst.green;

Dst.blue = Src.blue * Alpha + (1-alpha) * dst.blue;

Alpha has a value between 0 and 1, and 1 is completely opaque, but we'll use the color of the blend as black, or 0, so the code above looks like this:

P[3*i]: = p[3*i] * transtangle DIV 100;

The principle of glass tip window is probably the case, of course, its transparency effect is an illusion, encountered after the moving object will be exposed undoubtedly. But as a cue window, I think it's enough.

Http://www.cnblogs.com/dashan9zj/archive/2008/12/15/1355406.html

Delphi technique to transform the output mode of hint

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.