NO

Author Topic: How do I change the text and background color of a text box?  (Read 28956 times)

tpekar

  • Guest
I have tried using SetTextColor but I must be doing something wrong.  Here is my code:

#include <windows.h>
#include <stdio.h>
#define ID_MYBUTTON 101
#define ID_TAB 201
#define WM_CTLCOLORDLG                  0x0136


LPSTR szClassName = "MyClass";
HINSTANCE hInstance;
LRESULT CALLBACK MyWndProc(HWND, UINT, WPARAM, LPARAM);
HWND hwndText[3];
FILE *fp;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
   WNDCLASS wnd;
   MSG msg;
   HWND hwnd;
   HWND hWndBtn1;

   hInstance = hInst;
       
   wnd.style = CS_HREDRAW | CS_VREDRAW; //we will explain this later
   wnd.lpfnWndProc = MyWndProc;
   wnd.cbClsExtra = 0;
   wnd.cbWndExtra = 0;
   wnd.hInstance = hInstance;
   wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); //default icon
   wnd.hCursor = LoadCursor(NULL, IDC_ARROW);   //default arrow mouse cursor
   wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW);
   wnd.lpszMenuName = NULL;                     //no menu
   wnd.lpszClassName = szClassName;

   if(!RegisterClass(&wnd))                     //register the WNDCLASS
   {
       MessageBox(NULL, "This Program Requires Windows NT",
                        "Error", MB_OK);
       return 0;
   }

   hwnd = CreateWindow(szClassName,
                       "Window Title",
                       WS_OVERLAPPEDWINDOW, //basic window style
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,       //set starting point to default value
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,       //set all the dimensions to default value
                       NULL,                //no parent window
                       NULL,                //no menu
                       hInstance,
                       NULL);               //no parameters to pass
 
 
// create a text box and store the handle                                                       

         hwndText[0] = CreateWindow(
                               TEXT("edit"),                              // The class name required is edit
                               TEXT("Enter text here"),                                 // Default text.
                               WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, // the styles
                               100,100,                                      // the left and top co-ordinates
                               300,30,                                  // width and height
                               hwnd,                                     // parent window handle
                               (HMENU) ID_TAB,                         // the ID of your combobox
                               hInstance,                                // the instance of your application
                               NULL
                            );                                   // extra bits you dont really need
     
         hwndText[1] = CreateWindow(
                               TEXT("edit"),                              // The class name required is edit
                               TEXT("2nd field"),                                 // Default text.
                               WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | ES_PASSWORD, // the styles
                               100,200,                                      // the left and top co-ordinates
                               300,30,                                  // width and height
                               hwnd,                                     // parent window handle
                               NULL,                         // the ID of your combobox
                               hInstance,                                // the instance of your application
                               NULL
                            );                                   // extra bits you dont really need
       
       
   SetWindowText(hwndText[0],"revised"); 
   SetFocus(hwndText[0]);
   CreateWindow(TEXT("STATIC"), TEXT("Text1:"), WS_CHILD|WS_VISIBLE, 25, 100, 55, 22, hwnd, 0, hInstance, 0);
   hWndBtn1 = CreateWindow(TEXT("BUTTON"), TEXT("Update"), WS_CHILD|WS_VISIBLE, 5, 5, 55, 22, hwnd, (HMENU) ID_MYBUTTON, hInstance, 0);
   HDC hdc = GetDC(hwndText[0]);
         SetTextColor(hdc, RGB(255,0,0)); // red
         SetBkColor(hdc, RGB(255,255,0)); // yellow
   ShowWindow(hwnd, iCmdShow);              //display the window on the screen
   UpdateWindow(hwnd);             //make sure the window is updated correctly

   while(GetMessage(&msg, NULL, 0, 0))      //message loop
   {

      if (!IsDialogMessage(hwnd, &msg)) {
       
      TranslateMessage(&msg);
        DispatchMessage(&msg);
     }
   }
   return msg.wParam;
}



LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

 char data[256];
 HDC hdc;
  switch(msg)
   {
       

        case WM_CTLCOLORDLG:
            hdc = GetDC(hwndText[0]);
         SetTextColor(hdc, RGB(255,0,0)); // red
         SetBkColor(hdc, RGB(255,255,0)); // yellow
      break;
      
      case WM_CTLCOLOREDIT: // Never use this code in WM_PAINT.
         hdc = GetDC(hwndText[0]);
         SetTextColor(hdc, RGB(255,0,0)); // red
         SetBkColor(hdc, RGB(255,255,0)); // yellow
      break;
      case WM_COMMAND:

         
       if(ID_MYBUTTON == LOWORD(wParam))
          {         
         if (BN_CLICKED==HIWORD(wParam)) {
           GetWindowText(hwndText[0],data,255);
             MessageBox(hwnd,data,"notice",MB_OK);
                       
           if ((fp=fopen("tom","w"))==NULL)
                     MessageBox(hwnd,"could not open wikiwin.txt","error",MB_OK);
          fprintf(fp,"%s\n",data);
          fclose(fp);
          ShowWindow(hwndText[1],SW_HIDE); // hide the window
             ShowWindow(hwndText[1],SW_SHOW); // show the hidden window again
         }
          }

          break;
      case WM_DESTROY:
           
           PostQuitMessage(0);
           return 0;
   }
   return DefWindowProc(hwnd, msg, wParam, lParam);
}

CommonTater

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #1 on: June 24, 2011, 01:05:06 AM »
You need to respond to the WM_CTLCOLOREDIT message....

The procedure...
Code: [Select]
// colour control
LRESULT SetColors(HDC dc,HWND win)
  { SetTextColor(dc,GetSysColor(COLOR_WINDOWTEXT));
     SetBkMode(dc,OPAQUE);
     SetBkColor(dc,GetSysColor(COLOR_WINDOW));
     return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_WINDOW)); }
 

and In the message handler...
Code: [Select]
        case WM_CTLCOLOREDIT :
           return SetColors((HDC)wparm,(HWND)lparm);
« Last Edit: June 24, 2011, 01:06:54 AM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: How do I change the text and background color of a text box?
« Reply #2 on: June 24, 2011, 06:59:54 AM »
For that example:
Code: [Select]
case WM_CTLCOLOREDIT:
hdc = (HDC)wParam;
SetTextColor(hdc, RGB(255, 0, 0)); // red
SetBkColor(hdc, RGB(255, 255, 0)); // yellow
return (LRESULT)CreateSolidBrush(RGB(255, 255, 0));
May the source be with you

tpekar

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #3 on: June 24, 2011, 03:30:35 PM »
That worked.  Thanks.  But it changed all my text boxes.  How can I change just one?

CommonTater

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #4 on: June 24, 2011, 04:05:29 PM »
That worked.  Thanks.  But it changed all my text boxes.  How can I change just one?

You have to make it sensitive to the window handle... If you note my example function includes HWND in it's parameters and it is passed out of the switch() by the function call.  Inside the function you can just do this...
Code: [Select]
// colour control
LRESULT SetColors(HDC dc,HWND win)
  { if (win != MyChangeHandle)
       return 0;

     SetTextColor(dc,GetSysColor(COLOR_WINDOWTEXT));
     SetBkMode(dc,OPAQUE);
     SetBkColor(dc,GetSysColor(COLOR_WINDOW));
     return (LRESULT)CreateSolidBrush(GetSysColor(COLOR_WINDOW)); }

This, btw is why I suggested you not put code in switch() statements... it's just so much easier to alter and maintain when it's compartmentalized as function calls...


Offline DMac

  • Member
  • *
  • Posts: 272
Re: How do I change the text and background color of a text box?
« Reply #5 on: June 24, 2011, 04:34:49 PM »
A similar question came up a short while ago.  I posted a demo on that thread that shows a technique for changing the color of the text box that has the focus.

http://forum.pellesc.de/index.php?topic=3713.msg13789#msg13789
No one cares how much you know,
until they know how much you care.

CommonTater

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #6 on: June 24, 2011, 04:43:13 PM »
A similar question came up a short while ago.  I posted a demo on that thread that shows a technique for changing the color of the text box that has the focus.

http://forum.pellesc.de/index.php?topic=3713.msg13789#msg13789

Interresting... gotta try that one out.  Thanks!

tpekar

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #7 on: June 24, 2011, 05:34:03 PM »
Thanks.  I was able to get the GetFocus example to work.  Sorry for my code being so messy.  I am trying to learn the Windows API.  I have an IBM AS/400 background.  I have found the Microsoft documentation hard to follow.  What I am trying to do is change a field to red if the user makes an invalid entry.  However, in some cases like a state code and a zip code may disagree.  One of the two is wrong.  In this case I want to make both text boxes red and set the focus to the first one.  Also, I am wanting to equate the escape key to clicking the red X in the upper right hand corner (to close the window).

tpekar

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #8 on: June 24, 2011, 07:38:12 PM »
I was able to get my program to set the color for a text box that was not the focus as follows:

       case WM_CTLCOLOREDIT:
                if (lParam==(long)hwndText[0] && update>0) {
             hdc = (HDC)wParam;
              
            SetTextColor(hdc, RGB(0, 0, 0));   // black
             SetBkColor(hdc, RGB(255, 0, 0));   // red
             return (LRESULT)CreateSolidBrush(RGB(255, 0, 0)); // red
           }

   case WM_COMMAND:
       if(ID_MYBUTTON == LOWORD(wParam)) {
                             if (BN_CLICKED==HIWORD(wParam)) {
                     if ((fp=fopen("wikiwin.txt","w"))==NULL)
                     MessageBox(hwnd,"could not open wikiwin.txt","error",MB_OK);
          fprintf(fp,"%s\n",data);
          fclose(fp);
          update=1; // this is what I want to trigger color change to text field
                                         }
                                 }

My problem is that the text field does not change color till I click into it or tab into it.  How can I make it happen as soon as the button is clicked?

Offline DMac

  • Member
  • *
  • Posts: 272
Re: How do I change the text and background color of a text box?
« Reply #9 on: June 24, 2011, 09:18:26 PM »
       case WM_CTLCOLOREDIT:
                if (lParam==(long)hwndText[0] && update>0) {
             hdc = (HDC)wParam;
              
            SetTextColor(hdc, RGB(0, 0, 0));   // black
             SetBkColor(hdc, RGB(255, 0, 0));   // red
             return (LRESULT)CreateSolidBrush(RGB(255, 0, 0)); // red
           }
Although this is not related to your question I spotted a red flag in the above code.  The function CreateSolidBrush() allocates resources that you must free when you are finished with them.  You now have a memory leak that can be easily avoided by using the following handy function (borrowed from BCX the Basic to C compiler.)
Code: [Select]
static HBRUSH SetColor(HDC hdc, COLORREF TxtColr, COLORREF BkColr)
{
static HBRUSH ReUsableBrush;
DeleteObject(ReUsableBrush);
ReUsableBrush = CreateSolidBrush(BkColr);
SetTextColor(hdc, TxtColr);
SetBkColor(hdc, BkColr);
return ReUsableBrush;
}
It is implemented as follows:
Code: [Select]
      case WM_CTLCOLOREDIT:
        if (lParam==(long)hwndText[0] && update>0) {
    hdc = (HDC)wParam;
     return SetColor(hdc, 0, RGB(255, 0, 0)); //black and red
  }
No one cares how much you know,
until they know how much you care.

CommonTater

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #10 on: June 24, 2011, 10:05:29 PM »
Although this is not related to your question I spotted a red flag in the above code.  The function CreateSolidBrush() allocates resources that you must free when you are finished with them.

I believe the DefWindProc() expects a brush handle and disposes of it itself when finished drawing... 
That is to say when checking my code, I've never seen a memory leak because of this...


« Last Edit: June 24, 2011, 10:07:01 PM by CommonTater »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: How do I change the text and background color of a text box?
« Reply #11 on: June 25, 2011, 07:53:07 AM »
http://msdn.microsoft.com/en-us/library/bb761691
Quote
Remarks

If the application returns a brush that it created (for example, by using the CreateSolidBrush or CreateBrushIndirect function), the application must free the brush. If the application returns a system brush (for example, one that was retrieved by the GetStockObject or GetSysColorBrush function), the application does not need to free the brush.
May the source be with you

CommonTater

  • Guest
Re: How do I change the text and background color of a text box?
« Reply #12 on: June 25, 2011, 01:36:31 PM »
http://msdn.microsoft.com/en-us/library/bb761691
Quote
Remarks

If the application returns a brush that it created (for example, by using the CreateSolidBrush or CreateBrushIndirect function), the application must free the brush. If the application returns a system brush (for example, one that was retrieved by the GetStockObject or GetSysColorBrush function), the application does not need to free the brush.

Thanks Timo....  I guess I've got a little updating to do...  The good news is that I haven't used these messages very often, preferring to stay with the windows default colors.