UE4で比較的新しめのWindowsAPIを使おうとするとできなかったのでその関数を使うdllを作って対応した。
ここではその内容を記録する。
発生した現象
UE4.24でGetDpiForWindowを利用しようとすると以下のようなエラーが発生してコンパイルできない。
CompilerResultsLog: E:\Users\hotta\Documents\Unreal Projects\GoogleSpeechKitTest\Source\GoogleSpeechKitTest\MyTest.cpp(9) : error C2039: 'GetDpiForWindow': is not a member of '`global namespace''
CompilerResultsLog: E:\Users\hotta\Documents\Unreal Projects\GoogleSpeechKitTest\Source\GoogleSpeechKitTest\MyTest.cpp(9) : error C3861: 'GetDpiForWindow': identifier not found
原因
GetDpiForWindowが定義されているWinUser.hを確認すると
#if(WINVER >= 0x0605)
のなかで関数が定義されている。
UE_4.24/Engine/Source/Programs/UnrealBuildTool/Platform/Windows/UEBuildWindows.cs
を確認すると以下のようになっておりWINVERは-x0601か0x0602あたりにしかならなさそうで0x0605に達しない。
(UE4のWindowsにおけるマルチタッチについて : まったり開発日誌参照)
このため、関数が見つからないようになっていたと思われる。
/// <summary>
/// Value for the WINVER macro, defining the minimum supported Windows version
/// </summary>
public int TargetWindowsVersion = 0x601;
...
if (Target.WindowsPlatform.bUseWindowsSDK10)
{
CompileEnvironment.Definitions.Add(String.Format("_WIN32_WINNT=0x{0:X4}", 0x0602));
CompileEnvironment.Definitions.Add(String.Format("WINVER=0x{0:X4}", 0x0602));
}
else
{
CompileEnvironment.Definitions.Add(String.Format("_WIN32_WINNT=0x{0:X4}", Target.WindowsPlatform.TargetWindowsVersion));
CompileEnvironment.Definitions.Add(String.Format("WINVER=0x{0:X4}", Target.WindowsPlatform.TargetWindowsVersion));
}
対応方法
とりあず中でGetDpiForWindowを使う以下のような関数を提供するdllを使うようにすると利用できた。
New PluginのThird Party Libraryのテンプレートを参考にしてdllとそれを利用するプラグインを作って対応した。
(もっと簡単な対応法があったら知りたい)
unsigned int GetDPIFromWindow(void *hwnd)
{
#if defined _WIN32 || defined _WIN64
return ::GetDpiForWindow((HWND)hwnd);
#else
return 0;
#endif
}
2023/10/12追記
以下の記事のようにbuild.csのPublicDefinitionsでWINVER関係の定数を再定義する方法もあるみたいです。
UnrealEngineにおいてWindowsのタッチをシミュレートしてみる - Qiita