How do you set the background color of an existing window?
Posted on 2004-06-22 19:49:06 by msmith
If the window has an application defined class you can use SetClassLong to change the background brush for the class.

invoke CreateSolidBrush, 0FF0000h
mov , eax

invoke SetClassLong, , GCL_HBRBACKGROUND,

The brush cannot be destroyed for the life of the window or until it is replaced.
Posted on 2004-06-22 21:58:51 by donkey
Hi Donkey,

Thanks as usual.

Is it necessary to destroy the brush before ending the program.
Posted on 2004-06-22 23:18:04 by msmith
It is good programming practice however Windows will destroy it for you when your process is terminated.
Posted on 2004-06-22 23:19:01 by donkey
Hi Donkey

How do I know "If the window has an application defined class"?
Posted on 2004-06-22 23:25:11 by msmith
I think he means that you register your class with RegisterClass.
Posted on 2004-06-22 23:26:44 by roticv
Hi msmisth,

Generally it just means that it was created with RegisterClassEx and CreateWindowEx. Also the Dialog as main type windows fall into this category. If you have defined a class for the window within your program it is an application defined class. In Windows NT you can also change the brushes for global classes as they are copied to your process and you are using copies, however I generally don't like to modify global classes.
Posted on 2004-06-23 00:26:07 by donkey
Hi Donkey,

Thanks again, but still no colored window.

I tried your code and the olny error I got was due to the fact that there is no CreateSolidBrush function, just CreateSolidBrushA, and CreateSolidBrushW. So I tried CreateSolidBrushA.

No errors now, but no change in color.

Do I need WM_PAINT or something.

Thanks,

Mike
Posted on 2004-06-23 11:56:42 by msmith
You generally should destroy various objects (file handles, GDI stuff, etc) even if windows "will" destroy it at application termination. On NT most of this is "whatever", but it's still good programming practice (and will make it easier if you later need to encapsulate your application and make it "multiple windows from a single instance").

Also, 9x is _very_ sensitive to GDI leaks. I can't remember how good it is at cleaning up GDI objects on application termination, but GDI leaks inside your app can lead to VERY nasty crashes, including BSODs (first everything looks win3.x style rather than 9x style, then you get BSOD)
Posted on 2004-06-23 17:00:15 by f0dder
Hi Mike,

It should work. Remember to invalidate and update the window after you change the brush...

invoke CreateSolidBrush,0080FFFFh

invoke SetClassLongA,[hwnd],GCL_HBRBACKGROUND,eax
invoke InvalidateRect,[hwnd],NULL,TRUE
invoke UpdateWindow,[hwnd]


CreateSolidBrush is found in GDI32.DLL, there is no CreateSolidBrushA (it doesn't accept strings so no need for ANSI/UNICODE), perhaps you meant SetClassLongA
Posted on 2004-06-23 17:08:24 by donkey
Hi Donkey,

You're right, I meant SetClassLongA.



invoke CreateSolidBrush, 0FF0000h
mov [hClassBrush], eax
invoke SetClassLong, [OBMain], GCL_HBRBACKGROUND, [hClassBrush]
invoke InvalidateRect,[OBMain],NULL,TRUE
invoke UpdateWindow,[OBMain]


This still does nothing... does not change the window to blue.
Posted on 2004-06-23 18:24:01 by msmith
Hi Mike,

I am not sure what's happening with yours, here is a test project I threw together to demo it, I tested under 95 NT4 and 2K...
Posted on 2004-06-23 20:40:14 by donkey
Hi Donkey,

It tried yours and it works.

The real difference I can see is that yours uses RegisterClassExA while mine uses RegisterClass.

The docs say that the only difference concerns small icons.
Posted on 2004-06-23 21:06:50 by msmith
Hi Mike,

That is correct, it only affects the small icon, the problem is that SetClassLongA requires the WNDCLASSEX structure only available through RegisterClassExA

The SetClassLong function replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASSEX structure for the class to which the specified window belongs.
Posted on 2004-06-23 21:12:21 by donkey
Hi Donkey,

It sounds pretty plain from what you are saying that my program is not working because I am not using RegisterClassExA.

If this is true (and it seems to be), then the remark in the docs about only affecting the small icon is simply false (imagine that!). It seems it affects my ability to color the window background.

If I need to use RegisterClassExA in order to have the window accept SetClassLongA messages then there is clearly an additional difference.

Do you you know if I switch all my code to generate RegisterClassExA instead of RegisterClass I will experience any bad surprises?

Thanks,

Mike
Posted on 2004-06-23 21:22:42 by msmith
Hi Mike,

I have never used RegisterClass, it is a deprecated function left over from Win16 and I generally use the ~Ex versions of functions. However I know of no other side effect from the change.
Posted on 2004-06-23 21:46:57 by donkey
Hi Mike,

I just tried with RegisterClassA and it seems to work fine...
Posted on 2004-06-23 21:58:14 by donkey