Files
AX-Copilot-Codex/.decompiledproj/AxCopilot/Services/FileDialogWatcher.cs

102 lines
2.7 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Threading;
namespace AxCopilot.Services;
public class FileDialogWatcher : IDisposable
{
private delegate void WinEventDelegate(nint hWinEventHook, uint eventType, nint hwnd, int idObject, int idChild, uint idEventThread, uint dwmsEventTime);
private const uint EVENT_OBJECT_SHOW = 32770u;
private const uint EVENT_OBJECT_CREATE = 32768u;
private const uint WINEVENT_OUTOFCONTEXT = 0u;
private const uint WINEVENT_SKIPOWNPROCESS = 2u;
private nint _hook;
private WinEventDelegate? _delegate;
private bool _disposed;
private readonly Dispatcher _dispatcher;
public event EventHandler<nint>? FileDialogOpened;
[DllImport("user32.dll")]
private static extern nint SetWinEventHook(uint eventMin, uint eventMax, nint hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
private static extern bool UnhookWinEvent(nint hWinEventHook);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int GetClassName(nint hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int GetWindowText(nint hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(nint hWnd);
public FileDialogWatcher()
{
_dispatcher = Dispatcher.CurrentDispatcher;
}
public void Start()
{
if (_hook == IntPtr.Zero)
{
_delegate = OnWinEvent;
_hook = SetWinEventHook(32770u, 32770u, IntPtr.Zero, _delegate, 0u, 0u, 2u);
}
}
public void Stop()
{
if (_hook != IntPtr.Zero)
{
UnhookWinEvent(_hook);
_hook = IntPtr.Zero;
}
}
private void OnWinEvent(nint hWinEventHook, uint eventType, nint hwnd, int idObject, int idChild, uint idEventThread, uint dwmsEventTime)
{
if (hwnd == IntPtr.Zero || idObject != 0 || !IsWindowVisible(hwnd))
{
return;
}
StringBuilder stringBuilder = new StringBuilder(256);
GetClassName(hwnd, stringBuilder, 256);
string text = stringBuilder.ToString();
if (text != "#32770")
{
return;
}
StringBuilder stringBuilder2 = new StringBuilder(256);
GetWindowText(hwnd, stringBuilder2, 256);
string text2 = stringBuilder2.ToString();
if (text2.Contains("열기") || text2.Contains("Open") || text2.Contains("저장") || text2.Contains("Save") || text2.Contains("다른 이름") || text2.Contains("Browse") || text2.Contains("폴더") || text2.Contains("Folder"))
{
_dispatcher.BeginInvoke((Delegate)(Action)delegate
{
this.FileDialogOpened?.Invoke(this, hwnd);
}, Array.Empty<object>());
}
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
Stop();
}
}
}