SetText текстового поля во внешнем приложении. Win32 API - PullRequest
4 голосов
/ 09 июля 2009

Используя Winspector, я обнаружил, что идентификатор дочернего текстового поля, которое я хочу изменить, составляет 114. Почему этот код не изменяет текст TextBox?

    [DllImport("user32.dll")]
    static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int msg, int Param, string s);

    const int WM_SETTEXT = 0x000c;

    private void SetTextt(IntPtr hWnd, string text)
    {
        IntPtr boxHwnd = GetDlgItem(hWnd, 114);
        SendMessage(boxHwnd, WM_SETTEXT, 0, text);
    }

Ответы [ 4 ]

8 голосов
/ 09 июля 2009

Вот что я успешно использовал для этой цели с удаленной / отключенной проверкой ошибок GetLastError:

[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);
public const uint WM_SETTEXT = 0x000C;

private void InteropSetText(IntPtr iptrHWndDialog, int iControlID, string strTextToSet)
{
    IntPtr iptrHWndControl = GetDlgItem(iptrHWndDialog, iControlID);
    HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
    SendMessage(hrefHWndTarget, WM_SETTEXT, IntPtr.Zero, strTextToSet);
}

Я проверил этот код, и он работает, поэтому, если он не работает, вы должны быть уверены, что используете правильный дескриптор окна (дескриптор самого диалогового окна) и правильный идентификатор элемента управления. Также попробуйте что-нибудь простое, например, редактирование диалогового окна «Найти» в Блокноте.

Я пока не могу комментировать в сообщении об использовании (char *), но это не обязательно. См. Вторую перегрузку C # в p / Invoke SendMessage . Вы можете передать String или StringBuilder непосредственно в SendMessage.

Я также отмечаю, что вы говорите, что ваш контрольный идентификатор - 114. Вы уверены, что WinSpector дал вам это значение в базе 10? Потому что вы подаете его в GetDlgItem как базовый номер 10. Я использую Spy ++ для этого, и он возвращает идентификаторы управления в базе 16. В этом случае вы должны использовать:

IntPtr boxHwnd = GetDlgItem(hWnd, 0x0114);
2 голосов
/ 18 марта 2016

Пожалуйста, преобразуйте свой управляющий идентификатор (полученный из spy ++) из шестнадцатеричного числа в десятичное число и передайте это значение в функцию GetDlgItem. С этим
вы получите ручку текстового поля. Это сработало для меня.

[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int Param, string s);

const int WM_SETTEXT = 0x000c;

private void SetTextt(IntPtr hWnd, string text)
{
    IntPtr boxHwnd = GetDlgItem(hWnd, 114);
    SendMessage(boxHwnd, WM_SETTEXT, 0, text);
}
0 голосов
/ 08 июля 2014

Вы должны убедиться, что текст выделен в области памяти внешнего приложения. Вы не сможете выделить текст в приложении вызывающего абонента и передать его другому приложению, поскольку у каждого из них будет свое собственное пространство памяти.

0 голосов
/ 09 июля 2009

Вы уверены, что передаете текст правильно? Последний параметр SendMessage должен быть указателем на символ *, содержащий текст, который вы хотите установить.
Посмотрите на мой "грубый взлом" установки текста в Как получить выделенные ячейки из TDBGrid в Delphi 5
это делается в Delphi 5, где PChar - это псевдоним char *, и я просто приводил его как int (целое число в Delphi).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...