今回はWindowsFormでアプリケーションを作成する際、[×]ボタンの活性/非活性の制御ではまってしまった。解消をすることができたので、今回は備忘録として記録を残そうと思う。(今回が初めての投稿です。私の認識に誤りがあればご指摘いただければと思います。よろしくお願いします。)
処理としては、フォームの右上にある[×]を表示をそのままにボタンのみを無効にする動作の実装をした。
WindowsFormの既定のプロパティなどで活性制御が行えなかったため、Win32 API を使用し実装した。
サンプルコード
フォームに、[×]ボタンの有効/無効ボタンを設けClickイベントで有効/無効の制御処理を行っている。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace _test {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
///APIのDLL読み込み 外部で実装されるメソッドを宣言
[DllImport("user32.dll")]
static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
///定数宣言
///第二引数で使用する用
///×ボタンの設定されている定数
internal const UInt32 SC_CLOSE = 0x0000F060;
/// 第三引数で使用する用
/// 無効の設定されている定数
internal const UInt32 MF_GRAYED = 0x00000001;
/// 有効の設定されている定数
internal const UInt32 MF_ENABLED = 0x00000000;
/// <summary>
/// 有効化ボタン
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e) {
//×ボタンのシステムメニュー(フォームの)ハンドル取得する
IntPtr hMenu = GetSystemMenu(this.Handle, false);
if (hMenu != IntPtr.Zero) {
//閉じるメニュー有効化
EnableMenuItem(hMenu, SC_CLOSE, MF_ENABLED);
}
}
/// <summary>
/// 無効化ボタン
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e) {
IntPtr hMenu = GetSystemMenu(this.Handle, false);
if (hMenu != IntPtr.Zero) {
EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED);
}
}
}
}
関連するリファレンス
https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-enablemenuitem
確認環境
・Windows 10 Home
・開発環境:Visual Studio 2017
・.Net:5.0.16
参考サイト
https://www.pine4.net/Memo/Article/Archives/51
https://learn.microsoft.com/ja-jp/windows/apps/develop/ui-input/retrieve-hwnd
https://qiita.com/kob58im/items/34724e36603351d78596
http://wisdom.sakura.ne.jp/system/winapi/win32/win59.html
https://work-note32.com/c-close-button-invalid