2012-06-12 1 views
1

Я проектирую форму с горизонтальной полосой прокрутки, закрепленной внизу. Я хотел добавить поддержку боковой прокрутки с помощью кнопок наклона мыши и нашел this solution, который после небольшого переделания, казалось, сделал трюк - то есть, в то время как форма имела только графику GDI, нарисованную на ее поверхности.Сделать мышь наклона горизонтальной прокрутки всегда повторять

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

Чтобы увидеть, что я имею в виду (если у вас есть мышь с кнопками наклона) доком горизонтальной полосы прокрутки на дне формы, добавить несколько других элементов управления и вставьте этот код:

Public Class Form1 
    Const WM_MOUSEHWHEEL As Integer = &H20E 

    Protected Overrides Sub WndProc(ByRef m As Message) 
     MyBase.WndProc(m) 
     If Me.IsDisposed OrElse m.HWnd <> Me.Handle Then Return 
     Select Case m.Msg 
      Case WM_MOUSEHWHEEL 
       With HScrollBar1 
        If CType(m.WParam, Integer) < 0 Then '______________ Left Scroll 
         If .Value > 0 Then .Value -= 1 
        Else '______________________________________________ Right Scroll 
         If .Value < (.Maximum - .LargeChange + 1) Then .Value += 1 
        End If 
       End With 
       m.Result = CType(1, IntPtr) 'Indicates the message has been handled 
     End Select 
    End Sub 

    Private Sub HScrollBar1_ValueChanged(sender As Object, e As System.EventArgs) Handles HScrollBar1.ValueChanged 
     Console.WriteLine(HScrollBar1.Value) 
    End Sub 
End Class 

You» Посмотрим, что прокрутка в сторону повторяется, когда мышь находится над пустой частью формы, но только «однократные», когда она находится над элементом управления.

Я предполагаю, что решение лежит где-то в значении сообщения, но я не понимаю, что это должно быть. На самом деле, я даже не уверен, что я возвращаю правильное значение в любом случае, потому что код в исходном решении бросил исключение из функции DirectCast, поэтому я заменил это на CType, который, похоже, работал нормально. Я пробовал работать с помощью Spy ++, но я не вижу ничего очевидного.

Любые идеи, пожалуйста?


UPDATE

Я заметил, когда я включаю окно «ребенок» в Spy ++ есть два (0x020E) сообщения и два возвращаемые значения, 1 затем 0. Я предполагаю, то сообщение передается на управление формой. Поэтому, я думаю, теперь вопрос заключается в следующем: может ли сообщение не передаваться в элемент управления? Или можно перехватить возвращаемое значение элемента управления и преобразовать его в 1?

+0

Обычно в таком поведении элемент управления перехватывает событие мыши и никогда не достигает формы, которая удерживает и управляет полосой прокрутки. На самом деле, я удивлен, что даже одно событие попало в форму. Вам может потребоваться подключиться к системным DLL для выполнения этого .... –

+0

@SASS_Shooter Я думал, что WndProc получил * все * сообщения, предназначенные для формы и ее элементов управления.Я уже немного играл со Spy ++, и если я включаю окна «Child», становится ясно, что сообщение передается в элемент управления, который возвращает 0. Таким образом, вопрос заключается в том, может ли сообщение не передаваться в управление или контрольное значение возвращаемого значения перехватывается и преобразуется в 1? – Antagony

ответ

0

Мне удалось разработать обходное решение, но я уверен, что должен быть лучший метод, чем этот. То, что я сделал, это добавить класс для каждого типа элемента управления, который используется в моей форме и наследуется от элемента управления. Затем я добавил процедуру WndProc для каждого класса, так что 1 всегда возвращается для WM_MOUSEHWHEEL сообщений, обработанных этими элементами управления. Например, это класс кнопки:

Public Class scButton 
    Inherits Button 
    Protected Overrides Sub WndProc(ByRef m As Message) 
     MyBase.WndProc(m) 
     If Me.IsDisposed OrElse m.HWnd <> Me.Handle Then Return 
     If m.Msg = Win32Messages.WM_MOUSEHWHEEL Then m.Result = New IntPtr(1) 
    End Sub 
End Class 

Тогда это был просто вопрос изменения ссылки в коде конструктора формы.

Как я уже сказал, я уверен, что должен быть лучший метод, чем этот. Было бы больно, если бы вам приходилось делать это для большого количества различных классов управления, но в моем случае я просто нуждался в нем для нескольких основных элементов управления.


Я оставил это открытым в течение нескольких дней в надежде, что кто-то хотел бы предложить лучшее решение, но ничего не последовало, так что я буду принимать мой собственный ответ.