Custom drawing (layered) Embedded TabControls Error
I have a winform application that has tabcontrols that have 3 layers. I am dynamically coloring tabs using the below class. When it goes to color the built-in tabcontrol, it passes the fit.
A first chance exception of type 'System.ComponentModel.Win32Exception' occurred in System.Windows.Forms.dll
Do I need to do something different for those? If I comment out the inline form calls for the tabRenderer, then I don't get these errors. Am I getting rid of the TabRenderer object correctly?
Could it be something else entirely? How do I embed tab controls?
An example of what my program looks like at the moment is given here ->
(source: ggpht.com )
From DevFiles
As you can see, there are 3 layers of tabs. This happens twice in the program and both cause the mentioned error. There are 6 calls to tabRenderer in total since there are 5 tab controls. 1 upper level, 3 second level and 2 third level.
The code used for coloring the tabs:
public class psTabRenderer
{
private TabControl _tabControl;
private Color _fillColor;
private Color _selectedFillColor;
private Color _textColor;
private Color _selectedTextColor;
public psTabRenderer(TabControl tabControl, Color fillColor, Color selectedFillColor, Color textColor, Color selectedTextColor)
{
_tabControl = tabControl;
_fillColor = fillColor;
_selectedFillColor = selectedFillColor;
_textColor = textColor;
_selectedTextColor = selectedTextColor;
_tabControl.DrawMode = TabDrawMode.OwnerDrawFixed;
_tabControl.DrawItem += TabControlDrawItem;
}
private void TabControlDrawItem(object sender, DrawItemEventArgs e)
{
TabPage currentTab = _tabControl.TabPages[e.Index];
Rectangle itemRect = _tabControl.GetTabRect(e.Index);
var fillBrush = new SolidBrush(_fillColor);
var textBrush = new SolidBrush(_textColor);
var sf = new StringFormat
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
//If we are currently painting the Selected TabItem we'll
//change the brush colors and inflate the rectangle.
if (Convert.ToBoolean(e.State & DrawItemState.Selected))
{
fillBrush.Color = _selectedFillColor;
textBrush.Color = _selectedTextColor;
itemRect.Inflate(2, 2);
}
//Set up rotation for left and right aligned tabs
if (_tabControl.Alignment == TabAlignment.Left || _tabControl.Alignment == TabAlignment.Right)
{
float rotateAngle = 90;
if (_tabControl.Alignment == TabAlignment.Left)
rotateAngle = 270;
var cp = new PointF(itemRect.Left + (itemRect.Width / 2), itemRect.Top + (itemRect.Height / 2));
e.Graphics.TranslateTransform(cp.X, cp.Y);
e.Graphics.RotateTransform(rotateAngle);
itemRect = new Rectangle(-(itemRect.Height / 2), -(itemRect.Width / 2), itemRect.Height, itemRect.Width);
}
//Next we'll paint the TabItem with our Fill Brush
e.Graphics.FillRectangle(fillBrush, itemRect);
//Now draw the text.
e.Graphics.DrawString(currentTab.Text, e.Font, textBrush, (RectangleF)itemRect, sf);
//Reset any Graphics rotation
e.Graphics.ResetTransform();
//Finally, we should Dispose of our brushes.
fillBrush.Dispose();
textBrush.Dispose();
}
}
And this is how I call it:
private void frmMCPEmployment_Load(object sender, EventArgs e)
{
FormPaint();
}
public void FormPaint()
{
// ToDo: This call to the Tab Renderer is throwing a Win32 "Error Creating Window Handle"
new psTabRenderer(tclEmployment, Color.LightSteelBlue, Color.Khaki, Color.Black, Color.Black);
}
a source to share
Ok, I answered my own question. (kinda)
I believe what was happening is that when my application is loaded, it starts firing every Forms Load () event, which in turn fires the built-in Forms Load () event, and so on. I have challenged the TabRenderer on a boot Event and something I don't understand is happening. I pulled this call to the PaintTabs () function and then waited for the first one to complete before it calls the next one (I guess?).
It doesn't generate any errors anymore. Now I will call it like this from the TOP LEVEL TabControl:
public void PaintTabs()
{
new psTabRenderer(tclWWCModuleHost, Color.LightSteelBlue, Color.Khaki, Color.Black, Color.Black);
FrmWwcMemberHost.PaintTabs();
FrmWwcMcpHost.PaintTabs();
FrmCaseNotes.PaintTabs();
}
a source to share