ClickOnceアプリケーションでDPI認識を無効にしようとしています。
ClickOnceはマニフェストファイルでasm.v3をサポートしていないため、マニフェストで指定することはできません。
私が見つけた次のオプションは、新しいWindows関数SetProcessDpiAwarenessを呼び出すことでした。
このチュートリアルによると、
アプリケーションウィンドウを作成する前に、SetProcessDpiAwarenessを呼び出します。
そしてこのチュートリアル、
Win32APIを呼び出す前に、SetProcessDpiAwarenessを呼び出す必要があります
かなり早い段階で関数を呼び出す必要があります。したがって、テストするために、完全に空白のWPFアプリケーションを作成し、これをAppクラス全体にしました。
[DllImport("SHCore.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);
[DllImport("SHCore.dll", SetLastError = true)]
private static extern void GetProcessDpiAwareness(IntPtr hprocess, out PROCESS_DPI_AWARENESS awareness);
private enum PROCESS_DPI_AWARENESS
{
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}
static App()
{
var result = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_DPI_Unaware);
var setDpiError = Marshal.GetLastWin32Error();
MessageBox.Show("Dpi set: " + result.ToString());
PROCESS_DPI_AWARENESS awareness;
GetProcessDpiAwareness(Process.GetCurrentProcess().Handle, out awareness);
var getDpiError = Marshal.GetLastWin32Error();
MessageBox.Show(awareness.ToString());
MessageBox.Show("Set DPI error: " + new Win32Exception(setDpiError).ToString());
MessageBox.Show("Get DPI error: " + new Win32Exception(getDpiError).ToString());
}
3つのメッセージボックスにこのコンテンツが表示されます。
Dpiセット:True
Process_System_DPI_Aware
セットDPIエラー:System.ComponentModel.Win32Exception(0x80004005):アクセスが拒否されました
System.ComponentModel.Win32Exception(0x80004005):操作は正常に完了しました
アプリケーションがまだDPI_Awareに設定されているのはなぜですか?この電話は十分に早くありませんか?
アプリケーションは確かにDPIスケーリングを経験します。
マニフェスト定義を使用する場合:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
</windowsSettings>
</application>
Process_DPI_Unawareを返します。
編集1:
pInvokeメソッドの直後にMarshal.GetLastWin32Error()を取得するようになりました。これにより、実際にエラーが返されるようになりました。
注意してくださいSetLastError
とGetLastWin32Error
などの間のいずれかの呼び出しは、MessageBox.Show
その結果に影響を与えます。ネイティブメソッドを呼び出した直後に、必ず最後のエラーが発生するようにしてください。
したがって、期待どおりの動作が得られているのに、エラーコードに惑わされている可能性があります。
完全な説明については、このブログ投稿を参照してください:http://blogs.msdn.com/b/oldnewthing/archive/2015/08/19/10636096.aspx
編集
アクセスが拒否された原因についてはよくわかりませんが、DPIの認識を無効にする簡単で効果的なトリックがあります。
AssemblyInfo.csを編集し、以下を追加します。
[assembly: DisableDpiAwareness]
ソース:https://code.msdn.microsoft.com/windowsdesktop/Per-Monitor-Aware-WPF-e43cde33(PerMonitorAwareWPFWindow.xaml.csのコメント)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加