2012-10-08 48 views
1

怎样绘制在桌面窗口上绘制用户点击一个圆的动画......绘制在桌面强调鼠标点击德尔福

我已经尝试下面的代码,启动一个线程来绘制动画。 ..

以下作品的代码,但有一些油漆问题:

unit UMouseEmphasizer; 

interface 

implementation 

uses 
    Classes, Windows, Messages, Graphics, Forms; 

type 
    TEmphasizePointDrawer = class(TThread) 
    private 
    fPoint: TPoint; 
    fCanvas: TCanvas; 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(pt: TPoint); reintroduce; 
    destructor Destroy; override; 
    end; 

constructor TEmphasizePointDrawer.Create(pt: TPoint); 
begin 
    fPoint := pt; 
    fCanvas := TCanvas.Create; 
    fCanvas.Handle := GetDCEx(0, 0, DCX_PARENTCLIP); 
    inherited Create(True); 
    FreeOnTerminate := True; 
    Resume; 
end; 

destructor TEmphasizePointDrawer.Destroy; 
begin 
    ReleaseDC(0, fCanvas.Handle); 
    fCanvas.Free; 
    inherited; 
end; 

procedure TEmphasizePointDrawer.Execute; 
const 
    INFLATE_DELTA = 10; 
var 
    i: integer; 
    r: TRect; 
begin 
    r := rect(0,0,0,0); 
    with fCanvas do 
    begin 
    Brush.Style := bsClear; 
    Pen.Style := psSolid; 
    Pen.Color := clRed; 
    Pen.Width := 2; 

    for i := 0 to 2 do 
    begin 
     r := rect(
     fPoint.X - (i * INFLATE_DELTA), 
     fPoint.Y - (i * INFLATE_DELTA), 
     fPoint.X + (i * INFLATE_DELTA), 
     fPoint.Y + (i * INFLATE_DELTA) 
    ); 
     Ellipse(r); 

     sleep(100); 
    end; 
    end; 

    InflateRect(r, 2, 2); 
    RedrawWindow(0, @R, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ALLCHILDREN); 
end; 

function MouseHookHandler(nCode: Integer; MsgID: WParam; Data: LParam): LResult; stdcall; 
var 
    pt: TPoint; 
begin 
    Result := 0; 
    if nCode < 0 then 
    Exit; 

    pt := PMouseHookStruct(Data)^.pt; 

    case MsgID of 
    WM_LBUTTONUP: 
     TEmphasizePointDrawer.Create(pt); 
    end; 
end; 

var 
    gHook: HHOOK=0; 

procedure HookMouse; stdcall; 
begin 
    gHook := SetWindowsHookEx(WH_MOUSE, MouseHookHandler, HINSTANCE, 0); 
end; 

procedure UnhookMouse; 
begin 
    UnhookWindowsHookEx(gHook); 
    gHook := 0; 
end; 

initialization 
    HookMouse; 

finalization 
    UnhookMouse; 

end. 
+1

此功能在Windows中已存在。为什么只有桌面窗口?这将是非常有限的。 –

+0

出了什么问题? “有一些油漆问题”没有很好地描述这个问题。 –

+0

试试上面的代码来查看“问题”。 –

回答

3

我解决了这个问题:

procedure TEmphasizePointDrawer.Execute; 
const 
    INFLATE_DELTA = 5; 
    COUNT = 3; 
    BORDER = 2; 
var 
    i: integer; 
    r: TRect; 
begin 
    with fCanvas do 
    begin 
    Brush.Style := bsClear; 
    Pen.Style := psSolid; 
    Pen.Color := clRed; 
    Pen.Width := BORDER; 

    for i := COUNT downto 0 do 
    begin 
     if i < COUNT then 
     begin 
     InflateRect(r, BORDER, BORDER); 
     RedrawWindow(0, @R, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ALLCHILDREN); 
     sleep(0); 
     BitBlt(Handle, r.Left, r.Top, (r.Right - r.Left), (r.Bottom - r.Top), Handle, r.Left, r.Top, SRCCOPY); 
     end; 

     r := rect(
     fPoint.X - (i * INFLATE_DELTA), 
     fPoint.Y - (i * INFLATE_DELTA), 
     fPoint.X + (i * INFLATE_DELTA), 
     fPoint.Y + (i * INFLATE_DELTA) 
    ); 

     InflateRect(r, BORDER, BORDER); 
     RedrawWindow(0, @R, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ALLCHILDREN); 
     sleep(0); 
     BitBlt(Handle, r.Left, r.Top, (r.Right - r.Left), (r.Bottom - r.Top), Handle, r.Left, r.Top, SRCCOPY); 

     InflateRect(r, -BORDER, -BORDER); 
     Ellipse(r); 

     sleep(50); 
    end; 
    end; 

    r := rect(
    fPoint.X - (COUNT * INFLATE_DELTA) - BORDER, 
    fPoint.Y - (COUNT * INFLATE_DELTA) - BORDER, 
    fPoint.X + (COUNT * INFLATE_DELTA) + BORDER, 
    fPoint.Y + (COUNT * INFLATE_DELTA) + BORDER 
); 
    RedrawWindow(0, @R, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ALLCHILDREN); 
end; 

function MouseHookHandler(nCode: Integer; MsgID: WParam; Data: LParam): LResult; stdcall; 
var 
    pt: TPoint; 
begin 
    // draw only when over my application forms!!! 
    if (nCode < 0) or (FindControl(GetForegroundWindow()) = nil) then 
    begin 
    Result := CallNextHookEx(gHook, nCode, MsgID, Data); 
    Exit; 
    end; 

    pt := PMouseHookStruct(Data)^.pt; 

    case MsgID of 
    WM_LBUTTONUP, WM_RBUTTONUP, WM_MBUTTONUP: 
     TEmphasizePointDrawer.Create(pt); 

    end; 
    Result := 0; 
end; 

感谢您的答复!

0

Stardock的CursorXP方法,为我所知道的,是覆盖鼠标采用透明和移动窗口和这个透明窗口上绘制动画代替。

你也可能在桌面上制作ActiveDesktop对象,当鼠标拖拽到桌面上并呈现这些圆时,会看到该对象。


如果你的意思只是你自己的形式,那么“桌面窗口”是错误的术语。在Windows中,表示代表Windows桌面的系统无标题窗口

但是也适用类似的想法。你可以制作一个透明的动画GIF,当你点击dbl时,只需要在窗体上显示一些组件中的图片作为最顶层的控件。

更加兼容的方法是制作一些特定的ANI光标(或从WinXP主题中选择一些)来显示这些圆圈,然后在dblclick上临时切换TForm.Cursor到该ANI光标,并在一段时间后将其切换回crDefault 。

+0

我想在我的应用程序中内置此功能,而不是来自第三方。谢谢! –

+0

那么,“桌面窗口”是错误的术语。在Windows中,表示代表Windows桌面的系统无标题窗口 –

+0

但是也适用类似的想法。制作一个透明的GIF动画,当点击dbl时 - 只需将某个组件中的图片显示为表单上最顶层的控件。 更兼容的方法是使某些特定的ANI光标显示这些圆圈,然后在dblclick上临时切换TFrom.Cursor那个ANI光标。 –