gpt4 book ai didi

winforms - 如何使用 Windows 窗体在窗口标题栏中绘制自定义按钮?

转载 作者:行者123 更新时间:2023-12-04 11:32:59 25 4
gpt4 key购买 nike

如何在窗体标题栏中的最小化、最大化和关闭按钮旁边绘制自定义按钮?

我知道您需要使用 Win32 API 调用并覆盖 WndProc 过程,但我一直无法找到一个正确的解决方案。

有谁知道如何做到这一点?更具体地说,有没有人知道一种在 Vista 中有效的方法?

最佳答案

以下将在 XP 中工作,我没有方便的 Vista 机器来测试它,但我认为您的问题源于不正确的 hWnd。无论如何,继续使用注释不佳的代码。

// The state of our little button
ButtonState _buttState = ButtonState.Normal;
Rectangle _buttPosition = new Rectangle();

[DllImport("user32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hWnd,
ref Rectangle lpRect);
[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
protected override void WndProc(ref Message m)
{
int x, y;
Rectangle windowRect = new Rectangle();
GetWindowRect(m.HWnd, ref windowRect);

switch (m.Msg)
{
// WM_NCPAINT
case 0x85:
// WM_PAINT
case 0x0A:
base.WndProc(ref m);

DrawButton(m.HWnd);

m.Result = IntPtr.Zero;

break;

// WM_ACTIVATE
case 0x86:
base.WndProc(ref m);
DrawButton(m.HWnd);

break;

// WM_NCMOUSEMOVE
case 0xA0:
// Extract the least significant 16 bits
x = ((int)m.LParam << 16) >> 16;
// Extract the most significant 16 bits
y = (int)m.LParam >> 16;

x -= windowRect.Left;
y -= windowRect.Top;

base.WndProc(ref m);

if (!_buttPosition.Contains(new Point(x, y)) &&
_buttState == ButtonState.Pushed)
{
_buttState = ButtonState.Normal;
DrawButton(m.HWnd);
}

break;

// WM_NCLBUTTONDOWN
case 0xA1:
// Extract the least significant 16 bits
x = ((int)m.LParam << 16) >> 16;
// Extract the most significant 16 bits
y = (int)m.LParam >> 16;

x -= windowRect.Left;
y -= windowRect.Top;

if (_buttPosition.Contains(new Point(x, y)))
{
_buttState = ButtonState.Pushed;
DrawButton(m.HWnd);
}
else
base.WndProc(ref m);

break;

// WM_NCLBUTTONUP
case 0xA2:
// Extract the least significant 16 bits
x = ((int)m.LParam << 16) >> 16;
// Extract the most significant 16 bits
y = (int)m.LParam >> 16;

x -= windowRect.Left;
y -= windowRect.Top;

if (_buttPosition.Contains(new Point(x, y)) &&
_buttState == ButtonState.Pushed)
{
_buttState = ButtonState.Normal;
// [[TODO]]: Fire a click event for your button
// however you want to do it.
DrawButton(m.HWnd);
}
else
base.WndProc(ref m);

break;

// WM_NCHITTEST
case 0x84:
// Extract the least significant 16 bits
x = ((int)m.LParam << 16) >> 16;
// Extract the most significant 16 bits
y = (int)m.LParam >> 16;

x -= windowRect.Left;
y -= windowRect.Top;

if (_buttPosition.Contains(new Point(x, y)))
m.Result = (IntPtr)18; // HTBORDER
else
base.WndProc(ref m);

break;

default:
base.WndProc(ref m);
break;
}
}

private void DrawButton(IntPtr hwnd)
{
IntPtr hDC = GetWindowDC(hwnd);
int x, y;

using (Graphics g = Graphics.FromHdc(hDC))
{
// Work out size and positioning
int CaptionHeight = Bounds.Height - ClientRectangle.Height;
Size ButtonSize = SystemInformation.CaptionButtonSize;
x = Bounds.Width - 4 * ButtonSize.Width;
y = (CaptionHeight - ButtonSize.Height) / 2;
_buttPosition.Location = new Point(x, y);

// Work out color
Brush color;
if (_buttState == ButtonState.Pushed)
color = Brushes.LightGreen;
else
color = Brushes.Red;

// Draw our "button"
g.FillRectangle(color, x, y, ButtonSize.Width, ButtonSize.Height);
}

ReleaseDC(hwnd, hDC);
}

private void Form1_Load(object sender, EventArgs e)
{
_buttPosition.Size = SystemInformation.CaptionButtonSize;
}

关于winforms - 如何使用 Windows 窗体在窗口标题栏中绘制自定义按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/106912/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com