■99314 / inTopicNo.6) |
Re[2]: メッセージボックスの閉じるボタンを無効にしたい |
□投稿者/ KOZ (228回)-(2022/03/09(Wed) 01:12:31)
|
■No99313 (魔界の仮面弁士 さん) に返信
> 以下は VB6 のサンプルですが、参考までに。
> https://www.vbforums.com/showthread.php?866647-MessageBox-without-Red-X-close-button
.NET のサンプルが意外に見つからなかったので URL を参考にサンプルを書いてみました。
こんな感じで使います。
using (var remover = new CloseButtonRemover()) {
MessageBox.Show("TEST");
}
以下クラスです。
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
class CloseButtonRemover : SafeHandleZeroOrMinusOneIsInvalid
{
readonly HookProcDelegate hookProcDelegate;
readonly MessageBoxWindow messageBoxWindow = new MessageBoxWindow();
public CloseButtonRemover() : base(true) {
hookProcDelegate = new HookProcDelegate(HookProc);
handle = SetWindowsHookEx(WH_CALLWNDPROC, hookProcDelegate, IntPtr.Zero, GetCurrentThreadId());
}
protected override bool ReleaseHandle() {
return UnhookWindowsHookEx(handle);
}
private IntPtr HookProc(int code, IntPtr wp, IntPtr lp) {
var cwp = Marshal.PtrToStructure<CWPSTRUCT>(lp);
if (cwp.message == WM_CREATE) {
var sb = new StringBuilder(128);
GetClassName(cwp.hwnd, sb, sb.Capacity);
if (sb.ToString() == "#32770") {
messageBoxWindow.AssignHandle(cwp.hwnd);
}
}
return CallNextHookEx(handle, code, wp, lp);
}
class MessageBoxWindow : NativeWindow
{
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case WM_INITDIALOG:
IntPtr hMenu = GetSystemMenu(m.HWnd, false);
DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
const int WM_INITDIALOG = 0x0110;
const int MF_BYCOMMAND = 0x0000;
const int SC_CLOSE = 0xF060;
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
static extern bool DeleteMenu(IntPtr hMenu, int position, int flags);
}
const int WM_CREATE = 0x0001;
const int WH_CALLWNDPROC = 4;
delegate IntPtr HookProcDelegate(int code, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetWindowsHookEx(int hookType, HookProcDelegate lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[StructLayout(LayoutKind.Sequential)]
private struct CWPSTRUCT
{
public IntPtr lparam;
public IntPtr wparam;
public int message;
public IntPtr hwnd;
}
}
|
|