2012-09-13 23 views
8

Mientras un usuario cambia el tamaño de un formulario, en XE2 me gustaría mostrar el tamaño del formulario actual junto con el cursor actual del mouse. Yo usaría el evento OnResize.Cómo mostrar texto dinámico junto con el cursor del mouse

En otras palabras: necesito ideas sobre cómo mostrar texto dinámico (por ejemplo, coordenadas x, y como 300, 250 en la imagen siguiente) junto con el cursor del mouse cuando el usuario mueve el mouse.

enter image description here

Un enfoque sería burlarse de seguridad de un archivo .cur y asignarlo al cursor en OnResize. Parece engorroso y podría ser bastante lento (y aún no tengo idea del contenido del archivo)

Otra idea sería mostrar algún texto transparente (¿qué componente haría eso?) Que configuré .Top, .Entrás el evento OnResize.

Una preocupación que tengo es cómo detectaría cuando la operación de cambio de tamaño se complete para poder volver al cursor estándar del mouse.

¿Alguna sugerencia de seguir?

Respuesta

15

Actualización:

Aquí está una versión actualizada, donde se retiró la pieza de animación pista (ya que siento que necesita para mostrar la pista de inmediato para su propósito) y donde se añadió el doble buffer (debido para actualizaciones frecuentes de la pista) para evitar el parpadeo y también una mezcla alfa decente (solo por curiosidad).

¡Gracias a @NGLN solucionó la falta de asignación de una variable de ventana de sugerencia!

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. 

Y el resultado en forma de tamaño (bastante transparente para mi gusto :-)

enter image description here

+2

Wow! Gracias por el completo ejemplo de trabajo, TLama. Funciona perfectamente ¡GRACIAS DE NUEVO! – RobertFrank

+1

¡De nada! Pero no me gusta el uso de 'ActivateHint' varias veces allí. Trataré de sintonizar esto aún ... – TLama

+1

+1 Pero deberías usar 'FreeAndNil (FHintWindow)' cuando pruebas para que se asigne en 'WMSize', o perder la prueba por completo. – NGLN

3

¿Realmente es necesario ser transparente? Tenga en cuenta que el texto puede ser difícil de leer sobre ciertos fondos.

En su lugar, considere la posibilidad de mostrar una ventana con información sobre herramientas. Cree un control THintWindow, establezca su título y posición, y muéstrelo.

Cuando recibe un mensaje wm_ExitSizeMove, oculte o destruya la ventana.

Cuestiones relacionadas