mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
parent
5dbed370f8
commit
26835467ea
2 changed files with 120 additions and 88 deletions
|
|
@ -58,15 +58,73 @@ namespace Dalamud.Game.Gui.Internal
|
||||||
Marshal.FreeHGlobal((IntPtr)this.cursorPos);
|
Marshal.FreeHGlobal((IntPtr)this.cursorPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private unsafe void LoadCand(IntPtr hWnd)
|
||||||
|
{
|
||||||
|
if (hWnd == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var hIMC = ImmGetContext(hWnd);
|
||||||
|
if (hIMC == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var size = ImmGetCandidateListW(hIMC, 0, IntPtr.Zero, 0);
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var candlistPtr = Marshal.AllocHGlobal((int)size);
|
||||||
|
size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size);
|
||||||
|
|
||||||
|
var candlist = this.ImmCandNative = Marshal.PtrToStructure<CandidateList>(candlistPtr);
|
||||||
|
var pageSize = candlist.PageSize;
|
||||||
|
var candCount = candlist.Count;
|
||||||
|
|
||||||
|
if (pageSize > 0 && candCount > 1)
|
||||||
|
{
|
||||||
|
var dwOffsets = new int[candCount];
|
||||||
|
for (var i = 0; i < candCount; i++)
|
||||||
|
{
|
||||||
|
dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
var pageStart = candlist.PageStart;
|
||||||
|
|
||||||
|
var cand = new string[pageSize];
|
||||||
|
this.ImmCand.Clear();
|
||||||
|
|
||||||
|
for (var i = 0; i < pageSize; i++)
|
||||||
|
{
|
||||||
|
var offStart = dwOffsets[i + pageStart];
|
||||||
|
var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size;
|
||||||
|
|
||||||
|
var pStrStart = candlistPtr + (int)offStart;
|
||||||
|
var pStrEnd = candlistPtr + (int)offEnd;
|
||||||
|
|
||||||
|
var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64());
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
var candBytes = new byte[len];
|
||||||
|
Marshal.Copy(pStrStart, candBytes, 0, len);
|
||||||
|
|
||||||
|
var candStr = Encoding.Unicode.GetString(candBytes);
|
||||||
|
cand[i] = candStr;
|
||||||
|
|
||||||
|
this.ImmCand.Add(candStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal(candlistPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes window messages.
|
/// Processes window messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hWnd">Handle of the window.</param>
|
/// <param name="hWnd">Handle of the window.</param>
|
||||||
/// <param name="msg">Type of window message.</param>
|
/// <param name="msg">Type of window message.</param>
|
||||||
/// <param name="wParam">wParam.</param>
|
/// <param name="wParamPtr">wParam or the pointer to it.</param>
|
||||||
/// <param name="lParam">lParam.</param>
|
/// <param name="lParamPtr">lParam or the pointer to it.</param>
|
||||||
/// <returns>Return value, if not doing further processing.</returns>
|
/// <returns>Return value, if not doing further processing.</returns>
|
||||||
public unsafe IntPtr? ProcessWndProcW(IntPtr hWnd, User32.WindowMessage msg, void* wParam, void* lParam)
|
public unsafe IntPtr? ProcessWndProcW(IntPtr hWnd, User32.WindowMessage msg, void* wParamPtr, void* lParamPtr)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -74,6 +132,18 @@ namespace Dalamud.Game.Gui.Internal
|
||||||
{
|
{
|
||||||
var io = ImGui.GetIO();
|
var io = ImGui.GetIO();
|
||||||
var wmsg = (WindowsMessage)msg;
|
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)
|
switch (wmsg)
|
||||||
{
|
{
|
||||||
|
|
@ -82,73 +152,18 @@ namespace Dalamud.Game.Gui.Internal
|
||||||
{
|
{
|
||||||
case IMECommand.ChangeCandidate:
|
case IMECommand.ChangeCandidate:
|
||||||
this.ToggleWindow(true);
|
this.ToggleWindow(true);
|
||||||
|
this.LoadCand(hWnd);
|
||||||
if (hWnd == IntPtr.Zero)
|
|
||||||
return IntPtr.Zero;
|
|
||||||
|
|
||||||
var hIMC = ImmGetContext(hWnd);
|
|
||||||
if (hIMC == IntPtr.Zero)
|
|
||||||
return IntPtr.Zero;
|
|
||||||
|
|
||||||
var size = ImmGetCandidateListW(hIMC, 0, IntPtr.Zero, 0);
|
|
||||||
if (size == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
var candlistPtr = Marshal.AllocHGlobal((int)size);
|
|
||||||
size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size);
|
|
||||||
|
|
||||||
var candlist = this.ImmCandNative = Marshal.PtrToStructure<CandidateList>(candlistPtr);
|
|
||||||
var pageSize = candlist.PageSize;
|
|
||||||
var candCount = candlist.Count;
|
|
||||||
|
|
||||||
if (pageSize > 0 && candCount > 1)
|
|
||||||
{
|
|
||||||
var dwOffsets = new int[candCount];
|
|
||||||
for (var i = 0; i < candCount; i++)
|
|
||||||
{
|
|
||||||
dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int)));
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageStart = candlist.PageStart;
|
|
||||||
|
|
||||||
var cand = new string[pageSize];
|
|
||||||
this.ImmCand.Clear();
|
|
||||||
|
|
||||||
for (var i = 0; i < pageSize; i++)
|
|
||||||
{
|
|
||||||
var offStart = dwOffsets[i + pageStart];
|
|
||||||
var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size;
|
|
||||||
|
|
||||||
var pStrStart = candlistPtr + (int)offStart;
|
|
||||||
var pStrEnd = candlistPtr + (int)offEnd;
|
|
||||||
|
|
||||||
var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64());
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
var candBytes = new byte[len];
|
|
||||||
Marshal.Copy(pStrStart, candBytes, 0, len);
|
|
||||||
|
|
||||||
var candStr = Encoding.Unicode.GetString(candBytes);
|
|
||||||
cand[i] = candStr;
|
|
||||||
|
|
||||||
this.ImmCand.Add(candStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Marshal.FreeHGlobal(candlistPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IMECommand.OpenCandidate:
|
case IMECommand.OpenCandidate:
|
||||||
this.ToggleWindow(true);
|
this.ToggleWindow(true);
|
||||||
this.ImmCandNative = default;
|
this.ImmCandNative = default;
|
||||||
this.ImmCand.Clear();
|
// this.ImmCand.Clear();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMECommand.CloseCandidate:
|
case IMECommand.CloseCandidate:
|
||||||
this.ToggleWindow(false);
|
this.ToggleWindow(false);
|
||||||
this.ImmCandNative = default;
|
this.ImmCandNative = default;
|
||||||
this.ImmCand.Clear();
|
// this.ImmCand.Clear();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -157,6 +172,33 @@ namespace Dalamud.Game.Gui.Internal
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case WindowsMessage.WM_IME_COMPOSITION:
|
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)
|
if (((long)(IntPtr)lParam & (long)IMEComposition.ResultStr) > 0)
|
||||||
{
|
{
|
||||||
var hIMC = ImmGetContext(hWnd);
|
var hIMC = ImmGetContext(hWnd);
|
||||||
|
|
@ -180,27 +222,6 @@ namespace Dalamud.Game.Gui.Internal
|
||||||
this.ToggleWindow(false);
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ namespace Dalamud.Interface.Internal
|
||||||
private readonly SwapChainVtableResolver address;
|
private readonly SwapChainVtableResolver address;
|
||||||
private readonly Hook<DispatchMessageWDelegate> dispatchMessageWHook;
|
private readonly Hook<DispatchMessageWDelegate> dispatchMessageWHook;
|
||||||
private readonly Hook<SetCursorDelegate> setCursorHook;
|
private readonly Hook<SetCursorDelegate> setCursorHook;
|
||||||
|
private Hook<ProcessMessageDelegate> processMessageHook;
|
||||||
private RawDX11Scene? scene;
|
private RawDX11Scene? scene;
|
||||||
|
|
||||||
private Hook<PresentDelegate>? presentHook;
|
private Hook<PresentDelegate>? presentHook;
|
||||||
|
|
@ -97,6 +98,8 @@ namespace Dalamud.Interface.Internal
|
||||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||||
private delegate IntPtr DispatchMessageWDelegate(ref User32.MSG msg);
|
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>
|
/// <summary>
|
||||||
/// This event gets called each frame to facilitate ImGui drawing.
|
/// This event gets called each frame to facilitate ImGui drawing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -217,6 +220,7 @@ namespace Dalamud.Interface.Internal
|
||||||
this.presentHook?.Dispose();
|
this.presentHook?.Dispose();
|
||||||
this.resizeBuffersHook?.Dispose();
|
this.resizeBuffersHook?.Dispose();
|
||||||
this.dispatchMessageWHook.Dispose();
|
this.dispatchMessageWHook.Dispose();
|
||||||
|
this.processMessageHook?.Dispose();
|
||||||
}).Wait();
|
}).Wait();
|
||||||
|
|
||||||
this.scene?.Dispose();
|
this.scene?.Dispose();
|
||||||
|
|
@ -920,10 +924,15 @@ namespace Dalamud.Interface.Internal
|
||||||
Log.Verbose($"Present address 0x{this.presentHook!.Address.ToInt64():X}");
|
Log.Verbose($"Present address 0x{this.presentHook!.Address.ToInt64():X}");
|
||||||
Log.Verbose($"ResizeBuffers address 0x{this.resizeBuffersHook!.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.setCursorHook.Enable();
|
||||||
this.presentHook.Enable();
|
this.presentHook.Enable();
|
||||||
this.resizeBuffersHook.Enable();
|
this.resizeBuffersHook.Enable();
|
||||||
this.dispatchMessageWHook.Enable();
|
this.dispatchMessageWHook.Enable();
|
||||||
|
this.processMessageHook.Enable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -944,16 +953,18 @@ namespace Dalamud.Interface.Internal
|
||||||
this.isRebuildingFonts = false;
|
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)
|
private unsafe IntPtr DispatchMessageWDetour(ref User32.MSG msg)
|
||||||
{
|
{
|
||||||
if (msg.hwnd == this.GameWindowHandle && this.scene != null)
|
if (msg.hwnd == this.GameWindowHandle && this.scene != null)
|
||||||
{
|
{
|
||||||
var ime = Service<DalamudIME>.GetNullable();
|
var res = this.scene.ProcessWndProcW(msg.hwnd, msg.message, (void*)msg.wParam, (void*)msg.lParam);
|
||||||
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);
|
|
||||||
if (res != null)
|
if (res != null)
|
||||||
return res.Value;
|
return res.Value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue