フォームの右上の×をクリックしても終了させない
                                                         玄関へお回り下さい。
フォームの右上の×をクリックしても終了しないように設定する (078)
       QueryUnload イベント

記述
  Private Sub Form_QueryUnload(cancel As Integer, unloadmodeAs Integer)

  フォームまたはアプリケーションが閉じられる直前に発生します。

使用例
  Private Sub Form_QueryUnload(Cancel As Integer, UnloadModeAs Integer)
    If UnloadMode = 0 Then Cancel = 1
  End Sub

参考
定    数 説           明
vbFormControlMenu 0 ユーザーが、フォームのコントロールメニューの[閉じる]をクリックしました。
vbFormCode 1 コード内で Unload ステートメントが実行されました
vbAppWindows 2 現在の Windows セッションが終了します。
vbAppTaskManager 3 Windows の タスクマネージャーによってアプリケーションが閉じられます。
vbFormMDIForm 4 MDI フォームが閉じられたため、MDI 子フォームが閉じられました。

ユーザーが、フォームのコントロールメニューの 閉じる(UnloadMode = 0)クリックした時Cancel を 0 以外の値に設定すると、ロードされているすべてのフォームに対するQueryUnload イベントの発生は中止され、フォームおよびアプリケーションは閉じられません。

API関数を使ったやり方                      (078)
   少し複雑になりますが、結果は同じでもボタンの表示が無効色になります。

使用例
Option Explicit
'システムメニューのハンドルを取得(P133)
Private Declare Function GetSystemMenu Lib "user32" _
    (ByVal hwnd As Long, ByVal bRevert As Long) As Long
'メニューから項目を削除する(P122)
Private Declare Function DeleteMenu Lib "user32" _
    (ByVal hMenu As Long, ByVal nPosition As Long, _
    ByVal wFlags As Long) As Long
'メニューバーを再描画する(P123)
Private Declare Function DrawMenuBar Lib "user32" _
    (ByVal hwnd As Long) As Long
Private Const MF_BYCOMMAND = &H0&  'メニュー項目のID(P122)
Private Const MF_BYPOSITION = &H400& 'メニュー項目のインデックス
Private Const SC_CLOSE = &HF060   'システムメニューの閉じる


Private Sub Form_Load()
  Me.Move 7500, 1000, 3000, 3000
  Dim Result As Long
  Dim hwnd  As Long
  hwnd = GetSystemMenu(Me.hwnd, 0&)
  Result = DeleteMenu(hwnd, SC_CLOSE, MF_BYCOMMAND)
  Result = DeleteMenu(hwnd, 5&, MF_BYPOSITION)
  DrawMenuBar (hwnd)
End Sub


Private Sub Command1_Click()
  Unload Me
End Sub


[×]は灰色表示になるが、システムメニューの閉じるは表示(灰色でも)されません。

システムメニュー(Formの左上)を操作する(削除・元に戻す)   (078)
  デザイン時には一部変更が出来るのですが、プログラム上ではできないので、そのような時にはこれで操作が可能です。(下記は動作確認用のサンプルです)

Option Explicit   'SampleNo=078 WindowsXP VB6.0(SP5) 2002.05.17
'システムメニューのハンドルを取得(P133)
Private Declare Function GetSystemMenu Lib "user32" _
  (ByVal hWnd As Long, ByVal bRevert As Long) As Long
'メニューから項目を削除する(P122)
Private Declare Function DeleteMenu Lib "user32" _
  (ByVal hMenu As Long, ByVal nPosition As Long, _
   ByVal wFlags As Long) As Long
'メニューバーを再描画する(P123)
Private Declare Function DrawMenuBar Lib "user32" _
  (ByVal hWnd As Long) As Long
Private Const MF_BYCOMMAND = &H0&  'メニュー項目のID(P122)
Private Const SC_CLOSE = &HF060   'システムメニューの閉じる
Private Const SC_MOVE = &HF010    'システムメニューの移動
Private Const SC_SIZE = &HF000    'システムメニューのサイズ変更
Private Const SC_MAXIMIZE = &HF030  'システムメニューの最大化
Private Const SC_MINIMIZE = &HF020  'システムメニューの最小化
Private Const SC_RESTORE = &HF120  'システムメニューの元に戻す
Private Const MF_BYPOSITION = &H400& 'メニュー項目のインデックス


Private Sub Command1_Click()
'指定のポジションのメニューを削除する
  Call fDelSysMenu(Form1, CLng(Text1.Text), False)
  Form1.Hide
  Form1.Show
End Sub


Private Sub Command2_Click()
'指定のポジションのメニューを元に戻す
  Call fDelSysMenu(Form1, CLng(Text1.Text), True)
  Form1.Hide
  Form1.Show
End Sub


'**********************************************************
'* myForm   :メニューを削除するフォーム
'* nPosition  :削除するメニューの位置番号(一番上が 0)
'* sMenuOn   :False=削除 True=元に戻す
'* 戻り値   :正常終了のとき 0 以外 エラーのとき 0
'* 使用例 Call fDelSysMenu(Form1, CLng(Text1.Text), True)
'**********************************************************
Private Function fDelSysMenu(ByVal myForm As Form, _
    ByVal nPosition As Long, ByVal sMenuOn As Boolean) As Long
  Dim hWnd  As Long
  Dim Result As Long

  If sMenuOn Then   'システムメニューを元の状態に戻す
    hWnd = GetSystemMenu(myForm.hWnd, 1&)
  Else  '指定のメニューを削除する
    hWnd = GetSystemMenu(myForm.hWnd, sMenuOn)
    Select Case nPosition
      Case 0 '元のサイズに戻す
        Result = DeleteMenu(hWnd, SC_RESTORE, MF_BYCOMMAND)
      Case 1 '移動
        Result = DeleteMenu(hWnd, SC_MOVE, MF_BYCOMMAND)
      Case 2 'サイズ変更
        Result = DeleteMenu(hWnd, SC_SIZE, MF_BYCOMMAND)
      Case 3 '最小化
        Result = DeleteMenu(hWnd, SC_MINIMIZE, MF_BYCOMMAND)
      Case 4 '最大化
        Result = DeleteMenu(hWnd, SC_MAXIMIZE, MF_BYCOMMAND)
      Case 5, 6 '閉じる及びライン
        Result = DeleteMenu(hWnd, SC_CLOSE, MF_BYCOMMAND)
        Result = DeleteMenu(hWnd, 5&, MF_BYPOSITION)
    End Select
  End If
  fDelSysMenu = Result
  DrawMenuBar (myForm.hWnd)   'メニューバーを再描画する
End Function



最大化・最小化ボタンをプログラム上から削除する   (078)

'=========== 以下最大化・最小化ボタンを削除するの関係分 ============
'ウィンドウに関する属性を変更する(P60)
Private Declare Function SetWindowLong Lib "user32" _
  Alias "SetWindowLongA" (ByVal hWnd As Long, _
  ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
'ウィンドウに関するデータを取得する(P59)
Private Declare Function GetWindowLong Lib "user32" _
  Alias "GetWindowLongA" (ByVal hWnd As Long, _
  ByVal nIndex As Long) As Long
'SetWindowLongPtr
'GetWindowLongPtr
'SetWindowLong 関数の改訂版です。との事ですが情報がありません。

Private Const WS_MINIMIZEBOX = &H20000 '最小化ボタン
Private Const WS_MAXIMIZEBOX = &H10000 '最大化ボタン
Private Const GWL_STYLE = (-16)     'ウィンドウスタイル(P59)
'=================================================================
Private Sub Command3_Click()
'最大化・最小化ボタンを取り外す
  Dim NewLong As Long
  NewLong = GetWindowLong(Me.hWnd, GWL_STYLE)
  NewLong = NewLong And Not (WS_MINIMIZEBOX)
  NewLong = NewLong And Not (WS_MAXIMIZEBOX)
  NewLong = SetWindowLong(Me.hWnd, GWL_STYLE, NewLong)
  DrawMenuBar (Me.hWnd)    'メニューバーを再描画する
End Sub


Private Sub Command4_Click()
'最大化・最小化ボタンを元に戻す
  Dim NewLong As Long
  NewLong = GetWindowLong(Me.hWnd, GWL_STYLE)
  NewLong = NewLong Or (WS_MINIMIZEBOX)
  NewLong = NewLong Or (WS_MAXIMIZEBOX)
  NewLong = SetWindowLong(Me.hWnd, GWL_STYLE, NewLong)
  DrawMenuBar (Me.hWnd)    'メニューバーを再描画する
End Sub





2002/05/17