Вопрос по c#, winapi, interop – SetText текстового поля во внешнем приложении. Win32 API

4

Используя 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   ответа
0

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

0

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

2

преобразуйте свой управляющий идентификатор (полученный из 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);
}
8

что я успешно использовал для этой цели с удаленной / отключенной проверкой ошибок 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);
Я также попытался бы просмотреть элемент управления textbox с помощью Spy ++ (или любого другого инструмента, который вы предпочитаете), чтобы увидеть, какие сообщения он получает. Вы должны быть в состоянии убедиться, что текстовое поле получает ваш WM_SETTEXT и отправляет ли программа что-то, что может переопределять ваши действия.
Да, это так, и я могу получить существующий текст с помощью WM_GETTEXT. Это просто WM_SETTEXT, который не работает. Kirschstein
WinSpector возвращает 10 базовых чисел. Я сделал небольшое тестовое приложение для Visual Studio, и этот метод работает нормально, но он не работает для реального приложения, с которым я работаю. Kirschstein
Извините, если я предлагаю очевидные вещи, но иногда хорошо просто говорить об этом. Я думаю, что следующая вещь, которую я бы попробовал, это изменить что-то вроде текста в строке заголовка главного окна (если оно есть) и посмотреть, смогу ли я это изменить - другими словами, изменить текст окна, который скорее всего, не изменяется программой. Если это сработает, попробуйте в окне текст статического элемента управления, например метку. Если оба из них сработают, это будет означать, что программа обрабатывает это текстовое поле необычным образом. продолжение ...
Когда вы шагаете по коду с реальным приложением, возвращает ли GetDlgItem () ненулевое значение?

Похожие вопросы