Delphi:屏幕。光标不工作,可以';t计算Windows.SetCursor(crHourGlass)
在我的应用程序中,我有Delphi:屏幕。光标不工作,可以';t计算Windows.SetCursor(crHourGlass),delphi,Delphi,在我的应用程序中,我有 Screen.Cursor := crHourGlass; Application.ProcessMessages; try ... finally Screen.Cursor := crDefault; Application.ProcessMessages; end; 但这根本没有达到预期效果。在处理时,它似乎会立即变回crDefault 谷歌搜索之后,我决定试试Windows.SetCursor()——但我搜索了MSDN,找不到光标类型列表 更新 我以为
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
try
...
finally
Screen.Cursor := crDefault;
Application.ProcessMessages;
end;
但这根本没有达到预期效果。在处理时,它似乎会立即变回crDefault
谷歌搜索之后,我决定试试Windows.SetCursor()——但我搜索了MSDN,找不到光标类型列表
更新
我以为我找到了解决方案(使用SetSystemCursor(Screen.Cursors[crHourGlass],OCR_NORMAL)),但我似乎无法将光标更改回正常状态:(.取决于try块中的内容。如果这不需要任何时间,则光标将立即更改回原来的位置。如果将调试语句放在finally之前,则应该看到它在光标返回默认值之前执行 此外,在启动例程时,不必假定光标为默认值。安全的方法是:
var
C: TCursor;
begin
C : = Screen.Cursor;
Screen.Cursor := crHourGlass;
try
// long running code here
finally
Screen.Cursor := C;
end;
end;
最后(请原谅该表达式),如果使用Application.ProcessMessages的目的是确保显示更改的光标,则不需要它。我想我有解决方案: 以下是如何更改“整个桌面”的光标,而不仅仅是您的应用程序:
SetSystemCursor(Screen.Cursors[crDefault], OCR_NORMAL);
// MainFormUnit
type
TMainForm = class(TForm)
btnClickMe: TButton;
procedure btnClickMeClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
uses
LazyFormUnit;
{$R *.dfm}
procedure TMainForm.btnClickMeClick(Sender: TObject);
var
oLazyForm: TLazyForm
begin
oLazyForm := TLazyForm.Create(Self, 0);
oLazyForm.ShowModal;
oLazyForm.Free;
end;
但请注意:任何其他希望更改光标的应用程序/窗口都会这样做-因此,只有当您的应用程序繁忙时,您的用户不会与其他应用程序混在一起时,这才有效。作为一种过渡,您可以临时将所有系统默认光标更改为您想要的光标-并在过程结束后将其全部更改回来党卫军
我仍然对MSDN没有为SetCursor提供游标类型感到失望,但幸运的是,我最终没有使用它
更新:
这似乎是正确的轨迹,但在设置SystemCursor(Screen.Cursors[crHourGlass],OCR_NORMAL)之后,我似乎无法将光标更改回原来的位置;
如果有人在读这篇文章,如果你能花点时间给我提供一些工作代码,我将不胜感激。1.将系统光标设置为沙漏,然后返回到箭头
编辑:返回默认光标的示例代码:
procedure TForm1.Button1Click(Sender: TObject);
var
cArrow, cHour: HCURSOR;
begin
cArrow := CopyImage(Screen.Cursors[crArrow], IMAGE_CURSOR, 0, 0, LR_COPYFROMRESOURCE);
cHour := CopyImage(Screen.Cursors[crHourGlass], IMAGE_CURSOR, 0, 0, LR_COPYFROMRESOURCE);
if (cArrow <> 0) and (cHour <> 0) and SetSystemCursor(cHour, OCR_NORMAL) then
try
// do processing
finally
SetSystemCursor(cArrow, OCR_NORMAL);
end;
end;
procedure TForm1.按钮1点击(发送方:TObject);
变量
卡罗,乔尔:哈库索;
开始
cArrow:=CopyImage(Screen.Cursors[crArrow],IMAGE\u CURSOR,0,0,LR\u COPYFROMRESOURCE);
cHour:=CopyImage(Screen.Cursors[crHourGlass],IMAGE\u CURSOR,0,0,LR\u COPYFROMRESOURCE);
如果(cArrow 0)和(cHour 0)并设置系统光标(cHour,OCR_NORMAL),则
尝试
//处理
最后
设置系统光标(cArrow,OCR_NORMAL);
结束;
结束;
我的应用程序也遇到了同样的问题,我的解决方案是调用
Application.ProcessMessages
在表单构造函数中
这是我的测试应用程序:
SetSystemCursor(Screen.Cursors[crDefault], OCR_NORMAL);
// MainFormUnit
type
TMainForm = class(TForm)
btnClickMe: TButton;
procedure btnClickMeClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
uses
LazyFormUnit;
{$R *.dfm}
procedure TMainForm.btnClickMeClick(Sender: TObject);
var
oLazyForm: TLazyForm
begin
oLazyForm := TLazyForm.Create(Self, 0);
oLazyForm.ShowModal;
oLazyForm.Free;
end;
第二种形式
// LazyFormUnit
type
TLazyForm = class(TForm)
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
constructor Create(p_oComponent: TComponent; p_nValue: Integer); reintroduce;
end;
implementation
{$R *.dfm}
constructor TLazyForm.Create(p_oComponent: TComponent; p_nValue: Integer);
begin
inherited Create(p_oComponent);
Application.ProcessMessages;
end;
procedure TLazyForm.FormShow(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
try
Sleep(1000 * 5);
finally
Screen.Cursor := crDefault;
end;
end;
此解决方案将保持系统光标不变。尝试以下操作:
Screen.Cursor := crHourGlass;
try
...
finally
TThread.Synchronize(nil,
procedure
begin
Screen.Cursor := crDefault;
end
);
end;
对我来说,它工作正常。你的问题中没有更多细节,我能说的是:如果它似乎立即变回crDefault,那么try子句中的代码可能正在将其变回(或者调用一些进行更改的代码)或者它可能使用某种异步进程,例如启动另一个线程,该线程实际上是处理该事物的线程。因此,程序执行finally部分,并几乎立即将光标更改回crDefault。JachGrate>No似乎发生的是,设置光标仅在应用程序具有pr时有效oper focus(操作焦点)-但任何发生在应用程序之外的进程-例如调用DLL进程或要求扫描仪扫描(注意:我扫描时没有显示扫描仪进度的任何弹出表单等)-然后Windows恢复默认光标。因此,我想我需要一种方法在Windows中为所有应用程序设置光标,直到我的进程完成。“因此,我想我需要一种方法在Windows中为所有应用程序设置光标,直到我的进程完成”-这是一个非常奇怪的要求。只有您的应用程序忙。为什么您希望其他应用程序在不忙的时候看起来很忙?“只有您的应用程序忙。为什么您希望其他应用程序在不忙的时候看起来很忙?”那么,我该如何解决这个问题呢?当我按下一个按钮时,我设置了屏幕。光标:=crHourglass;然后我让我的扫描仪获取图像-这会导致应用程序在等待扫描完成时失去焦点10秒(注:如前所述,它在没有任何“新窗口”等的情况下失去焦点)然后它调用一个DLL,再次导致应用程序失去焦点。在所有这些“失去焦点”的时间内,光标解析回crDefault(箭头)@Richard:你可以一步一步地运行你的应用程序,而IDE不会与你的窗口重叠,在你执行每一行代码时检查光标,检查哪一行会将其更改回crDefault。然后跟踪该行并跟踪代码,直到你找到错误的指令。也许它真的是扫描仪dll打电话……因此,您无法采取任何措施使其正确,但您的代码或第三方库中可能有一些内容可以更改或解决。顺便说一句:如果您希望我收到您的回复,请在评论中使用@在我的名字之前。谢谢,但它根本不起作用。是的,在t中会发生很多处理他尝试..最后阻止,事实上尝试中有一些过程..最后调用其他过程等-这些过程中的一些可能会暂时将焦点从应用程序移开,例如让扫描仪扫描(应用程序将等待扫描)很明显,在这段时间内,我的光标不是沙漏。我如何才能强制执行此操作?您跟踪了吗?您的代码将更改光标。可能在try块的早期,您自己的代码或库(扫描仪?)中的代码包含再次更改光标的代码。如果该代码使sam