我怎样才能改变在Win32窗口中的文本?文本、窗口中

2023-09-02 21:39:22 作者:时光凉&春衫薄

寻找线索,提示和搜索方面的变化从C#中的win32窗口中输入文本。

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?

有一个类似的问题在这里,但它指向一个$ C $的CProject文章是waaay比需要的更复杂,正在我多一点的时间来分析,通过比我想花这一点。 TIA。

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.

推荐答案

您应该使用间谍++来看看对话框。类名是很重要的,按钮的控制ID。如果这是一个原生的Windows对话框,然后在类名应该是#32770。在这种情况下,您将有大量的使用了我的this螺纹。这里是另一个在C#。您可以通过P /调用SetWindowText函数()上的按钮,手柄改变按钮上的文字。

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

用法:

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