+ 1

How to Set the EDITTEXT Box in a Custom Dialog Box to a new color?

Here is the GDI Paint so far... // Its a Code::Blocks Project, but copying the files main.rc, main.cpp and resource.h into a new VC++ Project will work... // Its my second upload on GitHub, so I don't know how to create repositories properly... https://github.com/kinshuk-h/GDI-Paint Now, I was trying to create a color changing dialog box which would receive R,G and B values and change the Background color (See it by pressing Ctrl+B)... In that there are two options, Apply and Set. The Apply option will change the color of the EDITTEXT box above the Button to show how your color looks, and Set will simply set the color and close the dialog Box. The Background color is currently the color of the Eraser only... But the code fragment neither changes the color, nor shows me the color in the EDITTEXT Box. Apply though, changes the color of the Box receiving the R Reading... Please help me change the color properly...

15th Aug 2017, 4:29 AM
Kinshuk Vasisht
Kinshuk Vasisht - avatar
8 Réponses
+ 6
You have to handle the WM_ERASEBKGND message and WM_PAINT to change the color of the window background. I will post the code here as I'm also a newbie when it comes to GitHub and never made a commit yet. First you need to make the HWND of your main window global to be able to get its DC from the dialog callback. static HWND hwnd; This the new apply message handling: case ID_APPLY: { LPSTR R = new char[4],G=new char[4],B = new char[4]; CBCO = CBC; GetWindowText(hR,R,4); GetWindowText(hG,G,4); GetWindowText(hB,B,4); int r = atoi(R),g = atoi(G),b = atoi(B); ::CBC = RGB(r,g,b); //MessageBox(NULL,R,"",MB_OK); //MessageBox(NULL,G,"",MB_OK); //MessageBox(NULL,B,"",MB_OK); Apply = true; InvalidateRect(hwnd, NULL, TRUE); break; } Then add this handler for the erase background message in your main window WndProc: case WM_ERASEBKGND: { HPEN pen; HBRUSH brush; RECT rect; pen = CreatePen(PS_SOLID, 1, CBC); brush = CreateSolidBrush(CBC); SelectObject((HDC)wParam, pen); SelectObject((HDC)wParam, brush); GetClientRect(hwnd, &rect); Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom); return 0; } And the new WM_PAINT handling in that same WndProc case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); // BitBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, SRCCOPY); SetBkColor(GetDC(hwnd), CBC); EndPaint(hwnd, &ps); return 0; } It worked for me...though this only changes the background of the main window and not the EDITTEXT box but I leave that to you as Im sure you can do it. All you need to do is get its dc and handle the WM_ERASEBKGND and WM_PAINT messages
15th Aug 2017, 6:31 AM
Karl T.
Karl T. - avatar
+ 8
If it doesn't work for you tell me I will upload the updated source file.
15th Aug 2017, 7:36 AM
Karl T.
Karl T. - avatar
+ 7
Dunno I never tried RedrawWindow. You can always look at the MSDN docs and see what it says about it.
15th Aug 2017, 7:25 AM
Karl T.
Karl T. - avatar
+ 7
Well I have looked at your code again and you made a small error with the RGB values. All I had to do was change this and the eraser was fine: case ID_OK: { LPSTR R = new char[4],G=new char[4],B = new char[4]; GetWindowText(hR,R,4); GetWindowText(hG,G,4); GetWindowText(hB,B,4); int r = atoi(R),g = atoi(G),b = atoi(B); ::CBC = RGB(r,g,b); EndDialog(hWndDlg,0); break; }
17th Aug 2017, 2:53 PM
Karl T.
Karl T. - avatar
+ 3
@Karl T. I tried changing the code and handling the WM_ERASEBKGND message in WndProc. The color of the background does change, and I found a way for the EDITTEXT box (I was handling the wrong DC, my bad), but the eraser color after the closing of the dialog box does not change. It becomes black everytime I use the Set button. I tried making a global variable, but that still doesn't work, like in the original. How can I repair that ? I wish to change the eraser color now, which is a Pen and has the color CBC... EDIT : Fixed that one. Now colors can be easily selected, both for Foreground (PEN) and the Background (WINDOW and ERASER). Thank You!
17th Aug 2017, 3:03 PM
Kinshuk Vasisht
Kinshuk Vasisht - avatar
+ 1
The code fragment : INT_PTR CALLBACK DlgProcB(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND hR,hG,hB,hC; hR = GetDlgItem(hWndDlg,ID_R); hG = GetDlgItem(hWndDlg,ID_G); hB = GetDlgItem(hWndDlg,ID_B); hC = GetDlgItem(hWndDlg,IDM_BCOLOR); //Saving the boxes to window handles bool Apply = false; switch(uMsg) { case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_APPLY: { LPSTR R = new char[4],G=new char[4],B = new char[4]; GetWindowText(hR,R,4); GetWindowText(hG,G,4); GetWindowText(hB,B,4); int r = atoi(R),g = atoi(G),b = atoi(B); ::CBC = RGB(r,g,b); //MessageBox(NULL,R,"",MB_OK); // Just to see if the colors were read or not... Apply = true; RedrawWindow(hWndDlg, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); break; } case ID_OK: { LPSTR R = new char[3],G=new char[3],B = new char[3]; GetWindowText(hR,R,3); GetWindowText(hG,G,3); GetWindowText(hB,B,3); int r = atoi(R),g = atoi(G),b = atoi(B); ::CBC = RGB(r,g,b); EndDialog(hWndDlg,0); break; } } } return 1; case WM_CTLCOLOREDIT: { HBRUSH hbr; if (Apply && ((HWND)lParam == hC)) { SetBkColor((HDC) , ::CBC); SetTextColor((HDC) wParam, ::CBC); } Apply = false; HBRUSH br = CreateSolidBrush(::CBC); return(INT_PTR)((HBRUSH)br); } return 1; } }
15th Aug 2017, 4:33 AM
Kinshuk Vasisht
Kinshuk Vasisht - avatar
+ 1
@Karl T. Thank You very much! Ill try handling WM_ERASEBKGND now as well... I read on StackOverFlow that using Redraw Window is better than Invalidate Rect, but what should I use in this case?
15th Aug 2017, 7:09 AM
Kinshuk Vasisht
Kinshuk Vasisht - avatar
+ 1
@Karl T. I haven't tried it yet...
15th Aug 2017, 11:03 AM
Kinshuk Vasisht
Kinshuk Vasisht - avatar