Ограничить перемещение окна

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
beefon
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 104
Зарегистрирован: 26.09.2004 (Вс) 18:34
Откуда: Moscow Province

Ограничить перемещение окна

Сообщение beefon » 29.04.2007 (Вс) 16:57

Как можно сделать так, чтобы при перемещении какого-либо окна (например того же калькулятора) он "упирался" в границу экрана, а не уходил за нее? В частности, мне нужно, чтобы окна упирались только в границу снизу.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 29.04.2007 (Вс) 17:11

WM_WINDOWPOSCHANGING
Изображение

beefon
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 104
Зарегистрирован: 26.09.2004 (Вс) 18:34
Откуда: Moscow Province

Сообщение beefon » 29.04.2007 (Вс) 18:21

Это получается все время нужно посылать активному окну?
Ставить таймер?
API-функции такой нет, чтобы вообще всем окнам запретить пересекать границу экрана?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 29.04.2007 (Вс) 20:38

Нет, это нужно обрабатывать тому окну, которое не хочет, чтобы его утаскивали за экран.
Если все должны не хотеть, можешь ставить глобальный хук, ага.
Изображение

beefon
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 104
Зарегистрирован: 26.09.2004 (Вс) 18:34
Откуда: Moscow Province

Сообщение beefon » 01.05.2007 (Вт) 14:17

Можно более подробно о хуке? :)

Я сделал через SetWindowPlacement, она в принципе не пускает окно за нижнюю границу экрана, перемещая его вверх, но все это дело моргает, и как-то "куцо" выглядит :(

dr.MIG
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1441
Зарегистрирован: 18.12.2004 (Сб) 9:53
Откуда: г.Ярославль

Сообщение dr.MIG » 01.05.2007 (Вт) 14:32

beefon писал(а):Можно более подробно о хуке? :)

Первое, что попалось под руку http://bbs.vbstreets.ru/viewtopic.php?t=31255, только тебе надо, как уже сказал tyomitch обрабатывать WM_WINDOWPOSCHANGING.
А вообще поиск по SetWindowLong, CallWindowProc и т.д.
Salus populi suprema lex

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.05.2007 (Вт) 14:54

dr.MIG, как ты предлагаешь ему сабклассить чужие окна? :roll:
Изображение

dr.MIG
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1441
Зарегистрирован: 18.12.2004 (Сб) 9:53
Откуда: г.Ярославль

Сообщение dr.MIG » 01.05.2007 (Вт) 15:08

Вай-вай-вай. Невнимательно прочитал, думал, что речь про своё окно...
Salus populi suprema lex

beefon
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 104
Зарегистрирован: 26.09.2004 (Вс) 18:34
Откуда: Moscow Province

Сообщение beefon » 01.05.2007 (Вт) 18:44

Для своего окна граница ставится вот так:
Код: Выделить всё

Option Explicit

Public OldWindowProc As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = (-4)

Type WINDOWPOS
    hwnd As Long
    hWndInsertAfter As Long
    x As Long
    y As Long
    cx As Long
    cy As Long
    flags As Long
End Type
Public Const WM_WINDOWPOSCHANGING = &H46
Public Const WM_WINDOWPOSCHANGED = &H47

Public Function NewWindowProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
Const WM_NCDESTROY = &H82
Dim new_aspect As Single
    If msg = WM_NCDESTROY Then
        SetWindowLong hwnd, GWL_WNDPROC, OldWindowProc
    End If

    If msg = (WM_WINDOWPOSCHANGING) Then
        If lParam.y >= 600 Then
        lParam.y = 600    'граница на "высоте" 600 пикселей от верха экрана
        End If
    End If

    NewWindowProc = CallWindowProc(OldWindowProc, hwnd, msg, wParam, lParam)
End Function


Код: Выделить всё

Private Sub Form_Load()
    OldWindowProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf NewWindowProc)
End Sub


А как мне "распространить" это на все окна?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.05.2007 (Вт) 20:13

tyomitch писал(а):Если все должны не хотеть, можешь ставить глобальный хук, ага.
Изображение

beefon
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 104
Зарегистрирован: 26.09.2004 (Вс) 18:34
Откуда: Moscow Province

Сообщение beefon » 02.05.2007 (Ср) 8:34

Если честно, то я еще не сталкивался с такими задачами.
Ладно, поищу литературу. Может вы что-нибудь посоветуете? :)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.05.2007 (Ср) 9:11

Посоветую поиск по форуму. Там всё нужное тебе уже обсуждалось.
Изображение


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: AhrefsBot, Yandex-бот и гости: 43

    TopList