VB6 SetWindowLong, вызывающий проблему обновления в Windows 7, 64-разрядная версия

Я все еще поддерживаю старое приложение vb6, которое использует GetWindowLong и SetWindowLong для удаления ControlBox во время выполнения в зависимости от настроек. Это прекрасно работает на всех 32-битных системах, но при работе на 64-битной системе главное окно больше не обновляется должным образом. Кажется, проблема в элементах управления вводом, таких как TextBox, ListBox или CommandButton. После того, как они закрыты определенными окнами, они не отображаются, пока не получат фокус, и даже тогда их границы не отображаются должным образом.

Я прочитал документацию 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

Но я получаю ошибку "Не могу найти точку входа DLL GetWindowLongPtrA в user32". Поэтому я попытался оставить псевдоним как "...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

Спасибо

дублированный

1 ответ

Решение

Попробуйте добавить SWP_NOACTIVATE (&H10) немного к вашему swpFlags постоянная.

Кстати, это перерисовывает только не клиентскую область. Имя как RedrawNonclient сделает это очевидным.

Другие вопросы по тегам