当用户在使用 Delphi 代码的Windows 10设备上进入平板电脑模式时,人们将如何检测到?有没有人能给出一个代码示例?我不想检测用户是否有平板电脑。我只是想看看他们是否在平板电脑模式或没有。最好的办法是什么?
rlcwz9us1#
我删除了之前的变体(基于[SO]: How can I detect when Windows 10 enters tablet mode in a Windows Forms application? (@CheeseLover's answer)(@Remko的评论指出)),因为这是一个完全不同的场景(与桌面上运行的 Win 没有任何关系)。我花了一些时间在[MS.DevBlogs]: Raymond - How can I detect whether my PC is in tablet mode?上(在@RitaHan-MSFT的回答(+1)中指出),很明显,这就是要走的路。我不知道如何将代码“翻译”成 * Delphi *,因为自从我在其中编写大量代码以来已经过去了很多年(但我相信这是可能的),所以我做了下一件最好的事情:我写了一个 C++**.dll(包含Raymond代码的修改/改进版本),从 * Delphi * 调用。
注意:.dll 需要 VStudio 来构建,我使用的是 2015CommunityEdition,它是免费的,可以从[VStudio]: Visual Studio 2015 and other Products下载(不过需要 MS 账号)。
#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 * 相关代码(只有单元,因为其余部分可以很容易地制造,没有必要将其全部放在这里)。
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]>
型在下面的截图中,我运行了应用程序:
x1c 0d1x的数据
oo7oh9g92#
可以使用UIViewSettings.UserInteractionMode API。请参考@Raymond博客:“如何检测我的电脑是否处于平板电脑模式?”,C++中有UWP和桌面方式你可以参考。更多详细信息,您可以查看this thread。但是你需要了解如何在 Delphi 中做。这里有一些相关的问题希望对你有所帮助:delphi - call external WinAPI function的Can we call Native Windows API from Delphi?的
2条答案
按热度按时间rlcwz9us1#
我删除了之前的变体(基于[SO]: How can I detect when Windows 10 enters tablet mode in a Windows Forms application? (@CheeseLover's answer)(@Remko的评论指出)),因为这是一个完全不同的场景(与桌面上运行的 Win 没有任何关系)。
我花了一些时间在[MS.DevBlogs]: Raymond - How can I detect whether my PC is in tablet mode?上(在@RitaHan-MSFT的回答(+1)中指出),很明显,这就是要走的路。
我不知道如何将代码“翻译”成 * Delphi *,因为自从我在其中编写大量代码以来已经过去了很多年(但我相信这是可能的),所以我做了下一件最好的事情:我写了一个 C++**.dll(包含Raymond代码的修改/改进版本),从 * Delphi * 调用。
注意:.dll 需要 VStudio 来构建,我使用的是 2015CommunityEdition,它是免费的,可以从[VStudio]: Visual Studio 2015 and other Products下载(不过需要 MS 账号)。
字符串
下面是 * Delphi * 相关代码(只有单元,因为其余部分可以很容易地制造,没有必要将其全部放在这里)。
型
输出:
型
在下面的截图中,我运行了应用程序:
x1c 0d1x的数据
oo7oh9g92#
可以使用UIViewSettings.UserInteractionMode API。请参考@Raymond博客:“如何检测我的电脑是否处于平板电脑模式?”,C++中有UWP和桌面方式你可以参考。
更多详细信息,您可以查看this thread。
但是你需要了解如何在 Delphi 中做。这里有一些相关的问题希望对你有所帮助:
delphi - call external WinAPI function的
Can we call Native Windows API from Delphi?的