Я удалил предыдущий вариант (на основе [SO]: как я могу определить, когда Windows 10 входит в режим планшета в приложении Windows Forms? (Ответ @ CheeseLover) (на что указывает комментарий @ Remko) ) потому что это совершенно другой сценарий (не имеет ничего общего с Win на настольном компьютере).
Я потратил некоторое время на [MS.DevBlogs]: Raymond - Как я могу определить, находится ли мой компьютер в режиме планшета? (указано в ответе @ RitaHan-MSFT (+1)), и ясно, это путь .
Я не знаю, как "перевести" код в Delphi , так как прошло много лет с тех пор, как я написал в нем значительное количество кода (но я уверен, что это возможно), поэтому я сделал следующая лучшая вещь: написал C ++ .dll (содержащий измененную / улучшенную версию кода Рэймонда), который вызывается из Delphi .
Примечание : VStudio требуется для сборки .dll , я использовал 2015 Community Edition , которая бесплатна и может быть загружена с [VStudio]: Visual Studio 2015 и других продуктов (хотя вам нужна учетная запись MS ).
dll.cpp
#include <wrl/client.h>
#include <windows.ui.viewmanagement.h>
#include <UIViewSettingsInterop.h>
#include <wrl/wrappers/corewrappers.h>
namespace WRL = Microsoft::WRL;
namespace VM = ABI::Windows::UI::ViewManagement;
class Backend {
public:
static Backend &instance() {
static Backend m_instance;
return m_instance;
}
WRL::ComPtr<IUIViewSettingsInterop> interop() { return m_interop; }
private:
Backend() {
HRESULT res = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
m_comInit = (res == S_OK) || (res == S_FALSE);
if (m_comInit || (res == RPC_E_CHANGED_MODE)) {
res = Windows::Foundation::GetActivationFactory(WRL::Wrappers::HStringReference(
RuntimeClass_Windows_UI_ViewManagement_UIViewSettings).Get(), &m_interop);
}
}
Backend(const Backend &other) = delete;
Backend &operator =(const Backend &other) = delete;
~Backend() {
if (m_interop) { m_interop.Reset(); }
if (m_comInit) { CoUninitialize(); }
}
bool m_comInit = false;
WRL::ComPtr<IUIViewSettingsInterop> m_interop = nullptr;
};
/*!
Gets Tablet mode value.
\param hwnd Window handle to get the mode for
\returns:
1 - Tablet mode ON
0 - Tablet mode OFF
-X - Error
*/
extern "C" __declspec(dllexport) int GetTabletMode(HWND hwnd) {
WRL::ComPtr<IUIViewSettingsInterop> interop = Backend::instance().interop();
if (!interop) { return -3; }
WRL::ComPtr<VM::IUIViewSettings> viewSettings;
HRESULT res = interop->GetForWindow(hwnd != NULL ? hwnd : GetConsoleWindow(), IID_PPV_ARGS(&viewSettings));
if (!viewSettings) { return -2; }
VM::UserInteractionMode currentMode;
res = viewSettings->get_UserInteractionMode(¤tMode);
int ret = -1;
switch (currentMode) {
case VM::UserInteractionMode_Mouse: ret = 0; break;
case VM::UserInteractionMode_Touch: ret = 1; break;
default: ret = -1;
}
viewSettings.Reset();
return ret;
}
Ниже приведен соответствующий код Delphi (только устройство, так как остальные могут быть легко изготовлены, и размещать все здесь нет смысла).
Unit0.pas
unit Unit0;
interface
uses
Forms, Dialogs, Controls, StdCtrls, Classes;
type
TForm0 = class(TForm)
CheckButton: TButton;
procedure CheckButtonClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form0: TForm0;
function GetTabletMode(hwnd: THandle): Integer cdecl; external 'TabletUtils.dll';
implementation
{$R *.dfm}
procedure TForm0.CheckButtonClick(Sender: TObject);
var
TabletModeStr: String;
begin
case GetTabletMode(Self.Handle) of
0 : TabletModeStr := 'OFF';
1 : TabletModeStr := 'ON';
else TabletModeStr := 'ERROR';
end;
MessageDlg('Tablet Mode: ' + TabletModeStr, mtInformation, [mbOK], 0);
end;
end.
выход
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q056321591]> sopr.bat
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***
[prompt]> "c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x86
[prompt]> dir /b
App0.cfg
App0.dof
App0.dpr
App0.exe
App0.res
dll.cpp
other
Unit0.dcu
Unit0.ddp
Unit0.dfm
Unit0.pas
[prompt]> cl /nologo /DDLL /DNDEBUG /DUSRDLL /D_WINDOWS /MT dll.cpp /link /NOLOGO /DLL /OUT:TabletUtils.dll ole32.lib runtimeobject.lib
dll.cpp
Creating library TabletUtils.lib and object TabletUtils.exp
[prompt]> dir /b
App0.cfg
App0.dof
App0.dpr
App0.exe
App0.res
dll.cpp
dll.obj
other
TabletUtils.dll
TabletUtils.exp
TabletUtils.lib
Unit0.dcu
Unit0.ddp
Unit0.dfm
Unit0.pas
[prompt]> App0.exe
[prompt]>
На скриншоте ниже я запустил приложение:
- На моем ноутбуке ( Win 10 ) с Режим рабочего стола (правая сторона)
- На Win 10 VM с Режим планшета (левая сторона). Обратите внимание, что мне пришлось скопировать: