I figured out how to implement WndProc in WPF UserControl. UserControl must obtain a window pointer like by AppendWindow method in my example:
private static MyUserControl instanceWithFocus;
public void AppendWindow(Window window) {
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(window).Handle);
source.AddHook(new HwndSourceHook(WndProc));
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
switch (msg) {
case Win32Messages.WM_MOUSEHWHEEL:
MouseWheelTilt(wParam, lParam);
handled = true;
break;
default:
break;
}
return IntPtr.Zero;
}
private static void MouseWheelTilt(IntPtr wParam, IntPtr lParam) {
Int32 tilt = (Int16)Utils.HIWORD(wParam);
Int32 keys = Utils.LOWORD(wParam);
Int32 x = Utils.LOWORD(lParam);
Int32 y = Utils.HIWORD(lParam);
// call an event on active instance of this object
if (instanceWithFocus != null) {
instanceWithFocus.MouseWheelTilt(tilt, keys, x, y);
}
}
private void MouseWheelTilt(Int32 tilt, Int32 keys, Int32 x, Int32 y) {
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + tilt);
}
private void UserControl_MouseEnter(object sender, MouseEventArgs e) {
instanceWithFocus = this;
}
private void UserControl_MouseLeave(object sender, MouseEventArgs e) {
instanceWithFocus = null;
}
abstract class Win32Messages {
public const int WM_MOUSEHWHEEL = 0x020E;
}
abstract class Utils {
internal static Int32 HIWORD(IntPtr ptr) {
Int32 val32 = ptr.ToInt32();
return ((val32 >> 16) & 0xFFFF);
}
internal static Int32 LOWORD(IntPtr ptr) {
Int32 val32 = ptr.ToInt32();
return (val32 & 0xFFFF);
}
}