Problemas con CStatic

25/05/2004 - 10:15 por Sergio | Informe spam
Hola grupo,
Estoy intentando hacerme una clase que derive de CStatic. Todo va bien,
exceptuando cuando cambio el texto en tiempo de ejecución, el efecto que
se produce es que se "solapan" el texto antiguo y el texto nuevo.
Esto es lo que hago:

void CMyStatic2::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *dcbuff = CDC::FromHandle(lpDrawItemStruct->hDC);
COLORREF clrBackGrnd = RGB(255,255,255);
COLORREF clrTextOld = dcbuff->GetTextColor();
COLORREF clrTextNew = RGB(255,255,255);
CRect crctRect(lpDrawItemStruct->rcItem);
CString cstrTexto;
GetWindowText(cstrTexto);
dcbuff->SetBkMode(TRANSPARENT);
dcbuff->SetTextColor(clrTextNew);
dcbuff->DrawText(cstrTexto,crctRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);
dcbuff->SetTextColor(clrTextOld);
UpdateData(FALSE);
}

He probado ha escribir el texto con TextOut, y ha escribir una cadena de
espacios en blanco antes de la salida, pero sin éxito.

Preguntas similare

Leer las respuestas

#1 Hernán
26/05/2004 - 10:36 | Informe spam
Sergio escribía:

Hola grupo,
Estoy intentando hacerme una clase que derive de CStatic. Todo va bien,
exceptuando cuando cambio el texto en tiempo de ejecución, el efecto que
se produce es que se "solapan" el texto antiguo y el texto nuevo.
Esto es lo que hago:

void CMyStatic2::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *dcbuff = CDC::FromHandle(lpDrawItemStruct->hDC);
COLORREF clrBackGrnd = RGB(255,255,255);
COLORREF clrTextOld = dcbuff->GetTextColor();
COLORREF clrTextNew = RGB(255,255,255);
CRect crctRect(lpDrawItemStruct->rcItem);
CString cstrTexto;
GetWindowText(cstrTexto);
dcbuff->SetBkMode(TRANSPARENT);
dcbuff->SetTextColor(clrTextNew);
dcbuff->DrawText(cstrTexto,crctRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);
dcbuff->SetTextColor(clrTextOld);
UpdateData(FALSE);
}

He probado ha escribir el texto con TextOut, y ha escribir una cadena de
espacios en blanco antes de la salida, pero sin éxito.



Es responsabilidad del control, y en este caso del owner, pintar el
fondo (lo dice la doc cuando habla del procedimiento por defecto para el
WM_ERASEBKGND).

Fijate como los valores del rcItem abarcan la totalidad del client area.

Hernán (28)
Quilmes (ar)
Respuesta Responder a este mensaje
#2 Sergio
26/05/2004 - 11:58 | Informe spam
Hernán escribió:

Es responsabilidad del control, y en este caso del owner, pintar el
fondo (lo dice la doc cuando habla del procedimiento por defecto para el
WM_ERASEBKGND).

Fijate como los valores del rcItem abarcan la totalidad del client area.




Por lo que te he entendido, he de hacer siempre pDC->SetBkMode(OPAQUE);
y pDC->SetBkColor(color); no? Pero yo lo que quiero es que sea de color
transparente, porque lo muevo por un dibujo, y quiero que quede
transparente.
Respuesta Responder a este mensaje
#3 Hernán
26/05/2004 - 12:10 | Informe spam
Sergio escribía:

Hernán escribió:

Es responsabilidad del control, y en este caso del owner, pintar el
fondo (lo dice la doc cuando habla del procedimiento por defecto para el
WM_ERASEBKGND).

Fijate como los valores del rcItem abarcan la totalidad del client area.




Por lo que te he entendido, he de hacer siempre pDC->SetBkMode(OPAQUE);
y pDC->SetBkColor(color); no? Pero yo lo que quiero es que sea de color
transparente, porque lo muevo por un dibujo, y quiero que quede
transparente.



No. Tu primera línea sería, por ejemplo

FillRect(->hDC, & ->rcItem, GetStockObject(WHITE_BRUSH))

lo que te pintaría el fondo de blanco.

O, CreateCompatibleDC() / SelectObject() / BitBlt() si el fondo es una
imágen.

Al back mode del texto lo dejás transparente, sino te va a pintar las
celdas con el color que le asignes mediante SetBkColor().

Hernán (28)
Quilmes (ar)
Respuesta Responder a este mensaje
#4 Sergio
26/05/2004 - 16:21 | Informe spam
Hernán escribió:

No. Tu primera línea sería, por ejemplo

FillRect(->hDC, & ->rcItem, GetStockObject(WHITE_BRUSH))

lo que te pintaría el fondo de blanco.

O, CreateCompatibleDC() / SelectObject() / BitBlt() si el fondo es una
imágen.

Al back mode del texto lo dejás transparente, sino te va a pintar las
celdas con el color que le asignes mediante SetBkColor().




En que me equivoco?

void CMyStatic::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
COLORREF clrBackGrnd = RGB(255,255,255);
COLORREF clrTextOld = dc.GetTextColor();
COLORREF clrTextNew = RGB(0,0,0);
CRect crctRect(lpDrawItemStruct->rcItem);
CString cstrTexto;
GetWindowText(cstrTexto);
dc.SetBkMode(TRANSPARENT);

HDC comp = CreateCompatibleDC(GetParent()->GetDC()->m_hDC); //Creo un
dispositivo compatible con la vista
HBITMAP bitm =
CreateCompatibleBitmap(GetParent()->GetDC()->m_hDC,1280,1024); //Creo
un bitmap de la vista
SelectObject(comp,bitm); //Introduzco el bitmap en el dispositivo
compatible
CRect rr;
GetParent()->GetDlgItem(this->GetDlgCtrlID())->GetWindowRect(rr);
//Recojo las coordenadas del objeto en la vista
BitBlt(dc.m_hDC,0,0,crctRect.Width(),crctRect.Height(),comp,rr.left,rr.top,SRCCOPY);
//Vuelco en el DC el bitmap creado.

long centro;
centro = (crctRect.right - crctRect.left)/2 + crctRect.left;
crctRect.left = centro - (cstrTexto.GetLength() * 8)/2;
crctRect.right = centro + (cstrTexto.GetLength() * 8)/2;
dc.SetTextColor(clrTextNew);
dc.TextOut(crctRect.left+2,crctRect.top+2,cstrTexto);
dc.SetTextColor(clrTextOld);
dc.Detach();
}

Pinta todo de un color negro.
Respuesta Responder a este mensaje
#5 Hernán
26/05/2004 - 19:42 | Informe spam
Algo así,

#define dis (*((LPDRAWITEMSTRUCT)lParam))
case WM_DRAWITEM:
{
char bufer[64];

/* pintas el fondo del control */
FillRect(dis.hDC, &dis.rcItem, m_colorFondo);

/* pintas el frente del control */
SendMessage(dis.hwndItem, WM_GETTEXT, sizeof(bufer), (LPARAM)bufer);
SetTextColor(dis.hDC, m_colorTexto);
SetBkMode(dis.hDC, TRANSPARENT);
DrawText(dis.hDC, bufer, lstrlen(bufer), &dis.rcItem, \
DT_CENTER | DT_VCENTER | DT_SINGLELINE);

break;
}
#undef dis


o, si tienes una imagen asignada al fondo, seleccionas *esa* imagen,

#define dis (*((LPDRAWITEMSTRUCT)lParam))
case WM_DRAWITEM:
{
char bufer[64];

/* pintas una imagen como fondo del control */
HDC comp = CreateCompatibleDC(dis.hDC);

if (NULL != comp)
{
BITMAP bm;
HBITMAP original = SelectObject(comp, m_imagen);

GetObject(m_imagen, sizeof(BITMAP), &bm);
StretchBlt(dis.hDC, dis.rcItem.left, dis.rcItem.top, \
dis.rcItem.right - dis.rcItem.left, \
dis.rcItem.bottom - dis.rcItem.top, \
comp, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
SelectObject(comp, original);
DeleteDC(comp);
}

/* pintas el frente del control */
SendMessage(dis.hwndItem, WM_GETTEXT, sizeof(bufer), (LPARAM)bufer);
SetTextColor(dis.hDC, m_colorTexto);
SetBkMode(dis.hDC, TRANSPARENT);
DrawText(dis.hDC, bufer, lstrlen(bufer), &dis.rcItem, \
DT_CENTER | DT_VCENTER | DT_SINGLELINE);

break;
}
#undef dis

En otras palabras, tenés que pintar el item y el item es todo el client
area del control.

Distinto sería un listbox ownerdraw, donde para pintar el fondo vos
tenés que retornar un HBRUSH desde WM_CTLCOLORLISTBOX. En este caso, el
item es cada elemento de la lista.

Hernán (28)
Quilmes (ar)
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida