G
Guest
I'm trying to add another button to a window's title bar to use as a "keep
this window on top" button. I've managed to draw the button using the code
below (C#) but I'm having a couple of other problems...
....
private bool buttonChecked = false;
private int buttonSize = 16;
private int buttonX = 226;
private int buttonY = 6;
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
public const int WM_NCPAINT = 0x085;
public const int WM_NCLBUTTONDOWN = 0x0A1;
public const int WM_NCLBUTTONUP = 0x0A2;
....
....
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCPAINT:
base.WndProc (ref m);
IntPtr hDC = GetWindowDC(m.HWnd);
Graphics g = Graphics.FromHdc(hDC);
PaintNC(m.HWnd);
g.Dispose();
ReleaseDC(m.HWnd, hDC);
m.Result = IntPtr.Zero;
break;
case WM_NCLBUTTONDOWN:
base.WndProc (ref m);
Point pd = new Point((int)m.LParam);
int xPos = pd.X - this.Location.X;
int yPos = pd.Y - this.Location.Y;
if (xPos > buttonX && xPos < (buttonX + buttonSize) && yPos > buttonY &&
yPos < (buttonY + buttonSize))
{
IntPtr hDCa = GetWindowDC(m.HWnd);
Graphics gra = Graphics.FromHdc(hDCa);
buttonChecked = !buttonChecked;
}
break;
default:
base.WndProc(ref m);
break;
}
}
protected void PaintNC(System.IntPtr hWnd)
{
IntPtr hDC = GetWindowDC(hWnd);
Graphics g = Graphics.FromHdc(hDC);
if (buttonChecked)
ControlPaint.DrawButton(g, buttonX, buttonY, buttonSize, buttonSize,
ButtonState.Checked);
else
ControlPaint.DrawButton(g, buttonX, buttonY, buttonSize, buttonSize,
ButtonState.Normal);
g.Dispose();
ReleaseDC(hWnd, hDC);
}
....
The first problem I'm having is that is doesn't use the Window theme
anymore for the window. It uses the classic win98 style theme with the
gradient title bar.
The second problem is that when I click the button it doesn't refresh the
window so it doesn't show that it's pushed it. I have to minimise and then
maximise the window to see the changes. I tried using the invalidate() method
but that only works in the client area of the window.
Any ideas?
Darrell
this window on top" button. I've managed to draw the button using the code
below (C#) but I'm having a couple of other problems...
....
private bool buttonChecked = false;
private int buttonSize = 16;
private int buttonX = 226;
private int buttonY = 6;
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
public const int WM_NCPAINT = 0x085;
public const int WM_NCLBUTTONDOWN = 0x0A1;
public const int WM_NCLBUTTONUP = 0x0A2;
....
....
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCPAINT:
base.WndProc (ref m);
IntPtr hDC = GetWindowDC(m.HWnd);
Graphics g = Graphics.FromHdc(hDC);
PaintNC(m.HWnd);
g.Dispose();
ReleaseDC(m.HWnd, hDC);
m.Result = IntPtr.Zero;
break;
case WM_NCLBUTTONDOWN:
base.WndProc (ref m);
Point pd = new Point((int)m.LParam);
int xPos = pd.X - this.Location.X;
int yPos = pd.Y - this.Location.Y;
if (xPos > buttonX && xPos < (buttonX + buttonSize) && yPos > buttonY &&
yPos < (buttonY + buttonSize))
{
IntPtr hDCa = GetWindowDC(m.HWnd);
Graphics gra = Graphics.FromHdc(hDCa);
buttonChecked = !buttonChecked;
}
break;
default:
base.WndProc(ref m);
break;
}
}
protected void PaintNC(System.IntPtr hWnd)
{
IntPtr hDC = GetWindowDC(hWnd);
Graphics g = Graphics.FromHdc(hDC);
if (buttonChecked)
ControlPaint.DrawButton(g, buttonX, buttonY, buttonSize, buttonSize,
ButtonState.Checked);
else
ControlPaint.DrawButton(g, buttonX, buttonY, buttonSize, buttonSize,
ButtonState.Normal);
g.Dispose();
ReleaseDC(hWnd, hDC);
}
....
The first problem I'm having is that is doesn't use the Window theme
anymore for the window. It uses the classic win98 style theme with the
gradient title bar.
The second problem is that when I click the button it doesn't refresh the
window so it doesn't show that it's pushed it. I have to minimise and then
maximise the window to see the changes. I tried using the invalidate() method
but that only works in the client area of the window.
Any ideas?
Darrell