WPF の場合も、Form 同様に ... 。
待ったぁ~!。
そうは問屋が卸しません!。
WPF に於いて、 API を直接叩くには、 おまじない! が必要です。
先に投稿 した様に、Windows API を叩く事で、
画面のちらつきが無く、描画が出来る訳ですが、
そのまま、Form でのテクニックを WPF に持ち込んでも、動かない様です。
以下のサイトに簡潔に説明されていました。
WPF のウィンドウ(その1) by ダッチ さま
http://blogs.wankuma.com/youryella/archive/2009/10/20/182272.aspx
コードをお借りして、引用します。 著作権:ダッチ さま
Imports System.Windows.Interop
Private Class Window1
Private Sub Window1_SourceInitialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SourceInitialized
Dim wih As New WindowInteropHelper(Me)
Dim hs As HwndSource = HwndSource.FromHwnd(wih.Handle)
hs.AddHook(AddressOf WndProc)
End Sub
Private Function WndProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr
' WndProc と同じように処理できます。
Return IntPtr.Zero
End Function
End Class
WPF には、WndProc メソッドが無い のだそうです。
ですから、上記の様に、書き足す必要があるのですね。
Form と較べて、条件分岐は単純化が可能です。
冒頭に条件判断部分を入れてしまえば、簡潔に書けますね。
Window1 の xaml に CheckBox をひとつ用意し、CheckBox1 と命名します。
Code (Window1.xaml.vb) はこちら。 縦横比 4:3 (横長) で固定可能の例。
Imports System.Windows.Interop
Public Class Window1
Private Sub Window1_SourceInitialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SourceInitialized
Dim wih As New WindowInteropHelper(Me)
Dim hs As HwndSource = HwndSource.FromHwnd(wih.Handle)
hs.AddHook(AddressOf WndProc)
End Sub
' For Fixed WH_Ratio
Private fixedRate As Double = (CType(4 / 3, Double))
Private WM_SIZING As Integer = 532
Private WMSZ_LEFT As Integer = 1
Private WMSZ_RIGHT As Integer = 2
Private WMSZ_TOP As Integer = 3
Private WMSZ_TOPLEFT As Integer = 4
Private WMSZ_TOPRIGHT As Integer = 5
Private WMSZ_BOTTOM As Integer = 6
Private WMSZ_BOTTOMLEFT As Integer = 7
Private WMSZ_BOTTOMRIGHT As Integer = 8
Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure
Private Function WndProc(ByVal hwnd As IntPtr,
ByVal msg As Integer,
ByVal wParam As IntPtr,
ByVal lParam As IntPtr,
ByRef handled As Boolean) As IntPtr
' Like Form's WndProc
If msg = WM_SIZING Then
If Me.CheckBox1.IsChecked Then
Dim r = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, GetType(RECT)), RECT)
Dim w = r.right - r.left
Dim h = r.bottom - r.top
Dim dw As Integer = (CType(((h * fixedRate) _
+ 0.5), Integer) - w)
Dim dh As Integer = (CType(((w / fixedRate) _
+ 0.5), Integer) - h)
Select Case wParam.ToInt32
Case WMSZ_TOP, WMSZ_BOTTOM
r.right = (r.right + dw)
Case WMSZ_LEFT, WMSZ_RIGHT
r.bottom = (r.bottom + dh)
Case WMSZ_TOPLEFT
If (dw > 0) Then
r.left = (r.left - dw)
Else
r.top = (r.top - dh)
End If
Case WMSZ_TOPRIGHT
If (dw > 0) Then
r.right = (r.right + dw)
Else
r.top = (r.top - dh)
End If
Case WMSZ_BOTTOMLEFT
If (dw > 0) Then
r.left = (r.left - dw)
Else
r.bottom = (r.bottom + dh)
End If
Case WMSZ_BOTTOMRIGHT
If (dw > 0) Then
r.right = (r.right + dw)
Else
r.bottom = (r.bottom + dh)
End If
End Select
System.Runtime.InteropServices.Marshal.StructureToPtr(r, lParam, False)
Else
'MyBase.WndProc(m)
End If
End If
Return IntPtr.Zero
End Function
End Class
これで、何とか、目的達成! です。
[2019/05/14] Sample Code 挿入
0 件のコメント:
コメントを投稿