Co-authored-by: Loskh <1020612624@qq.com>
This commit is contained in:
Bluefissure 2022-08-31 15:09:24 -05:00 committed by GitHub
parent 5dbed370f8
commit 26835467ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 88 deletions

View file

@ -58,41 +58,18 @@ namespace Dalamud.Game.Gui.Internal
Marshal.FreeHGlobal((IntPtr)this.cursorPos);
}
/// <summary>
/// Processes window messages.
/// </summary>
/// <param name="hWnd">Handle of the window.</param>
/// <param name="msg">Type of window message.</param>
/// <param name="wParam">wParam.</param>
/// <param name="lParam">lParam.</param>
/// <returns>Return value, if not doing further processing.</returns>
public unsafe IntPtr? ProcessWndProcW(IntPtr hWnd, User32.WindowMessage msg, void* wParam, void* lParam)
private unsafe void LoadCand(IntPtr hWnd)
{
try
{
if (ImGui.GetCurrentContext() != IntPtr.Zero && ImGui.GetIO().WantTextInput)
{
var io = ImGui.GetIO();
var wmsg = (WindowsMessage)msg;
switch (wmsg)
{
case WindowsMessage.WM_IME_NOTIFY:
switch ((IMECommand)(IntPtr)wParam)
{
case IMECommand.ChangeCandidate:
this.ToggleWindow(true);
if (hWnd == IntPtr.Zero)
return IntPtr.Zero;
return;
var hIMC = ImmGetContext(hWnd);
if (hIMC == IntPtr.Zero)
return IntPtr.Zero;
return;
var size = ImmGetCandidateListW(hIMC, 0, IntPtr.Zero, 0);
if (size == 0)
break;
return;
var candlistPtr = Marshal.AllocHGlobal((int)size);
size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size);
@ -137,18 +114,56 @@ namespace Dalamud.Game.Gui.Internal
Marshal.FreeHGlobal(candlistPtr);
}
}
/// <summary>
/// Processes window messages.
/// </summary>
/// <param name="hWnd">Handle of the window.</param>
/// <param name="msg">Type of window message.</param>
/// <param name="wParamPtr">wParam or the pointer to it.</param>
/// <param name="lParamPtr">lParam or the pointer to it.</param>
/// <returns>Return value, if not doing further processing.</returns>
public unsafe IntPtr? ProcessWndProcW(IntPtr hWnd, User32.WindowMessage msg, void* wParamPtr, void* lParamPtr)
{
try
{
if (ImGui.GetCurrentContext() != IntPtr.Zero && ImGui.GetIO().WantTextInput)
{
var io = ImGui.GetIO();
var wmsg = (WindowsMessage)msg;
long wParam = (long)wParamPtr, lParam = (long)lParamPtr;
try
{
wParam = Marshal.ReadInt32((IntPtr)wParamPtr);
}
catch { }
try
{
lParam = Marshal.ReadInt32((IntPtr)lParamPtr);
}
catch { }
switch (wmsg)
{
case WindowsMessage.WM_IME_NOTIFY:
switch ((IMECommand)(IntPtr)wParam)
{
case IMECommand.ChangeCandidate:
this.ToggleWindow(true);
this.LoadCand(hWnd);
break;
case IMECommand.OpenCandidate:
this.ToggleWindow(true);
this.ImmCandNative = default;
this.ImmCand.Clear();
// this.ImmCand.Clear();
break;
case IMECommand.CloseCandidate:
this.ToggleWindow(false);
this.ImmCandNative = default;
this.ImmCand.Clear();
// this.ImmCand.Clear();
break;
default:
@ -157,6 +172,33 @@ namespace Dalamud.Game.Gui.Internal
break;
case WindowsMessage.WM_IME_COMPOSITION:
if (((long)(IMEComposition.CompStr | IMEComposition.CompAttr | IMEComposition.CompClause |
IMEComposition.CompReadAttr | IMEComposition.CompReadClause | IMEComposition.CompReadStr) & (long)(IntPtr)lParam) > 0)
{
var hIMC = ImmGetContext(hWnd);
if (hIMC == IntPtr.Zero)
return IntPtr.Zero;
var dwSize = ImmGetCompositionStringW(hIMC, IMEComposition.CompStr, IntPtr.Zero, 0);
var unmanagedPointer = Marshal.AllocHGlobal((int)dwSize);
ImmGetCompositionStringW(hIMC, IMEComposition.CompStr, unmanagedPointer, (uint)dwSize);
var bytes = new byte[dwSize];
Marshal.Copy(unmanagedPointer, bytes, 0, (int)dwSize);
Marshal.FreeHGlobal(unmanagedPointer);
var lpstr = Encoding.Unicode.GetString(bytes);
this.ImmComp = lpstr;
if (lpstr == string.Empty)
{
this.ToggleWindow(false);
}
else
{
this.LoadCand(hWnd);
}
}
if (((long)(IntPtr)lParam & (long)IMEComposition.ResultStr) > 0)
{
var hIMC = ImmGetContext(hWnd);
@ -180,27 +222,6 @@ namespace Dalamud.Game.Gui.Internal
this.ToggleWindow(false);
}
if (((long)(IMEComposition.CompStr | IMEComposition.CompAttr | IMEComposition.CompClause |
IMEComposition.CompReadAttr | IMEComposition.CompReadClause | IMEComposition.CompReadStr) & (long)(IntPtr)lParam) > 0)
{
var hIMC = ImmGetContext(hWnd);
if (hIMC == IntPtr.Zero)
return IntPtr.Zero;
var dwSize = ImmGetCompositionStringW(hIMC, IMEComposition.CompStr, IntPtr.Zero, 0);
var unmanagedPointer = Marshal.AllocHGlobal((int)dwSize);
ImmGetCompositionStringW(hIMC, IMEComposition.CompStr, unmanagedPointer, (uint)dwSize);
var bytes = new byte[dwSize];
Marshal.Copy(unmanagedPointer, bytes, 0, (int)dwSize);
Marshal.FreeHGlobal(unmanagedPointer);
var lpstr = Encoding.Unicode.GetString(bytes);
this.ImmComp = lpstr;
if (lpstr == string.Empty)
this.ToggleWindow(false);
}
break;
default:

View file

@ -62,6 +62,7 @@ namespace Dalamud.Interface.Internal
private readonly SwapChainVtableResolver address;
private readonly Hook<DispatchMessageWDelegate> dispatchMessageWHook;
private readonly Hook<SetCursorDelegate> setCursorHook;
private Hook<ProcessMessageDelegate> processMessageHook;
private RawDX11Scene? scene;
private Hook<PresentDelegate>? presentHook;
@ -97,6 +98,8 @@ namespace Dalamud.Interface.Internal
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr DispatchMessageWDelegate(ref User32.MSG msg);
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr ProcessMessageDelegate(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled);
/// <summary>
/// This event gets called each frame to facilitate ImGui drawing.
/// </summary>
@ -217,6 +220,7 @@ namespace Dalamud.Interface.Internal
this.presentHook?.Dispose();
this.resizeBuffersHook?.Dispose();
this.dispatchMessageWHook.Dispose();
this.processMessageHook?.Dispose();
}).Wait();
this.scene?.Dispose();
@ -920,10 +924,15 @@ namespace Dalamud.Interface.Internal
Log.Verbose($"Present address 0x{this.presentHook!.Address.ToInt64():X}");
Log.Verbose($"ResizeBuffers address 0x{this.resizeBuffersHook!.Address.ToInt64():X}");
var wndProcAddress = sigScanner.ScanText("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8");
Log.Verbose($"WndProc address 0x{wndProcAddress.ToInt64():X}");
this.processMessageHook = Hook<ProcessMessageDelegate>.FromAddress(wndProcAddress, this.ProcessMessageDetour);
this.setCursorHook.Enable();
this.presentHook.Enable();
this.resizeBuffersHook.Enable();
this.dispatchMessageWHook.Enable();
this.processMessageHook.Enable();
});
}
@ -944,16 +953,18 @@ namespace Dalamud.Interface.Internal
this.isRebuildingFonts = false;
}
private unsafe IntPtr ProcessMessageDetour(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled)
{
var ime = Service<DalamudIME>.GetNullable();
var res = ime?.ProcessWndProcW(hWnd, (User32.WindowMessage)msg, (void*)wParam, (void*)lParam);
return this.processMessageHook.Original(hWnd, msg, wParam, lParam, handeled);
}
private unsafe IntPtr DispatchMessageWDetour(ref User32.MSG msg)
{
if (msg.hwnd == this.GameWindowHandle && this.scene != null)
{
var ime = Service<DalamudIME>.GetNullable();
var res = ime?.ProcessWndProcW(msg.hwnd, msg.message, (void*)msg.wParam, (void*)msg.lParam);
if (res != null)
return res.Value;
res = this.scene.ProcessWndProcW(msg.hwnd, msg.message, (void*)msg.wParam, (void*)msg.lParam);
var res = this.scene.ProcessWndProcW(msg.hwnd, msg.message, (void*)msg.wParam, (void*)msg.lParam);
if (res != null)
return res.Value;
}