Возможно ли сделать перехват сообщений Windows?

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

kanut
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 24.03.2013 (Вс) 12:10

Возможно ли сделать перехват сообщений Windows?

Сообщение kanut » 06.04.2014 (Вс) 17:15

Долго пытался сделать перехват сообщений Windows с помощью вызова функции SetWindowLongA, но до конца сделать не могу.

Код: Выделить всё
Private lpPrevWndProc As Long
Private Delegat As New DWindowProc(AddressOf WindowProc)

Private Declare Function SetWindowLong Lib "User32.dll" Alias "SetWindowLongA" (ByVal hWnd As IntPtr, _
ByVal nIndex As Integer, ByVal newWndProc As DWindowProc) As Long

Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" _
(ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Long

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

   lpPrevWndProc = SetWindowLongA(Me.Handle, GWL_WNDPROC, Delegat)

End Sub

Private Function WindowProc(ByVal hWnd As IntPtr, ByVal uMsg As UInteger, _
ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Long

   'Сообщения и hwnd здесь отлавливаются

   Return DefWindowProc(hWnd, uMsg, wParam, lParam)

End Function


При установке перехвата, окно программы при перекрывании другими окнами начинает "затираться", т. е. на нем остаются отпечатки других окон. Хотя сообщения в функции перехвата отлавливаются. Долго искал решение на русских и английских сайтах, но ничего рабочего не нашел. Есть у кого-нибудь соображения что может быть не так?

В итоге я сделал перехват с помощью нетовской функции:
Код: Выделить всё
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

   If m.Msg = WM_... AndAlso m.LParam = hWnd... Then



   Else

      MyBase.WndProc(m)

   End If

End Function

но хотелось бы все-таки разобраться почему не работает обычный вызов. :evil:
Последний раз редактировалось kanut 07.04.2014 (Пн) 18:42, всего редактировалось 2 раз(а).

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 06.04.2014 (Вс) 21:24

kanut писал(а):Есть у кого-нибудь соображения что может быть не так?

Есть. Оригинальную оконную процедуру при перехвате кто вызывать будет?

kanut
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 24.03.2013 (Вс) 12:10

Re: Возможно ли сделать перехват сообщений Windows?

Сообщение kanut » 07.04.2014 (Пн) 14:10

Удалось решить проблему.

В интернете рабочих примеров для VB .Net найти так и не удалось. Сначала я вызывал функцию CallWindowProc, но с ней постоянно возникали ошибки "Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена." и "Внешний компонент создал исключение.". Потом я нашел примеры без нее и с DefWindowProc, и эти ошибки исчезли, но окно не перерисовывалось как надо. Оказывается в VB .Net надо везде для указателей вместо типа Long использовать тип данных IntPtr. Еще когда я перебирал все подряд, то забыл сменить в функции ByRef lpPrevWndFunc обратно на ByVal lpPrevWndFunc.

Qwertiy, спасибо что указал нужное направление!

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 08.04.2014 (Вт) 1:08

kanut писал(а):Оказывается в VB .Net надо везде для указателей вместо типа Long использовать тип данных IntPtr.

Хм.. Я это знал, но твой код с win-api не рассматривал...
Для хендлов тоже, кстати.

PS: Зачем было пост с вопросом редактировать?

kanut
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 24.03.2013 (Вс) 12:10

Re: Возможно ли сделать перехват сообщений Windows?

Сообщение kanut » 08.04.2014 (Вт) 11:32

Раньше я думал, что надо использовать IntPtr только для хендлов и т. п. указателей, а оказывается для указателей Long тоже нужен IntPtr или UIntPtr. Ситуацию еще сильно осложнила ошибка с ByRef - когда перебирал наобум, то менял и все Long на IntPtr, но тогда это не сработало.
В редактировании добавил MyBase.WndProc(m), чтобы пример сразу заработал, а не был только схемой.


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 87

    TopList