?
Solved

api: change edit background color

Posted on 2005-05-01
19
Medium Priority
?
458 Views
Last Modified: 2010-04-05
i'm trying to change the background color of an edit control with api..

i'm trying this..

SetBkColor(GetDC(GetDlgItem(prefs_detail,USER_EDIT)),RGB(255,0,0));

but it doesn't seem to be working? any ideas?

i'm trying to duplicate the VCL Edit1.Color := clRed; not font properties.
0
Comment
Question by:gwarguitar
  • 9
  • 8
  • 2
19 Comments
 
LVL 26

Expert Comment

by:Eddie Shipman
ID: 13908945
"i'm trying to duplicate the VCL Edit1.Color := clRed"

Why? What you are doing is trying to override the VCL's painting of the Edit but
it isn't working because you are not actuallu overriding it, you are painting and
then the VCL is repainting because it needs to be.

Why are you using the API to do this anyway?
0
 

Author Comment

by:gwarguitar
ID: 13910333
because i'm not using the vcl. i'm using dialogs designed in visual studio and controlling them with api messages.

i was just giving an example of the vcl, when you set that property it changes the whole control color, not just the text background.
0
 
LVL 26

Expert Comment

by:Eddie Shipman
ID: 13910395
That was definately not clear in your original post.

Did you set the background mode to OPAQUE first?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:gwarguitar
ID: 13911457
no, i did set it to transparent? how do you set to opaque?
0
 

Author Comment

by:gwarguitar
ID: 13911521
oh, SetBkMode...

set to opaque.. now what? seems like i need to respond to a notification, was hoping just to do this with a simple message.. :)
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13911987
hello  gwarguitar, ?? you seem to think that Device Contexts are persistant, but they are not, your code

GetDC(GetDlgItem(prefs_detail,USER_EDIT))

does not get the DC the system uses to draw an Edit, to change the system DC colors used for an Edit drawing, you will need to process the  WM_CTLCOLOREDIT  message in it's parents Window Proc, I guess it's Dialog Window Proc. .


maybe something like this -


function DialogProc(hWnd, Msg, wParam, lParam: Integer): Integer; stdcall;
begin
Result := Zero {False};
case Msg of
  WM_INITDIALOG: WhatEverCode;

  WM_CTLCOLOREDIT: if lParam = Integer(GetDlgItem(prefs_detail,USER_EDIT)) then
    {pre Paint message for Edits = WM_CTLCOLOREDIT}
    begin
    {this can set the colos used for hEdit1
     the wParam is the DC for the edit}
    SetTextColor(wParam,$0000FF);
    SetBkColor(wParam,GetSysColor(COLOR_BTNHIGHLIGHT));
    Result := GetSysColorBrush(COLOR_BTNHIGHLIGHT);
    {Result is the brush used to paint NON-Text areas,
     for your colors you will need to create your brush object of that color}
     end;
  end;

end;


for some information about API Dialogs in Delphi you might look at this web page -

http://www.angelfire.com/hi5/delphizeus/dialogs.html

ask questions if you need more information
0
 

Author Comment

by:gwarguitar
ID: 13912270
that's getting closer, i get a rangecheck error on settext color..

anyhow, i'm still confused... here's what i want to do.

i have a dialog with several edit controls, they're all default color.
when the user click "OK" if an edit control is empty (i already do the check for this...) i want it to turn red.
if they click ok and the text has been filled in, i want it to go back to default..

so it's just like visual error checking is what i want to accomplish.

raised the points on this one :)
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13915156
I really do not understand your Error, how can you get a rangeCheck error on a call for SetTextColor(wParam, $CFCF00); ?
maybe
SetTextColor(Cardinal(wParam), $CFCF00);

here is my version of Fill in the Edits, this will flash the first empty (less than 2 charaters) Edit in the Dialog with 3 edits -

var   {global variables}
  hBrush1, Flash, EditID: Integer;
  ColorID: Integer = 0;



function DialogProc(hWnd, Msg, wParam, lParam: Integer): Integer; stdcall;
var
i: Integer;
begin
Result := Zero {False};
case Msg of
  WM_INITDIALOG: begin
    hBrush1 := CreateSolidBrush($FF);
    SendMessage(hWnd, WM_SETICON, 1, LoadIcon(hInstance,'MainIcon'));
    SetDlgItemText(hWnd,300,'Fill in this Edit');
    end;

  WM_CLOSE:
    begin
    EndDialog(hWnd, IDCANCEL);
    Result := 1 {True};
    end;

  WM_TIMER: if WParam = 117 then
    begin
    if Flash > 5 then
    KillTimer(hWnd,117);
    Inc(Flash);
    if ColorID = 0 then
      begin
      SetDlgItemText(hWnd,201,'ALL EDITS MUST BE FILLED');
      ColorID := EditID;
      end else
      begin
      SetDlgItemText(hWnd,201,'all edits must be filled');
      ColorID := 0;
      end;
    InvalidateRect(GetDlgItem(hWnd,EditID), nil, True);
    end;

  WM_COMMAND: if LOWORD(wParam) = IDOK then
    begin
    for i := 300 to 302 do
    if GetWindowTextLength(GetDlgItem(hWnd, i)) < 2 then
      begin
      SetTimer(hWnd, 117,700, nil);
      EditID := i;
      ColorID := i;
      Flash := 0;
      InvalidateRect(GetDlgItem(hWnd,EditID), nil, True);
      SetDlgItemText(hWnd,201,'ALL EDITS MUST BE FILLED');
      Exit;
      end;
    DeleteObject(hBrush1);
    EndDialog(hWnd, IDOK);
    Result := 1;
    end;

  WM_CTLCOLOREDIT: {pre Paint message for Edits = WM_CTLCOLOREDIT}
    if lParam = Integer(GetDlgItem(hWnd,ColorID)) then
    begin
    SetTextColor(wParam,$CFCF00);
    SetBkColor(wParam,$FF);
    Result := hBrush1;
    end;
  end;

end;


 = = = = = = = = = = = = = = = = = = = = = = = = = = =

here is the EditDlg1.rc  resource creation code for the Dialog


EditDlg DIALOG  12, 10, 116, 80
     STYLE WS_POPUP | WS_DLGFRAME | WS_CAPTION | WS_SYSMENU
     CAPTION " Fill in the Edits"
     FONT 10, "MS Sans Serif"
     {
     CTEXT "This is an EDIT Dialog"     200, 10, 1, 102, 10
     LTEXT "Please Fill ALL Edits"  201, 5, 12, 196, 10
     EDITTEXT      300, 4, 23, 108, 10
     EDITTEXT      301, 4, 34, 108, 10
     EDITTEXT      302, 4, 45, 108, 10
     DEFPUSHBUTTON "&OK"   IDOK, 43, 62, 32, 12, WS_GROUP
     }


= = = = = = = = = = = = = = = = = = = = = = = = = = =

and the call to shoe the dialog

if DialogBox(hInstance, 'EditDlg', hForm1, @DialogProc) = IDOK then

 = = = = = = = = = = = = = = = = = = =  = =

this code works for me
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13915198
forgot the deleteObject, , change the close code to -

  WM_CLOSE:
    begin
    DeleteObject(hBrush1);
    EndDialog(hWnd, IDCANCEL);
    Result := 1 {True};
    end;
0
 

Author Comment

by:gwarguitar
ID: 13939175
hmm... still not quite working...

sorry to be a pain in the ass :)

could you maybe write a function like this...

procedure ChangeControlColor(hDlg : hwnd; nIDDlgItem : Integer, color: cardinal);
begin
 change the color of GetDlgItem(hdlg,nIDDlgItem) to color
end;

severe psuedo code :)

increased points again since i suck. hehe
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13940166
no I can not, there is no API to just change the color of Edit controls, that I know of, sorry. . .
many (most) standard API system controls do not have a "Color" attribute, I wonder why you think they would?
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13940204
let me state that in API, if you want to change an Edits color in the system draw you will need to handle the WM_CTLCOLOREDIT message in it's parent's Window Proc as in the code below


WM_CTLCOLOREDIT: {pre Paint message for Edits = WM_CTLCOLOREDIT}
    if lParam = Integer(GetDlgItem(hWnd,ColorID)) then
    begin
    SetTextColor(wParam,$CFCF00);
    SetBkColor(wParam,$FF);
    Result := hBrush1;
    end;

the background color is the handle of a Brush that you send back in the Result of the Window Proc, if you want to change the text color then you do it with the wParam, which is the hDC used to draw the Edit

I have not seen any methods as you want, to just call a function to change a color for an edit
0
 

Author Comment

by:gwarguitar
ID: 13940206
yeah, i know there is no color property, but you're clearly able to write to code to do it :)

i was just saying, using your previous code, just making it more of a procedure, without the timer and stuff.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13940347
if you have more than One Edit, then you will need to come up with your own code for the -

 if lParam = Integer(GetDlgItem(hWnd,ColorID)) then

I use the ColorID to identify the Edit to change to color for, I set the ColorID in the button click message of

 if LOWORD(wParam) = IDOK then

with the for loop of

 for i := 300 to 302 do // there are 3 Edits ID from 300 to 302
    if GetWindowTextLength(GetDlgItem(hWnd, i)) < 2 then
      begin
     // SetTimer(hWnd, 117,700, nil); leave out timer
     // EditID := i;
      ColorID := i; set the ColorID to your Edit ID number
      //Flash := 0;
      InvalidateRect(GetDlgItem(hWnd,ColorID), nil, True); // must redraw the edit to show change
      //SetDlgItemText(hWnd,201,'ALL EDITS MUST BE FILLED');
      Exit;
      end

 = = = = = = =

maybe less is more easy


if LOWORD(wParam) = IDOK then
  begin
   ColorID := 301; set the ColorID to your Edit ID number
   InvalidateRect(GetDlgItem(hWnd,ColorID), nil, True); // must redraw the edit to show change
    Exit;
    end;

but this is a one time set, it does not go back
0
 

Author Comment

by:gwarguitar
ID: 13940510
yeah i have about 8 edit's that need the ability to change color :)

thanks Slick, i'll try the lesser code and see what i can do there!
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 1200 total points
ID: 13940565
?? maybe this code, but it seems that the code I gave at first, has all of the methods to do an edit change color? I now use a Handle for the Edit Identifier instead of an ID, now in the  OK button click it test for the hEditC as 0 and will get the Edit handle (for red color) or set  hEditC to zero for normal color

var   {global variables}
  hBrush1: Integer;
  hEditC: Integer = 0;



function DialogProc(hWnd, Msg, wParam, lParam: Integer): Integer; stdcall;
var
i: Integer;
begin
Result := Zero {False};
case Msg of
  WM_INITDIALOG: begin
    hBrush1 := CreateSolidBrush($FF);
    end;

  WM_CLOSE:
    begin
    DeleteObject(hBrush1);
    EndDialog(hWnd, IDCANCEL);
    Result := 1 {True};
    end;

  WM_COMMAND: if LOWORD(wParam) = IDOK then
    begin
      if hEditC = 0 then
        begin
        hEditC := GetDlgItem(hWnd,USER_EDIT)
        InvalidateRect(hEditC, nil, True);;
        end  else
        begin
        i := hEditC;
        hEditC := 0;
        InvalidateRect(i, nil, True);
        end;
     
      Exit;
      end;
   // DeleteObject(hBrush1);
   // EndDialog(hWnd, IDOK);
   // Result := 1;
    end;

  WM_CTLCOLOREDIT: {pre Paint message for Edits = WM_CTLCOLOREDIT}
    if lParam = Integer(GetDlgItem(hWnd,hEditC)) then
    begin
    SetTextColor(wParam,$CFCF00);
    SetBkColor(wParam,$FF);
    Result := hBrush1;
    end;
  end;

end;




 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 I do not think I can do less than that. . .


and the code

for i := 300 to 302 do // there are 3 Edits ID from 300 to 302
    if GetWindowTextLength(GetDlgItem(hWnd, i)) < 2 then

is whatI used to get the first edit without text
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13940580
I really wonder, why are you using an API Dialog at all, if you are not familar with using one? Wouldn't a TForm be easier for you?
0
 

Author Comment

by:gwarguitar
ID: 13940632
i'm familiar with api dialogs, just not the WM_CTLCOLOREDIT message and changing colors and such.
0
 
LVL 34

Expert Comment

by:Slick812
ID: 13942427
I did not get this line correct -

 if lParam = Integer(GetDlgItem(hWnd,hEditC)) then

should be

 if lParam = hEditC then
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Is your OST file inaccessible, Need to transfer OST file from one computer to another? Want to convert OST file to PST? If the answer to any of the above question is yes, then look no further. With the help of Stellar OST to PST Converter, you can e…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses
Course of the Month16 days, 12 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question