'---- Form1.frm ------------------------------------------------------
Option Explicit

Private Sub Form_Initialize()
Debug.Print "Form1::Form_Initialize"
End Sub

Private Sub Form_Load()
Debug.Print "Form1::Form_Load"
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Debug.Print "Form1::Form_QueryUnload"
End Sub

Private Sub Form_Terminate()
Debug.Print "Form1::Form_Terminate"
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print "Form1::Form_Unload"
End Sub
'--- End of file -----------------------------------------------------

'---- Form2.frm ------------------------------------------------------
Option Explicit

Private Sub Form_Initialize()
Debug.Print "Form2::Form_Initialize"
End Sub

Private Sub Form_Load()
Debug.Print "Form2::Form_Load"
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Debug.Print "Form2::Form_QueryUnload"
End Sub

Private Sub Form_Terminate()
Debug.Print "Form2::Form_Terminate"
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print "Form2::Form_Unload"
End Sub
'--- End of file -----------------------------------------------------

'---- Form3.frm ------------------------------------------------------
Option Explicit

Private Sub Form_Initialize()
Debug.Print "Form3::Form_Initialize"
End Sub

Private Sub Form_Load()
Debug.Print "Form3::Form_Load"
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Debug.Print "Form3::Form_QueryUnload"
End Sub

Private Sub Form_Terminate()
Debug.Print "Form3::Form_Terminate"
End Sub

Private Sub Form_Unload(Cancel As Integer)
Debug.Print "Form3::Form_Unload"
End Sub
'--- End of file -----------------------------------------------------


'---- frmMain.frm ------------------------------------------------------
Option Explicit

Private Sub Command1_Click()
Dim frm As Form

Form1.Show
Form2.Show
Form3.Show
For Each frm In Forms
Debug.Print frm.Name
Next frm

End Sub

Private Sub Command2_Click()
Debug.Print "End.."
End
End Sub
'--- End of file -----------------------------------------------------


'--- イミディエントの出力結果 ----------------------------------------
Form1::Form_Initialize
Form1::Form_Load
Form2::Form_Initialize
Form2::Form_Load
Form3::Form_Initialize
Form3::Form_Load
frmMain
Form1
Form2
Form3
End..
'---------------------------------------------------------------------

以上のことからForm1,Form2,Form3のForm_Unload,Form_Terminateイベントは
呼ばれていないことが判明しました。
そこでEndステートメントの直前からForm1のウインドウに送られるメッセージを
監視することにしました。
以下のログはEndステートメントが呼ばれた後にForm1ウインドウが受け取る
メッセージの一部抜粋です。
このメッセージ以前にもいくつかのメッセージは受け取っていましたが、画面の
再描画やそのメッセージに伴うメッセージなので割愛しました。

'--- Spy++ のメッセージ出力 ------------------------------------------
006C02A4 S WM_WINDOWPOSCHANGED lpwp:0012EFC0
006C02A4 R WM_WINDOWPOSCHANGED
006C02A4 S .WM_DESTROY
006C02A4 S ..WM_SECTION fType:False hicon:00000000
006C02A4 R ..WM_SECTION hPrevIcon:00000000
006C02A4 R .WM_DESTROY
006C02A4 S .WM_NCDESTROY
006C02A4 R .WM_NCDESTROY
'---------------------------------------------------------------------

以上の事からEndステートメントが呼ばれた場合はWM_DESTROYメッセージが送られて
くる事が伺えます。Exeにした場合も同様にWM_DESTROYメッセージが送られていました。
また、Form1をシステムメニューの「閉じる」から明示的に閉じた場合は、

'--- イミディエントの出力結果 ----------------------------------------
Form1::Form_QueryUnload
Form1::Form_Unload
'---------------------------------------------------------------------


'--- Spy++ のメッセージ出力 ------------------------------------------
002C028E S WM_WINDOWPOSCHANGED lpwp:0012EFC0
002C028E R WM_WINDOWPOSCHANGED
:
002C028E S WM_KILLFOCUS hwndGetFocus:(null)
002C028E R WM_KILLFOCUS
002C028E S ..WM_IME_SETCONTEXT fSet:0 (LONG)iShow:C0000000F
002C028E S ...WM_IME_NOTIFY dwCommand:00000001 dwData:00000000
002C028E R ...WM_IME_NOTIFY
002C028E R ..WM_IME_SETCONTEXT
002C028E S .WM_DESTROY
002C028E S ..WM_SECTION fType:False hicon:00000000
002C028E R ..WM_SECTION hPrevIcon:00000000
002C028E R .WM_DESTROY
002C028E S .WM_NCDESTROY
002C028E R .WM_NCDESTROY
002C028E R WM_SYSCOMMAND
002C028E s WM_NCDESTROY
'---------------------------------------------------------------------


となりました。
結果としては、ウインドウの解放はEndステートメントを使用した場合でも適切に
行われていますが、Form_QueryUnload,Form_Unloadは呼ばれないという事です。

以下はWM_DESTROYメッセージを送るDestroyWindow()API関数の解説です。
(api32wh.hlpより抜粋)

'--- DestroyWindow ---------------------------------------------------
BOOL DestroyWindow(hwnd)HWND hwnd; /* 破棄するウィンドウのハンドル */
DestroyWindow関数は、 指定されたウィンドウを破棄します。この関数は、
WM_DESTROYメッセージおよびWM_NCDESTROYメッセージをウィンドウに送って
ウィンドウを非アクティブ化し、 入力フォーカスを取り除きます。また、 この関数は、
ウィンドウ メニューの破棄、 スレッドのメッセージ キューのフラッシュ、 タイマの破棄、
クリップボードの所有権の除去、 クリップボード ビューア チェインの切断
(ウィンドウがビューア チェインの先頭にあるとき) をそれぞれ実行します。
指定されたウィンドウが親ウィンドウまたはオーナー ウィンドウの場合、
DestroyWindow関数は親ウィンドウやオーナー ウィンドウを破棄するときに自動的に
その子ウィンドウやオーナー付きウィンドウも破棄します。このとき、 先にそれらを
破棄してから、 親ウィンドウやオーナー ウィンドウを自身を破棄します。

DestroyWindow関数は、 CreateDialog関数を使用して作成したモードレス ダイアログ
ボックスも破棄します。
'---------------------------------------------------------------------


以上の事からVBのEndステートメントは一般的な使用については安全だと思われます。
しかしEndステートメントは上記の終了関数を呼び出さないので、以下のような場合には
問題があるかもしれません。
・InitializeイベントやLoadイベントでGlobalAlloc,LocalAlloc等を使用して
動的にメモリを確保してTerminateイベントやUnloadイベントでメモリの解放を
行う場合。