【问题标题】:How can I force a WIA progress bar to stay in focus如何强制 WIA 进度条保持焦点
【发布时间】:2013-04-26 12:23:12
【问题描述】:

我使用 WIA ShowTransfer 方法从我的 WPF 应用程序中的设备扫描图片。但是用户可以将焦点设置在 WPF 应用程序上,然后 WIA 显示的进度条隐藏在 WPF 应用程序后面。如何强制进度条保持在所有内容之上?

【问题讨论】:

    标签: c# wpf wia


    【解决方案1】:

    我尝试了几件事,例如枚举所有正在运行的进程,通过 WPF 应用程序枚举所有窗口,但没有运气。这就是最终的帮助:

    #region Force Scan Progress to front hack
    
    [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);
    
    [DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int _GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
    
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWindowVisible(IntPtr hWnd);
    
    [DllImport("user32.dll")]
    public static extern int SetForegroundWindow(IntPtr hWnd);
    
    const int MAXTITLE = 255;
    
    private delegate bool EnumDelegate(IntPtr hWnd, int lParam);
    
    public static string GetWindowText(IntPtr hWnd)
    {
        StringBuilder strbTitle = new StringBuilder(MAXTITLE);
        int nLength = _GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
        strbTitle.Length = nLength;
        return strbTitle.ToString();
    }
    
    private static bool EnumWindowsProc(IntPtr hWnd, int lParam)
    {
        string strTitle = GetWindowText(hWnd);
        if (strTitle.StartsWith("Title of progress bar")) SetForegroundWindow(hWnd);
        return true;
    }
    
    private void forceScanProgressToFront(object source, EventArgs ea)
    {
        EnumDelegate delEnumfunc = new EnumDelegate(EnumWindowsProc);
        bool bSuccessful = EnumDesktopWindows(IntPtr.Zero, delEnumfunc, IntPtr.Zero);
        if (!bSuccessful)
        {
            // Get the last Win32 error code
            int nErrorCode = Marshal.GetLastWin32Error();
            string strErrMsg = String.Format("EnumDesktopWindows failed with code {0}.", nErrorCode);
            throw new Exception(strErrMsg);
        }
    }
    
    #endregion
    

    我将它绑定到每 500 毫秒触发一次的 DispatcherTimer。因此,即使用户试图隐藏进度条,它也会每 500 毫秒弹出一次。

    另请参阅:http://hintdesk.com/how-to-enumerate-all-opened-windows/

    【讨论】:

      【解决方案2】:

      解决方案是从 UI 线程调用 ShowTransfer 方法,而不是从工作线程调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-19
        • 2012-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多