02-18-2021, 07:20 PM (This post was last modified: 02-19-2021, 07:09 PM by GraPhiX.)
Hello
my first post, i am new to PowerToys purchased today, i am going through the samples and converting from C# to VB.NET, i have a project i have been working on for 3- 4 years and it is in VB.NET unfortunately i am not good with C#.
I have converted most of a sample i am interested in but having an issue with this class:
Code:
public class MouseWheelMessageFilter : IMessageFilter
{
private const int WM_MOUSEWHEEL = 0x020A;
private FrameworkElement _element;
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
public static void RegisterMouseWheelHandling(FrameworkElement element)
{
var mouseWheelMessageFilter = new MouseWheelMessageFilter(element);
}
public bool PreFilterMessage(ref Message m)
{
if (!_element.IsVisible)
return false;
if (m.Msg == WM_MOUSEWHEEL)
{
Rect rect = new Rect(0, 0, _element.ActualWidth, _element.ActualHeight);
System.Windows.Point pt = Mouse.GetPosition(_element);
i have tried to convert it to VB but it does not work :( can anyone point me in the right direction this is what i have:
Code:
Public Class MouseWheelMessageFilter
Inherits IMessageFilter
Private Const WM_MOUSEWHEEL As Integer = &H20A
Private _element As FrameworkElement
<DllImport("user32.dll")>
Public Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
Public Sub New(ByVal element As FrameworkElement)
_element = element
End Sub
Public Function PreFilterMessage(ByRef m As Message) As Boolean
If m.Msg = WM_MOUSEWHEEL Then
Dim rect As Rect = New Rect(0, 0, _element.ActualWidth, _element.ActualHeight)
Dim pt As Point = Mouse.GetPosition(_element)
If rect.Contains(pt) Then
Dim hwndSource As HwndSource = CType(hwndSource.FromVisual(_element), HwndSource)
SendMessage(hwndSource.Handle, m.Msg, m.WParam, m.LParam)
Return True
End If
End If
The "private MouseWheelMessageFilter(FrameworkElement element)" line create a private constructor for the MouseWheelMessageFilter class. This means that the MouseWheelMessageFilter class can be created only from the public static method RegisterMouseWheelHandling.
You can also change that so that you have a standard constructor that takes the FrameworkElement as a parameter.
The important thing (that is missing from your code) is that you need to subscribe element (as FrameworkElement) Loaded and Unloaded event. In the Loaded event you call System.Windows.Forms.Application.AddMessageFilter and pass an instance of MouseWheelMessageFilter object as a parameter. In the Unloaded event you call RemoveMessageFilter method.
02-19-2021, 10:35 AM (This post was last modified: 02-19-2021, 07:10 PM by GraPhiX.)
Hi thank you for your reply, i have got further along but it is still not quite right :(
Code:
Public Class MouseWheelMessageFilter
Implements IMessageFilter
Private Sub New(ByVal element As FrameworkElement)
Me._element = element
AddHandler Me._element.Loaded, (sender, args) >= Application.AddMessageFilter(Me)
AddHandler Me._element.Unloaded, (sender, args) >= Application.RemoveMessageFilter(Me)
End Sub
Public Function PreFilterMessage(ByRef m As Message) As Boolean
Dim flag2 As Boolean
If Me._element.IsVisible Then
If (m.Msg = &H20A) Then
Dim rect As New Rect(0, 0, Me._element.ActualWidth, Me._element.ActualHeight)
If rect.Contains(Mouse.GetPosition(Me._element)) Then
MouseWheelMessageFilter.SendMessage(DirectCast(PresentationSource.FromVisual(Me._element), HwndSource).Handle, m.Msg, m.WParam, m.LParam)
Return True
End If
End If
flag2 = False
Else
flag2 = False
End If
Return flag2
End Function
Public Shared Sub RegisterMouseWheelHandling(ByVal element As FrameworkElement)
Dim filter As New MouseWheelMessageFilter(element)
End Sub
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
' Fields
Private Const WM_MOUSEWHEEL As Integer = &H20A
Private _element As FrameworkElement
End Class
I will look at the URL you sent me see if i can work it out.
Regards
Kev
02-19-2021, 01:32 PM (This post was last modified: 02-19-2021, 07:10 PM by GraPhiX.)
I got it working :) not 100% sure its clean but it works i have commented out the addhandler the mouse capture works but not sure why the addhandler causes grief
here is the conversion from C# class to VB.NET if anyone else can make use :)
Private _viewport3D As Viewport3D
Private _targetPositionCamera As TargetPositionCamera
Private _mouseCameraController As MouseCameraController
Private _rootGrid As Grid
Private _eventManager3D As EventManager3D
Dim _isSelectedBoxClicked As Boolean
Dim _totalClickedHeight As Double
Private _normalMaterial As DiffuseMaterial = New DiffuseMaterial(System.Windows.Media.Brushes.Silver)
Private _selectedMaterial As DiffuseMaterial = New DiffuseMaterial(System.Windows.Media.Brushes.Orange)
Private _clickedMaterial As DiffuseMaterial = New DiffuseMaterial(System.Windows.Media.Brushes.Red)
Private Sub Setup3DObjects()
Me._eventManager3D = New EventManager3D(Me._viewport3D)
Dim visuald1 As New Ab3d.Visuals.WireGridVisual3D
visuald1.Size = New Size(1000, 1000)
visuald1.HeightCellsCount = 10
visuald1.WidthCellsCount = 10
visuald1.LineThickness = 3
Dim visuald As Ab3d.Visuals.WireGridVisual3D = visuald1
Me._viewport3D.Children.Add(visuald)
Dim num As Integer = -3
Do While True
If (num > 3) Then
Me.ToggleCameraAnimation()
Return
End If
Dim num2 As Integer = -3
Do While True
If (num2 > 3) Then
num += 1
Exit Do
End If
Dim y As Double = ((5 - Math.Sqrt(CDbl(((num2 * num2) + (num * num))))) * 60)
Dim visuald3 As New Ab3d.Visuals.BoxVisual3D
visuald3.CenterPosition = New Point3D(CDbl((num2 * 100)), (y / 2), CDbl((num * 100)))
visuald3.Size = New Size3D(80, y, 80)
visuald3.Material = Me._normalMaterial
Dim visuald2 As Ab3d.Visuals.BoxVisual3D = visuald3
Me._viewport3D.Children.Add(visuald2)
Dim eventSource As New VisualEventSource3D(visuald2)
AddHandler eventSource.MouseEnter, New Mouse3DEventHandler(AddressOf Me.BoxOnMouseEnter)
AddHandler eventSource.MouseLeave, New Mouse3DEventHandler(AddressOf Me.BoxOnMouseLeave)
AddHandler eventSource.MouseClick, New MouseButton3DEventHandler(AddressOf Me.BoxOnMouseClick)
Me._eventManager3D.RegisterEventSource3D(eventSource)
num2 += 1
Loop
Loop
ToggleCameraAnimation()
End Sub
Private Sub BoxOnMouseEnter(ByVal sender As Object, ByVal mouse3DEventArgs As Mouse3DEventArgs)
Dim boxVisual3D = TryCast(mouse3DEventArgs.HitObject, Ab3d.Visuals.BoxVisual3D)
If boxVisual3D Is Nothing Then Return
_isSelectedBoxClicked = ReferenceEquals(boxVisual3D.Material, _clickedMaterial)
boxVisual3D.Material = _selectedMaterial
End Sub
Private Sub BoxOnMouseLeave(ByVal sender As Object, ByVal mouse3DEventArgs As Mouse3DEventArgs)
Dim boxVisual3D = TryCast(mouse3DEventArgs.HitObject, Ab3d.Visuals.BoxVisual3D)
If boxVisual3D Is Nothing Then Return
If _isSelectedBoxClicked Then
boxVisual3D.Material = _clickedMaterial
Else
boxVisual3D.Material = _normalMaterial
End If
End Sub
Private Sub BoxOnMouseClick(ByVal sender As Object, ByVal mouseButton3DEventArgs As MouseButton3DEventArgs)
Dim boxVisual3D = TryCast(mouseButton3DEventArgs.HitObject, Ab3d.Visuals.BoxVisual3D)
If boxVisual3D Is Nothing Then Return
If Not _isSelectedBoxClicked Then
boxVisual3D.Material = _clickedMaterial
_isSelectedBoxClicked = True
_totalClickedHeight += boxVisual3D.Size.Y
Else
boxVisual3D.Material = _normalMaterial
_isSelectedBoxClicked = False
_totalClickedHeight -= boxVisual3D.Size.Y
End If
End Sub
Private Sub SetUpWpf3D()
_rootGrid = New Grid()
_rootGrid.Background = System.Windows.Media.Brushes.White
_viewport3D = New Viewport3D()
_rootGrid.Children.Add(_viewport3D)
_targetPositionCamera = New Ab3d.Cameras.TargetPositionCamera()
With _targetPositionCamera
.TargetPosition = New Point3D(0, 0, 0)
.Distance = 1300
.Heading = 30
.Attitude = -20
.ShowCameraLight = ShowCameraLightType.Always
.TargetViewport3D = _viewport3D
End With
_rootGrid.Children.Add(_targetPositionCamera)
_mouseCameraController = New Ab3d.Controls.MouseCameraController()
With _mouseCameraController
.RotateCameraConditions = MouseCameraController.MouseAndKeyboardConditions.RightMouseButtonPressed
.MoveCameraConditions = MouseCameraController.MouseAndKeyboardConditions.RightMouseButtonPressed Or MouseCameraController.MouseAndKeyboardConditions.ControlKey
.EventsSourceElement = _rootGrid
.TargetCamera = _targetPositionCamera
End With
_rootGrid.Children.Add(_mouseCameraController)
Dim cameraControlPanel = New Ab3d.Controls.CameraControlPanel()
With cameraControlPanel
.VerticalAlignment = VerticalAlignment.Bottom
.HorizontalAlignment = HorizontalAlignment.Right
.Margin = New Thickness(5, 5, 5, 5)
.Width = 225
.Height = 75
.ShowMoveButtons = True
.TargetCamera = _targetPositionCamera
End With
_rootGrid.Children.Add(cameraControlPanel)
ElementHost1.Child = _rootGrid
End Sub
Private Sub BTN_animateButton_Click(sender As Object, e As EventArgs) Handles BTN_animateButton.Click
ToggleCameraAnimation()
End Sub
Private Sub ToggleCameraAnimation()
If _targetPositionCamera.IsRotating Then
_targetPositionCamera.StopRotation()
BTN_animateButton.Text = "Start animation"
Else
_targetPositionCamera.StartRotation(10, 0)
BTN_animateButton.Text = "Stop animation"
End If
End Sub
Public Class MouseWheelMessageFilter
Implements IMessageFilter
Private Const WM_MOUSEWHEEL As Integer = &H20A
Private _element As FrameworkElement
Private sender As Object
Private args As Object
Private Sub New(ByVal element As FrameworkElement)
Me._element = element
'AddHandler Me._element.Loaded, (sender, args) >= Application.AddMessageFilter(Me)
'AddHandler Me._element.Unloaded, (sender, args) >= Application.RemoveMessageFilter(Me)
End Sub
Public Shared Sub RegisterMouseWheelHandling(ByVal element As FrameworkElement)
Dim filter As New MouseWheelMessageFilter(element)
End Sub
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
Public Function IMessageFilter_PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
Dim flag2 As Boolean
If Me._element.IsVisible Then
If (m.Msg = &H20A) Then
Dim rect As New Rect(0, 0, Me._element.ActualWidth, Me._element.ActualHeight)
If rect.Contains(Mouse.GetPosition(Me._element)) Then
MouseWheelMessageFilter.SendMessage(DirectCast(PresentationSource.FromVisual(Me._element), HwndSource).Handle, m.Msg, m.WParam, m.LParam)
Return True
End If
End If
flag2 = False
Else
flag2 = False
End If
Return flag2
End Function
End Class
No problem, now all I have to do is work out how to import and export models with Assimp.
What I need is a model viewer/convertor hence the purchase.
I wish there were VB examples converting and not quite understand C# makes the job twice as difficult
02-19-2021, 07:14 PM (This post was last modified: 02-19-2021, 07:21 PM by GraPhiX.)
Now i have elementhost setup i have tried converting Assimp sample (the one i actually need)
i have converted all the subs and classes but the ShowModel sub as one issue,
ContentVisual.Content = model3D
i assume this assigns the loaded model on a WPF form how do i get it to use my elementhost ? this is the code i have:
Code:
Private Sub ShowModel(ByVal model3D As Model3D, ByVal updateCamera As Boolean)
ContentVisual.Content = model3D
If Not Object.ReferenceEquals(model3D, Nothing) Then
Me.ContentWireframeVisual.BeginInit
Me.ContentWireframeVisual.ShowPolygonLines = Me.ReadPolygonIndicesCheckBox.IsChecked.GetValueOrDefault
Me.ContentWireframeVisual.OriginalModel = model3D
Me.ContentWireframeVisual.EndInit
If updateCamera Then
Dim bounds As Rect3D = model3D.Bounds
Dim pointd As New Point3D((bounds.X + (bounds.SizeX / 2)), (bounds.Y + (bounds.SizeY / 2)), (bounds.Z + (bounds.SizeZ / 2)))
Dim num As Double = Math.Sqrt((((bounds.SizeX * bounds.SizeX) + (bounds.SizeY * bounds.SizeY)) + (bounds.SizeZ * bounds.SizeZ)))
Me.Camera1.TargetPosition = pointd
Me.Camera1.Distance = (num * 2)
End If
Me.Camera1.ShowCameraLight = If(Not ModelUtils.HasAnyLight(model3D, True), ShowCameraLightType.Always, ShowCameraLightType.Never)
Me.ShowInfoButton.IsEnabled = True
End If
I see that you already have a field ContentVisual, but because of the exception, you get it seems that you did not yet create an instance of it. As seen from the XAML, you will need to assign it to a new instance of ModelVisual3D object and then add that instance to Viewport3D objects with (MainViewport is the field that is an instance of Viewport3D):
Private _contentVisual As ModelVisual3D
...
Me._contentVisual = new ModelVisual3D()
Me._viewport3D.Children.Add(_contentVisual)
I see that you already have a field ContentVisual, but because of the exception, you get it seems that you did not yet create an instance of it. As seen from the XAML, you will need to assign it to a new instance of ModelVisual3D object and then add that instance to Viewport3D objects with (MainViewport is the field that is an instance of Viewport3D):
Private _contentVisual As ModelVisual3D
...
Me._contentVisual = new ModelVisual3D()
Me._viewport3D.Children.Add(_contentVisual)
Doh! simple when you write it like that :) thank you....... plodding on Model now loads :) now i need to reset the view to load another model at the moment i am adding to the scene i would rather clear it an load fresh each time.