Archive: Change BG color for NSISDL download file static control


Change BG color for NSISDL download file static control
I am trying to change the color for all my dialogs into white. The only thing I could not do was to change the background color for the static control text in the NSISDL download component (downloading file speed ... etc etc).

Does anyone have an idea how such a thing can be done?

Thanks in advance.


I was looking at NSISdl source and I found that this control doesn't have an ID, so you can't use GetDlgItem to paint the control. (this means, the control can only be accessed by the plugin itself)


Thanks deguix, this is what I am trying to do now: in file nsisdl.cpp, function download, after these lines
// set initial text
char *p = filename;
while (*p) p++;
while (*p != '\\' && p != filename) p = CharPrev(filename, p);
wsprintf(buf, szDownloading, p != filename ? p + 1 : p);
SetDlgItemText(childwnd, 1006, buf);
SetWindowText(g_hwndStatic, szConnecting);


I added the following lines

HDC hdcStatic = GetDC(g_hwndStatic);
SetBkMode(hdcStatic, OPAQUE);
SetBkColor(hdcStatic, RGB(255,255,255)); // i want it changed to white
LOGBRUSH lh;
lh.lbColor = RGB(255,255,255);
lh.lbStyle = BS_SOLID;
CreateBrushIndirect(&lh);

Still it doesn't work :(

Duz anyone have any idea what am I doing wrong?


Those messages are for the WM_PAINT, or WM_CTLCOLORSTATIC....

You don't need to get the DC, the DC is in the WM_CTLCOLORSTATIC from ParentWndProc message ...


The recommended solution would be:

- Adding a new control to 106 dialog resource.
- Making the plugin to use this control instead of creating a new one.

This would allow NSIS to use this control.


it should b possible to get the handle to a dialog even if it has no id, use FindWindow with the childafter parameter


Why not re-compile nsisdl and assign an ID? These way can be used with GetDlgItem from NSIS.

Another recommendation :D


Thanks Lobo Lunar, deguix and Anders

I can not use FindWindow because the control is not created until I make the NSISDL:download command. Placing the findwindow before or after the statement would be useless.

Also assigning an ID would not do the trick for the same reason.

The suggestion by deguix seems the only viable choice, but I was hoping to find something a bit less complicated, maybe plant a few statements inside the NSISdl code. All I need to do is turn the background color into white, and I don't mind hard coding the color there ;)

In any case, Thank you for all your replies, I appreciate you taking the time to answer :)

Still, I wonder if someone can come up with any other ideas. If someone does please do not hold back :)


Also assigning an ID would not do the trick for the same reason.
Now I'll explain simply:

1)Open an UI with Resource Hacker.

2)Go to dialog 106.

3)Create a new static control with an unique ID. Also, position it where you want it to be. Remove the flag "WS_VISIBLE" so it will be hidden initially. The recommended position is:

x1 = 0

x2 = wndRect.right (266 for Default UI, 300 for Modern UI)

y1 = wndRect.bottom / 2 + (ctlRect.bottom - ctlRect.top) / 2 (70 for Default UI w/ 10 for control height, 75 for Modern UI w/ 10 for control height)

y2 = y1 + (ctlRect.bottom - ctlRect.top) (80 for Default UI w/ 10 for control height, 85 for Modern UI w/ 10 for control height)


4)Save and exit the program.

5)Open a program to edit "nsisdl.cpp"

6)Search for "HWND hwndS = GetDlgItem(childwnd, 1006);".

7)Add this code below that line you found:

HWND s = g_hwndStatic = GetDlgItem(childwnd, YourUniqueID);
So it can recognize that the control is located in a resource. (Replace "YourUniqueID" with the ID of the control you added)

8)Search for the line "hwndB = NULL;"

9)Add this code below that line you found:

        if (IsWindowVisible(g_hwndStatic))
ShowWindow(g_hwndStatic, SW_SHOWNA);
else
s = g_hwndStatic = NULL;
This enables the control to show when the user calls NSISdl::download function.

And also enables you to remove this control from the resource so the details won't appear anymore.

10)Then search for "HWND s = g_hwndStatic = CreateWindow"

11)Delete entirely the CreateWindow function. We don't want to create a control that already exists...

12)Search for "if (hwndL)"

13)Below "}", add this piece of code:

      if (g_hwndStatic)
{
ShowWindow(hwndL, SW_HIDE);
s = g_hwndStatic = NULL;
}
So it will hide the control after the user clicked "cancel".

14)Search for "DestroyWindow(g_hwndStatic);"

15)Remove this code:

      if (g_hwndStatic)
{
DestroyWindow(g_hwndStatic);
g_hwndStatic = NULL;
}
We don't need to destroy the control, as the plugin didn't create it.

16) Compile and test it for errors.

17) Color the control on sections or functions derived of sections as you normally would.

Ok, another one:

You can try subclassing the static's hwnd.


Thanks deguix and Lobo Lunar :)

I followed the steps spelled out by deguix and it worked (with a few changes).


That was a very well written tutorial :D

-Stu


That I've done was only a basic concept and I didn't test it before... (you had to do some changes by yourself though)