寻找从 C# 更改 win32 窗口上的文本的提示、技巧和搜索词。
更具体地说,我正在尝试将打印对话框上的文本从“打印”更改为“确定”,因为我正在使用该对话框来创建打印票而不进行任何打印。
如何找到对话框的窗口句柄?一旦我得到它,我将如何在表单的子窗口中找到按钮?一旦我发现,我将如何更改按钮上的文本?在显示对话框之前我怎么能做到这一切?
这里有一个类似的问题,但它指向了一篇 CodeProject 文章,它比需要的复杂得多,而且我解析的时间比我想花的时间要长一些。TIA。
寻找从 C# 更改 win32 窗口上的文本的提示、技巧和搜索词。
更具体地说,我正在尝试将打印对话框上的文本从“打印”更改为“确定”,因为我正在使用该对话框来创建打印票而不进行任何打印。
如何找到对话框的窗口句柄?一旦我得到它,我将如何在表单的子窗口中找到按钮?一旦我发现,我将如何更改按钮上的文本?在显示对话框之前我怎么能做到这一切?
这里有一个类似的问题,但它指向了一篇 CodeProject 文章,它比需要的复杂得多,而且我解析的时间比我想花的时间要长一些。TIA。
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();
}