gwarguitar
asked on
api: change edit background color
i'm trying to change the background color of an edit control with api..
i'm trying this..
SetBkColor(GetDC(GetDlgIte m(prefs_de tail,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.
i'm trying this..
SetBkColor(GetDC(GetDlgIte
but it doesn't seem to be working? any ideas?
i'm trying to duplicate the VCL Edit1.Color := clRed; not font properties.
ASKER
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.
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.
That was definately not clear in your original post.
Did you set the background mode to OPAQUE first?
Did you set the background mode to OPAQUE first?
ASKER
no, i did set it to transparent? how do you set to opaque?
ASKER
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.. :)
set to opaque.. now what? seems like i need to respond to a notification, was hoping just to do this with a simple message.. :)
hello gwarguitar, ?? you seem to think that Device Contexts are persistant, but they are not, your code
GetDC(GetDlgItem(prefs_det ail,USER_E DIT))
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_d etail,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,$0000F F);
SetBkColor(wParam,GetSysCo lor(COLOR_ BTNHIGHLIG HT));
Result := GetSysColorBrush(COLOR_BTN HIGHLIGHT) ;
{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
GetDC(GetDlgItem(prefs_det
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_d
{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,$0000F
SetBkColor(wParam,GetSysCo
Result := GetSysColorBrush(COLOR_BTN
{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
ASKER
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 :)
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 :)
I really do not understand your Error, how can you get a rangeCheck error on a call for SetTextColor(wParam, $CFCF00); ?
maybe
SetTextColor(Cardinal(wPar am), $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,'MainIc on'));
SetDlgItemText(hWnd,300,'F ill 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,'A LL EDITS MUST BE FILLED');
ColorID := EditID;
end else
begin
SetDlgItemText(hWnd,201,'a ll edits must be filled');
ColorID := 0;
end;
InvalidateRect(GetDlgItem( hWnd,EditI D), nil, True);
end;
WM_COMMAND: if LOWORD(wParam) = IDOK then
begin
for i := 300 to 302 do
if GetWindowTextLength(GetDlg Item(hWnd, i)) < 2 then
begin
SetTimer(hWnd, 117,700, nil);
EditID := i;
ColorID := i;
Flash := 0;
InvalidateRect(GetDlgItem( hWnd,EditI D), nil, True);
SetDlgItemText(hWnd,201,'A LL 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,Co lorID)) then
begin
SetTextColor(wParam,$CFCF0 0);
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
maybe
SetTextColor(Cardinal(wPar
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,'MainIc
SetDlgItemText(hWnd,300,'F
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,'A
ColorID := EditID;
end else
begin
SetDlgItemText(hWnd,201,'a
ColorID := 0;
end;
InvalidateRect(GetDlgItem(
end;
WM_COMMAND: if LOWORD(wParam) = IDOK then
begin
for i := 300 to 302 do
if GetWindowTextLength(GetDlg
begin
SetTimer(hWnd, 117,700, nil);
EditID := i;
ColorID := i;
Flash := 0;
InvalidateRect(GetDlgItem(
SetDlgItemText(hWnd,201,'A
Exit;
end;
DeleteObject(hBrush1);
EndDialog(hWnd, IDOK);
Result := 1;
end;
WM_CTLCOLOREDIT: {pre Paint message for Edits = WM_CTLCOLOREDIT}
if lParam = Integer(GetDlgItem(hWnd,Co
begin
SetTextColor(wParam,$CFCF0
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
forgot the deleteObject, , change the close code to -
WM_CLOSE:
begin
DeleteObject(hBrush1);
EndDialog(hWnd, IDCANCEL);
Result := 1 {True};
end;
WM_CLOSE:
begin
DeleteObject(hBrush1);
EndDialog(hWnd, IDCANCEL);
Result := 1 {True};
end;
ASKER
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
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
end;
severe psuedo code :)
increased points again since i suck. hehe
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?
many (most) standard API system controls do not have a "Color" attribute, I wonder why you think they would?
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,Co lorID)) then
begin
SetTextColor(wParam,$CFCF0 0);
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
WM_CTLCOLOREDIT: {pre Paint message for Edits = WM_CTLCOLOREDIT}
if lParam = Integer(GetDlgItem(hWnd,Co
begin
SetTextColor(wParam,$CFCF0
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
ASKER
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.
i was just saying, using your previous code, just making it more of a procedure, without the timer and stuff.
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,Co lorID)) 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(GetDlg Item(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,Color ID), 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,Color ID), nil, True); // must redraw the edit to show change
Exit;
end;
but this is a one time set, it does not go back
if lParam = Integer(GetDlgItem(hWnd,Co
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(GetDlg
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(
//SetDlgItemText(hWnd,201,
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(
Exit;
end;
but this is a one time set, it does not go back
ASKER
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!
thanks Slick, i'll try the lesser code and see what i can do there!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
ASKER
i'm familiar with api dialogs, just not the WM_CTLCOLOREDIT message and changing colors and such.
I did not get this line correct -
if lParam = Integer(GetDlgItem(hWnd,hE ditC)) then
should be
if lParam = hEditC then
if lParam = Integer(GetDlgItem(hWnd,hE
should be
if lParam = hEditC then
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?