Отследить скролл на панели

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

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

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Отследить скролл на панели

Сообщение sergey-911 » 05.08.2008 (Вт) 21:44

Доброго времени суток уважаемые. Прошу прощение за беспокойство.
Есть форма (Frm1) с панелью (Panel1), занимющей 2/3 формы. Панель отрисовывает CAD-овский чертеж, путем библиотеки "CAD Image DLL". При наведении мышки на Panel1 пользователю должна быть представлена возможность масштабировать чертеж. При переходе курсора мыши за пределы Panel1 такую возможность нужно отключить.
Вопрос - как?
Попытался реализовать через событие "MouseWheel" панели, не получилось. При вращении скроллом - ничего не происходит, видимо Panel1 не может перехватить это событие, т.к. не фокусируется.
Поэтому я отслеживаю "MouseWheel" формой и ставлю дополнительно проверку на нахождение курсора в области панели.
Код: Выделить всё

    Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
        'Скролл
        'Проверяем наведение курсора на область
        If e.X < 0 Or e.Y < 0 Then Exit Sub
        If panel1.Location.X + panel1.Size.Width < e.X Then Exit Sub
        If panel1.Location.y + panel1.Size.Width < e.y Then Exit Sub
        'Масштабируем
        If FScale < 0 And e.Delta < 0 Then Exit Sub
        FScale = Convert.ToInt32(FScale + e.Delta / 7)
        panel1.Invalidate()
    End Sub

Но, думаю, есть более грамотное решение. Не подскажите?
С уважением, Сергей.

Mleha
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 146
Зарегистрирован: 06.10.2004 (Ср) 7:49
Откуда: Ангарск

Сообщение Mleha » 06.08.2008 (Ср) 8:02

Код: Выделить всё
    Private Structure POINTAPI
        Public x As Int32
        Public y As Int32
    End Structure

    Private Declare Function GetCursorPos Lib "user32.dll" (ByRef lpPoint As POINTAPI) As Int32
    Private Declare Function WindowFromPoint Lib "user32.dll" (ByVal xPoint As Int32, ByVal yPoint As Int32) As Int32


Юзай эти функции, и проверяй совпадает ли возвращаемое значение WindowFromPoint с хендлом панели

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 06.08.2008 (Ср) 8:55

Mleha
вот не надо советовать, что не очень понимаете...

sergey-911
а события Mouse_Enter и MouseLeave срабатывают?
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 06.08.2008 (Ср) 9:45

Спасибо всем.
Да Sebas, события Mouse_Enter и MouseLeave срабатывают, соответственно при наведении \ покидании Panel1 курсора мыши.

Неужели нужно использовать:
Код: Выделить всё

Public Class Form1
   Dim fp As Boolean   'True - курсор на Panel1, False - нет

    Private Sub panel1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles panel1.MouseEnter
        fp = True
    End Sub

    Private Sub panel1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles panel1.MouseLeave
        fp = False
    End Sub

    Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
        'Скролл
        'Проверяем наведение курсора на область
        If fp = False Then Exit Sub
        'Масштабируем
        If FScale < 0 And e.Delta < 0 Then Exit Sub
        FScale = Convert.ToInt32(FScale + e.Delta / 7)
        panel1.Invalidate()
    End Sub
End Class

?
Почему не срабанывает panel1_MouseWheel?
С уважением, Сергей.

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 06.08.2008 (Ср) 15:04

скорее всего форма не получает сообщений. Их берёт на себя твой кадовский контрол. нужно избавить его от фокуса)
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 07.08.2008 (Чт) 6:26

Не Sebas, форма сообщения получает. Сообщения не получает панель. Ведь, если работает
Код: Выделить всё

    Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
        'Скролл
        'Проверяем наведение курсора на область
        If fp = False Then Exit Sub
        'Масштабируем
        If FScale < 0 And e.Delta < 0 Then Exit Sub
        FScale = Convert.ToInt32(FScale + e.Delta / 7)
        panel1.Invalidate()
    End Sub

, то форма события получает? Или ошибаюсь?

В аттач прикрепил проект, для большей наглядности. Правда весит он почти мегабайт. :shock:
Вложения
CADImageDLL v.6.1.rar
Проект с библиотекой
(720.96 Кб) Скачиваний: 63
С уважением, Сергей.

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 07.08.2008 (Чт) 10:21

Если на панеле есть объект который в фокусе, то панель получает событие.
Вложения
panel.rar
Всё работает!
(131.06 Кб) Скачиваний: 57
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 13.08.2008 (Ср) 9:14

Да Sebas, действительно работает, только в том случае, если на панеле есть объект в фокусе.
Но в моем примере на панеле отображается чертеж, картинка и т.п., т.е. на пенеле нет объекта в фокусе.
Значит ли это, что нужно поступить так:

Код: Выделить всё
Public Class Form1
        Dim fp As Boolean   'True - курсор на Panel1, False - нет

    Private Sub panel1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles panel1.MouseEnter
        fp = True
    End Sub

    Private Sub panel1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles panel1.MouseLeave
        fp = False
    End Sub

    Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
        'Скролл
        'Проверяем наведение курсора на область
        If fp = False Then Exit Sub
        'Масштабируем
        If FScale < 0 And e.Delta < 0 Then Exit Sub
        FScale = Convert.ToInt32(FScale + e.Delta / 7)
        panel1.Invalidate()
    End Sub
End Class


, или же есть другой выход, более правильный?
С уважением, Сергей.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Re: Отследить скролл на панели

Сообщение Atoman » 13.08.2008 (Ср) 20:03

Мне кажется так попроще.
Код: Выделить всё
Public Class PanelMouseWheel
    Inherits Panel '  ScrollableControl

    Public Sub New()
        MyBase.New()
        Me.TabStop = True
        MyBase.SetStyle(ControlStyles.Selectable, True)
    End Sub

    Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
        If (e.X >= 0 And e.X <= Me.Width) And (e.Y >= 0 And e.Y <= Me.Height) Then
            MyBase.OnMouseWheel(e)
        End If
    End Sub
End Class

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 15.08.2008 (Пт) 7:53

Atoman писал(а):Мне кажется так попроще.
Код: Выделить всё
Public Class PanelMouseWheel
    Inherits Panel '  ScrollableControl

    Public Sub New()
        MyBase.New()
        Me.TabStop = True
        MyBase.SetStyle(ControlStyles.Selectable, True)
    End Sub

    Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
        If (e.X >= 0 And e.X <= Me.Width) And (e.Y >= 0 And e.Y <= Me.Height) Then
            MyBase.OnMouseWheel(e)
        End If
    End Sub
End Class


Извини Atoman, как данной класс применить к остальному коду? Никак не могу понять... Поясни плиз. Что в нем к чему и как заюзать. :oops:
С уважением, Сергей.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Re: Отследить скролл на панели

Сообщение Atoman » 15.08.2008 (Пт) 11:10

Это класс унаследованный от Panel'и, и юзается как контрол.

Код: Выделить всё
    Private WithEvents MyPanel As PanelMouseWheel
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.MyPanel = New PanelMouseWheel
        Me.MyPanel.Location = New Point(20, 20)
        Me.MyPanel.Size = New Size(300, 300)
        Me.Controls.Add(Me.MyPanel)
    End Sub

    Private Sub MyPanel_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyPanel.MouseWheel
        '...
    End Sub

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 15.08.2008 (Пт) 12:59

Atoman писал(а):Это класс унаследованный от Panel'и, и юзается как контрол.

Код: Выделить всё
    Private WithEvents MyPanel As PanelMouseWheel
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.MyPanel = New PanelMouseWheel
        Me.MyPanel.Location = New Point(20, 20)
        Me.MyPanel.Size = New Size(300, 300)
        Me.Controls.Add(Me.MyPanel)
    End Sub

    Private Sub MyPanel_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyPanel.MouseWheel
        '...
    End Sub


Попробовал - ничего.
Atoman, зачем унаследовать у панели свойство "MouseWheel", если оно в моем случае не срабатывает?
Спасибо.
С уважением, Сергей.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Re: Отследить скролл на панели

Сообщение Atoman » 15.08.2008 (Пт) 13:39

Создай новый контрол унаследованный от панели,
в конструктор добавь:
Код: Выделить всё
        Me.TabStop = True
        MyBase.SetStyle(ControlStyles.Selectable, True)

переопредели метод OnMouseWheel:
Код: Выделить всё
    Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
        If (e.X >= 0 And e.X <= Me.Width) And (e.Y >= 0 And e.Y <= Me.Height) Then
            MyBase.OnMouseWheel(e)
        End If
    End Sub

и замени свою панель на этот контрол.
Усё.

Ну а если ещё не понятно, вот пример.
Вложения
TestPanelMouseWheel.zip
(67.37 Кб) Скачиваний: 82

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 16.08.2008 (Сб) 21:00

Спасибо Atoman, спасибо всем. В понедельник попробую. :D
С уважением, Сергей.

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 18.08.2008 (Пн) 17:44

Atoman писал(а):Создай новый контрол унаследованный от панели,
в конструктор добавь:
Код: Выделить всё
        Me.TabStop = True
        MyBase.SetStyle(ControlStyles.Selectable, True)

переопредели метод OnMouseWheel:
Код: Выделить всё
    Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
        If (e.X >= 0 And e.X <= Me.Width) And (e.Y >= 0 And e.Y <= Me.Height) Then
            MyBase.OnMouseWheel(e)
        End If
    End Sub

и замени свою панель на этот контрол.
Усё.
Ну а если ещё не понятно, вот пример.


Atoman, если я правильно понял, ты создал свой контрол "PanelMouseWheel" и использовал его в тестовом проекте "TestPanelMouseWheel", причем "PanelMouseWheel.dll" в проекте нет, но есть класс "PanelMouseWheel.vb". Прокомментируй плиз, что значит "PanelMouseWheel.vb"? И, если компонент "PanelMouseWheel" предворительно был создан, выложи его исходник плиз.
В книгах очень мало освещается проблемам создания собственных компонентов.

В общем, я совсем запутался...
Буду рад любой информации.
Прошу прощения за вопрос.
С уважением, Сергей.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Re: Отследить скролл на панели

Сообщение Atoman » 21.08.2008 (Чт) 11:43

PanelMouseWheel.vb, PanelMouseWheel.Designer.vb это файлы проекта, в которых содержится один класс унаследованный от панели.
Про создание собственных компонентов можешь почитать здесь:
http://vbstreets.ru/VBdotNET/Articles/default.aspx
http://www.progs.biz/vbnet/vbnet01.aspx

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 21.08.2008 (Чт) 18:13

Спасибо Atoman.
С уважением, Сергей.

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 26.08.2008 (Вт) 15:15

Atoman писал(а):Создай новый контрол унаследованный от панели, замени свою панель на этот контрол.


Прошу прощения Atoman.
Как создать новый контрол, унаследованный от панели?

Пробовал создать поект, далее ADD=>ADD New Item=>Component Class
Получаю класс, наследованный от System.Windows.Forms.UserControl, а не от System.Windows.Forms.Panel.
Пытался добавить Inherited User Control, тоже не то. :(
С уважением, Сергей.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Re: Отследить скролл на панели

Сообщение Atoman » 26.08.2008 (Вт) 15:24

А что тебе мешает заменить System.Windows.Forms.UserControl на System.Windows.Forms.Panel.

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 26.08.2008 (Вт) 20:04

Atoman писал(а):А что тебе мешает заменить System.Windows.Forms.UserControl на System.Windows.Forms.Panel.

Atoman, плиз, подскажи, как?
Сегодня весь день убил, так и не смог... :oops:
С уважением, Сергей.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: Отследить скролл на панели

Сообщение Viper » 27.08.2008 (Ср) 6:58

sergey-911 писал(а):
Atoman писал(а):А что тебе мешает заменить System.Windows.Forms.UserControl на System.Windows.Forms.Panel.

Atoman, плиз, подскажи, как?
Сегодня весь день убил, так и не смог... :oops:
Нет слов! Ну как,как... буквами... Заменяешь
Код: Выделить всё
Inherits System.Windows.Forms.UserControl
на
Код: Выделить всё
Inherits System.Windows.Forms.Panel
Весь мир матрица, а мы в нем потоки байтов!

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 27.08.2008 (Ср) 10:26

Viper писал(а):Нет слов! Ну как,как... буквами... Заменяешь
Код: Выделить всё
Inherits System.Windows.Forms.UserControl
на
Код: Выделить всё
Inherits System.Windows.Forms.Panel


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

Но дело не в этом. Хочу уточнить оставшиеся неясности.
Правильно ли я делаю:
1) Создаю проект "Windows Forms", с формой, соответственно.
2) Добавляю контрол следующим образом:
ADD=>New Item=>Custom Control
3) Поиском ищу "Inherits System.Windows.Forms.UserControl", попадаю в дизайнер и правлю на "Inherits System.Windows.Forms.Panel"

Ну, по 3-у пункту и так ясно, должен путь покороче. Как открыть Component.Designer.vb?

По 2-у хочу уточнить, тот ли контрол я добавляю в проект, чтобы cоздать новый контрол, унаследованный от панели? В студии всевозможных контролов целая куча... :roll:

Где нибудь есть описание (желательно на русском) всех доступных в VS2008 форм, компонентов и т.п...? Можно, конечно, сослаться на MSDN, но не разбирусь. :oops:
С уважением, Сергей.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Re: Отследить скролл на панели

Сообщение Atoman » 27.08.2008 (Ср) 11:58

2) Всё верно.
3) В окне Solution Explorer выбери Show All Files
Вложения
Solution Explorer.PNG
Solution Explorer.PNG (12.82 Кб) Просмотров: 2277

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Re: Отследить скролл на панели

Сообщение sergey-911 » 27.08.2008 (Ср) 13:48

Спасибо Atoman.
А по поводу
Где нибудь есть описание (желательно на русском) всех доступных в VS2008 форм, компонентов и т.п...? Можно, конечно, сослаться на MSDN, но не разбирусь. :oops:

?
С уважением, Сергей.


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

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

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

    TopList  
cron