soukoku / ntwain

A TWAIN lib for dotnet.
MIT License
117 stars 47 forks source link

Question - UI Handle #54

Closed mikebm closed 6 months ago

mikebm commented 6 months ago

Hello again,

I am sometimes finding that the Twain UI shows behind my application instead of in front. Any idea how to figure out how to get the HWND for the UI that twain opens?

I was hoping to inject some code in the TwainSessionInternal.cs when if (msg == WM_ACTIVATEAPP && wParam == 1), then bring it forward, but struggling to find the window. It doesn't seem to be a child window on the hWnd to this. and the hWnd is the custom NTWAIN_LOOPER window.

Thanks.

mikebm commented 6 months ago

I was able to figure out a solution...

After calling Enable, I wrote the following code to get the Win32 handles to visible windows.

public class WindowHandleHelper
{
    delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWindowVisible(IntPtr hWnd);

    private static uint currentProcessId = (uint)Process.GetCurrentProcess().Id;

    public static List<IntPtr> GetWin32WindowHandles()
    {
        List<IntPtr> handles = new List<IntPtr>();

        EnumWindows(
            (hWnd, lParam) =>
            {
                uint windowProcessId;
                GetWindowThreadProcessId(hWnd, out windowProcessId);

                // If the process ID matches the current process ID, add the window handle to the list
                if (windowProcessId == currentProcessId)
                {
                    HwndSource source = HwndSource.FromHwnd(hWnd);
                    // If its null, then its a win32 process handle, so include it.
                    if (source == null && IsWindowVisible(hWnd))
                    {
                        handles.Add(hWnd);
                    }
                }

                return true;
            },
            IntPtr.Zero
        );

        return handles;
    }
}