26

I am trying to change my application' s title bar and border colors programmatically. I tried lots of things but with no success, and decided to change these colors system-wide. Because it is also acceptable for me to change title bar and border colors as my application is running, and revert them back in the end of my application. (Managed environment, with small set of applications running)

Is it possible to change these colors dynamically(process-wide, or system-wide unless process-wide change is possible)? Can you suggest any way to achieve this?

I tried something like the following but it doesn' t do what I want:

int aElements[2] = {COLOR_WINDOW, COLOR_ACTIVECAPTION};
DWORD aOldColors[2];
DWORD aNewColors[2];

aOldColors[0] = GetSysColor(aElements[0]); 
aOldColors[1] = GetSysColor(aElements[1]); 
aNewColors[0] = RGB(0x80, 0x80, 0x80);  // light gray 
aNewColors[1] = RGB(0x80, 0x00, 0x80);  // dark purple 

SetSysColors(2, aElements, aNewColors);
SetSysColors(2, aElements, aOldColors);

Thanks in advance

EDIT

This is exactly what I want:

enter image description here

15

3 Answers 3

4

I don't recommend to customize border and title redrawing. It's really hard to do it the right way. Office just draws everything by itself in the client area but using normal border. Using NC_PAINT the right way is a pain and may introduce flickering. Especially positioning the minimize,maximize and close buttons is difficult, because every windows does it differently. Also take into account accessibility, larger fonts used, customized user settings.

Whats the purpose of changing the colors?

To change the global colors you have to at least separate your code

// call this once at startup of your application (e.g. in WM_CREATE)

SetSysColors(2, aElements, aNewColors); 

// call this when closing you application (e.g. in WM_DESTROY)

SetSysColors(2, aElements, aOldColors); 
Sign up to request clarification or add additional context in comments.

Comments

3

I know you are using C++, but I am handy with C#. So that you may get some idea, take look at the following code, which modifies form appearance.

[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("User32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hWnd);

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    const int WM_NCPAINT = 0x85;
    if (m.Msg == WM_NCPAINT)
    {
        IntPtr hdc = GetWindowDC(m.HWnd);
        if ((int)hdc != 0)
        {
            Graphics g = Graphics.FromHdc(hdc);
            g.FillRectangle(Brushes.Green, new Rectangle(0, 0, 4800, 23));
            g.Flush();
            ReleaseDC(m.HWnd, hdc);
        }
    }
}

Also, you could use the Drawing Custom Borders in Windows Forms project from CodePlex. This project is a tiny library that allows users to customize Windows Forms, like customizing a windows' non-client area.

6 Comments

Can you explain why this answer is not useful? I clearly mentioned that from this code block you can get some idea.
Mark as answer if this suggestion is helpful.
Disclaimer: I've cast no vote. However, reasons I imagine this answer has been beaten-up include (a) No return value. (b) Calls the rough equivalent of DefWindowProc before painting over - does this not obscure the buttons? (c) Makes no reference to the HRGN passed with the WM_NCPAINT (d) uses hard-coded values for the size of the rect to paint (and also paints over the client area) (e) code really very different to C++ code, the use of the GDI+ Graphics class is almost the only thing in common. (f) appears to be for rep points for you rather than an answer for the OP.
This code just doesn' t do anything in Win8.1. I saw this approach on the internet and tried this one, but Desktop Window Manager doesn' t allow this kind of code to make any change on the window titles, or borders (Actually any non-client area object) I believe this won' t do anything on the systems running Vista or higher
This answer is just give some idea regrading customizing form title bar. Please look at geekswithblogs.net/kobush/articles/CustomBorderForms.aspx again I am not that much handy with C++ so sharing other language example.
|
2

Remove the second SetSysColors(2, aElements, aOldColors); line of code, which reverts back to the orignal color and then try again. The code example you have seems almost identical to the MSDN link https://msdn.microsoft.com/en-us/library/windows/desktop/ms724940%28v=vs.85%29.aspx link minus the sleep. Their example shows how to set color, sleeps and then reverts back.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.