2021/12/17(Fri) 23:28:32 編集(投稿者)
Module1.vbのソース
Imports System.Runtime.InteropServices
Module Module1
<DllImport("user32.dll")>
Private Function GetWindowRect(ByVal hwnd As IntPtr, ByRef lpRect As RECT) As Boolean
End Function
<StructLayout(LayoutKind.Sequential)>
Private Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure
<DllImport("dwmapi.dll")>
Private Function DwmGetWindowAttribute(ByVal hWnd As IntPtr, ByVal dwAttribute As DWMWINDOWATTRIBUTE, ByRef rect As RECT, ByVal cbAttribute As Integer) As Long
End Function
Private Enum DWMWINDOWATTRIBUTE
DWMWA_NCRENDERING_ENABLED = 1
DWMWA_NCRENDERING_POLICY
DWMWA_TRANSITIONS_FORCEDISABLED
DWMWA_ALLOW_NCPAINT
DWMWA_CAPTION_BUTTON_BOUNDS
DWMWA_NONCLIENT_RTL_LAYOUT
DWMWA_FORCE_ICONIC_REPRESENTATION
DWMWA_FLIP3D_POLICY
DWMWA_EXTENDED_FRAME_BOUNDS 'ウィンドウのRect
DWMWA_HAS_ICONIC_BITMAP
DWMWA_DISALLOW_PEEK
DWMWA_EXCLUDED_FROM_PEEK
DWMWA_CLOAK
DWMWA_CLOAKED
DWMWA_FREEZE_REPRESENTATION
DWMWA_LAST
End Enum
<DllImport("user32.dll")>
Private Function GetDpiForWindow(ByVal hWnd As IntPtr) As Integer
End Function
<DllImport("kernel32.dll")>
Private Function MulDiv(ByVal nNumber As Integer, ByVal nNumerator As Integer, ByVal nDenominator As Integer) As Integer
End Function
Public Structure WindowSize
Public X As Integer
Public Y As Integer
Public Width As Integer
Public Height As Integer
Public OffsetX As Integer
Public OffsetY As Integer
End Structure
Function GetWindowSize(ByVal hWnd As IntPtr) As WindowSize
Dim lpRect As RECT
Dim bounds As RECT
'従来のフォームサイズの取得方法
Call GetWindowRect(hWnd, lpRect)
'プログラマから見たWindows 10 #4 〜 最新情報とプログラミングTips
'https://www.webtech.co.jp/blog/os/win10/8445/
'「ウィンドウのサイズと枠線についての仕様変更」より
' Windows10でのウインドウサイズの正確な求め方
Call DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, bounds, Marshal.SizeOf(GetType(RECT)))
'各座標を設定
Dim ws As WindowSize
ws.X = bounds.left
ws.Y = bounds.top
ws.Width = bounds.right - bounds.left
ws.Height = bounds.bottom - bounds.top
'C#での画面キャプチャの取得方法を徹底解説!
'https://www.fenet.jp/dotnet/column/language/4633/
'BitBlt API等で取得する際、x, y座標に指定する値
ws.OffsetX = bounds.left - lpRect.left
ws.OffsetY = bounds.top - lpRect.top
'ここから後が必要かわからないが一応
'Windows での高 DPI デスクトップアプリケーション開発
'https://docs.microsoft.com/ja-jp/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
'現在表示されているウインドウのモニターのDPIを取得
'SetWindowPos API等は96DPI固定で計算されているので、現在のDPIで96DPI相当の位置を再計算
Dim iDpi As Long = GetDpiForWindow(hWnd)
ws.X = MulDiv(ws.X, iDpi, 96)
ws.Y = MulDiv(ws.Y, iDpi, 96)
ws.Width = MulDiv(ws.Width, iDpi, 96)
ws.Height = MulDiv(ws.Height, iDpi, 96)
ws.OffsetX = MulDiv(ws.OffsetX, iDpi, 96)
ws.OffsetY = MulDiv(ws.OffsetY, iDpi, 96)
Return ws
End Function
End Module