Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating text in a C Win32 API STATIC control drawn with WS_EX_TRANSPARENT

Tags:

c++

winapi

I have window with some STATIC labels and BUTTONs on it. I make all the LABELS transparent background so I can make the background RED say. In the CALLBACK i process the WM_CTLCOLORSTATIC message, determine the ID of the control with GetDlgCtrlID() and then:

SetBkMode((HDC)wParam, TRANSPARENT); // Make STATIC control Bkgd transparent
return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);

So far so good. Form is drawn, background is RED and label text is drawn on top.

After user interaction I need to change the text, so I issue a SetDlgItemText() message and the new text is draw. The problem is the old text is not erased, and the new text is drawn on top of it.

Having read somewhat today, it seems the problem is the controls parent (the form) is responsible for drawing the background. This means that when you change the label text, the control redraws the new text, BUT the form doesn't automatically redraw the background.

THe question is HOW do I force the form to redraw the rectangle area of the label control (preferably without subclassing anything)?

ADDED:

I have tried the following:

HWND hctrl;
hctrl = GetDlgItem(hwnd, ControlID);
RedrawWindow( hctrl, 0, 0, 
RDW_UPDATENOW || RDW_ALLCHILDREN || RDW_FRAME || RDW_INVALIDATE || RDW_ERASE || RDW_INTERNALPAINT ); // RDW_UPDATENOW 

and:

I am not handling the WM_PAINT message at all, only:

case WM_CTLCOLORSTATIC:
 SetBkMode((HDC)wParam, TRANSPARENT); 
 return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);




int Library::SetControlTxt( int ControlID, string sText  ) // Dialog Out
{ 
 int RetVal;

  RetVal = SetDlgItemText( hwnd, ControlID, sText.c_str() ); 
  RECT rect;
  HWND hctrl;
  hctrl = GetDlgItem(hwnd, ControlID);
  GetClientRect(hctrl, &rect);
  MapWindowPoints(hctrl, hwnd, (POINT *)&rect, 2);
  InvalidateRect(hwnd, &rect, TRUE);

       return RetVal;
} 

Mark, Thank you this works.

like image 940
Mike Trader Avatar asked Oct 11 '25 08:10

Mike Trader


1 Answers

Use InvalidateRect on the rectangle occupied by the control.

RECT rect;
GetClientRect(hctrl, &rect);
InvalidateRect(hctrl, &rect, TRUE);
MapWindowPoints(hctrl, hwnd, (POINT *) &rect, 2);
RedrawWindow(hwnd, &rect, NULL, RDW_ERASE | RDW_INVALIDATE);
like image 147
Mark Ransom Avatar answered Oct 14 '25 09:10

Mark Ransom