【问题标题】:Delphi apps - Windows tablet mode keyboard covering appDelphi 应用程序 - Windows 平板模式键盘覆盖应用程序
【发布时间】:2022-10-07 01:15:21
【问题描述】:

我们正在寻求将我们的服务技术人员从笔记本电脑转移到 Windows 平板电脑。测试时的一个问题是,当屏幕键盘弹出时,它会遮挡应用程序的底部。当键盘弹出并调整应用程序大小时,我们如何才能捕捉到这种情况不会发生?应用程序目前在 Delphi XE5 中,但正在迁移到 Delphi 11.1。

  • 如果添加 Windows 标签,您可能会得到更多关注。

标签: delphi tablet delphi-xe5 delphi-11-alexandria


【解决方案1】:

您需要使用IFrameworkInputPaneHandler 这是实现它的示例单元。

unit UFrameworkInputPaneHandler;

interface

uses
  Winapi.Windows;

const
  CLSID_FrameworkInputPane: TGUID = '{D5120AA3-46BA-44C5-822D-CA8092C1FC72}';
  SID_IFrameworkInputPane = '{5752238B-24F0-495A-82F1-2FD593056796}';
  SID_IFrameworkInputPaneHandler = '{226C537B-1E76-4D9E-A760-33DB29922F18}';

type
  IFrameworkInputPaneHandler = interface(IInterface)
    [SID_IFrameworkInputPaneHandler]
    function Showing(var AInputPaneScreenLocation: TRect;
      AEnsureFocusedElementInView: BOOL): HResult; stdcall;
    function Hiding(AEnsureFocusedElementInView: BOOL): HResult; stdcall;
  end;

  IFrameworkInputPane = interface(IInterface)
    [SID_IFrameworkInputPane]
    function Advise(AWindow: IUnknown; AHandler: IFrameworkInputPaneHandler;
      var Cookie: DWORD): HRESULT; stdcall;
    function AdviseWithHWND(AWnd: HWND; const AHandler: IFrameworkInputPaneHandler;
      var Cookie: DWORD): HRESULT; stdcall;
    function Unadvise(dwCookie: DWORD): HRESULT; stdcall;
    function Location(var rcInputPaneScreenLocation: TRect): HRESULT; stdcall;
  end;

  TTouchKeyboardChangeEvent = procedure(Sender: TObject; const IsShowing: Boolean; var Rect: TRect;
    const EnsureFocusedElementInView: Boolean) of object;

  TFrameworkInputHandler = class(TInterfacedObject, IFrameworkInputPaneHandler)
  strict private
    FAdviseCookie: DWORD;
    FInputPane: IFrameworkInputPane;
    FOnTouchKeyboardVisibilityChanged: TTouchKeyboardChangeEvent;
  public
    { IFrameworkInputPaneHandler }
    function Showing(var AInputPaneScreenLocation: TRect; AEnsureFocusedElementInView: BOOL): HRESULT; stdcall;
    function Hiding(AEnsureFocusedElementInView: BOOL): HRESULT; stdcall;

    constructor Create(const AWnd: HWND);
    destructor Destroy; override;
    function GetLocation(var ARect: TRect): Boolean;
    property OnTouchKeyboardChanged: TTouchKeyboardChangeEvent
      read FOnTouchKeyboardVisibilityChanged write FOnTouchKeyboardVisibilityChanged;
    property InputPane: IFrameworkInputPane read FInputPane;
  end;

implementation

uses
  Winapi.ActiveX, System.Win.ComObj, System.Types;

constructor TFrameworkInputHandler.Create(const AWnd: HWND);
var
  HR: HRESULT;
begin
  inherited Create();

  FAdviseCookie := 0;
  FInputPane    := nil;
  FOnTouchKeyboardVisibilityChanged := nil;

  HR := CoCreateInstance(CLSID_FrameworkInputPane, nil, CLSCTX_ALL,
    StringToGUID(SID_IFrameworkInputPane), FInputPane);
  if (not FAILED(HR)) and Assigned(FInputPane) then
  begin
    FInputPane.AdviseWithHWND(AWnd, Self, FAdviseCookie);
  end;
end;

destructor TFrameworkInputHandler.Destroy();
begin
  if Assigned(FInputPane) then
  begin
    FInputPane.Unadvise(FAdviseCookie);
    FInputPane := nil;
  end;

  inherited Destroy();
end;

function TFrameworkInputHandler.GetLocation(var ARect: TRect): Boolean;
begin
  Result := False;
  ARect := TRect.Empty;
  if Assigned(FInputPane) then
  begin
    Result := not FAILED(FInputPane.Location(ARect));
  end;
end;

function TFrameworkInputHandler.Hiding(AEnsureFocusedElementInView: BOOL): HRESULT;
begin
  if Assigned(FOnTouchKeyboardVisibilityChanged) then
  begin
    var Rect := TRect.Empty;
    FOnTouchKeyboardVisibilityChanged(Self, False, Rect, AEnsureFocusedElementInView);
  end;

  Result := S_OK;
end;

function TFrameworkInputHandler.Showing(var AInputPaneScreenLocation: TRect;
  AEnsureFocusedElementInView: BOOL): HRESULT;
begin
  if Assigned(FOnTouchKeyboardVisibilityChanged) then
  begin
    FOnTouchKeyboardVisibilityChanged(Self, True, AInputPaneScreenLocation,
      AEnsureFocusedElementInView);
  end;

  Result := S_OK;
end;

end.

在您的表格中将其声明为

FInputHandler: IFrameworkInputPaneHandler;

并将其创建为

  if not Assigned(FInputHandler) then
  begin
    FInputHandler := TFrameworkInputHandler.Create(Handle);
    (FInputHandler as TFrameworkInputHandler).OnTouchKeyboardChanged := OnTouchKeyboardChanged;
  end;

在 OnTouchKeyboardChanged 中,它将为您提供屏幕键盘的位置

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 2017-04-12
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 2020-10-05
    • 1970-01-01
    相关资源
    最近更新 更多