Как я могу изменить текст в окне win32? - PullRequest
4 голосов
/ 19 апреля 2010

Поиск подсказок, советов и условий поиска для изменения текста в окне win32 из C #.

В частности, я пытаюсь изменить текст в диалоговом окне печати с «Печать» на «ОК», так как я использую диалоговое окно для создания заявки на печать, а не для печати.

Как мне найти дескриптор окна диалога? Как только я его получу, как мне найти кнопку в дочерних окнах формы? Как только я найду это, как мне изменить текст на кнопке? И как я могу сделать все это до того, как появится диалоговое окно?

Здесь есть похожий вопрос, но он указывает на статью CodeProject, которая на самом деле сложнее, чем нужно, и занимает у меня немного больше времени для анализа, чем я бы хотел потратить на это. ТИА.

1 Ответ

8 голосов
/ 19 апреля 2010

Вы должны использовать Spy ++, чтобы взглянуть на диалог. Важно имя класса и идентификатор элемента управления кнопки. Если это родное диалоговое окно Windows, тогда имя класса должно быть «# 32770». В этом случае вы будете использовать мой пост в этой теме . Вот еще один в 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();
        }
...