On occasion my application gets the error below.
Normally this happens when the user steps away from their desk leaving my program open. When they come back this error has appeared.
TMouse.GetCursorPostion does not do anything except make the Windows API call to GetCursorPosition. Then it checks the return value and calls GetLastError if it failed.
"A call to an OS function failed" is not very helpful in tracking down the cause of this. Could a screen saver or sleep mode be kicking in causing this error? I could modify the component to just catch and ignore the error, but if possible I would rather know what/why it is happening in the first place.
My application is using Delphi 2007 and the call is being made from Transfer@Once (v 1.7) component by Quasidata.
Here is the call stack:
operating system : Windows XP Service Pack 3 build 2600 exception number : 1 exception class : EOSError exception message : A call to an OS function failed. main thread ($d34): 0045e208 UaarSales.exe SysUtils RaiseLastOSError 0045e191 UaarSales.exe SysUtils RaiseLastOSError 0045e237 UaarSales.exe SysUtils Win32Check 004c6de9 UaarSales.exe Controls TMouse.GetCursorPos 00736d8b UaarSales.exe taoCntrr 3999 TtaoHoverTimer.Timer 004a1d27 UaarSales.exe ExtCtrls TTimer.WndProc 0047a7a0 UaarSales.exe Classes StdWndProc 7e4196c2 USER32.dll DispatchMessageA 004da230 UaarSales.exe Forms TApplication.ProcessMessage 004da26a UaarSales.exe Forms TApplication.HandleMessage 004da55f UaarSales.exe Forms TApplication.Run 00b3ea76 UaarSales.exe UaarSales 117 initialization
Here is the Timer procedure
procedure TtaoHoverTimer.Timer;
var
lPos: TPoint;
begin
lPos := Mouse.CursorPos; // this is line 3999
if (lPos.X = FMousePos.X) and (lPos.Y = FMousePos.Y) and
not ((lPos.X = FOutdatedPos.X) and (lPos.Y = FOutdatedPos.Y)) then
begin
inherited Timer;
FOutdatedPos := Point(MaxInt, MaxInt);
end;
Enabled := False;
end;
CursorPos uses the Windows GetCursorPos method. The remarks on MSDN says it has two requirements:
So, chances are that the screensaver is running on another desktop. Alternately, if you're using Vista I'm pretty sure the password dialog (for unlocking a computer) runs on another desktop as well.
Since you have the source for this component, you may want to write your own wrapper for CursorPos that returns a dummy value when there's a problem. (Edit: or a commenter suggested handling the failure to get a position inline instead of writing a function to return a dummy value.)
Finally, you can call GetLastError to see what the last Windows error was, after it's thrown the exception. That should tell you for sure what the actual problem it's encountering is. As in a comment (thanks!) you have already encountered the error message in the exception message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With