Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ShowCursor в Windows 8, не отображается курсор 
:(
    Опции темы
Ciber SLasH
Дата 3.8.2015, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: нет
Всего: 67



Приветствую всех!
Есть такой код:
Код
program SCursor;
uses Windows;
var
  CState: Integer;
begin
  Cstate := ShowCursor(True);
  while CState < 0 do CState := ShowCursor(True);
end.

Задача: отобразить курсор, когда в систему зашли нестандартным образом.
Захожу в систему так:
1) меняю 2 параметра реестра
[HKEY_LOCAL_MACHINE\SYSTEM\Setup]
CmdLine = "cmd.exe"
SetupType = 2
2) перезагружаюсь и появляется консоль, но без курсора мыши (в Win7 и XP был курсор)

Как отобразить курсор при таком входе в ОС ?
PM   Вверх
Poseidon
Дата 3.8.2015, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Уверен что первый вызов ShowCursor возвращает < 0? Отладчик с этим согасен?


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Ciber SLasH
Дата 3.8.2015, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: нет
Всего: 67



Проверил: ShowCursor возвращает 1.
А цикл в инете нашёл. Там про 8-ку писали, что нужно в цикле.
Возвращает функция 1, но курсор так и не появляется, хотя события от мыши на компонентах отрисовываются (отрисовываются и без этой программы).
PM   Вверх
Ciber SLasH
Дата 4.8.2015, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: нет
Всего: 67



Сделал временное, топорное решение.
Поставил hook на WM_MOUSEMOVE и вывел картинку курсора вследа за движением мыши.
MouseHook.dpr:
Код

library MouseHook;
uses
  Windows, Messages, Graphics;

{$R MouseHook.res}

const
  MMFName: PChar = 'HookDLLMMF';       // имя объекта файлового отображения в память
  EventName: PChar = 'HookEvent';      // имя объекта "события"

type
  { Структура глобальных данных }
  PGlobalData = ^TGlobalData;
  TGlobalData = packed record
    SysHook: HHook;  // дескриптор установленной ловушки
  end;

var
  GlobalData: PGlobalData;  // глобальные данные
  hMMF: THandle;            // дескриптор объекта файлового отображения в память
  hEvent: THandle;          // дескриптор объекта "события"
  DLLPath: String;          // путь, откуда была загружена наша DLL
  Cnv: TCanvas;
  bmp: TBitmap;

////////////////////////////////////////////////////////////////////////////////
//== Описание основных подпрограмм =============================================
////////////////////////////////////////////////////////////////////////////////

{--- Открытие глобальных данных ---}
procedure OpenGlobalData;
begin
  // Пытаемся открыть объект файлового отображения в память (возможно он уже был создан)
  hMMF := OpenFileMapping(FILE_MAP_ALL_ACCESS, true, MMFName);
  if hMMF = 0 then  // если объект ещё не был создан
  begin
    { Создаём объект файлового отображения в память, значение INVALID_HANDLE_VALUE = -1 и говорит о том,
      что данные будут отображены в файл "подкачки" }
    hMMF := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalData), MMFName);
    if hMMF = 0 then
    begin
      MessageBox(0, 'Не удалось создать объект файлового отображения в память !!',
                 'Error (HookDLL::OpenGlobalData -> CreateFileMapping)', MB_OK + MB_ICONERROR);
      DLLProc := nil;  // "прячем" точку входа в DLL
      HALT
    end
  end;
  { Отображаем глобальные данные на АП вызывающего процесса и
    получаем указатель на начало выделенного пространства }
  GlobalData:= MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalData));
  if GlobalData = nil then
  begin
    MessageBox(0, 'Не удалось отобразить глобальные данные на АП вызывающего процесса !!',
               'Error (HookDLL::OpenGlobalData -> MapViewOfFile', MB_OK + MB_ICONERROR);
    CloseHandle(hMMF);
    DLLProc := nil;  // "прячем" точку входа в DLL
    HALT
  end;
  // Пытаемся открыть объект "событие"
  hEvent := OpenEvent(EVENT_ALL_ACCESS, true, EventName);
  if hEvent = 0 then  // если объект ещё не был создан, то ...
    hEvent := CreateEvent(nil, false, {false}true, EventName);  // создаём его
  bmp := TBitmap.Create;
  bmp.Handle := LoadBitmap(HInstance,'BITMAP_1');
  bmp.TransparentColor := clBlack;
  bmp.Transparent := True;
  Cnv := TCanvas.Create;
end;

{--- Закрытие глобальных данных ---}
procedure CloseGlobalData;
begin
  if GlobalData <> nil then
  begin
    UnmapViewOfFile(GlobalData);  // освобождаем объект файлового отображения
    ReleaseDC(0, Cnv.Handle);
    Cnv.Free;
    GlobalData := nil
  end;
  if hMMF <> 0 then
  begin
    CloseHandle(hMMF);
    hMMF := 0
  end;
  if hEvent <> 0 then
    CloseHandle(hEvent)
end;

{--- Точка входа в DLL ---}
procedure DLLEntryPoint(dwReason: DWORD);
begin
  case dwReason of
    { При подключении процесса к DLL }
    DLL_PROCESS_ATTACH: OpenGlobalData;  // открываем глобальные данные
    { При отключении процесса от DLL }
    DLL_PROCESS_DETACH: CloseGlobalData  // закрываем глобальные данные
  end
end;

{--- Функция перехвата клавиатуры ---}
function JournalProc(nCode: Integer; wParam: WPARAM; var EventStrut: TEventMsg): LRESULT; stdcall;
var
  cord: TPoint;
begin
  Result := CallNextHookEx(GlobalData^.SysHook, nCode, wParam, Longint(@EventStrut));  // отдаём на съедение другим :)
  if nCode < 0 then Exit;
  // Проверяю сообщение
  if nCode = HC_ACTION then
  begin
    case EventStrut.message of
      WM_MOUSEMOVE:
      begin
        InValidateRect(0, nil, false);
        GetCursorPos(cord);
        //Rectangle(ScreenDC, cord.X, cord.Y, cord.X + 15, cord.Y + 15);
        Cnv.Handle := GetDC(0);
        Cnv.Draw(cord.X, cord.Y, bmp);
      end;
    end;
  end;
end;

{--- Установка/сброс хука ---}
procedure RSHook(State: Boolean);
begin
  if State then
  begin
    // Устанавливаем Hook
    GlobalData^.SysHook := SetWindowsHookEx(WH_JOURNALRECORD, @JournalProc, hInstance, 0);
    if SetWindowsHook(WH_JOURNALRECORD, @JournalProc) > 0 then
      //
    else
    begin
      MessageBox(0, 'Hook не удалось установить !!', 'Error (HookDLL::RSHook -> SetWindowsHookEx)', MB_OK + MB_ICONERROR);
      CloseGlobalData;  // закрываем глобальные данные
      HALT              // аут
    end;
  end
  else
    // Снимаем хук
    if not UnhookWindowsHookEx(GlobalData^.SysHook) then
      MessageBox(0, 'Hook снять не удалось !!', 'Error (HookDLL::RSHook -> UnhookWindowsHookEx', MB_OK + MB_ICONERROR)
end;

////////////////////////////////////////////////////////////////////////////////
//== Экспортируемые функции и начальные установки ==============================
////////////////////////////////////////////////////////////////////////////////

exports RSHook;

var
  ModPath: PChar;
begin
  DLLProc := @DLLEntryPoint;         // устанавливаем точку входа в DLL
  DLLEntryPoint(DLL_PROCESS_ATTACH);  // уведобляем о подключении к DLL-ке нашего процесса
end.

SCursor.dpr:
Код

program SCursor;
uses  Windows, Messages;
{$R *.res}

// Внешняя функция установки/сброса хука из нашей DLL-ки
procedure RSHook(State: Boolean); external 'MouseHook.dll';

////////////////////////////////////////////////////////////////////////////////
//==[ Создание окна ]===========================================================
////////////////////////////////////////////////////////////////////////////////

const
  wndClassName = 'SCursor_Wnd';

var
  MainWndClass: TWndClassEx;  // класс главного окна
  Msg: TMsg;                  // обрабатываемое сообщение
  hMainWnd: HWND;

{*** Оконная процедура главного окна ***}
function WindowProc(Wnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  Result := 0;
  case uMsg of
    WM_DESTROY:
    begin
      PostQuitMessage(0);
      Exit;
    end;
    WM_COMMAND:
    case LoWord(wParam) of
      IDCANCEL: DestroyWindow(Wnd)
    end;
  else
    Result := DefWindowProc(Wnd, uMsg, wParam, lParam);
  end;
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
begin
  // Структура TWndClassEx
  MainWndClass.cbSize := SizeOf(MainWndClass);       // размер структуры
  MainWndClass.Lpfnwndproc := @WindowProc;           // указатель на функцию, выполняющую все операции с окном
  MainWndClass.cbClsExtra := 0;                      // кол-во доп. байт, выделяемых структуре
  MainWndClass.cbWndExtra := 0;                      // кол-во доп. байт, выделяемых для всех доп. структур
  MainWndClass.hInstance := hInstance;               // экземпляр приложения
  MainWndClass.hCursor := LoadCursor(0, IDC_ARROW);  // курсор проги
  MainWndClass.hbrBackground := COLOR_BTNFACE + 1;   // цвет фона окна
  MainWndClass.lpszMenuName := nil;                  // имя ресурса меню
  MainWndClass.LpszClassName := wndClassName;        // имя класса окна

  RegisterClassEx(MainWndClass);  // регистрируем класс окна

  // Создаём главное окно
  hMainWnd := CreateWindowEx(0, wndClassName, 'Mouse Hook', WS_OVERLAPPEDWINDOW,
    0,0, 100,100, 0,0, hInstance, nil);

  // Устанавливаем хук
  RSHook(true);

  // Показываем форму
  ShowWindow(hMainWnd, SW_SHOW);

  // Цикл обработки сообщений
  while (GetMessage(Msg, 0,0,0)) do
  begin
    if hMainWnd <> 0 then
      { IsDialogMessage- Опpеделяет и обpабатывает сообщения для безpежимных блоков
         диалога, пpееобpазуя сообщения от клавиатуpы в командные сообщения }
      if IsDialogMessage(hMainWnd, Msg) then
        Continue;
    TranslateMessage(Msg);
    DispatchMessage(Msg)
  end
end.

Мало того, что решение топорное, так ещё и ряд глюков:
1) мерцание
2) bmp.TransparentColor := clBlack; - игнорируется в Win8. В Win7 всё нормально

Это сообщение отредактировал(а) Ciber SLasH - 4.8.2015, 00:27

Присоединённый файл ( Кол-во скачиваний: 0 )
Присоединённый файл  ShowBitmap.rar 65,60 Kb
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1201 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.