如何更改 win32 窗口上的文本?

Posted

技术标签:

【中文标题】如何更改 win32 窗口上的文本?【英文标题】:How can I change text on a win32 window? 【发布时间】:2011-02-09 18:08:56 【问题描述】:

寻找从 C# 更改 win32 窗口上的文本的提示、技巧和搜索词。

更具体地说,我正在尝试将打印对话框上的文本从“打印”更改为“确定”,因为我正在使用该对话框来创建打印票而不进行任何打印。

如何找到对话框的窗口句柄?一旦我得到它,我将如何在表单的子窗口中找到按钮?一旦我发现了,我将如何更改按钮上的文本?在显示对话框之前,我怎样才能做到这一切?

这里有一个类似的问题,但它指向了一篇 CodeProject 文章,该文章比需要的复杂得多,而且我花费的时间比我想花的时间更长。 TIA。

【问题讨论】:

你能稍微完善一下你的问题吗?我对哪些部分正在更改为哪些部分感到困惑(我计算机上“打印”对话框中的接受按钮已经显示“OK”)。 +1 对 Jon 的评论 - 我在 Windows Vista Business 下得到了同样的结果 @jon (and jon... JonJon) 当通过 System.Windows.Controls.PrintDialog 使用时,它总是“打印”。然而,这与问题的核心无关。按钮说X,我想让它说Y,请问如何。 【参考方案1】:

您应该使用 Spy++ 查看对话框。类名和按钮的控件 ID 很重要。如果它是本机 Windows 对话框,则类名应为“#32770”。在这种情况下,我在this thread 的帖子会很有用。这里是another in C#。您可以通过 P/Invoking SetWindowText() 在按钮句柄上更改按钮文本。


using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class SetDialogButton : IDisposable 
    private Timer mTimer = new Timer();
    private int mCtlId;
    private string mText;

    public SetDialogButton(int ctlId, string txt) 
        mCtlId = ctlId;
        mText = txt;
        mTimer.Interval = 50;
        mTimer.Enabled = true;
        mTimer.Tick += (o, e) => findDialog();
    

    private void findDialog() 
        // Enumerate windows to find the message box
        EnumThreadWndProc callback = new EnumThreadWndProc(checkWindow);
        if (!EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero)) mTimer.Enabled = false;
    
    private bool checkWindow(IntPtr hWnd, IntPtr lp) 
        // Checks if <hWnd> is a dialog
        StringBuilder sb = new StringBuilder(260);
        GetClassName(hWnd, sb, sb.Capacity);
        if (sb.ToString() != "#32770") return true;
        // Got it, get the STATIC control that displays the text
        IntPtr hCtl = GetDlgItem(hWnd, mCtlId);
        SetWindowText(hCtl, mText);
        // Done
        return true;
    
    public void Dispose() 
        mTimer.Enabled = false;
    

    // P/Invoke declarations
    private const int WM_SETFONT = 0x30;
    private const int WM_GETFONT = 0x31;
    private delegate bool EnumThreadWndProc(IntPtr hWnd, IntPtr lp);
    [DllImport("user32.dll")]
    private static extern bool EnumThreadWindows(int tid, EnumThreadWndProc callback, IntPtr lp);
    [DllImport("kernel32.dll")]
    private static extern int GetCurrentThreadId();
    [DllImport("user32.dll")]
    private static extern int GetClassName(IntPtr hWnd, StringBuilder buffer, int buflen);
    [DllImport("user32.dll")]
    private static extern IntPtr GetDlgItem(IntPtr hWnd, int item);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern bool SetWindowText(IntPtr hWnd, string txt);

用法:

        using (new SetDialogButton(1, "Okay")) 
            printDialog1.ShowDialog();
        

【讨论】:

@Hans 好吧,该死的。我设法利用您的代码来定位对话框,然后我能够枚举子窗口并更改其中的所有文本。除了我需要更改的一个按钮没有。请参阅:i43.tinypic.com/6xvr7m.png 有什么想法吗? 嗯,单步执行我的代码,按钮窗口说它的文本是好的,它说它改变了,但是当对话框出现时它仍然是“打印”...... 笨蛋,你似乎是从屏幕截图开始的。我只能猜你没有找到正确的按钮。 我看到它是 PrintDialog 类。或许重要的是 Print 按钮是第一个控件,控件 ID 1。您应该使用 GetDlgItem() 来获取它的句柄。 我试过 SetDlgItemText(hWnd, 1, "OMFG"); 和 GetDlgItem/SetWindowText 但都不起作用。

以上是关于如何更改 win32 窗口上的文本?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 win32API 中更改静态窗口的背景颜色? [复制]

在 Win32 中,如何使用更改颜色对话框来更改 STATIC 文本?

如何在不显示文本的情况下分配 Win32 EDIT 控件的窗口名称?

WIN32 API 中 WM_MOUSEHOVER 上的弹出窗口 - 如何关闭它?

c++ win32输出一个文本

如何在 vc++ win32 中制作可滚动窗口