Страница: 1 |
Страница: 1 |
Вопрос: Перетаскивание формы
Добавлено: 21.06.06 22:04
Автор вопроса: Sacred Phoenix | ICQ: 304238252
Можно ли реализовать перетаскивание формы за какой-нибудь контрол, не используя ReleaseCapture и SendMessage? Просто интересно есть ли для этого средства в .NET Framework 2.0.
Ответы
Всего ответов: 14
Номер ответа: 1
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #1
Добавлено: 21.06.06 22:38
боюсь, что вряд ли.. ибо то, что ты хочешь.. не есть стандартное поведение формы.. это уже относится к разряду примочек и фишек...
Номер ответа: 2
Автор ответа:
Sacred Phoenix
ICQ: 304238252
Вопросов: 52
Ответов: 927
Профиль | | #2
Добавлено: 22.06.06 23:09
а жаль, ибо нестандартное поведение в виде прилипания формы к рабочей области экрана реализовалось с помощью чистого .NET Framework'а. Единственное, пришлось взять константу и тип данных из API Viewer'а от vb6. Конкретно вот енто:
Private Structure WindowPos
Public hWnd As Integer '// identifies the window
Public hWndInsertAfter As Integer '// window above this one
Public X As Integer '// left edge of the window
Public Y As Integer '// right edge of the window
Public Width As Integer '// window width
Public Height As Integer '// window height
Public Flags As UInteger '// window-positioning options
End Structure
Номер ответа: 3
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #3
Добавлено: 23.06.06 02:20
Что то я в этом сильно сомневаюсь... раз ты выдергивал константы и типы, значит без API тут явно не обошлось... а если ты перехватывал сообщение через WndProc, то это уже называется hook ... хотя в НЕТ с этим гораздо проще...
А, собственно, чем тебя ReleaseCapture и SendMessage не устраивают?
Номер ответа: 4
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #4
Добавлено: 23.06.06 02:21
а вообще.. хотелось бы взглянуть на твой код...
Номер ответа: 5
Автор ответа:
Sacred Phoenix
ICQ: 304238252
Вопросов: 52
Ответов: 927
Профиль | | #5
Добавлено: 23.06.06 14:19
Всё гораздо легче - я только лишь перегрузил WndProc:
Private Structure WindowPos
Public hWnd As Integer '// identifies the window
Public hWndInsertAfter As Integer '// window above this one
Public X As Integer '// left edge of the window
Public Y As Integer '// right edge of the window
Public Width As Integer '// window width
Public Height As Integer '// window height
Public Flags As UInteger '// window-positioning options
End Structure
Private lpWP As WindowPos
Private DockAt As Byte = 16
Protected Overrides Sub WndProc(ByRef Message As System.Windows.Forms.Message)
If (Message.Msg = WM_WINDOWPOSCHANGING) Then
lpWP = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(Message.LParam, lpWP.GetType), WindowPos)
If ((lpWP.X < My.Computer.Screen.WorkingArea.Left + DockAt) And chkLeftBorder.Checked) Then lpWP.X = My.Computer.Screen.WorkingArea.Left
If ((lpWP.Y < My.Computer.Screen.WorkingArea.Top + DockAt) And chkTopBorder.Checked) Then lpWP.Y = My.Computer.Screen.WorkingArea.Top
If ((lpWP.X > My.Computer.Screen.WorkingArea.Right - DockAt - lpWP.Width) And chkRightBorder.Checked) Then lpWP.X = My.Computer.Screen.WorkingArea.Right - lpWP.Width
If ((lpWP.Y > My.Computer.Screen.WorkingArea.Bottom - DockAt - lpWP.Height) And chkBottomBorder.Checked) Then lpWP.Y = My.Computer.Screen.WorkingArea.Bottom - lpWP.Height
System.Runtime.InteropServices.Marshal.StructureToPtr(lpWP, Message.LParam, True)
End If
MyBase.WndProc(Message)
End Sub
Тем более что в vb6 хуки для этого были не нужны (эт когда нада перехватить сообщения для других окошек). А для своего окошка достаточно субклассинга)) На [dot]NET еще легче - перегрузка))
Номер ответа: 6
Автор ответа:
Sacred Phoenix
ICQ: 304238252
Вопросов: 52
Ответов: 927
Профиль | | #6
Добавлено: 23.06.06 14:21
ReleaseCapture() и SendMessage() устраивают, но это как никак API. По идее фреимворка, он должен заменить собою API, поэтому хотел узнать, нет ли встроенных возможностей для реализации такого поведения формы.
Номер ответа: 7
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #7
Добавлено: 23.06.06 18:38
встроенной возможности, как таковой, нет.. но раз ты знаком с сабклассингом и WndProc, то я покажу тебе одну хитрость позволяющую реализовать то, что тебе надо без применения API..
Фишка в том, чтобы WndProc вызывала сама себя...
Const WM_MOUSEMOVE As Int32 = &H200
Const WM_NCLBUTTONDOWN As Int32 = &HA1
Const HTCAPTION As Int32 = 2
'// Перехватываем WM_MOUSEMOVE
If m.Msg = WM_MOUSEMOVE Then
'// Вызываем ReleaseCapture
MyBase.Capture = False
'// Создаем свое сообщение
Dim message As New Message
With message
.HWnd = Me.Handle
.Msg = WM_NCLBUTTONDOWN
.WParam = HTCAPTION
.LParam = 0&
End With
'// Отправляем наше сообщение окну
MyBase.WndProc(message)
End If
MyBase.WndProc(m)
End Sub
В результате работы этого кода ты сможешь таскать форму не только за заголовок, а за любое место..
Номер ответа: 8
Автор ответа:
Sacred Phoenix
ICQ: 304238252
Вопросов: 52
Ответов: 927
Профиль | | #8
Добавлено: 23.06.06 19:54
Хм, чего-чего, а такого я не ожидал)) Но именно это я и хотел увидеть. Thx огромное))
Кста, у тя видно в настройках не стоит Option Strict On, ибо HTCAPTION и даже 0& пришлось явно приводить к типу IntPtr.
Номер ответа: 9
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #9
Добавлено: 23.06.06 20:07
рад, что смог помочь...
тогда уж не к IntPtr, а к Int32..
А Option Strict на самом деле отключен, хотя и полезная фишка, но меня она почему то бесит.. )) (ленивый я ... )
Номер ответа: 10
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #10
Добавлено: 23.06.06 20:12
вру... ты прав... именно IntPtr...
Номер ответа: 11
Автор ответа:
Алексей
ICQ: 207504159
Вопросов: 1
Ответов: 14
Web-сайт:
Профиль | | #11
Добавлено: 23.06.06 20:21
А я совсем по другому делал
Dim cX As Integer, cY As Integer
Dim Ok As Boolean
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Ok = True
cX = X
cY = Y
End Sub
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Ok Then
Me.Left = Me.Left + (X - cX)
Me.Top = Me.Top + (Y - cY)
DoEvents
End If
End Sub
Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Ok = False
End Sub
Таскается на УРА и париться не надо!
Номер ответа: 12
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #12
Добавлено: 23.06.06 21:14
Алексей, твой метод имеет следующие недостатки:
- ты вынужден хранить 3 переменные уровня формы
- твой код разбросан по 3 процедурам..
хотя, как вариант, решение имеет право на жизнь..
Номер ответа: 13
Автор ответа:
Sacred Phoenix
ICQ: 304238252
Вопросов: 52
Ответов: 927
Профиль | | #13
Добавлено: 23.06.06 21:28
безусловно имеет, но я люблю придерживаться строгих правил и аккуратного оформления кода, люблю, когда всё лежит в одном месте. Тока поэтому у меня всегда включён Option Strict (меня он тоже иногда бесит, но зато я защищён от кучи глупых логических ошибок), тока поэтому я предпочитаю перегрузить WndProc, нежели объявлять 3 переменные + обрабатывать 3 функции.
Кста, раз уж зашла речь о Int32. Так и не понял, чем отличаются Int32 от Integer, а Int16 от Short?
Номер ответа: 14
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #14
Добавлено: 23.06.06 21:40
Ничем... это одно и тоже..
просто эти ключевые слова Integer,Short оставлены для обеспечения совместимости и облегчения перехода...