deal051298
asked on
Delay form resize until mouse release?
I'm resizing all my controls as the user resizes one of my forms. I'd like to get rid of the ugly flashing that takes place as the user resizes. Is there any way to prevent the resize until the user releases the mouse button? I want to have a ghost outline of the new form size appear as the user resizes and then update the display once the resizing's done.
Having the form resize without the controls is not enough (ie. all or nothing). I imagine some Win32 API is needed. Cheers & thanks.
Having the form resize without the controls is not enough (ie. all or nothing). I imagine some Win32 API is needed. Cheers & thanks.
I think that this is a general option in your control panel (or in option in tweekUI), but not per window.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
What method are you using to do this? If you're not already doing so, resize the form controls under Form_Resize(). Processing shouldn't occur until the mouse button is released.
ASKER
Anzen, I've only done windows API calls through Visual Basic so I'm not totally sure what you mean by "subclassing the form" and my "message processing routine". I'll be researching your answer in the win32 documentation but a little help would go a long way.
jgv, the resize code is executed continually as the form is resized, not just on mouse release.
Mirkwood, do you ever sleep man!
jgv, the resize code is executed continually as the form is resized, not just on mouse release.
Mirkwood, do you ever sleep man!
To subclass a form You must use the Get/Set..WindowLong API calls together with a user supplied function to process the incoming windows messages, the code is something like this:
' Messages - declare as needed
Private Const WM_ENTERSIZEMOVE = 561&
Private Const WM_SIZING = 532&
Private Const WM_SIZE = 5&
Private Conts WM_EXITSIZEMOVE = 562&
' Subclassing APIs
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private 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
' Enables/Disables window subclassing, note that
' You must store in a safe place the value returned
' by this function since it's needed to disable the
' subclassing for the window and You MUST disable the
' subclassing whenever You unload the window or all You
' got is a system crash !!
Public Function SubClass(ByVal hWnd As Long, ByVal bOnOff As Boolean) As Long
Dim lpWindowProc As Long
On Local Error Resume Next
If bOnOff = True Then
' Enables subclassing
lpWindowProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
ElseIf lpWindowProc <> 0 Then
' disables subclassing
lpWindowProc = SetWindowLong(hWnd, GWL_WNDPROC, lpWindowProc)
lpWindowProc = 0
End If
SubClass = lpWindowProc
End Function
' User WindowProc, all messages sent from Windows
' to the subclassed hWnd now come here and can be
' manipulated as needed
Public Function WindowProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim lRet As Long
' There MUST be this !!
On Local Error Resume Next
' calls default windowproc - just to be safe
' You could also decide NOT to call the default
' WinProc and to have this function "eat" the message
lRet = CallWindowProc(lpWindowPro c, hWnd, Msg, wParam, lParam)
' Now let's do some msg handling
Select Case Msg
Case WM_ENTERSIZEMOVE ' begin size/move
' prepare...
Case WM_SIZING ' sizing (mouse down/moving)
' noop
Case WM_SIZE ' size paused (mouse still down)
' can give some feedback
' e.g. move controls....
Case WM_EXITSIZEMOVE ' end size/move (mouse up)
' now do the full resizing !
Case Else
' nothing here
End Select
' returns result to windows
WindowProc = lRet
End Function
' Helper fn: Extracts HiWord from a Long
Public Function HiWord(dwValue As Long) As Integer
On Local Error Resume Next
If dwValue And &H80000000 Then
HiWord = (dwValue \ 65535) - 1
Else
HiWord = dwValue \ 65535
End If
End Function
' Helper fn: Extracts LoWord from a Long
Public Function LoWord(dwValue As Long) As Integer
On Local Error Resume Next
If dwValue And &H8000& Then
LoWord = &H8000 Or (dwValue And &H7FFF&)
Else
LoWord = dwValue And &HFFFF&
End If
End Function
keep in mind that You MUST store the value returned from the SubClass() function and use it to disable subclassing for Your window whenever You unload it or terminate Your app, failure to do this will result in a system crash !!
Hope it's clear ... Bye
' Messages - declare as needed
Private Const WM_ENTERSIZEMOVE = 561&
Private Const WM_SIZING = 532&
Private Const WM_SIZE = 5&
Private Conts WM_EXITSIZEMOVE = 562&
' Subclassing APIs
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private 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
' Enables/Disables window subclassing, note that
' You must store in a safe place the value returned
' by this function since it's needed to disable the
' subclassing for the window and You MUST disable the
' subclassing whenever You unload the window or all You
' got is a system crash !!
Public Function SubClass(ByVal hWnd As Long, ByVal bOnOff As Boolean) As Long
Dim lpWindowProc As Long
On Local Error Resume Next
If bOnOff = True Then
' Enables subclassing
lpWindowProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc)
ElseIf lpWindowProc <> 0 Then
' disables subclassing
lpWindowProc = SetWindowLong(hWnd, GWL_WNDPROC, lpWindowProc)
lpWindowProc = 0
End If
SubClass = lpWindowProc
End Function
' User WindowProc, all messages sent from Windows
' to the subclassed hWnd now come here and can be
' manipulated as needed
Public Function WindowProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim lRet As Long
' There MUST be this !!
On Local Error Resume Next
' calls default windowproc - just to be safe
' You could also decide NOT to call the default
' WinProc and to have this function "eat" the message
lRet = CallWindowProc(lpWindowPro
' Now let's do some msg handling
Select Case Msg
Case WM_ENTERSIZEMOVE ' begin size/move
' prepare...
Case WM_SIZING ' sizing (mouse down/moving)
' noop
Case WM_SIZE ' size paused (mouse still down)
' can give some feedback
' e.g. move controls....
Case WM_EXITSIZEMOVE ' end size/move (mouse up)
' now do the full resizing !
Case Else
' nothing here
End Select
' returns result to windows
WindowProc = lRet
End Function
' Helper fn: Extracts HiWord from a Long
Public Function HiWord(dwValue As Long) As Integer
On Local Error Resume Next
If dwValue And &H80000000 Then
HiWord = (dwValue \ 65535) - 1
Else
HiWord = dwValue \ 65535
End If
End Function
' Helper fn: Extracts LoWord from a Long
Public Function LoWord(dwValue As Long) As Integer
On Local Error Resume Next
If dwValue And &H8000& Then
LoWord = &H8000 Or (dwValue And &H7FFF&)
Else
LoWord = dwValue And &HFFFF&
End If
End Function
keep in mind that You MUST store the value returned from the SubClass() function and use it to disable subclassing for Your window whenever You unload it or terminate Your app, failure to do this will result in a system crash !!
Hope it's clear ... Bye
I leave out one thing: before You activate Your code to do the resizing/moving job call the LockWindowUpdate API to avoid flickering, then when You're done call it again to restore painting for the target form, that is:
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
' Disable repainting
lRet = LockWindowUpdate(frmForm.h Wnd)
' ... do Your job...
' Re-Enable painting
lRet = LockWindowUpdate( 0&)
Bye
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
' Disable repainting
lRet = LockWindowUpdate(frmForm.h
' ... do Your job...
' Re-Enable painting
lRet = LockWindowUpdate( 0&)
Bye
anzen:
I don't know if you're still around, but when I try your code I end up with WindowProc being called in an infinite loop. Any ideas?
I don't know if you're still around, but when I try your code I end up with WindowProc being called in an infinite loop. Any ideas?