尝试在我的程序中看到活动窗口打开时收到问号

时间:2015-09-04 07:58:20

标签: c# winforms

我构建的软件可以抓住重量并投入光标所在的打开窗口。一切都很好 - 我只有一个问题烦人 当我打开 Word 时,会收到一个问号(?)。然后软件挂起无法正确识别窗口。

当我打开Word时 - 我看到 Word? - 123.docx 例如。即使我删除了问号,在这种情况下软件仍然存在。

我的代码:

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    private string GetActiveWindowTitle()
    {
        const int nChars = 256;
        StringBuilder Buff = new StringBuilder(nChars);
        IntPtr handle = GetForegroundWindow();
        if (GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
        return null;
    }

    [DllImport("user32.dll")]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    public void Start(string NAME)
    {
        MSG = lblMSG.Text.Trim();
        IntPtr zero = IntPtr.Zero;
        for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++) 
        {
            Thread.Sleep(500);
            zero = FindWindow(null, NAME);
        }
        if (zero != IntPtr.Zero)
        {
           .
           .
           .
        }
    }

有什么问题?如何解决?

感谢

1 个答案:

答案 0 :(得分:3)

默认情况下,字符串和StringBuilder在Windows上编组为Unicode,因此这不是问题。但是,您正在调用GetWindowText方法的ANSI版本(与FindWindow相同) - 这根本不起作用。 Windows尝试将其可以从unicode转换为ANSI,但它不能对当前ANSI代码页之外的字符执行任何操作。

您需要使用CharSet.Auto

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

这将在unicode系统上使用unicode版本的GetWindowTextGetWindowTextW),在非unicode系统上使用ANSI版本。

为了进行比较,没有CharSet.Auto,我的Word会生成

??? ?? عربي ,عربى‎‎ [Compatibility Mode] - Microsoft Word

有了它,

ščř řč عربي ,عربى‎‎ [Compatibility Mode] - Microsoft Word

我的系统区域设置当前设置为阿拉伯语,因此即使使用ANSI GetWindowText,阿拉伯语也能正常工作 - 如果我改回捷克语,ščř řč在ANSI中可以正常工作,而阿拉伯语字母则可以用问号代替。更改为英语会替换带有问号的所有,因为英语ANSI代码页中既不支持捷克语也不支持阿拉伯语字母。