Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 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 Const WM_WINDOWPOSCHANGING As Integer = &H46 '// on window position changing

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
прилипания формы к рабочей области экрана реализовалось с помощью чистого .NET Framework'а

Что то я в этом сильно сомневаюсь... раз ты выдергивал константы и типы, значит без 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 Const WM_WINDOWPOSCHANGING As Integer = &H46 '// on window position changing

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 вызывала сама себя...

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

        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
рад, что смог помочь...

HTCAPTION и даже 0& пришлось явно приводить к типу IntPtr


тогда уж не к IntPtr, а к Int32..

А Option Strict на самом деле отключен, хотя и полезная фишка, но меня она почему то бесит.. :-))) (ленивый я ... )

Ответить

Номер ответа: 10
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #10 Добавлено: 23.06.06 20:12
вру... ты прав... именно IntPtr...

Ответить

Номер ответа: 11
Автор ответа:
 Алексей



ICQ: 207504159 

Вопросов: 1
Ответов: 14
 Web-сайт: lehs.info
 Профиль | | #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 оставлены для обеспечения совместимости и облегчения перехода...

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам