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

发布于 2024-08-29 13:50:43 字数 284 浏览 8 评论 0原文

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

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

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

这里有一个类似的问题,但它指向一篇 CodeProject 文章,该文章比需要的更复杂,并且花费我更长的时间来解析,而不是我愿意花在这上面的时间。 TIA。

Looking for hints, tips and search terms for changing the text on a win32 window from C#.

More specifically, I'm trying to change the text on the print dialog from "Print" to "OK", as I am using the dialog to create a print ticket and not do any printing.

How can I find the dialog's window handle? Once I've got it, how would I go about finding the button in the child windows of the form? Once I've found that, how would I change the text on the button? And how can I do all this before the dialog is shown?

There's a similar question here, but it points to a CodeProject article that is waaay more complex than needed and is taking me a bit longer to parse through than I'd like to spend on this. TIA.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酸甜透明夹心 2024-09-05 13:50:43

您应该使用 Spy++ 查看该对话框。类名和按钮的控件 ID 都很重要。如果它是本机 Windows 对话框,则类名称应为“#32770”。在这种情况下,您将在 这个帖子中得到很多用处线程。这是另一个 C# 。您可以通过在按钮手柄上调用 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();
        }

You should use Spy++ to take a look at the dialog. The class name is important and the control ID of the button. If it is a native Windows dialog then the class name should be "#32770". In which case you'll have a lot of use for my post in this thread. Here is another in C#. You change the button text by P/Invoking SetWindowText() on the button handle.


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);
}

Usage:

        using (new SetDialogButton(1, "Okay")) {
            printDialog1.ShowDialog();
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文