2012-09-13 15 views
8

Mentre un utente sta ridimensionando un modulo, in XE2 vorrei visualizzare la dimensione del modulo corrente accanto al cursore del mouse corrente. Vorrei utilizzare l'evento OnResize.Come visualizzare il testo dinamico con il cursore del mouse

In altre parole: ho bisogno di idee su come visualizzare il testo dinamico (ad esempio, coordinate x, y come 300, 250 nell'immagine seguente) insieme al cursore del mouse mentre un utente sposta il mouse.

enter image description here

Un approccio potrebbe essere quello di prendere in giro un file cur e assegnarlo al cursore in OnResize. Sembra piuttosto ingombrante e potrebbe essere piuttosto lento (e non ho ancora idea del contenuto del file)

Un'altra idea sarebbe quella di visualizzare del testo trasparente (quale componente lo farebbe?) Che ho impostato .Top, .Left in l'evento OnResize.

Una preoccupazione che ho è come vorrei rilevare quando l'operazione di ridimensionamento è completa in modo da poter tornare al cursore del mouse standard.

Qualche suggerimento una direzione da seguire?

risposta

15

Aggiornamento:

Ecco una versione aggiornata, in cui è stato rimosso la parte suggerimento di animazione (dal momento che mi sento è necessario visualizzare il suggerimento immediatamente per il vostro scopo) e dove è stata aggiunta doppio buffering (a causa frequenti aggiornamenti del suggerimento) per prevenire lo sfarfallio e anche un discreto mix alfa (solo per curiosità).

Grazie a @NGLN è stato corretto unassegnazione non assegnata di una variabile della finestra di suggerimento!

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TAlphaHintWindow = class(THintWindow) 
    private 
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED; 
    protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    procedure CreateWindowHandle(const Params: TCreateParams); override; 
    public 
    constructor Create(AOwner: TComponent); override; 
    procedure ActivateHint(Rect: TRect; const AHint: string); override; 
    end; 

type 
    TForm1 = class(TForm) 
    private 
    FSizeMove: Boolean; 
    FHintWindow: TAlphaHintWindow; 
    procedure WMEnterSizeMove(var AMessage: TMessage); message WM_ENTERSIZEMOVE; 
    procedure WMSize(var AMessage: TWMSize); message WM_SIZE; 
    procedure WMExitSizeMove(var AMessage: TMessage); message WM_EXITSIZEMOVE; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ TAlphaHintWindow } 

constructor TAlphaHintWindow.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    // window might be updated quite frequently, so enable double buffer 
    DoubleBuffered := True; 
end; 

procedure TAlphaHintWindow.CreateParams(var Params: TCreateParams); 
begin 
    inherited CreateParams(Params); 
    // include the layered window style (for alpha blending) 
    Params.ExStyle := Params.ExStyle or WS_EX_LAYERED; 
end; 

procedure TAlphaHintWindow.CreateWindowHandle(const Params: TCreateParams); 
begin 
    inherited CreateWindowHandle(Params); 
    // value of 220 here is the alpha (the same as form's AlphaBlendValue) 
    SetLayeredWindowAttributes(Handle, ColorToRGB(clNone), 220, LWA_ALPHA); 
end; 

procedure TAlphaHintWindow.ActivateHint(Rect: TRect; const AHint: string); 
var 
    Monitor: TMonitor; 
begin 
    // from here was just stripped the animation part and fixed one bug 
    // (setting a hint window top position when going off screen; it is 
    // at least in Delphi 2009 with the most recent updates) 
    Caption := AHint; 
    Inc(Rect.Bottom, 4); 
    UpdateBoundsRect(Rect); 
    Monitor := Screen.MonitorFromPoint(Point(Rect.Left, Rect.Top)); 
    if Width > Monitor.Width then 
    Width := Monitor.Width; 
    if Height > Monitor.Height then 
    Height := Monitor.Height; 
    if Rect.Top + Height > Monitor.Top + Monitor.Height then 
    Rect.Top := (Monitor.Top + Monitor.Height) - Height; 
    if Rect.Left + Width > Monitor.Left + Monitor.Width then 
    Rect.Left := (Monitor.Left + Monitor.Width) - Width; 
    if Rect.Left < Monitor.Left then 
    Rect.Left := Monitor.Left; 
    if Rect.Top < Monitor.Top then 
    Rect.Top := Monitor.Top; 
    ParentWindow := Application.Handle; 
    SetWindowPos(Handle, HWND_TOPMOST, Rect.Left, Rect.Top, Width, Height, 
    SWP_NOACTIVATE); 
    ShowWindow(Handle, SW_SHOWNOACTIVATE); 
    Invalidate; 
end; 

procedure TAlphaHintWindow.CMTextChanged(var Message: TMessage); 
begin 
    // do exactly nothing, because we're adjusting the size by ourselves 
    // and the ancestor would just autosize the window by the text; text 
    // or if you want Caption, is updated only by calling ActivateHint 
end; 

{ TForm1 } 

procedure TForm1.WMEnterSizeMove(var AMessage: TMessage); 
begin 
    inherited; 
    FSizeMove := True; 
end; 

procedure TForm1.WMSize(var AMessage: TWMSize); 
var 
    CurPos: TPoint; 
begin 
    inherited; 
    if FSizeMove and GetCursorPos(CurPos) then 
    begin 
    if not Assigned(FHintWindow) then 
     FHintWindow := TAlphaHintWindow.Create(nil); 
    FHintWindow.ActivateHint(
     Rect(CurPos.X + 20, CurPos.Y - 20, CurPos.X + 120, CurPos.Y + 30), 
     'Current size' + sLineBreak + 
     'Width: ' + IntToStr(Width) + sLineBreak + 
     'Height: ' + IntToStr(Height)); 
    end; 
end; 

procedure TForm1.WMExitSizeMove(var AMessage: TMessage); 
begin 
    inherited; 
    FHintWindow.Free; 
    FHintWindow := nil; 
    FSizeMove := False; 
end; 

end. 

E il risultato al modulo di dimensionamento (un bel po 'trasparente per i miei gusti :-)

enter image description here

+2

Wow! Grazie per l'esempio operativo completo, TLama. Funziona perfettamente. GRAZIE ANCORA! – RobertFrank

+1

Prego! Ma non mi piace l'uso di "ActivateHint" più volte lì. Proverò a perfezionarlo ancora ... – TLama

+1

+1 Ma dovresti usare 'FreeAndNil (FHintWindow)' quando esegui il test per essere assegnato in 'WMSize', o perdere del tutto il test. – NGLN

3

Ha davvero bisogno di essere trasparente? Tieni presente che il testo può essere difficile da leggere su determinati sfondi.

Invece, considerare di mostrare una finestra di suggerimento. Creare un controllo THintWindow, impostarne la didascalia e la posizione e visualizzarlo.

Quando si riceve un messaggio wm_ExitSizeMove, nascondere o distruggere la finestra.

Problemi correlati