Is there something special I have to do for vizard embedded to get mouse and keyboard?
I need to embed my vizard window in a WPF control. I adapted
this tutorial and
this one(thanks farshizzo) to suit and made a nice control that starts up a vizard script and passes the handle to the window I've created as the first paramater. The script, if it sees the first parameter, takes that to be a window handle and embeds itself in that window. It almost entirely works.
However, I can't seem to get input to go through. Microsoft's tutorial works just fine with their own listbox, but I'm not sure if vizard's input is handled differently.
I know the script itself is properly receiving input. If I run this script with the only difference being that it isn't embedded, it responds properly to mouse and keyboard input.
I know vizard isn't hanging or blocked out of input: The ball spins, and if I check the keyboard state manually (e.g., viz.key.isDown(' ', True)), I can see if keys are up or down. onkeydown doesn't seem to work, however.
p/invoking win32's setfocus does not appear to do anything.
here's the vizard script:
Code:
import viz
import vizact
viz.add('tut_ground.wrl')
ball = viz.add('ball.wrl',pos=(0,1.8,2))
ball.add(vizact.spin(0,1,0,90))
def mytimer(num):
if num is 0:
ball.setPosition(0, 1.8, 4)
elif num is 1:
if viz.key.isDown(' ', True):
ball.setPosition(0, 1.8, 3)
vizact.ontimer(0.1666, mytimer, 1)
vizact.ontimer(1.5, mytimer, 0)
vizact.onkeydown('b', ball.setPosition, [0,1.8,5])
if(len(sys.argv) > 1):
viz.go(viz.EMBEDDED, window=int(sys.argv[1]))
while True:
viz.updateframe()
else:
viz.go()
and here's the vizard box control:
Code:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace vizardbox
{
public partial class VizardBox : UserControl
{
public String VizardAdditionalStartupArguments
{
get { return (String)GetValue(VizardAdditionalStartupArgumentsProperty); }
set { SetValue(VizardAdditionalStartupArgumentsProperty, value); }
}
public bool VizardConsole
{
get { return (bool)GetValue(VizardConsoleProperty); }
set { SetValue(VizardConsoleProperty, value); }
}
public String VizardScript
{
get { return (String)GetValue(VizardScriptProperty); }
set { SetValue(VizardScriptProperty, value); }
}
public String VizardInstallation
{
get { return (String)GetValue(VizardInstallationProperty); }
set { SetValue(VizardInstallationProperty, value); }
}
public static readonly DependencyProperty VizardAdditionalStartupArgumentsProperty = DependencyProperty.Register("VizardAdditionalStartupArguments", typeof(String), typeof(VizardBox), new UIPropertyMetadata(""));
public static readonly DependencyProperty VizardConsoleProperty = DependencyProperty.Register("VizardConsole", typeof(bool), typeof(VizardBox), new UIPropertyMetadata(false));
public static readonly DependencyProperty VizardScriptProperty = DependencyProperty.Register("VizardScript", typeof(String), typeof(VizardBox), new UIPropertyMetadata(""));
public static readonly DependencyProperty VizardInstallationProperty = DependencyProperty.Register("VizardInstallation", typeof(String), typeof(VizardBox), new UIPropertyMetadata("C:\\Program Files (x86)\\WorldViz\\Vizard4\\bin\\winviz.exe"));
vizHwndHost vh;
public VizardBox()
{
InitializeComponent();
}
public void Go()
{
vh = new vizHwndHost();
_hostborder.Child=vh;
vh.go(VizardScript, VizardInstallation, VizardAdditionalStartupArguments, VizardConsole);
}
public void Stop()
{
_hostborder.Child = null;
vh.stop();
}
}
public class vizHwndHost : HwndHost
{
IntPtr hwndVizardHandle;
Process vizardProc;
~vizHwndHost()
{
stop();
DestroyWindow(hwndVizardHandle);
}
public void stop()
{
if (vizardProc != null)
if(!vizardProc.HasExited)
vizardProc.Kill();
}
public void go(string script, string vizardLocation, string additionalStartupArguments, bool console)
{
vizardProc = new Process();
vizardProc.StartInfo.FileName = vizardLocation;
vizardProc.StartInfo.Arguments = (console? "-console" : "") + " \"" + script + "\" " + hwndVizardHandle.ToString() + " " + additionalStartupArguments;
vizardProc.Start();
}
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
hwndVizardHandle = IntPtr.Zero;
hwndVizardHandle = CreateWindowEx(0, "static", "",
WS_CHILD | WS_VISIBLE,
0, 0,
0, 0,
hwndParent.Handle,
(IntPtr)HOST_ID,
IntPtr.Zero,
0);
return new HandleRef(this, hwndVizardHandle);
}
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
handled = false;
return IntPtr.Zero;
}
public void setFocus()
{
SetFocus(hwndVizardHandle);
}
protected override void OnGotMouseCapture(MouseEventArgs e)
{
base.OnGotMouseCapture(e);
e.Handled = true;
}
protected override void DestroyWindowCore(HandleRef hwnd)
{
DestroyWindow(hwnd.Handle);
}
//PInvoke declarations
[DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode)]
internal static extern IntPtr CreateWindowEx(int dwExStyle,
string lpszClassName,
string lpszWindowName,
int style,
int x, int y,
int width, int height,
IntPtr hwndParent,
IntPtr hMenu,
IntPtr hInst,
[MarshalAs(UnmanagedType.AsAny)] object pvParam);
[DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
internal static extern bool DestroyWindow(IntPtr hwnd);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
static extern IntPtr SetFocus(IntPtr hWnd);
internal const int
WS_CHILD = 0x40000000,
WS_VISIBLE = 0x10000000,
LBS_NOTIFY = 0x00000001,
HOST_ID = 0x00000002;
}
}