I am still supporting and old vb6 application that utilizes GetWindowLong and SetWindowLong to remove the ControlBox at runtime depending on a setting. This works great on all 32-bit systems but when it runs on a 64bit system the main window no longer refreshes properly. The problem seems to be input controls like TextBox, ListBox, or CommandButton. After being covered up by certain windows they don't display until they receive the focus and even then their borders don't show up properly.
I've read the MSDN documentation http://msdn.microsoft.com/en-us/library/ms633591%28v=vs.85%29.aspx that says these functions have been superseded by ...WindowLongPtr functions to be compatible with both 32-bit and 64-bit systems. From everything I've been able to read that is really talking about compiling both 32-bit and 64-bit version instead of running on the different platforms. I've tried changing my declare from
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
To
Public Declare Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
But I get the error "Can't find DLL entry point GetWindowLongPtrA in user32". So I tried leaving the Alias as "...WindowLongA" and that runs and as I would expect doesn't make any difference in the refresh problem.
Has anybody else seen this or have any suggestions.
Here is a sample of how the code is used.
Private Sub Form_Activate()
...
Call SetControlBox(Me.hWnd, DisableFullScreen)
End Sub
Public Sub SetControlBox(ByVal hWnd As Long, ByVal Value As Boolean)
' Set WS_SYSMENU On or Off as requested.
Call FlipBit(hWnd, WS_SYSMENU, Value)
End Sub
Public Function FlipBit(ByVal hWnd As Long, ByVal Bit As Long, ByVal Value As Boolean) As Boolean
Dim nStyle As Long
' Retrieve current style bits.
nStyle = GetWindowLongPtr(hWnd, GWL_STYLE)
' Attempt to set requested bit On or Off,
' and redraw
If Value Then
nStyle = nStyle Or Bit
Else
nStyle = nStyle And Not Bit
End If
Call SetWindowLongPtr(hWnd, GWL_STYLE, nStyle)
Call Redraw(hWnd)
' Return success code.
FlipBit = (nStyle = GetWindowLongPtr(hWnd, GWL_STYLE))
End Function
Public Sub Redraw(ByVal hWnd As Long)
' Redraw window with new style.
Const swpFlags As Long = SWP_FRAMECHANGED Or SWP_NOMOVE Or SWP_NOZORDER Or SWP_NOSIZE
SetWindowPos hWnd, 0, 0, 0, 0, 0, swpFlags
End Sub
Thanks
dbl
Try adding SWP_NOACTIVATE (&H10)
bit to your swpFlags
constant.
Btw, this redraws non-client area only. A name like RedrawNonclient
would make it apparent.