Winapi VB6 SetWindowLong导致Windows 7 64位中出现刷新问题

Winapi VB6 SetWindowLong导致Windows 7 64位中出现刷新问题,winapi,vb6,setwindowlong,getwindowlong,Winapi,Vb6,Setwindowlong,Getwindowlong,我仍然支持旧的vb6应用程序,它利用GetWindowLong和SetWindowLong在运行时根据设置删除控制框。这在所有32位系统上都非常有效,但当它在64位系统上运行时,主窗口不再正常刷新。问题似乎是输入控件,如TextBox、ListBox或CommandButton。在被某些窗口覆盖后,它们在接收到焦点之前不会显示,甚至它们的边框也不会正确显示 我已经阅读了MSDN文档,其中说这些函数已被…WindowLongPtr函数取代,以便与32位和64位系统兼容。从我所读到的所有内容来看,这

我仍然支持旧的vb6应用程序,它利用GetWindowLong和SetWindowLong在运行时根据设置删除控制框。这在所有32位系统上都非常有效,但当它在64位系统上运行时,主窗口不再正常刷新。问题似乎是输入控件,如TextBox、ListBox或CommandButton。在被某些窗口覆盖后,它们在接收到焦点之前不会显示,甚至它们的边框也不会正确显示

我已经阅读了MSDN文档,其中说这些函数已被…WindowLongPtr函数取代,以便与32位和64位系统兼容。从我所读到的所有内容来看,这实际上是指编译32位和64位版本,而不是在不同的平台上运行。我试着把我的申报单从

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

但是我得到了错误“在user32中找不到DLL入口点GetWindowLongPtrA”。因此,我尝试将别名保留为“…WindowLongA”,这样就可以运行,并且正如我所预期的那样,不会对刷新问题产生任何影响

有没有其他人看到这一点或有任何建议

下面是如何使用代码的示例

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
谢谢


dbl

尝试将
SWP\u NOACTIVATE(&H10)
位添加到
swpFlags
常量中


顺便说一句,这只重绘非客户区。类似于
RedrawNonclient
的名称会让它变得明显。

MSDN文章提到,为了使某些更改生效,您可能必须调用SetWindowPos-您的代码是否会这样做(例如在Redraw方法中)?就在SetWindowLongPtr(hWnd,GWL_STYLE,nStyle)调用之后。我已经在上面的代码中添加了Sub Redraw(),成功了!非常感谢!
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