Thread: SetClassLong changes are delayed

  1. #1
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465

    SetClassLong changes are delayed

    I have this code to change the background of a window:

    Code:
    			HBRUSH hBrush = NULL;
    			switch(LOWORD(wParam))
    			{
    
    				//
    				// ... some other stuff ...
    				//
    
    				case IDM_RED: hBrush = ::CreateSolidBrush(RGB(0xFF, 0x00, 0x00)); break;
    				case IDM_YELLOW: hBrush = ::CreateSolidBrush(RGB(0xFF, 0xFF, 0x00)); break;
    				case IDM_BLACK: hBrush = ::CreateSolidBrush(RGB(0x00, 0x00, 0x00)); break;
    				case IDM_WHITE: hBrush = ::CreateSolidBrush(RGB(0xFF, 0xFF, 0xFF)); break;
    				case IDM_GREEN: hBrush = ::CreateSolidBrush(RGB(0x00, 0xFF, 0x00)); break;
    				case IDM_BLUE: hBrush = ::CreateSolidBrush(RGB(0x00, 0x00, 0xFF)); break;
    			}
    			if(hBrush)
    			{
    				::SetClassLong(hwnd, GCL_HBRBACKGROUND, (long) hBrush);
    			}
    However, the background color only changes when I go away and come back to the window. MSDN warned of this sort of thing like delayed repainting or something, but I was not sure of a remedy. Also, it says that this function was superceded by SetClassLongPtr(..) but when I tried to use it it said it was undeclared even when I put

    Code:
    #define _WIN32_WINNT 0x501
    #include <windows.h>
    Any ideas for that?

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Did you try putting:
    Code:
    InvalidateRect(hwnd,NULL,true);
    UpdateWindow(hwnd);
    After you call SetClassLong to change the background color?

    And I don't know why you're getting the undeclared error for SetClassLongPtr; it works for me without defining _WIN32_WINNT.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    That works, thank you. Why it is not working is probably because I have VC6

    I have one more small related question related to the deletion of these brushes. MSDN says:

    Quote Originally Posted by MSDN
    The system automatically deletes class background brushes when the class is unregistered by using UnregisterClass. An application should not delete these brushes.
    If I am replacing these brushes one by another changing the color of the background, should I be applying DeleteObject(..) to them as I recieve them from the return of SetClassLong?

  4. #4
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    >>Why it is not working is probably because I have VC6<<

    Any of the psdk from the last few years should have it defined.

    >>should I be applying DeleteObject<<

    If you're using more than one brush, yes - it's definitely a good habit to delete what you create anyway, even though gdi objects etc. are automatically released by the system, except for win9x, when your application closes, whether you manually invoke UnregisterClass or not.

    I take it your intention is to affect all windows of a specific window class, which SetClassLong/Ptr will do, rather than just a specific window?
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  5. #5
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    >> I take it your intention is to affect all windows of a specific window class, which SetClassLong/Ptr will do, rather than just a specific window?

    Not necessarily, but it just so happens that I only have one window of that class. I might look into something like ::FillRect(..) on the client area instead I guess. Thank you for the help.

  6. #6
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Okay. I now am experiencing trouble which I has something to do with device-contexts and confuses me. I now am using FillRect to paint the window, and unfortunently now whenever it encounters a repaint, it repaints it the default class color instead of remembering what I have done to the DC. Here is the code:

    Code:
    				if(hBrush)
    				{
    					HDC hDC = ::GetDC(hwnd);
    					RECT cR;
    					
    					::GetClientRect(hwnd, &cR);
    					::FillRect(hDC, &cR, hBrush);
    					
    
    					::DeleteObject(hBrush);
    					::ReleaseDC(hwnd, hDC);
    				}
    Could I get any advice or some buzzwords?

  7. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    The background painting using the class brush is done in the handling of WM_ERASEBKGND by DefWindowProc. This means that you should either you a class background brush of NULL (in which case no background painting will be done by DefWindowProc) or override the WM_ERASEBKGND message and do your own background painting.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Delayed cin?
    By ranko_6 in forum C++ Programming
    Replies: 2
    Last Post: 04-25-2007, 01:14 PM
  2. Delayed Replacement Sort
    By Cpro in forum C++ Programming
    Replies: 3
    Last Post: 04-12-2007, 03:36 PM
  3. Delayed Functions?
    By suzumebachi in forum C++ Programming
    Replies: 4
    Last Post: 03-09-2005, 01:26 PM