Нужно получить хендл курсора
Этот код прекрасно работает в Win10:
procedure TForm5.Button1Click(Sender: TObject);
var
ci: TCursorInfo;
err: integer;
r: LongBool;
begin
ZeroMemory(@ci, SizeOf(TCursorInfo));
ci.cbSize := SizeOf(TCursorInfo);
ci.hCursor := 0;
r := GetCursorInfo(ci);
err := GetLastError;
Memo1.Lines.Add('Err: ' + IntToStr(err));
Memo1.Lines.Add('hCur: ' + IntToStr(ci.hCursor));
end;
Но, в WinServer2012R2 err = 170 (Требуемый ресурс занят) и hCursor = 0
В чем причина непойму
Здравствуйте, xteam777, Вы писали:
X>Нужно получить хендл курсора
X>Этот код прекрасно работает в Win10:
X>X>procedure TForm5.Button1Click(Sender: TObject);
X>var
X> ci: TCursorInfo;
X> err: integer;
X> r: LongBool;
X>begin
X> ZeroMemory(@ci, SizeOf(TCursorInfo));
X> ci.cbSize := SizeOf(TCursorInfo);
X> ci.hCursor := 0;
X> r := GetCursorInfo(ci);
X> err := GetLastError;
X> Memo1.Lines.Add('Err: ' + IntToStr(err));
X> Memo1.Lines.Add('hCur: ' + IntToStr(ci.hCursor));
X>end;
X>
X>Но, в WinServer2012R2 err = 170 (Требуемый ресурс занят) и hCursor = 0
X>В чем причина непойму
Скорее всего, last error неопределен если функция завершилась успешно:
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getcursorinfo
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Чему равно r?
Здравствуйте, LuciferNovoros, Вы писали:
LN>Здравствуйте, BlackEric, Вы писали:
BE>>На любом 2012 или только на одном? Может там что-то установлено что его держит? ClassicShell какой-нибудь?
LN>Вряд ли. Проверил на своем WinSrv 2012R2 с установленным ClassicShell.
LN>Lasarus 1.8.4, FPC 3.1, x64 — полет нормальный. Все курсоры четко возвращаются. ИМХО, ошибка где-то на уровне более глубоком.
Проверьте, чтобы текущий десктоп был активным OpenInputDesktop, GetThreadDesktop, SetThreadDesktop
Так же можно получить хендл курсора функцией GetCursor
Есть еще способ. Там нужно присоединяться к активному потоку:
function TCursorInfoThread.GetCursorInfoWithAttach: TCursorInfo;
var
hWindow: HWND;
pt: TPoint;
dwThreadID, dwCurrentThreadID: DWORD;
begin
Result.hCursor := 0;
ZeroMemory(@Result, SizeOf(Result));
Result.cbSize := SizeOf(TCursorInfo);
// Find out which window owns the cursor
if GetCursorPos(pt) then
begin
Result.ptScreenPos := pt;
hWindow := WindowFromPoint(pt);
if IsWindow(hWindow) then
begin
// Get the thread ID for the cursor owner.
dwThreadID := GetWindowThreadProcessId(hWindow, nil);
// Get the thread ID for the current thread
dwCurrentThreadID := GetCurrentThreadId;
// If the cursor owner is not us then we must attach to
// the other thread in so that we can use GetCursor() to
// return the correct hCursor
if (dwCurrentThreadID <> dwThreadID) then
begin
if AttachThreadInput(dwCurrentThreadID, dwThreadID, True) then
begin
// Get the handle to the cursor
Result.hCursor := GetCursor;
AttachThreadInput(dwCurrentThreadID, dwThreadID, False);
end;
end
else
begin
Result.hCursor := GetCursor;
end;
end;
end;
end;