Share via


Changing Background color by using button (Win32 API)

Question

Tuesday, June 12, 2012 8:51 AM

i have tried a lot of time by using WM_ERASEBKGND,

and found that SetBkColor is only for rectangle???

i have learnt C++ before but i have not learnt any coding of window application interface.

i hope that someone can help me with present of code.

my code is below:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

int wmId, wmEvent;

PAINTSTRUCT ps;

HDC hdc;

 

TCHAR helloWorld[] = _T(

"Hello World!");

switch (message)

{

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: Add any drawing code here...

SetBkColor(hdc, windowBackgroundColor);

TextOut(hdc, 360, 250, helloWorld, _tcslen(helloWorld));

EndPaint(hWnd, &ps);

break;

case WM_COMMAND:

wmId = LOWORD(wParam);

wmEvent = HIWORD(wParam);

 

// Parse the menu selections:

switch (wmId)

{

case IDM_ABOUT:

DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

break;

case IDM_EXIT:

DestroyWindow(hWnd);

break;

case BTN_MYBUTTON_ID:

// Your code here.

WM_ERASEBKGND;

WNDCLASSEX wcex;

windowBackgroundColor = RGB(0xff, 0xff, 0x00);

windowBackgroundBrush = CreateSolidBrush(windowBackgroundColor);

wcex.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

 

MessageBox(hWnd, L

"Background color was changed!", L"Message", MB_OK);

 

break;

 

default:

return DefWindowProc(hWnd, message, wParam, lParam);//This function ensures that every message is processed

}

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

:

All replies (8)

Tuesday, June 12, 2012 10:39 AM ✅Answered | 3 votes

If you want to change the background color you must handle the WM_ERASEBKGND message. In the example I posted here I will change the background color when I select the menu item with the ID_TEST:

// ColorBkGnd.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "ColorBkGnd.h"#define MAX_LOADSTRING 100// Global Variables:HINSTANCE hInst;                             // current instanceTCHAR szTitle[MAX_LOADSTRING];                   // The title bar textTCHAR szWindowClass[MAX_LOADSTRING];           // the main window class nameCOLORREF bkgndcolor;// Forward declarations of functions included in this code module:ATOM             MyRegisterClass(HINSTANCE hInstance);BOOL               InitInstance(HINSTANCE, int);LRESULT CALLBACK   WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPTSTR    lpCmdLine,                     int       nCmdShow){    UNREFERENCED_PARAMETER(hPrevInstance);  UNREFERENCED_PARAMETER(lpCmdLine);  // TODO: Place code here.   MSG msg;    HACCEL hAccelTable; // Initialize global strings    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);  LoadString(hInstance, IDC_COLORBKGND, szWindowClass, MAX_LOADSTRING);   MyRegisterClass(hInstance); // Perform application initialization:  if (!InitInstance (hInstance, nCmdShow))    {       return FALSE;   }   hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_COLORBKGND)); // Main message loop:   while (GetMessage(&msg, NULL, 0, 0))    {       if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))     {           TranslateMessage(&msg);         DispatchMessage(&msg);      }   }   return (int) msg.wParam;}////  FUNCTION: MyRegisterClass()////  PURPOSE: Registers the window class.////  COMMENTS:////    This function and its usage are only necessary if you want this code//    to be compatible with Win32 systems prior to the 'RegisterClassEx'//    function that was added to Windows 95. It is important to call this function//    so that the application will get 'well formed' small icons associated//    with it.//ATOM MyRegisterClass(HINSTANCE hInstance){  WNDCLASSEX wcex;    wcex.cbSize = sizeof(WNDCLASSEX);   wcex.style          = CS_HREDRAW | CS_VREDRAW;  wcex.lpfnWndProc    = WndProc;  wcex.cbClsExtra     = 0;    wcex.cbWndExtra     = 0;    wcex.hInstance      = hInstance;    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_COLORBKGND)); wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_COLORBKGND);  wcex.lpszClassName  = szWindowClass;    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex);}////   FUNCTION: InitInstance(HINSTANCE, int)////   PURPOSE: Saves instance handle and creates main window////   COMMENTS:////        In this function, we save the instance handle in a global variable and//        create and display the main program window.//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){   HWND hWnd;   hInst = hInstance; // Store instance handle in our global variable   bkgndcolor=0x00FFFFFF;   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd)   {      return FALSE;   }   ShowWindow(hWnd, nCmdShow);   UpdateWindow(hWnd);   return TRUE;}void ChangeBkGnd(HWND hWnd){  bkgndcolor=0x00FF00FF;  InvalidateRect(hWnd,NULL, TRUE);}////  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)////  PURPOSE:  Processes messages for the main window.////  WM_COMMAND   - process the application menu//  WM_PAINT  - Paint the main window//  WM_DESTROY   - post a quit message and return////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    int wmId, wmEvent;  PAINTSTRUCT ps; HDC hdc;    switch (message)    {   case WM_COMMAND:        wmId    = LOWORD(wParam);       wmEvent = HIWORD(wParam);       // Parse the menu selections:       switch (wmId)       {       case IDM_ABOUT:         DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);           break;      case IDM_EXIT:          DestroyWindow(hWnd);            break;      case ID_TEST:         ChangeBkGnd(hWnd);            default:            return DefWindowProc(hWnd, message, wParam, lParam);        }       break;  case WM_ERASEBKGND:   HPEN pen;   HBRUSH    brush;    RECT rect;              pen=CreatePen(PS_SOLID, 1, bkgndcolor);     brush=CreateSolidBrush(bkgndcolor);     SelectObject((HDC)wParam, pen);     SelectObject((HDC)wParam, brush);       GetClientRect(hWnd, &rect);         Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom);             break;  case WM_PAINT:      hdc = BeginPaint(hWnd, &ps);        // TODO: Add any drawing code here...       EndPaint(hWnd, &ps);        break;  case WM_DESTROY:        PostQuitMessage(0);     break;  default:        return DefWindowProc(hWnd, message, wParam, lParam);    }   return 0;}// Message handler for about box.INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){   UNREFERENCED_PARAMETER(lParam); switch (message)    {   case WM_INITDIALOG:     return (INT_PTR)TRUE;   case WM_COMMAND:        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)       {           EndDialog(hDlg, LOWORD(wParam));            return (INT_PTR)TRUE;       }       break;  }   return (INT_PTR)FALSE;}

I force the change of the background color in changing the default background color variable bkgndcolor I use in WM_ERASEBKGND.


Thursday, June 14, 2012 4:49 AM ✅Answered

In my very first post in the code I posted in the post there you also see a "case WM_PAINT:". This is the correct location for checking the WM_PAINT message. In your example you include the code for painting your "hello world" text at this location.

WM_PAINT has nothing to do with WM_COMMAND and therefore it does not make sense to check for a WM_PAINT in the WM_COMMAND switch construct.

Have you checked the links of the thread I posted? From the questions you are asking the problem you have sees to be very basic. What tutorial are you using or how are you trying to learn windows porgramming? A good beginner tutorial .

Here a nice begin with a lot explanations:

http://www.winprog.org/tutorial/simple_window.html

Also nice is this one:

http://winapi.foosyerdoos.org.uk/info/user_cntrls.php#SimpleWnd

http://www.functionx.com/win32/index.htm


Wednesday, June 13, 2012 3:13 AM

thank you very much. i can change the background color successfully. but i discover that i have a problem of the text background color. i have set it to my defauly setting color and after i click my button , the background color can be changed to RGB(0xff,0xff,0x00), but the text background color still not ben changed.

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

int wmId, wmEvent;

PAINTSTRUCT ps;

HDC hdc;

TCHAR helloWorld[] = _T(

"Hello World!"); //added by jay

switch (message)

{

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: Add any drawing code here...

SetBkColor(hdc, windowBackgroundColor);

//added by jay , for word block bk color

TextOut(hdc, 300, 350, helloWorld, _tcslen(helloWorld));

//added by jay

EndPaint(hWnd, &ps);

break;

case WM_COMMAND:

wmId = LOWORD(wParam);

wmEvent = HIWORD(wParam);

 

// Parse the menu selections:

switch (wmId)

{

case IDM_ABOUT:

DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

break;

case IDM_EXIT:

DestroyWindow(hWnd);

break;

case BTN_MYBUTTON_ID://added by jay

{

// Your code here.

windowBackgroundBrush = CreateSolidBrush(RGB(0xff,0xff,0x00));

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: Add any drawing code here...

SetBkColor(hdc, RGB(0xff,0xff,0x00));

//added by jay , for word block bk color

TextOut(hdc, 300, 350, helloWorld, _tcslen(helloWorld));

//added by jay

EndPaint(hWnd, &ps);

ChangeBkGnd(hWnd);

MessageBox(hWnd, L

"Background color was changed!", L"Message", MB_OK);

break;

}

case BTN_MYRADIOBUTTON_ID: //added by jay

MessageBox(hWnd, L

"Warning!", L"Message", MB_OK|MB_ICONEXCLAMATION);

break;

case BTN_MYRADIOBUTTON_ID2: //added by jay

MessageBox(hWnd, L

"You have clicked a radio button!", L"Message", MB_OK|MB_ICONASTERISK);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);//This function ensures that every message is processed

}

break;

case WM_ERASEBKGND:

HPEN pen;

HBRUSH brush;

RECT rect;

pen=CreatePen(PS_SOLID, 1, bkgndcolor);

brush=CreateSolidBrush(bkgndcolor);

SelectObject((HDC)wParam, pen);

SelectObject((HDC)wParam, brush);

GetClientRect(hWnd, &rect);

Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}


Wednesday, June 13, 2012 5:01 AM | 1 vote

thank you very much. i can change the background color successfully. but i discover that i have a problem of the text background color. i have set it to my defauly setting color and after i click my button , the background color can be changed to RGB(0xff,0xff,0x00), but the text background color still not ben changed.

I'm not really sure what your problem is. If you want to change the background color for your text output you can do it with "SetBkcolor": (Note the variable names may differ from your code!)

case WM_PAINT:    hdc = BeginPaint(hWnd, &ps);         SetBkColor(hdc, bkgndcolor);         TextOut(hdc, 300, 350, helloWorld, _tcslen(helloWorld));     EndPaint(hWnd, &ps);break;

You already did this is your code when I check your WM_PAINT code part. The strange thing is the nested WM_PAINT in your "case BTN_MYBUTTON_ID:".

You can also use

SetBkMode(hdc, TRANSPARENT) ;

to have an transparent background.


Wednesday, June 13, 2012 5:55 AM

yes i have already do this part before because i want my text bg color same as my bg color/

after that, i want to change my bg color but the text color does not be changed. I discover that there is some problem in nested WM_PAINT in your "case BTN_MYBUTTON_ID:". It is because i dont know where i need to put the code in. I just start to learn those function before 2 days.


Wednesday, June 13, 2012 6:45 AM | 1 vote

It is because i dont know where i need to put the code in. I just start to learn those function before 2 days.

That you are new in window programming is ok. We all started at this point.  :-)

Here you can find useful sources for beginners. This thread is a few days old.

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/3a485143-d4fa-410c-8dd4-17215cc6e5c9


Thursday, June 14, 2012 3:59 AM

but i really dont understand which region i need to put the "change text background color" code in.

Is it wrong that i don't need to write case WM_PAINT. it is because i want it to be happened by clicking the button. Is it wrong that i put it in to case case BTN_MYBUTTON_ID?


Friday, June 15, 2012 2:20 AM

thank you very much..

But unfortunately i need to learn MFC now. i just start to learn it in http://www.functionx.com/visualc/index.htm

Your link is very useful.