Linda,
I tried the solution you provided so far and noted the same issues you
raised as well as some others. So I simplified the DrawFrame routine while
at the same time providing more contrast to what was happening. Here is my
DrawFrame method:
private void DrawFrame()
{
int frameWidth = this.Width;
int frameHeight = this.Height - this.ClientSize.Height - borderwidth;
int textWidth = frameWidth - 2 * borderwidth;
int textHeight = frameHeight - 2 * borderwidth;
IntPtr hdc = User32DllImports.GetWindowDC( this.Handle );
using ( Graphics g = Graphics.FromHdc( hdc ) )
{
g.FillRectangle( Brushes.DarkBlue, 0, 0, frameWidth, frameHeight );
g.FillRectangle( Brushes.LightBlue, borderwidth, borderwidth,
textWidth, textHeight );
g.DrawString( this.Text, this.Font, Brushes.Yellow, 28, 3 );
}
User32DllImports.ReleaseDC( this.Handle, hdc );
}
I observed the following while trying the solution in my application:
1. If the MDI application is iconified and restored, the child form's
original title bar is drawn, not the new title bar.
2. The new title bar is drawn if I move the child form up in the client area.
3. The title bar's control box buttons (Minimum, Close, etc.) are drawn one
by one as the mouse moves over their locations. However, they disappear if
the child form is moved up.
4. The icon associated with the child form is only drawn when the old title
bar is displayed. It does not appear when the new title bar is displayed and
the mouse is moved over its location, which is different than the control box
behavior.
As for the system menu not working, don't spend too much time on it. It is
just a want, not a must requirement.
Thanks,
Dave
--
Dave Leach
Agilent Technologies, Inc.
Linda Liu said:
Hi Dave,
I spent several hours researching on this issue and come to realize that
the only way to get what you want is to draw the non-client area of the MDI
child form by ourselves.
To draw the non-client area of a form, we need to override the WndProc
method of the form and capture the WM_NCPAINT Windows message. I have
managed to accomplish the following tasks:
- The normal title bar background can be replaced with a bmp image.
- The normal title bar text is displayed with a specified pen color.
- The normal control box is still used.
- The child forms can be moved by dragging from the title bar.
As for showing a system menu when right clicking on the title bar, a normal
form has provided such a function internally. But for an MDI child form,
this funciton is not supported inherently. I have tried posting some
Windows messages such as WM_RBUTTONUP, WM_NCLBUTTONDOWN and etc to the MDI
child form to get the system menu to pop up, but without luck.
I think a possible solution may be to call the Win32 API GetSystemMenu and
then copy the system menu items into our own context menu. We could show
our own context menu at last. I haven't tried it out by now, but I'll do it
later.
The following is my sample code so far. There's one shortcoming in this
sample code that I haven't overcome until now, i.e. the intrinsic Minimize,
Maximize and Close buttons on the title bar don't appear when the MDI child
form shows for the first time, but appears when the user moves the mouse
into the MDI child form.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
int titleheight = 0;
int borderwidth = 0;
int WM_NCACTIVATE = 0x0086;
int WM_NCPAINT = 0x0085;
int WM_PAINT = 0x000F;
int WM_NCLBUTTONDOWN = 0xA1;
[DllImport("user32.dll")]
static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("User32.dll")]
static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
Rectangle m_rect = new Rectangle(6, 6, 20, 20);
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCPAINT || m.Msg == WM_NCACTIVATE)
{
DrawFrame();
}
}
private void DrawFrame()
{
IntPtr hdc = GetWindowDC(this.Handle);
using (Graphics g = Graphics.FromHdc(hdc))
{
g.FillRectangle(Brushes.Blue, 0, 0, this.Width,
titleheight);
g.FillRectangle(Brushes.Blue, 0, titleheight, borderwidth,
this.Height - titleheight);
g.FillRectangle(Brushes.Blue, borderwidth, this.Height -
borderwidth, this.ClientSize.Width, borderwidth);
g.FillRectangle(Brushes.Blue, this.Width - borderwidth,
titleheight, borderwidth, this.Height - titleheight);
g.DrawString(this.Text, this.Font, Brushes.Coral, 35, 8);
g.FillRectangle(new LinearGradientBrush(m_rect, Color.Pink,
Color.Purple, LinearGradientMode.BackwardDiagonal), m_rect);
StringFormat strFmt = new StringFormat();
strFmt.Alignment = StringAlignment.Center;
strFmt.LineAlignment = StringAlignment.Center;
g.DrawString("¡Ì", this.Font, Brushes.BlanchedAlmond,
m_rect,strFmt);
}
ReleaseDC(this.Handle, hdc);
}
private void Form2_Load(object sender, EventArgs e)
{
titleheight = this.Height - this.ClientSize.Height -
borderwidth - 8;
borderwidth = (this.Width - this.ClientSize.Width) / 2;
}
}
I will go on the research and would get the result back to you ASAP.
I appreciate your patience!
Sincerely,
Linda Liu
Microsoft Online Community Support