powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
9 сообщений из 9, страница 1 из 1
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38118920
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyСабклассинг нужно снимать всегда.
Ну допустим с опытом про такие вещи как

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
    SaveReestrValues 'сохранение настроек в реестре (могут быть например размеры/положени формы и ее элементов на экране)
   'либо напр. сохраняем настройки в ini-файле
    SaveIniSettings
    SetWindowLong Me.hwnd, GWL_WNDPROC, OldFormMainWindowProc
    '...
    DestroyWindow my_hwnd
    ImageList_Destroy m_hIml



(список примеров можно продолжать) стараешься не забывать и таки делать.

Понятно, что если что-то "больше не нужно", то как только так сразу и чем скорее тем лучше.

В большинстве случаев сабклассинг, иконки, ImageList-ы, тулбары и прочее существует и нужно на протяжении всего периода жизни формы.

В нек. примерах все "уничтожается" в Form_Unload, в других в Form_QueryUnload.
Как (где) все-таки правильно? В Unload? Или в _QueryUnload?

И что делать сначала? Что потом?
SaveSettings
или
Destroy_ALL
Думаю SaveSettings.
Например сохранял параметр "Показывать/не показывать Rebar" проверяя IsWindowVisible(g_hwndRebar)
и сдуру перед этим ляпнул
DestroyWindow g_hwndRebar
накололся, ибо после Destroy IsWindowVisible=false без вариантов.

Можно ли снимать сабклассинг до SaveSettings?

Понятно, что наверно можно по-разному, но хотелось бы выработать хоть какие-то правила.
Чтоб в разных частных случаях не выдумывать иногда часами частные "затычки".
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38118932
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Как (где) все-таки правильно? В Unload? Или в _QueryUnload?Если в QueryUnload не собираешься отменять закрытие, то пофиг.

Дмитрий77Можно ли снимать сабклассинг до SaveSettings?Почему нет? Просто нужно помнить, зависят ли сохраняемые параметры от сабклассинга.
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38119039
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

А если я использую, как бы это сказать, несколько сабклассингов одного и того же hwnd (часто так делаю):

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    'меню
    OldMenuWindowProc = SetWindowLong( _
        Me.hwnd, GWL_WNDPROC, _
        AddressOf NewMenuWindowProc)

    'Toolbar (внутри Rebar)
    OldReBarWindowProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, _
        AddressOf NewReBarWindowProc)

    'форма на предмет ограничения ее размеров
    OldFormMeWindowProc = SetWindowLong( _
        Me.hwnd, GWL_WNDPROC, _
        AddressOf NewFormMeWindowProc)

Public Function NewMenuWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Public Function NewReBarWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Public Function NewFormMeWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long



То как мне их снимать?

Если
Код: vbnet
1.
2.
3.
  SetWindowLong Me.hwnd, GWL_WNDPROC, OldMenuWindowProc
  SetWindowLong Me.hwnd, GWL_WNDPROC, OldMenuRebarWindowProc
  SetWindowLong Me.hwnd, GWL_WNDPROC, OldFormMeWindowProc



Что-то тут не так...

Ну допустим, Menu и Rebar я еще могу совместить,
а вот FormMe никак не воткнешь - нужна отдельная ф-ция.
Код: vbnet
1.
2.
ByVal lParam As Long
lParam As WINDOWPOS



Или любая строчка из трех вышеприведенных снимет все 3 сабклассинга?
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38119141
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А если я использую, как бы это сказать, несколько сабклассингов одного и того же hwnd (часто так делаю):Зачем? Можно же объединить процедуры в одну, если они не в разных библиотеках. А если в разных, то и вопрос такой не стоит, у каждой библиотеки единственный указатель.

Я делал наоборот, использовал одну процедуру для сабклассинга разных окон.
Дмитрий77То как мне их снимать?Нужно восстановить оригинальную процедуру, то есть первый полученный указатель: OldMenuWindowProc.

На всякий случай:
1) OldReBarWindowProc = AddressOf NewMenuWindowProc, OldFormMeWindowProc = AddressOf NewReBarWindowProc
2)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
Public Function NewMenuWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    ...
    NewMenuWindowProc = CallWindowProc(OldMenuWindowProc)
End Function
Public Function NewReBarWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    ...
    NewMenuWindowProc = CallWindowProc(OldReBarWindowProc)
End Function
Public Function NewFormMeWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
    ...
    NewMenuWindowProc = CallWindowProc(OldFormMeWindowProc)
End Function

=

Public Function NewMenuWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    ...
    Call NewReBarWindowProc
    Call NewFormMeWindowProc
    NewMenuWindowProc = CallWindowProc(OldMenuWindowProc)
End Function

Public Function NewReBarWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    ...
End Function
Public Function NewFormMeWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
    ...
End Function
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38119147
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибка копипаста
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Public Function NewReBarWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    ...
    NewReBarWindowProc = CallWindowProc(OldReBarWindowProc)
End Function
Public Function NewFormMeWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
    ...
    NewFormMeWindowProc = CallWindowProc(OldFormMeWindowProc)
End Function

=
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38119154
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ну допустим, Menu и Rebar я еще могу совместить,
а вот FormMe никак не воткнешь - нужна отдельная ф-ция.Если это из-за lParam As WINDOWPOS, то это не проблема. Делай ByVal lParam As Long, а записать в него значение, если нужно, можно с помощью CopyMemory. А уж прочитать тем более. lParam это же адрес блока памяти, выделенный под переменную типа WINDOWPOS, и размер этого блока известен.
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38120638
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чет у меня мозги плохо варят с "вложенными" сабклассингами.

AntonariyЕсли это из-за lParam As WINDOWPOS, то это не проблема..
Да в общем то нет. Скорее привычка лепить новый сабклассинг на тот же hwnd не задумываясь.

AntonariyДелай ByVal lParam As Long, а записать в него значение, если нужно, можно с помощью CopyMemory. А уж прочитать тем более. lParam это же адрес блока памяти, выделенный под переменную типа WINDOWPOS, и размер этого блока известен.
Ну в данном конкретном случае я воспользовался этим советом и совместил меню, тулбар и ограничение размеров формы 3 в 1.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
  OldFormMeWindowProc = SetWindowLong( _
   Me.hwnd, GWL_WNDPROC, _
   AddressOf NewFormMeWindowProc)

Public Function NewFormMeWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
...
  Dim mWndPos As WINDOWPOS 'window position
...
  Select Case Msg
    Case WM_MENUSELECT 'menu
    Case WM_EXITMENULOOP 'menu
    Case WM_NOTIFY 'toolbar
    Case 512 'опытным путем, т.к.предыдущий код плохо работает при сходе с кнопок кот. disabled -toolbar
    Case 273 'WM_NOTIFY -toolbar
    Case WM_WINDOWPOSCHANGING 'form min width/height
      If (Form1.Visible = True) And (Not (Form1.ScaleWidth = 0)) Then
        CopyMemory mWndPos, ByVal lParam, LenB(mWndPos)
        If mWndPos.cx < MIN_WIDTH Then
          If mWndPos.x > the_X Then '(уменьшаем за левый край-чтобы форма не уезжала влево)
            mWndPos.x = mWndPos.x - (MIN_WIDTH - mWndPos.cx)
          End If
          mWndPos.cx = MIN_WIDTH
        End If
        the_X = mWndPos.x
        If mWndPos.cy < MIN_HEIGHT Then
          If mWndPos.y > the_Y Then '(уменьшаем за верхний край-чтобы форма не уезжала вниз)
            mWndPos.y = mWndPos.y - (MIN_HEIGHT - mWndPos.cy)
          End If
          mWndPos.cy = MIN_HEIGHT
        End If
        the_Y = mWndPos.y
        CopyMemory ByVal lParam, mWndPos, LenB(mWndPos)
      End If
    Case Else
  End Select
    
  NewFormMeWindowProc = CallWindowProc( _
   OldFormMeWindowProc, hwnd, Msg, wParam, _
   lParam)
End Function

  'снятие сабклассинга
...
   SetWindowLong Me.hwnd, GWL_WNDPROC, OldFormMeWindowProc



Посмотрим с чем столкнусь. Счас просто делаю новый "красивый" exe-шник с нуля, но по шаблону старого.
Ну и стараюсь устранять ляпы, типа отсутствия того о чем писал в начале. Как бы по науке, а не на авось.

Но думаю если будет чего-то совсем сложное-причесываемое трудно-понимаемое, просто забью на снятие сабклассинга в пользу наглядности и экономии времени.
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38249773
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вот понять не могу.

У меня два сабклассинга.
Первый стандартный.
Код: vbnet
1.
2.
3.
  OldFormMainWindowProc = SetWindowLong( _
   FormMain.hwnd, GWL_WNDPROC, _
   AddressOf NewFormMainWindowProc)


Ловит WM_COPYDATA, теперь WM_WINDOWPOSCHANGING и прочую рутину

Второй покруче -занимается проигрыванием файлов:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  'необходимо для проигрывания WAV
  OldFormWindowProc = SetWindowLong(FormMain.hwnd, GWL_WNDPROC, _
   AddressOf NewFormWindowProc)

Private Declare Function waveOutOpen_play Lib "winmm.dll" Alias "waveOutOpen" (hWaveOut As Long, _
 ByVal uDeviceID As Long, ByVal Format As String, ByVal dwCallback As Long, ByRef fPlaying As Boolean, _
 ByVal dwFlags As Long) As Long


Public Function snd_PlayFile(ByRef err_text As String, ByVal device_name As String, _
...
  lR = waveOutOpen_play(hWaveOut, id, sFormatBuffer, FormMain.hwnd, True, CALLBACK_WINDOW)

Public Function NewFormWindowProc _
 (ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
...
  Select Case Msg
    Case MM_WOM_DONE
...



Совмещать абсолютно неудобно, т.к. вторая ф-ция находится в своем - "звуковом" модуле.

Ну, дай думаю заменю FormMain.hwnd на какую-нибудь FormMain. Picture_CALLBACK .hwnd
Какая этому PlayWav разница, куда Msg-ы слать, в картинку или в форму.
И нифига не работает!!! Приложение считай виснет после первого Callback-а.

Ну, цель-то была просто чтоб сабклассинги снять поотдельности.

В чем проблема? Что-то где-то недоглядел? Или waveOutOpen требует форму для этой цели?
...
Рейтинг: 0 / 0
А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
    #38249777
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77В чем проблема? Что-то где-то недоглядел?
О, теперь доглядел:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
Public Function snd_PlayFile(ByRef err_text As String, ByVal device_name As String, _
...
  lR = waveOutOpen_play(hWaveOut, id, sFormatBuffer, FormMain.Picture_WAV_Callback.hwnd, True, CALLBACK_WINDOW)

  ' Start playing by posting callback functions to read into
  ' the five buffers & play:
  For iBuffer = 1 To NUM_BUFFERS
    PostWavMessage FormMain.hwnd, MM_WOM_DONE, 0, tHdr(iBuffer)
  Next


В одном месте подправил, в другом проглядел.
Этот вопрос снят.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / А где правильно снимать сабклассинг, делать всякие Destroy и т.п.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]