unit wdHintWnd;interfaceusesWindows, Classes, Controls, Graphics, Forms, SysUtils, ExtCtrls;typeTwdHintWnd = class(THintWindow)privateFWndBmp: TBitmap; //窗口位图FHintBmp: TBitmap; //提示信息位图protectedprocedure CreateParams(var Params: TCreateParams); override;procedure Paint; override;procedure NCPaint(DC: HDC); override;{画提示的图象}procedure DrawHintImg(Bmp:TBitmap; AHint: string);{取得提示窗口对应的桌面区域的图象}procedure GetDesktopImg(Bmp: TBitmap; R: TRect);{对桌面区域图象作处理,使其看起来像一块玻璃且带有一点阴影}procedure EffectHandle(WndBmp, HintBmp: TBitmap);publicconstructor 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);varP: TPoint;begin//在这里取得一个适当的尺寸显示文字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 thenLeft := Screen.DesktopLeft;if Top < Screen.DesktopTop thenTop := Screen.DesktopTop;if Left + Width > Screen.DesktopWidth thenLeft := Screen.DesktopWidth - Width;if Top + Height > Screen.DesktopHeight thenTop := 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);begininherited;FWndBmp := TBitmap.Create;FWndBmp.PixelFormat := pf24bit;FHintBmp := TBitmap.Create;end;
procedure TwdHintWnd.CreateParams(var Params: TCreateParams);begininherited;//去掉窗口边框Params.Style := Params.Style and not WS_BORDER;end;
destructor TwdHintWnd.Destroy;beginFWndBmp.Free;FHintBmp.Free;inherited;end;
procedure TwdHintWnd.GetDesktopImg(Bmp: TBitmap; R: TRect);varC: TCanvas;beginC:= TCanvas.Create;tryC.Handle := GetDC(0);Bmp.Canvas.CopyRect(Rect(0, 0, Bmp.Width, Bmp.Height), C, R);finallyC.Free;end;end;
procedure TwdHintWnd.EffectHandle(WndBmp, HintBmp: TBitmap);varR: TRect;i, j: Integer;P: PByteArray;Transt, TranstAngle: Integer;beginR := Rect(0, 0, WndBmp.Width - 4, WndBmp.Height - 4);Frame3D(WndBmp.Canvas, R, clMedGray, clBtnShadow, 1);//作窗口底下的阴影效果Transt := 60;for j:= WndBmp.Height - 4 to WndBmp.Height - 1 dobeginP := WndBmp.ScanLine[j];TranstAngle := Transt;for i:= 3 to WndBmp.Width - 1 dobegin//如果正处于右下角if i > WndBmp.Width - 5 thenbeginP[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 > 90 then TranstAngle := 90;endelse beginP[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;//作窗口右边的阴影效果for j := 3 to WndBmp.Height - 5 dobeginP := WndBmp.ScanLine[j];Transt := 60;for i:= WndBmp.Width - 4 to WndBmp.Width -1 dobeginP[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(10, 10, HintBmp);end;
procedure TwdHintWnd.NCPaint;begin//重载不让画边框end;
procedure TwdHintWnd.Paint;beginCanvas.CopyRect(ClientRect, FWndBmp.Canvas, ClientRect);end;
procedure TwdHintWnd.DrawHintImg(Bmp: TBitmap; AHint: string);varR: TRect;beginBmp.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 orDT_WORDBREAK or DrawTextBiDiModeFlagsReadingOnly);end;
initializationApplication.ShowHint := False;HintWindowClass := TwdHintWnd;Application.ShowHint := True;end.