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

#6 Sergio
27/05/2004 - 11:38 | Informe spam
La primera parte funciona a las mil maravillas, gracias, pero tengo una
duda con lo que corresponde a la segunda parte.

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




donde haces: HBITMAP original = SelectObject(comp, m_imagen); me imagino
que m_imagen es el bitmap, pero tengo un pequeño problema, porque la
imagen de fondo donde tengo que pintar es un jpg, que no se lleva nada
bien con bitmaps.
¿Hay alguna forma de cargar el jpg?
Respuesta Responder a este mensaje
#7 Hernán
27/05/2004 - 17:20 | Informe spam
Sergio escribía:

¿Hay alguna forma de cargar el jpg?



Tienes IPicture, que a este respecto esta mal documentada, pero a mi me
va (igualmente con gif). No recuerdo si está condicionada a alguna
versión del IE.

Si querés un ejemplo, puedo pasarte alguna cosa...

Hernán (28)
Quilmes (ar)
Respuesta Responder a este mensaje
#8 Sergio
27/05/2004 - 17:39 | Informe spam
Hernán escribió:


Tienes IPicture, que a este respecto esta mal documentada, pero a mi me
va (igualmente con gif). No recuerdo si está condicionada a alguna
versión del IE.

Si querés un ejemplo, puedo pasarte alguna cosa...




Pues te lo agradeceria. Yo uso la clase CPicture, que se basa en
IPicture, pero no se como hacer para que solo coja la parte que me
interesa de la imagen.
Me explico, necesito poner un pequeño cstatic sobre una imagen, y con
CPicture no he encontrado (no creo que tenga) una forma de hacerlo.
Respuesta Responder a este mensaje
#9 Hernán
27/05/2004 - 20:11 | Informe spam
Sergio escribía:

Hernán escribió:


Tienes IPicture, que a este respecto esta mal documentada, pero a mi me
va (igualmente con gif). No recuerdo si está condicionada a alguna
versión del IE.

Si querés un ejemplo, puedo pasarte alguna cosa...




Pues te lo agradeceria. Yo uso la clase CPicture, que se basa en
IPicture, pero no se como hacer para que solo coja la parte que me
interesa de la imagen.
Me explico, necesito poner un pequeño cstatic sobre una imagen, y con
CPicture no he encontrado (no creo que tenga) una forma de hacerlo.



Si te entiendo bien, Render() sí te deja. Digamos que tenés la esquina
superior izquierda del static sobre las coordenadas 50, 60 en pixeles.

Tenés que pasarlo de pixeles a centésimas de milímetro

offsetx = MulDiv(50, 2540, GetDeviceCaps(dis.hDC, LOGPIXELSX));
offsety = MulDiv(60, 2540, GetDeviceCaps(dis.hDC, LOGPIXELSY));

m_imagen->lpVtbl->Render(
m_imagen, /* puntero a la interfaz (this en c++) */
hDC, /* dis.hDC en tu draw-item */
0, 0, ancho, alto, /* valores en dis.rcItem */
offsetx,
altoImagen - offsety, /* altoImagen te lo da get_Height*/
anchoImagen, /* get_Width */
-altoImagen, /* cosas del MM_HIMETRIC */
NULL);

Por un lado pones área de la ventana donde va la imagen (en este caso
todo el client area de tu static) y por otro el área de la imagen.

Bueno, no sé. Revisá los cálculos, probablemente escribí cualquier cosa.


Ahí te dejo un cutipaste de un par de funciones que suelo usar.

Ok, el ejemplo está en C, por lo que aparecen la indirección (lpVtbl) y
el this (m_imagen en la lista de argumentos), que están implícitos en
C++.

Yo acostumbro compilar el IID por mi cuenta, así me ahorro un par de
horas buscando el módulo en el que lo han compilado.

/* identificador de la interfaz IPicture */
const IID IID_IPicture {0x7BF80980, 0xBF32, 0x101A, 0x8B, 0xBB,
0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB};

/* este es mi puntero a la interfaz */
static LPPICTURE m_imagen;

/* */
static void CargaImagenDesdeArchivo(
LPCSTR archivo) /* nombre del archivo */
{
/* falla si el puntero es nulo ó si la cadena está vacía */
/* podrías usar un ASSERT, yo prefiero mantenerlo en el release */
if ((NULL == archivo)||('\0' == *archivo)) return;

/* abre el fichero */
HANDLE fich = CreateFile(archivo, GENERIC_READ, 0, NULL, \
OPEN_EXISTING, 0, NULL);

if (INVALID_HANDLE_VALUE != fich)
{
/* tamaño del archivo */
DWORD largo = GetFileSize(fich, NULL);

/* memoria donde cargar el archivo*/
HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, largo);

if (NULL != mem)
{
LPVOID datos = GlobalLock(mem);

if (NULL == datos)
{
GlobalFree(mem);
}
else
{
DWORD leidos = 0;

/* blockread del archivo */
if (ReadFile(fich, datos, largo, &leidos, NULL) && \
(leidos == largo))
{
LPSTREAM pIS = NULL;

/* obtiene un IStream y libera la memoria */
GlobalUnlock(mem);
HRESULT hr = CreateStreamOnHGlobal(mem, TRUE, &pIS);

if (S_OK == hr)
{
/* obtiene un IPicture */
hr = OleLoadPicture(pIS, largo, FALSE, \
&IID_IPicture, (LPVOID *)&m_imagen);

/* si la función falla la imagen no es creada */
if (S_OK != hr) m_imagen = NULL;

/* libera el IStream */
pIS->lpVtbl->Release(pIS);
}
}
else
{
GlobalUnlock(mem);
}
}
}
CloseHandle(fich);
}
else
{
/* ERROR: la función no pudo abrir el archivo */
}
}


/* para pintar usas el método Render de IPicture */
static void wmPaint_PintaImagen(
HDC hDC,
int ancho,
int alto)
{
LONG altoImagen;
LONG anchoImagen;

/* tamaño de la imagen en centésimas de milímetro */
m_imagen->lpVtbl->get_Width(m_imagen, &anchoImagen);
m_imagen->lpVtbl->get_Height(m_imagen, &altoImagen);


/* pinta la imagen extendiéndola sobre el área indicada */
m_imagen->lpVtbl->Render(m_imagen, hDC, 0, 0, ancho, alto, \
0, altoImagen, anchoImagen, -altoImagen, NULL);
}


/* el recurso se libera cuando ya no se usa más */
m_imagen->lpVtbl->Release(m_imagen);

Hernán (28)
Quilmes (ar)
Respuesta Responder a este mensaje
#10 Hernán
27/05/2004 - 20:25 | Informe spam

Tenés que pasarlo de pixeles a centésimas de milímetro

offsetx = MulDiv(50, 2540, GetDeviceCaps(dis.hDC, LOGPIXELSX));
offsety = MulDiv(60, 2540, GetDeviceCaps(dis.hDC, LOGPIXELSY));

m_imagen->lpVtbl->Render(
m_imagen, /* puntero a la interfaz (this en c++) */
hDC, /* dis.hDC en tu draw-item */
0, 0, ancho, alto, /* valores en dis.rcItem */
offsetx,
altoImagen - offsety, /* altoImagen te lo da get_Height*/
anchoImagen, /* get_Width */
-altoImagen, /* cosas del MM_HIMETRIC */
NULL);




No te decía...

En realidad no es anchoImagen/altoImagen sino anchoControl/altoControl

int anchoControl = MulDiv(ancho, 2540, \
GetDeviceCaps(dis.hDC, LOGPIXELSX));

int altoControl = MulDiv(alto, 2540, \
GetDeviceCaps(dis.hDC, LOGPIXELSY));

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