С# - получить событие из SetWindowText

Мы пишем плагин для существующего приложения VB6 (через COM-взаимодействие), и нам требуются некоторые функции, которые они не поддерживают. Мы могли бы легко получить требуемую функциональность, если бы каким-то образом получали событие, когда текст конкретного элемента управления в его окне изменяется.

Мы уже можем захватить их существующий дескриптор окна элемента управления с помощью FindWindow и получить текст с помощью GetWindowText.

Есть ли какой-либо неуправляемый/pinvoke-метод для получения события при изменении текста в окне?

Мы не хотим проводить опрос с помощью цикла while — мы можем захотеть сделать это для нескольких их элементов управления в будущем.

PS - я знаю, что есть способы перехватывать вызовы p/invoke (Google EasyHook), но мы не хотим перехватывать каждый вызов SetWindowText. Мы просто хотим получить его за один элемент управления, и использование чего-то вроде EasyHook, вероятно, добавляет ненужной сложности.


person jonathanpeppers    schedule 10.11.2009    source источник


Ответы (2)


Вы можете попробовать создать новый класс в С#, производный от NativeWindow.

Переопределите функцию WndProc, и если сообщение типа WM SETWINDOWTEXT добавьте свою функциональность - игнорируйте все остальные сообщения и вызовите реализацию базового класса

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM SETWINDOWTEXT:
            // Custom code here
            break;
    }
    base.WndProc(ref m);
}

Создайте экземпляр этого класса C# и вызовите функцию AssignHandle с hWnd для элемента управления, полученного с помощью FindWindow.

См. эту ссылку для получения дополнительной информации и более подробного объяснения: Переопределение WndProc в классе NativeWindow

person John Sibly    schedule 10.11.2009
comment
Это выглядит очень многообещающе. Я попробую и сообщу вам о своих результатах. - person jonathanpeppers; 10.11.2009
comment
Работал отлично. _ - person jonathanpeppers; 10.11.2009
comment
Отличный материал. Это эквивалент .NET для подкласса окна с использованием MFC или Win32 API. - person John Sibly; 11.11.2009
comment
что, если окно принадлежит другому процессу? - person Giorgi; 03.09.2010
comment
@Giorgi не уверен, насколько легко было бы начать работать в .NET, но взгляните на документацию для SetWindowsHookEx, которая была бы C++ для перехвата WndProc для другого процесса msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx Также хорошей отправной точкой может стать эта статья: codeproject.com/KB/dotnet/HookingInMicrosoftDotNET. aspx - person John Sibly; 03.09.2010

Для обычных окон такого события нет. Если элемент управления является элементом управления Edit, он может отправить EN_CHANGE через WM_NOTIFY своему родителю, однако вы не можете внедрить управляемый код в другой процесс для перехвата уведомления. Я предлагаю вам связаться с автором приложения VB6, чтобы добавить для вас событие COM, или отказаться от требования уведомления.

person Sheng Jiang 蒋晟    schedule 10.11.2009
comment
К сожалению, приложение устарело, и оригинальные разработчики не вносят (или не могут) никаких изменений. Я хотел бы прокомментировать, что на самом деле мы находимся в одном и том же процессе, их приложение загружает нашу сборку C # в качестве элемента управления ActiveX и помещает ее в свою форму, открывает ли это что-нибудь? - person jonathanpeppers; 10.11.2009
comment
Зависит от того, каков класс окна окна? - person Sheng Jiang 蒋晟; 11.11.2009