Skip to content

Instantly share code, notes, and snippets.

@toptensoftware
Last active November 2, 2016 12:06
Show Gist options
  • Save toptensoftware/9b45bf73e6474e7ecc275a676820cea7 to your computer and use it in GitHub Desktop.
Save toptensoftware/9b45bf73e6474e7ecc275a676820cea7 to your computer and use it in GitHub Desktop.
// Wrap a 16-bit virtual window procedure in a managed delegate that
// when invoked will call the virtual proc.
public IntPtr GetWndProc32(uint lpfnWndProc)
{
if (lpfnWndProc == 0)
return IntPtr.Zero;
// Check if already wrapped
IntPtr wndProc32 = WndProcMap.To32(lpfnWndProc);
if (wndProc32!=IntPtr.Zero)
return wndProc32;
// Nope, create one
Win32.WNDPROC wndProc32Managed = (hWnd, message, wParam, lParam) =>
{
return CallWndProc16from32(lpfnWndProc, hWnd, message, wParam, lParam);
};
// Connect
return WndProcMap.Connect(wndProc32Managed, lpfnWndProc);
}
// Create a 16-bit thunk that will call a Win32 window procedure
public uint GetWndProc16(IntPtr lpfnWndProc32, bool create = true)
{
if (lpfnWndProc32 == IntPtr.Zero)
return 0;
// Already wrapped?
uint wndProc16 = WndProcMap.To16(lpfnWndProc32);
if (wndProc16 != 0)
return wndProc16;
if (!create)
return 0;
// Create a 16-bit thunk that calls it
wndProc16 = _machine.CreateSystemThunk(() =>
{
ushort hWnd16 = _machine.ReadWord(_machine.ss, (ushort)(_machine.sp + 12));
ushort message16 = _machine.ReadWord(_machine.ss, (ushort)(_machine.sp + 10));
ushort wParam16 = _machine.ReadWord(_machine.ss, (ushort)(_machine.sp + 8));
uint lParam16 = _machine.ReadDWord(_machine.ss, (ushort)(_machine.sp + 4));
_machine.dxax = CallWndProc32from16(lpfnWndProc32, hWnd16, message16, wParam16, lParam16);
}, 10, false, "WndProc32"); // hWnd = 2, msg = 2, wParam = 2, lParam = 4
// Update maps
WndProcMap.Connect(lpfnWndProc32, wndProc16);
// Done
return wndProc16;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment