home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Softwarová Záchrana 3
/
Softwarova-zachrana-3.bin
/
ArsClip
/
source.zip
/
UnitFrmDummyUnicodeTooltip.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2004-05-28
|
9KB
|
381 lines
unit UnitFrmDummyUnicodeTooltip;
{
Purpose:
Gather up all the logic needed to display Unicode in a Tooltip
I have to parasite The TTooltip to a form so it can specify
the NotifyFOrmat
}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls,
UnitTWideChar, UnitClipQueue;
type TTooltipWindow = class(THintWindow)
private
ShowingHint : boolean;
MaxWidth : cardinal;
hwndTip : THandle;
LastPoint : TPoint;
protected
HittestActive : boolean;
procedure AlterSizePosition(var r : TRect; Pos : TPoint);
//procedure WMNCHitTest(VAR Msg: TWMNcHitTest); message WM_NCHITTEST;
public
constructor Create; reintroduce;
destructor Destroy; override;
procedure SetMaxWidth(max : cardinal);
procedure ShowTooltip(s : string; Pos : TPoint); overload;
procedure ShowTooltip(ci : TClipItem; Pos : TPoint); overload;
procedure ShowTooltip(wc : TWideChar; Pos : TPoint); overload;
procedure CloseTooltip;
function IsHit(Pos : TPoint) : boolean;
end;
type
TFrmDummyUnicodeTooltip = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
LastHint : string;
LastClipItem : TClipItem;
TooltipWindows : TTooltipWindow;
wc : TWideChar;
{For Unicode Popup}
procedure WMNotifyFormat(var msg : TWMNotifyFormat); message WM_NOTIFYFORMAT;
procedure WMNotify(var msg : TWMNotify); message WM_NOTIFY;
public
procedure SetLastClip(ci : TClipItem); overload;
procedure SetLastClip(s : string); overload;
procedure SetLastClip(wcc : TWideChar); overload;
{ Public declarations }
end;
var
FrmDummyUnicodeTooltip: TFrmDummyUnicodeTooltip;
implementation
{$R *.dfm}
uses CommCtrl, UnitMisc, Math;
{ TTooltipWindow }
procedure TTooltipWindow.CloseTooltip;
var ti : TOOLINFOW;
begin
Windows.SetLastError(ERROR_SUCCESS);
self.ReleaseHandle;
self.ShowingHint := false;
if (hwndTip <> 0) then begin
fillchar(ti, sizeof(ti), #0);
ti.cbSize := sizeof(TOOLINFO);
ti.uFlags := TTF_SUBCLASS;
ti.hInst := hInstance; // ??
// only hwndTip, .uId, cbSize are used, all else is ignored
SendMessage(hwndTip, TTM_TRACKACTIVATE, Integer(false), Integer(@ti));
Windows.DestroyWindow(hwndTip);
end;
hwndTip := 0;
end;
constructor TTooltipWindow.Create;
begin
inherited Create(FrmDummyUnicodeTooltip);
self.MaxWidth := 300;
self.Font.Name := 'Arial';
self.Color := Graphics.clInfoBk;
end;
destructor TTooltipWindow.Destroy;
begin
inherited;
end;
procedure TTooltipWindow.SetMaxWidth(max: cardinal);
begin
MaxWidth := max;
end;
procedure TTooltipWindow.AlterSizePosition(var r: TRect; Pos : TPoint);
begin
if self.MaxWidth <> 0 then begin
if (r.Bottom - r.top) > self.MaxWidth then r.Bottom := r.top + self.MaxWidth;
end;
inc(r.Top, Pos.y );
inc(r.Bottom, Pos.Y );
inc(r.Left, Pos.X );
inc(r.right, Pos.X );
end;
procedure TTooltipWindow.ShowTooltip(s: string; Pos : TPoint);
var r : TRect;
begin
UnitMisc.AppendLog('ShowTooltip(s,pos)');
self.LastPoint := pos;
if self.ShowingHint then EXIT;
self.ShowingHint := true;
FrmDummyUnicodeTooltip.SetLastClip(s);
if (s <> '') then begin
r := self.CalcHintRect(180, s, nil);
self.AlterSizePosition(r, Pos);
self.ActivateHint(r, s);
end else begin
self.CloseTooltip;
end;
end;
procedure TTooltipWindow.ShowTooltip(wc: TWideChar; Pos: TPoint);
var r : TRect;
ti : TOOLINFOw;
begin
Windows.SetLastError(ERROR_SUCCESS);
UnitMisc.AppendLog('ShowTooltip(wc,pos)');
self.LastPoint := pos;
if self.ShowingHint then EXIT;
self.ShowingHint := true;
FrmDummyUnicodeTooltip.SetLastClip(wc);
r := Rect(0, 0, Self.MaxWidth, 0);
DrawTextW(self.Canvas.Handle, wc.Memory, (-1),
r,
DT_CALCRECT or DT_LEFT or
DT_WORDBREAK or DT_NOPREFIX or DrawTextBiDiModeFlagsReadingOnly);
Inc(r.right, 6);
Inc(r.bottom, 2);
self.AlterSizePosition(r, Pos);
//
// Set the size & text callback options
//
fillchar(ti, sizeof(ti), #0);
ti.cbSize := sizeof(TOOLINFO);
ti.uFlags := TTF_SUBCLASS or TTF_TRACK or TTF_ABSOLUTE; // Docs never said anything about TTF_TRACK!
ti.hwnd := FrmDummyUnicodeTooltip.handle;
ti.uId := 0;
ti.lpszText := LPSTR_TEXTCALLBACKw;
ti.hInst := hInstance;
ti.rect.Top := r.top;
ti.rect.Bottom := r.Bottom;
ti.rect.Right := r.Right;
ti.rect.Left := r.Left;
//
// Create, set max width, activate, and set position
//
hwndTip := CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, nil,
TTS_ALWAYSTIP or TTS_NOPREFIX or WS_POPUP,
0,0,0,0, FrmDummyUnicodeTooltip.handle, 0, hInstance, nil);
SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
SendMessage(hwndTip, TTM_SETMAXTIPWIDTH, 0, Self.MaxWidth);
SendMessage(hwndTip, TTM_ADDTOOL, 0, Integer(@ti));
SendMessage(hwndTip, TTM_TRACKPOSITION, 0, MakeLong(pos.x, pos.y));
SendMessage(hwndTip, TTM_TRACKACTIVATE, Integer(true),
Integer(@ti));
end;
procedure TTooltipWindow.ShowTooltip(ci: TClipItem; Pos : TPoint);
var wcc : TWideChar;
begin
Windows.SetLastError(ERROR_SUCCESS);
self.LastPoint := pos;
//
// Only Unicode items are show directly in this method
//
if (ci.GetFormat <> CF_UNICODETEXT) then begin
Self.ShowTooltip(ci.GetAsText, Pos);
EXIT;
end;
//
// Set size based on size of text
//
wcc := TWideChar.Create;
wcc.Append(ci.getHandle, ci.GetDataSize );
self.ShowTooltip(wcc, pos);
wcc.Clear;
MyFree(wcc);
end;
{
//
// Removed - inconsistant!
// A plain text item would receive this message, a unicode text item
// would not
// REPLACED with IsHit
procedure TTooltipWindow.WMNCHitTest(var Msg: TWMNcHitTest);
}
function TTooltipWindow.IsHit(Pos: TPoint): boolean;
var r : TRect;
begin
Windows.SetLastError(ERROR_SUCCESS);
if (hwndTip <> 0) then begin
windows.GetClientRect(hwndTip, r);
end else begin
r := Self.GetClientRect;
end;
inc(r.left, LastPoint.x);
inc(r.Right, LastPoint.X);
inc(r.Top, lastpoint.Y);
inc(r.Bottom, Lastpoint.y);
result := Windows.PtInRect(r, Pos);
{
// DOES NOT WORK!!!!!! Damn MS documentation
// unable to find any case where it fires a true result
fillchar(hi,sizeof(hi),#0);
hi.pt.x := Pos.x;
hi.pt.y := Pos.Y;
hi.hwnd := self.hwndTip;
hi.ti.cbSize := sizeof(hi.ti);
result := (Windows.SendMessage(self.hwndTip, TTM_HITTEST, 0,Integer(@hi)) <> 0);
}
end;
{ TFrmDummyUnicodeTooltip }
//
// I'm created, then multiple calls to Show/Close Tooltip
//
procedure TFrmDummyUnicodeTooltip.FormCreate(Sender: TObject);
begin
TooltipWindows := TTooltipWindow.Create;
wc := TWideChar.Create;
end;
//
// Callbacks used when UNICODE is sent via the ShowTooltip method
// Say "I've got Unicode" for the format
// Say, "Here's the string you asked for" for the content
//
procedure TFrmDummyUnicodeTooltip.WMNotifyFormat(var msg: TWMNotifyFormat);
begin
if (self.wc.size <> 0) then begin
msg.Result := NFR_UNICODE;
end else begin
msg.Result := NFR_ANSI;
end;
end;
procedure TFrmDummyUnicodeTooltip.WMNotify(var msg: TWMNotify);
const TTN_FIRST = $-520;
const TTN_GETDISPINFO = (TTN_FIRST - 0);
const TTN_GETDISPINFOW = (TTN_FIRST - 10);
var pdiw : ^tagNMTTDISPINFOW;
pdia : ^tagNMTTDISPINFO;
begin
// Tell the popup what text to show
//
// NOTE: This string must exist while the tooltip is being shown
// Bad, bad, bad things happen when the string disappears
//
if msg.NMHdr^.code = TTN_GETDISPINFOW then begin
pdiw := Pointer(TMessage(msg).lparam);
{if (self.LastClipItem <> nil) then begin
wc.Clear;
wc.Append(self.LastClipItem.getHandle, self.LastClipItem.GetDataSize);
wc.LeftStr(600);
end;}
wc.LeftStr(600);
pdiw.lpszText := wc.Memory;
msg.Result := 0;
end else if msg.NMHdr^.code = TTN_GETDISPINFO then begin
pdia := Pointer(TMessage(msg).lparam);
pdia.lpszText := PChar(self.LastHint);
pdia.hinst := 0;
msg.Result := 0;
end;
end;
procedure TFrmDummyUnicodeTooltip.SetLastClip(ci: TClipItem);
begin
self.LastClipItem := ci;
self.LastHint := '';
end;
procedure TFrmDummyUnicodeTooltip.SetLastClip(s: string);
begin
self.LastHint := s;
self.LastClipItem := nil;
self.wc.Clear;
end;
procedure TFrmDummyUnicodeTooltip.SetLastClip(wcc: TWideChar);
begin
self.wc.clear;
self.wc.Append(wcc);
self.LastHint := '';
self.LastClipItem := nil;
end;
end.