zig*_*zig 5 delphi vcl delphi-7
我会尽量简化我的问题。例如,如果您删除 2TSpeedButton
并执行以下操作:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
SpeedButton2.Cursor := crHandPoint; // note I'm setting other cursor than crDefault
end;
Run Code Online (Sandbox Code Playgroud)
SpeedButton2.Cursor
显示Screen.Cursor
设置为的剩余部分crHourGlass
。
我已经调查了TScreen.SetCursor
代码,并意识到它为整个表单设置了光标。
我的问题:是否有可能以某种方式使用Screen.Cursor
整个表单,但不会影响我想设置其他光标的某些控件。
同样的情况发生在TButton
. 如果我可以在Screen.Cursor
设置为时以某种方式控制它的光标,我不介意将 SpeedButton 放在窗口控件上crHourGlass
。
谢谢。
这是故意行为,如文档中所述TScreen.Cursor
:
... 当 Cursor 为 crDefault 时,单个对象确定光标图像。分配任何其他值将为属于应用程序的所有窗口设置鼠标光标图像。全局鼠标光标图像一直有效,直到屏幕的 Cursor 属性改回 crDefault。..
窗口控件在TWinControl.WMSetCursor
过程、WM_SETCURSOR
消息处理程序中处理它们的光标,如果屏幕光标不是crDefault
它们自己的光标,则它们显式设置屏幕光标并忽略它们自己的光标。
因此,要更改行为,您可以处理提到的消息。对于TButton
中介层,示例可能是:
procedure TButton.WMSetCursor(var Message: TWMSetCursor);
begin
if (Cursor <> crDefault) and (Message.HitTest = HTCLIENT) then begin
Message.Result := 1;
Windows.SetCursor(Screen.Cursors[Cursor]);
end else
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
图形控件的光标由其父级处理TWinControl
。因此,要更改速度按钮的行为,您仍然需要在其父级上处理相同的消息。这可能是不切实际的,因为可能事先不知道父类。
尽管如此,一个非常非通用的实现,例如直接放置在表单上的图形控件,可能如下所示:
procedure TForm1.WMSetCursor(var Message: TWMSetCursor);
var
SmPt: TSmallPoint;
Control: TControl;
begin
DWORD(SmPt) := GetMessagePos;
Control := ControlAtPos(ScreenToClient(SmallPointToPoint(SmPt)), True);
if Assigned(Control) and Boolean(Control.Tag) then begin
Message.Result := 1;
Windows.SetCursor(Screen.Cursors[Control.Cursor])
end else
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
上面的示例要求图形控件具有非零标记值。例如:
procedure TForm1.Button1Click(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
SpeedButton1.Cursor := crHandPoint;
SpeedButton1.Tag := 1;
end;
Run Code Online (Sandbox Code Playgroud)