【问题标题】:VB6 SetWindowLong Causing Refresh Issue in Windows 7 64-bitVB6 SetWindowLong 导致 Windows 7 64 位中的刷新问题
【发布时间】:2014-09-07 11:52:56
【问题描述】:

我仍然支持旧的 vb6 应用程序,它利用 GetWindowLong 和 SetWindowLong 在运行时根据设置删除 ControlBox。这适用于所有 32 位系统,但是当它在 64 位系统上运行时,主窗口不再正确刷新。问题似乎是文本框、列表框或命令按钮等输入控件。在被某些窗口覆盖后,它们在获得焦点之前不会显示,即使这样它们的边框也不会正确显示。

我已阅读 MSDN 文档 http://msdn.microsoft.com/en-us/library/ms633591%28v=vs.85%29.aspx,其中说这些函数已被 ...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

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

但我收到错误“在 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

【问题讨论】:

  • MSDN 文章提到您可能必须调用 SetWindowPos 才能使某些更改生效 - 您的代码是否这样做(例如在 Redraw 方法中)?
  • 就在 SetWindowLongPtr(hWnd, GWL_STYLE, nStyle) 调用之后。我已将 Sub Redraw() 添加到上面的代码中。

标签: winapi vb6 setwindowlong getwindowlong


【解决方案1】:

尝试将SWP_NOACTIVATE (&H10) 位添加到您的swpFlags 常量中。

顺便说一句,这只重绘非客户区。像RedrawNonclient 这样的名字会很明显。

【讨论】:

  • 做到了!非常感谢!
猜你喜欢
  • 2013-06-06
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 2011-04-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多