home *** CD-ROM | disk | FTP | other *** search
- 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.
-