tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルMDIフォームの最大化・最小化ボタンを無効にする方法
記事No16262
投稿日: 2016/12/04(Sun) 19:29
投稿者スマートPIG
VB6でプログラム作成を始め15年近くなります。
今回、MDIフォームの最大化・最小化ボタンを無効化する目的で、以下のコードを貼り付け、実行しましたが、「閉じる(×)」ボタンは無効化されたものの、最大化・最小化ボタンは無効化されませんでした。解決法をご教授いただければ幸いです。よろしくお願いいたします。
なお、現在利用中のOSはウィンドウズ10です。

Option Explicit
    'MDIフォームのクリップボタンを無効化する
    Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As         Long 'システムメニューのハンドルを取得
    Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long 'メニューから項目を削除する
    Private Declare Function DrawMenuBar Lib "user32" (ByVal hWnd As Long) As Long 'メニューバーを再描画する
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long 'ウインドウに関する属性を変更する
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal     nIndex As Long) As Long 'ウインドウに関するデータを取得する
    Private Const WS_MINIMIZEBOX = &H20000 '最小化ボタン
    Private Const WS_MAXIMIZEBOX = &H10000 '最大化ボタン
    Private Const GWL_STYLE = (-16)
    Private Const MF_BYCOMMAND = &H0& 'メニュー項目のID
    Private Const MF_BYPOSITION = &H400& 'メニュー項目のインデックス
    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 Sub MDIForm_Load()
    Dim Result As Long
    Dim hWnd As Long
    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) 'メニューバーを再描画する  
    '
    hWnd = GetSystemMenu(Me.hWnd, 0&)
    Result = DeleteMenu(hWnd, SC_CLOSE, MF_BYCOMMAND) '「閉じる」ボタンを無効化する
    Result = DeleteMenu(hWnd, 5&, MF_BYPOSITION)
End Sub

[ツリー表示へ]
タイトルRe: MDIフォームの最大化・最小化ボタンを無効にする方法
記事No16263
投稿日: 2016/12/05(Mon) 10:19
投稿者魔界の仮面弁士
>    DrawMenuBar (Me.hWnd) 'メニューバーを再描画する
VB.NET とは異なり、VB6 では戻り値をとらないメソッド呼び出しには
括弧を付けない言語仕様になっています。ゆえに上記は本来、
  Result = DrawMenuBar(Me.hWnd)
  Call DrawMenuBar(Me.hWnd)
  DrawMenuBar Me.hWnd
のいずれかで記述した方がベターです。

今回のように引数が 1 個であれば括弧付きで書けますが、それは
  Result = DrawMenuBar( (Me.hWnd) )
のように、式としての括弧となりますので、意味が変わってきます。


>    hWnd = GetSystemMenu(Me.hWnd, 0&)
GetSystemMenu の戻り値を hWnd という変数名にするのは避けましょう。
この戻り値は Window Handle ではなく、Menu Handle なのですから。

同様の理由で、現状の API 宣言の引数名も不自然な印象を受けますので、
一度見直しておかれることをお奨めします。


> 「閉じる(×)」ボタンは無効化されたものの、
[閉じる]だけならば、API を使うまでも無いですけれどね。
今回の目的には副わないとは思いますが。

Private Sub MDIForm_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  If UnloadMode = vbFormControlMenu Then
    Cancel = 1
  End If
End Sub



> 最大化・最小化ボタンは無効化されませんでした。

(案1) DrawMenuBar する前に、「GetSystemMenu Me.hWnd, 1&」を呼びだし、
 ウィンドウメニューをリセットしておく。

Call GetSystemMenu(Me.hWnd, 1&)
NewLong = GetWindowLong(Me.hWnd, GWL_STYLE)
If 削除する場合 Then
  NewLong = NewLong And Not WS_MINIMIZEBOX
  NewLong = NewLong And Not WS_MAXIMIZEBOX
ElseIf 復活させる場合 Then
  NewLong = NewLong Or WS_MINIMIZEBOX
  NewLong = NewLong Or WS_MAXIMIZEBOX
End If
NewLong = SetWindowLong(Me.hWnd, GWL_STYLE, NewLong)
Call DrawMenuBar(Me.hWnd)




(案2) DeleteMenu の対象として
6番目のアイテム SC_CLOSE (閉じる)ボタンと
5番目のアイテム(セパレータ)だけを処理するのではなく、
3番目のアイテム SC_MAXIMIZE (最小化) と
4番目のアイテム SC_MAXIMIZE (最大化) にも
手を加えるようにする。


If 削除 Then
  hMenu = GetSystemMenu(Me.hWnd, 0)
  Result = DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND)
  Result = DeleteMenu(hMenu, 5&, MF_BYPOSITION)
  Result = DeleteMenu(hMenu, SC_MAXIMIZE, MF_BYCOMMAND)
  Result = DeleteMenu(hMenu, SC_MINIMIZE, MF_BYCOMMAND)
ElseIf 復活 Then
  Call GetSystemMenu(Me.hWnd, 1)
End If
Call DrawMenuBar(Me.hWnd)

[ツリー表示へ]
タイトルRe^2: MDIフォームの最大化・最小化ボタンを無効にする方法
記事No16264
投稿日: 2016/12/05(Mon) 18:56
投稿者スマートPIG
魔界の仮面弁士 様

さっそくご回答いただき、ありがとうございます。
案2により、MDIフォームの最小化・最大化両ボタンを無効にすることができました。長年の懸案事項が解決でき、感謝しております。(ちなみに、当方に関する限り、案1では無効化に至りませんでした)

また、ほかにもいろいろ細かくご教示いただきありがとうございました。今後の参考にさせていただきます。

[ツリー表示へ]