我将尝试简化我的问题。例如,如果您丢下2 TSpeedButton
并执行:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
SpeedButton2.Cursor := crHandPoint; // note I'm setting other cursor than crDefault
end;
SpeedButton2.Cursor
仍然显示设置为Screen.Cursor
的crHourGlass
。我研究了TScreen.SetCursor
代码,并意识到它为整个表单设置了光标。我的问题:是否可以在整个表格中使用Screen.Cursor
,但不影响要设置其他光标的some控件。
TButton
也会发生同样的情况。如果在Screen.Cursor
设置为crHourGlass
时可以某种方式控制光标,则我不介意将SpeedButton放在窗口控件上。
谢谢。
[这是documentation的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;
图形控件的游标由其父控件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;
以上示例将要求图形控件具有非零标记值。例如:
procedure TForm1.Button1Click(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
SpeedButton1.Cursor := crHandPoint;
SpeedButton1.Tag := 1;
end;