Как отслеживать перемещения окна

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Wolfie
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 213
Зарегистрирован: 06.03.2006 (Пн) 18:52
Откуда: Россия, Москва, СЗАО

Как отслеживать перемещения окна

Сообщение Wolfie » 18.05.2007 (Пт) 20:40

Приветствую!
Есть такая задачка - нужно запоминать позицию окна - сохранять ее в реестр, вроде просто - сейвь перед выходом Top и Left и хорошо... но окно можно закрыть из свернутого режима или развернутого - тогда эти топ и лефт имеют, кхм, не те значения... Стартует же программа всегда в Нормальном режиме окна, т.е. сохранять WindowState не выход... короче проблема - как мне отслеживать премещения окна по экрану, чтобы сразу после перемещения в переменные сейвить Топ и Лефт... может я туплю, но никак не пойму как мне решить проблему... Подскажите пожалуйста
··•··•••··•··••·•·•·•···••·•••···•···•••·•··•·•··
C:\> per asper ad astra
'ASTRA' answer: Path 'ASPER' Not Found
684 Errare humanum est!
C:\> _

Cytron
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 266
Зарегистрирован: 15.02.2007 (Чт) 21:09

Сообщение Cytron » 18.05.2007 (Пт) 22:47

нмм ты сохраняй топ и лефт при перемещении если виндоустэйт равен 0
Код: Выделить всё

If Windowstate = 0 Then
' Сохраняем в реестр
End If

итого у тебя в реестр запишется всегда последнее значение позиции проги в нормальном режиме окна

EUGY
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 214
Зарегистрирован: 09.11.2006 (Чт) 22:51
Откуда: Мурманск

Сообщение EUGY » 19.05.2007 (Сб) 1:32

может где-то там.
GetWindowPlacement / WINDOWPLACEMENT / rcNormalPosition

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 19.05.2007 (Сб) 8:49

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

Wolfie
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 213
Зарегистрирован: 06.03.2006 (Пн) 18:52
Откуда: Россия, Москва, СЗАО

Сообщение Wolfie » 19.05.2007 (Сб) 18:05

Cytron писал(а):нмм ты сохраняй топ и лефт при перемещении если виндоустэйт равен 0
спасибо, но я именно это делать собираюсь, только с переменными а не с реестром - вопрос как раз в том - КАК мне следить за перемещением окна, ведь нет же события Move...
EUGY взять координаты можно и обычным .Top .Left, вопрос в том - КОГДА нужно их взять, когда нужно сделать
Код: Выделить всё
If Not WindowState Then
SvT=Me.Top
SvL=Me.Left
End If
?
Twister процесс то мой, но может, все же, Вы подробнее раскроете свой ответ?
··•··•••··•··••·•·•·•···••·•••···•···•••·•··•·•··
C:\> per asper ad astra
'ASTRA' answer: Path 'ASPER' Not Found
684 Errare humanum est!
C:\> _

EUGY
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 214
Зарегистрирован: 09.11.2006 (Чт) 22:51
Откуда: Мурманск

Сообщение EUGY » 19.05.2007 (Сб) 18:19

Dim wpl As WINDOWPLACEMENT
GetWindowPlacement Me.hwnd, wpl
Debug.Print wpl.rcNormalPosition.Top

rcNormalPosition будет содержать нужные данные независимо от WindowState, даже если окно свернуто. Это и сохраняй перед выходом, только преобразуй в твипы: wpl.rcNormalPosition.Top * 15 == Me.Top

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

Option Explicit
Private Type POINTAPI
        x As Long
        y As Long
End Type
Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
Private Type WINDOWPLACEMENT
        Length As Long
        flags As Long
        showCmd As Long
        ptMinPosition As POINTAPI
        ptMaxPosition As POINTAPI
        rcNormalPosition As RECT
End Type
Private Declare Function GetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long

Private Sub Form_Unload(Cancel As Integer)
Dim SvT As Integer
Dim SvL As Integer
Dim wpl As WINDOWPLACEMENT
    GetWindowPlacement Me.hwnd, wpl
    SvT = wpl.rcNormalPosition.Top * 15
    SvL = wpl.rcNormalPosition.Left * 15
End Sub

Ну, вот, как-то так.[/syntax]

Cytron
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 266
Зарегистрирован: 15.02.2007 (Чт) 21:09

Сообщение Cytron » 19.05.2007 (Сб) 22:45

Wolfie писал(а):ведь нет же события Move...

Да, но есть событие resize, которое воспроизводится при перемещении.
Обьясни все по порядку, я не совсем понимаю что именно тебе нужно.

VB-constructor
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 160
Зарегистрирован: 24.07.2006 (Пн) 21:37
Откуда: Ростов-на-Дону

Сообщение VB-constructor » 20.05.2007 (Вс) 14:15

которое воспроизводится при перемещении.
разве?

я тоже так сначала подумал, но когда проверил, оказалось, что нет
Человек рождён для того, чтобы достичь жизни...

Wolfie
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 213
Зарегистрирован: 06.03.2006 (Пн) 18:52
Откуда: Россия, Москва, СЗАО

ПРОБЛЕМА РЕШЕНА

Сообщение Wolfie » 20.05.2007 (Вс) 14:39

EUGY большое спасибо - за подсказку и код - все сделал - работает как надо :wink: Только мне кажется, для преобразования в Твипы, на всякий случай, стоит использовать Screen.TwipsPerPixelX и Y :wink:

Cytron Никакого события при перемещении не происходит...
Ну все уже решено, однако, в событии Resize можно следить за изменением лишь ширины и высоты окна, и соответсвенно при WindowState=0 'Normal можно сейвить эти данные в переменные и при выходе в режиме WindowState<>0 сохранить в реестр не Me.Top и Me.Left, которые имеют совсем не те данные, а сохраненные заранее в событии Resize; но как таким способом сохранять Normal .Top .Left ? Короче EUGY предложил не следить а получить готовое.

Всем спасибо за внимание
··•··•••··•··••·•·•·•···••·•••···•···•••·•··•·•··
C:\> per asper ad astra
'ASTRA' answer: Path 'ASPER' Not Found
684 Errare humanum est!
C:\> _

Kostyan
Постоялец
Постоялец
 
Сообщения: 439
Зарегистрирован: 20.09.2002 (Пт) 4:14
Откуда: Россия, Уссурийск

Сообщение Kostyan » 20.05.2007 (Вс) 16:13

Так, для справки, перемещение окна можно отловить по сообщениям WM_MOVE и WM_MOVING.
Это в форму:
Код: Выделить всё
Private Sub Form_Load()
SetProc Form1.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
Call SetWindowLong(Me.hwnd, -4, lngOldProc)
End Sub

Это в модуль:
Код: Выделить всё
Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long

Public Const WM_MOVING = &H216
Public Const WM_MOVE = &H3

Public lngOldProc As Long, R As RECT

Public Sub SetProc(ByVal lngHandle As Long)
lngOldProc = SetWindowLong(lngHandle, -4, AddressOf WinProc)
End Sub

Private Function WinProc(ByVal lngHandle As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = WM_MOVING Or Msg = WM_MOVE Then
    Call GetWindowRect(Form1.hwnd, R)
    Form1.Caption = R.Left & " - " & R.Top
End If
WinProc = CallWindowProc(lngOldProc, lngHandle, Msg, wParam, lParam)
End Function
Нет ничего невозможного для человека с интеллектом.

Wolfie
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 213
Зарегистрирован: 06.03.2006 (Пн) 18:52
Откуда: Россия, Москва, СЗАО

Сообщение Wolfie » 20.05.2007 (Вс) 19:33

Kostyan спасибо, сохраню на будущее
··•··•••··•··••·•·•·•···••·•••···•···•••·•··•·•··
C:\> per asper ad astra
'ASTRA' answer: Path 'ASPER' Not Found
684 Errare humanum est!
C:\> _


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

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

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

    TopList