Перейти к содержанию
Fire Monkey от А до Я

dnekrasov

Пользователи
  • Постов

    317
  • Зарегистрирован

  • Посещение

  • Победитель дней

    52

Сообщения, опубликованные dnekrasov

  1. Создаю глобальный hook на несколько событий:

    {$IFDEF MACOS}
    var
      EvtTap: CFMachPortRef;
      RunLoopSource: CFRunLoopSourceRef;
    {$ENDIF}
    ...
    procedure CreateGlobalHook;
    {$IFDEF MACOS} 
    var 
      EvtMask: UInt64; 
    {$ENDIF} 
    begin 
    {$IFDEF MACOS} 
      if EvtTap = nil then
      begin 
        EvtMask := (1 shl kCGEventKeyDown) or (1 shl kCGEventFlagsChanged) or (1 shl kCGEventLeftMouseUp); 
        EvtTap := CGEventTapCreate(kCGAnnotatedSessionEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, 
        EvtMask, @EventTapHandler, nil); 
        RunLoopSource := CFMachPortCreateRunLoopSource(kCFAllocatorDefault, EvtTap, 0); 
        CFRunLoopAddSource(CFRunLoopGetCurrent, RunLoopSource, kCFRunLoopCommonModes); 
      end; 
    
      CGEventTapEnable(EvtTap, 1);
    {$ENDIF} 
    end;
    
    function EventTapHandler(proxy: CGEventTapProxy; type_: CGEventType; event: CGEventRef; refcon: Pointer): CGEventRef; cdecl;
    {$IFDEF MACOS}
    var
      iKey: Integer;
      iType: Integer;
    {$ENDIF}
    begin
    {$IFDEF MACOS}
      Result := event;
    
      iType := CGEventGetType(event);
      iKey := CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
    
      case iType of
        kCGEventFlagsChanged: ...;
        kCGEventLeftMouseUp: ...;
        kCGEventKeyDown: ...;
      end;
    {$ENDIF}
    end;
    
    
    При обработке события возникает проблема: приходят все события кроме kCGEventKeyDown

    В документации нашел, что kCGEventKeyDown и kCGEventKeyUp приходят только в том случае если приложение запущено от root-а или внесено в список "System Preferences->Security & Privacy->Privacy->Accessibility"

     

    Может кто знает как мне программно получить доступ к этим событиям?

  2. function GetHDDSerialID: String;
    Const
      kIOPlatformSerialNumberKey = 'IOPlatformSerialNumber';
    var
      PlatformExpert: io_service_t;
      M: CFMutableDictionaryRef;
      CFTR: CFTypeRef;
      pac: PAnsiChar;
    begin
      M := IOServiceMatching('IOPlatformExpertDevice');
      PlatformExpert := IOServiceGetMatchingService(kIOMasterPortDefault, CFDictionaryRef(M));
      try
        CFTR := IORegistryEntryCreateCFProperty(PlatformExpert,
          CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0);
    
        pac := CFStringGetCStringPtr(CFTR, 0);
    
        Result := String(AnsiString(pac));
      finally
        IOObjectRelease(PlatformExpert);
      end;
    end;
  3. Приложение убрано из панели задач

    Свойства формы:

    BorderStyle = None

    Transparency = True

     

    Немного поэкспериментировав нашел лучший способ:
    ...
    TMyForm = class(TForm)
    ...
    protected
        procedure CreateHandle; override;
    ...
    end;
    ...
    procedure TMyForm.CreateHandle;
    begin
      inherited CreateHandle;
    
      SetWindowLong(WindowHandleToPlatform(Handle).Wnd, GWL_EXSTYLE,
        GetWindowLong(WindowHandleToPlatform(Handle).Wnd, GWL_EXSTYLE) or WS_EX_APPWINDOW);
    end;
    ...
    end.
    
    Этот код вставлять нужно в каждой форме, которую Вы хотите отобразить на панели задач
  4.    FHandle := WindowHandleToPlatform(Form2.Handle).Wnd;
       SetWindowLong(FHandle, GWL_EXSTYLE,
                     GetWindowLong(FHandle, gwl_exstyle) or WS_EX_APPWINDOW or WS_EX_ACCEPTFILES);
    

     

    Этот код работает,только его надо переместить из обработчика события OnCreate в обработчик OnShow

    Не знаю в чем проблема, но FHandle в этих событиях принимает разные значения и, как я понял, правильный именно в FormShow.

     

    Как это работает можно посмотреть в приложении Clip2net (написано на Delphi XE6)

    iYbCad.jpg

×
×
  • Создать...