Получить хендл курсора
От: xteam777  
Дата: 08.02.19 13:06
Оценка:
Нужно получить хендл курсора

Этот код прекрасно работает в 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

В чем причина непойму
Re: Получить хендл курсора
От: BlackEric http://black-eric.lj.ru
Дата: 08.02.19 13:47
Оценка:
Здравствуйте, xteam777, Вы писали:

X>В чем причина непойму


На любом 2012 или только на одном? Может там что-то установлено что его держит? ClassicShell какой-нибудь?
https://github.com/BlackEric001
Re: Получить хендл курсора
От: ole! США http://files.rsdn.org/4543/rsdn.gif
Дата: 10.02.19 22:51
Оценка:
Здравствуйте, 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?
my $.02
Re[2]: Получить хендл курсора
От: LuciferNovoros Россия  
Дата: 11.02.19 05:49
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>На любом 2012 или только на одном? Может там что-то установлено что его держит? ClassicShell какой-нибудь?


Вряд ли. Проверил на своем WinSrv 2012R2 с установленным ClassicShell.

Lasarus 1.8.4, FPC 3.1, x64 — полет нормальный. Все курсоры четко возвращаются. ИМХО, ошибка где-то на уровне более глубоком.
Re[3]: Получить хендл курсора
От: xteam777  
Дата: 03.03.19 16:56
Оценка:
Здравствуйте, 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;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.