From comments, a test by overriding WM_PAINT to replace Tab Control background color (behind the Pages, the Pages using parent Form.BackColor)
(add using System.Runtime.InteropServices; at beginning and replace default TabControl class by this one named TabControlPaint ) :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Color colorBackgroundDark = Color.FromArgb(255, 32, 32, 32);
Color colorBackgroundDark = Color.FromArgb(255, 39, 39, 39);
//Color colorBackgroundDark = Color.Blue;
//Color colorBackgroundDark = SystemColors.ControlDarkDark;
private void Form1_Load(object sender, EventArgs e)
{
BackColor = colorBackgroundDark;
//button1.BackColor = Color.Black;
//button1.ForeColor = Color.White;
//textBox1.BackColor = Color.Black;
//textBox1.ForeColor = Color.White;
}
}
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(System.ComponentModel.Design.IDesigner))]
public partial class TabControlPaint : TabControl
{
public enum HRESULT : int
{
S_OK = 0,
S_FALSE = 1,
E_NOINTERFACE = unchecked((int)0x80004002),
E_NOTIMPL = unchecked((int)0x80004001),
E_FAIL = unchecked((int)0x80004005),
E_UNEXPECTED = unchecked((int)0x8000FFFF),
E_OUTOFMEMORY = unchecked((int)0x8007000E)
}
[DllImport("UxTheme.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr BeginBufferedPaint(IntPtr hdcTarget, ref RECT prcTarget, BP_BUFFERFORMAT dwFormat, IntPtr pPaintParams, out IntPtr phdc);
public enum BP_BUFFERFORMAT
{
BPBF_COMPATIBLEBITMAP,
BPBF_DIB,
BPBF_TOPDOWNDIB,
BPBF_TOPDOWNMONODIB
}
[DllImport("UxTheme.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern HRESULT EndBufferedPaint(IntPtr hBufferedPaint, bool fUpdateTarget);
[DllImport("UxTheme.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern HRESULT BufferedPaintInit();
[DllImport("UxTheme.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern HRESULT BufferedPaintUnInit();
[DllImport("User32.dll", SetLastError = true)]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int Left, int Top, int Right, int Bottom)
{
left = Left;
top = Top;
right = Right;
bottom = Bottom;
}
}
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeleteObject(IntPtr ho);
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateSolidBrush(int crColor);
[DllImport("Msimg32.dll", SetLastError = true)]
public static extern bool TransparentBlt(IntPtr hdcDest, int xoriginDest, int yoriginDest, int wDest, int hDest, IntPtr hdcSrc, int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, uint crTransparent);
[DllImport("Gdi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
public const int SRCCOPY = 0x00CC0020;
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool FillRect(IntPtr hdc, [In] ref RECT rect, IntPtr hbrush);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint msg, int wParam, IntPtr lParam);
public const int WM_PRINT = 0x0317;
public const int WM_PRINTCLIENT = 0x0318;
public const int PRF_CHECKVISIBLE = 0x00000001;
public const int PRF_NONCLIENT = 0x00000002;
public const int PRF_CLIENT = 0x00000004;
public const int PRF_ERASEBKGND = 0x00000008;
public const int PRF_CHILDREN = 0x00000010;
public const int PRF_OWNED = 0x00000020;
[DllImport("User32.dll", SetLastError = true, ExactSpelling = true, EntryPoint = "BeginPaint", CharSet = CharSet.Auto)]
private static extern int BeginPaint(IntPtr hWnd, [In, Out] ref PAINTSTRUCT lpPaint);
[DllImport("User32.dll", SetLastError = true, ExactSpelling = true, EntryPoint = "EndPaint", CharSet = CharSet.Auto)]
private static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
[StructLayout(LayoutKind.Sequential)]
public struct PAINTSTRUCT
{
public IntPtr hdc;
public bool fErase;
public int rcPaint_left;
public int rcPaint_top;
public int rcPaint_right;
public int rcPaint_bottom;
public bool fRestore;
public bool fIncUpdate;
public int reserved1;
public int reserved2;
public int reserved3;
public int reserved4;
public int reserved5;
public int reserved6;
public int reserved7;
public int reserved8;
}
public const int WM_PAINT = 0x000F;
public TabControlPaint()
{
BufferedPaintInit();
//this.SetStyle(ControlStyles.UserPaint, true);
this.DrawMode = TabDrawMode.OwnerDrawFixed;
this.DrawItem += new System.Windows.Forms.DrawItemEventHandler(tabControl_DrawItem);
}
protected override void OnCreateControl()
{
base.OnCreateControl();
((Form)this.Parent).Closing += new CancelEventHandler(Parent_Closing);
((Form)this.Parent).Load += Parent_Load;
}
private void Parent_Load(object sender, EventArgs e)
{
foreach (TabPage tp in this.TabPages)
{
tp.BackColor = this.Parent.BackColor;
}
}
private void Parent_Closing(object sender, CancelEventArgs e)
{
BufferedPaintUnInit();
}
private void tabControl_DrawItem(object sender, DrawItemEventArgs e)
{
TabControl tc = (TabControl)sender;
TabPage tp = tc.TabPages[e.Index];
SolidBrush backBrush = (e.State == DrawItemState.Selected) ? new SolidBrush(tp.BackColor) : new SolidBrush(Color.Black);
e.Graphics.FillRectangle(backBrush, e.Bounds);
Rectangle rectBounds = e.Bounds;
int nYOffset = (e.State == DrawItemState.Selected) ? -1 : 1;
rectBounds.Offset(1, nYOffset);
Color textColor = (e.State == DrawItemState.Selected) ? Color.White : Color.LightGray;
Color backColor = this.Parent.BackColor;
if (backColor == SystemColors.Control)
textColor = (e.State == DrawItemState.Selected) ? Color.Black : Color.LightGray;
TextRenderer.DrawText(e.Graphics, tp.Text, e.Font, rectBounds, textColor);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_PAINT)
{
PAINTSTRUCT ps = new PAINTSTRUCT();
IntPtr hDC = (IntPtr)BeginPaint(m.HWnd, ref ps);
IntPtr targetDC = hDC;
IntPtr bufferedDC = IntPtr.Zero;
HRESULT hr = HRESULT.S_OK;
RECT rectClient;
GetClientRect(this.Handle, out rectClient);
IntPtr pb = BeginBufferedPaint(targetDC, ref rectClient, BP_BUFFERFORMAT.BPBF_TOPDOWNDIB, IntPtr.Zero, out bufferedDC);
IntPtr hDCMem = CreateCompatibleDC(hDC);
IntPtr hBitmap = CreateCompatibleBitmap(hDC, rectClient.right - rectClient.left, rectClient.bottom - rectClient.top);
IntPtr hBitmapOld = SelectObject(hDCMem, hBitmap);
// Copie control image into Memory DC with custom color as background
IntPtr hBrush1 = CreateSolidBrush(ColorTranslator.ToWin32(Color.FromArgb(255, 255, 254, 255)));
FillRect(hDCMem, ref rectClient, hBrush1);
DeleteObject(hBrush1);
SendMessage(this.Handle, WM_PRINTCLIENT, (int)hDCMem, (IntPtr)PRF_CLIENT);
IntPtr hDCMem2 = CreateCompatibleDC(hDC);
IntPtr hBitmap2 = CreateCompatibleBitmap(hDC, rectClient.right - rectClient.left, rectClient.bottom - rectClient.top);
IntPtr hBitmapOld2 = SelectObject(hDCMem2, hBitmap2);
// Custom color => Back color
IntPtr hBrush2 = CreateSolidBrush(ColorTranslator.ToWin32(this.Parent.BackColor));
FillRect(hDCMem2, ref rectClient, hBrush2);
DeleteObject(hBrush2);
TransparentBlt(hDCMem2, 0, 0, rectClient.right - rectClient.left, rectClient.bottom - rectClient.top, hDCMem, 0, 0,
rectClient.right - rectClient.left, rectClient.bottom - rectClient.top, (uint)ColorTranslator.ToWin32(Color.FromArgb(255, 255, 254, 255)));
BitBlt(bufferedDC, 0, 0, rectClient.right - rectClient.left, rectClient.bottom - rectClient.top, hDCMem2, 0, 0, SRCCOPY);
SelectObject(hDCMem, hBitmapOld);
DeleteObject(hBitmap);
DeleteDC(hDCMem);
SelectObject(hDCMem2, hBitmapOld2);
DeleteObject(hBitmap2);
DeleteDC(hDCMem2);
hr = EndBufferedPaint(pb, true);
EndPaint(m.HWnd, ref ps);
m.Result = IntPtr.Zero;
}
else
base.WndProc(ref m);
}
}