Red de conocimiento informático - Material del sitio web - Cómo utilizar el nuevo objeto gdi en win32

Cómo utilizar el nuevo objeto gdi en win32

1. ¿Cómo hacer que la interfaz sea colorida?

¿Qué es una interfaz bonita? ¿Buena foto? ¿Alfa transparente?

Cada uno tiene una estética diferente, así que si tu interfaz le parece hermosa a mucha gente, está bien. El diseño de la interfaz es principalmente trabajo del diseñador, incluido el diseño lógico de la interfaz de usuario, el diseño de combinación de colores, etc. Creo que esto se puede dividir en: diseñadores familiarizados con los hábitos de los usuarios, diseñadores estéticos, etc. Pero en términos generales, estas son tareas que deben realizar los programadores.

Las siguientes son interfaces relevantes proporcionadas por Windows para desarrolladores. Utilice estas interfaces para diseñar una interfaz que le parezca magnífica.

2. ¿Qué tan transparente? ¿Cómo hacerlo translúcido? ¿Cómo hacer gradiente?

La siguiente es una función que encapsulé usando el componente Imaging COM. Esta función se puede usar para dibujar imágenes PNG. Por supuesto, también puedes dibujar otras imágenes. La transparencia se logra dibujando una imagen PNG con un canal alfa.

#include

#include

#include

# comentario pragma(lib, " Imaging.lib")

BOOL DrawPNG(HDC hDC, TCHAR *szPicString, RECT &rcDraw)

{

BOOL br = FALSE ;

IImagingFactory * pImgFactory = NULL;

IImage *pImage = NULL;

ImageInfo sImgInfo;

CoInitializeEx(NULL, COINIT_MULTITHREADED) ;

// Crea una fábrica de imágenes.

if (SUCCEED(CoCreateInstance(CLSID_ImagingFactory,

NULL,

CLSCTX_INPROC_SERVER,

IID_IImagingFactory,

( void **)&pImgFactory)))

{

// Carga una imagen desde un archivo JPG.

if (SUCCEED(pImgFactory- >CreateImageFromFile(

szPicString,

& pImage)))

{

// Dibuja la imagen.

pImage->Draw(hDC, & rcDraw, NULL);

pImage->Release();

pImage = NULL;

br = VERDADERO;

}

pImgFactory->Release();

}

CoUninitialize();

volver br;

}

--------------------- - -------------------------------------------------- -- ---------------------

Esta función de paquete utiliza la función GDI AlphaBlend para dibujar un DC de forma semitransparente en otro DC .

BOOL AlphaBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest,

int nWidthDest, int nHeightDest,

HDC hdcSrc, int nXOriginSrc, int nYoriginSrc,

p>

int nWidthSrc, int nHeightSrc,

BYTE alfa) {

BLENDFUNCTION bf;

bf. BlendOp = AC_SRC_OVER;

bf.BlendFlags = 0;

bf.SourceConstantAlpha = alpha;

bf.AlphaFormat = 0;

return AlphaBlend(hdcDest, nXOriginDest, nXOriginDest nYOriginDest, nWidthDest, nHeightDest,

hdcSrc, nXOriginSrc, nYoriginSrc, nWidthSrc, nHeightSrc, bf);

}

si Es mejor si su dispositivo admite la aceleración de hardware AlphaBlend; de lo contrario, el enfoque del software puede tener algún impacto en el rendimiento.

------------------------------------------- ----- --------------------------------------------- ----- ---------

Los degradados de color también se pueden admitir directamente mediante la API:

BOOL GradientFill(

HDC hdc,

PTRIVERTEX pVertex,

ULONG nVertex,

PVOID pMesh,

ULONG nCount,

ULONG ulMode

);

hdc

[in] Identificador de contexto del dispositivo de destino.

pVertex

[in] Puntero a una matriz de estructuras TRIVERTEX, cada una de las cuales define un vértice de triángulo.

nVertex

[in] El número de vértices en pVertex.

pMesh

[in] Matriz de estructuras GRADIENT_RECT en modo rectangular.

nCount

[in] El número de rectángulos en pMesh.

ulMode

[in] Especificación La siguiente tabla muestra los valores posibles para ulMode.

Esta función rellena un área rectangular con un color de fondo interpolado a partir del valor de color especificado por el vértice.

Estos efectos se pueden lograr ya sea que utilice la plataforma .Net CF o llame a estas API directamente desde Win32/MFC/ATL/WTL. Para obtener más información, consulte la documentación de desarrollo; después de todo, esa es la mejor referencia.

3. ¿Cómo lograr el efecto de animación?

El principio de la animación es que la pantalla retrocede cuadro por cuadro según la línea de tiempo, engañando a los ojos y convirtiéndose en animación, por lo que la forma más sencilla de obtener animación es combinar diferentes imágenes en ciertos intervalos. en la pantalla uno por uno, aunque es muy sencillo, este método se suele utilizar en programación. A veces, lo simple es lo mejor.

Aquí tienes otro pequeño truco, como usar el filtro de movimiento en Photoshop para desenfocar cada imagen, de modo que la animación que obtengas usando el método anterior tendrá una sensación muy rápida.

También puede utilizar un método similar para representar cosas tridimensionales en dos dimensiones para lograr efectos de animación tridimensional.

También puedes utilizar GIF animados, por ejemplo durante el inicio y el apagado. Las siguientes funciones del paquete son solo de referencia y no las he organizado cuidadosamente.

BOOL DisplayGIF(TCHAR *szPicString)

{

HANDLE hFile = CreateFile(strFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );

if (hFile == INVALID_HANDLE_VALUE)

{

return FALSE;

}

DWORD dwFileSize = GetFileSize (hFile, NULL);

if ( (DWORD)-1 == dwFileSize )

{

CloseHandle(hFile);

return FALSE;

}

HGLOBAL hGlobal = GlobalAlloc(GMEM_ MOVEABLE, dwFileSize);

if (hGlobal == NULL)

{

CloseHandle(hFile);

return FALSE;

}

LPVOID pvData = GlobalLock(hGlobal);

if (pvData == NULL)

{

GlobalUnlock(hGlobal);

CloseHandle(hFile);

return FALSE;

Esta es la primera vez que utiliza esta función.

p>}

DWORD dwBytesRead = 0;

BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);

GlobalUnlock(hGlobal);

CloseHandle(hFile);

if (!bRead)

{

return FALSE;

}

IStream* pStream = NULL;

if ( FAILED( CreateStreamOnHGlobal(hGlobal, TRUE, &pStream)) )

{

return FALSE;

}

IImage *pImage = NULL;

RECT rc;

IImagingFactory *pImgFactory = NULL;

CoInitializeEx(NULL, COINIT_MULTITHREADED);

if ( !SUCCEED(CoCreateInstance(CLSID_ ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&pImgFactory)) )

{

devuelve FALSO;

}

IImageDecoder* pDecoder = NULL;

UINT nCount = 0;

if ( !SUCCEED(pImgFactory->CreateImageDecoder(pStream, DecoderInitFlagNone, &pDecoder)) )

{

return FALSE;

}

pDecoder->GetFrameDimensionsCount(&nCount);

GUID *pDimensionIDs = (GUID*)nuevo GUID[nCount];

pDecoder->GetFrameDimensionsList(pDimensionIDs,nCount);

TCHAR strGuid[39];

StringFromGUID2(pDimensionIDs[0], strGuid, 39);

UINT frameCount = 0;

pDecoder->GetFrameCount(&.pDimensionIDs[0],&frameCount);

UINT iSize = 0;

pDecoder->GetPropertyItemSize(PropertyTagFrameDelay,&iSize);

BYTE* pBuff = nuevo BYTE[iSize];

PropertyItem* pItem = (PropertyItem*)pBuff;

pDecoder->GetPropertyItem( PropertyTagFrameDelay,iSize,pItem); p>

int fC

ount = 0;

ImageInfo;

pImgFactory->CreateImageFromStream(pStream, & amp;pImage);

pImage->GetImageInfo(&Info); p>

rc.left = rc.top = 0;

rc.right = Información.Ancho;

rc.bottom = Información.Alto;

rc.right = Info.Width;

rc.bottom = Info.Height;LARGE_INTEGER* lpPerformanceCount

);

lpPerformanceCount

[in] Puntero a una variable que la función establece en recuentos. Este parámetro se puede establecer en cero si el hardware instalado no admite contadores de rendimiento de alta resolución.

Si el hardware instalado no admite contadores de rendimiento de alta resolución, este parámetro se puede establecer en cero.

Si el OEM proporciona un contador de rendimiento de alta resolución, esta función recupera el valor actual de ese contador.

BOOL QueryPerformanceFrequency(

LARGE_INTEGER* lpFrequency

);

lpFrequency

[out] puntero variable, La función establece esta variable en la frecuencia del contador de rendimiento actual en conteos por segundo. Si el hardware instalado no admite contadores de rendimiento de alta resolución, el valor devuelto a través de este puntero puede ser cero.

Si el OEM proporciona un contador de rendimiento de alta resolución, esta función recupera la frecuencia de ese contador.

El OEM debe implementar las dos API anteriores en la capa OAL y la precisión puede ser inferior a 1 ms; de lo contrario, puede utilizar las siguientes API.

DWORD GetTickCount(void);

Para las configuraciones de versión, esta función devuelve el número de milisegundos desde que se inició el dispositivo, excluyendo cualquier momento en que el sistema estuvo en pausa.

Para las configuraciones de depuración, se restan 180 segundos de la cantidad de milisegundos desde que se inició el dispositivo, pero no incluyen el momento en que el sistema estuvo en pausa.

Para las configuraciones de depuración, se restan 180 segundos del número de milisegundos desde el inicio del dispositivo.

PNG, mapa de bits, GIF y otras imágenes también están optimizadas para obtener la claridad y el tamaño adecuados.

7. ¿Por qué la eficiencia del control es tan baja? ¿Cómo reducir el uso de controles?

El software para teléfonos móviles se diferencia del software de escritorio. Por un lado, la velocidad de procesamiento de los teléfonos móviles es menor y la capacidad de la batería es menor. Por otro lado, los usuarios utilizan los teléfonos móviles para manejar asuntos más urgentes. . Por lo tanto, creo que no deberíamos aprovechar completamente la experiencia de desarrollo de software de escritorio para desarrollar software móvil. En una interfaz de teléfono móvil con una resolución de 240x320, si coloca 5 o 6 controles, o incluso más, dicha interfaz seguramente no será muy eficiente y no es adecuada para las interfaces más utilizadas por los usuarios. como la interfaz actual. Por otro lado, los controles universales estándar de Windows no parecen demasiado llamativos incluso cuando están personalizados. Pero estos controles pueden generar una velocidad de desarrollo muy significativa. Por lo tanto, necesitamos armonizar. No podemos hacer ventanas por el hecho de ser ventanas, y no podemos permitir que todo se convierta en ventanas.

Entonces, quizás te preguntes cómo coordinar.

Mi sugerencia es no usar controles donde no se necesitan controles. En la mayoría de los lugares, las imágenes se pueden usar directamente. Por ejemplo, puede implementar botones de múltiples estados:

En el procesamiento de mensajes WM_LBUTTONDOWN, primero debe determinar. si el punto está en el botón Rect, si es así, cambie el estado de la imagen presionada al procesamiento de mensajes DC BitBlt WM_LBUTTONUP, procesamiento de mensajes WM_LBUTTONDOWN, procesamiento de mensajes WM_LBUTTONDOWN y procesamiento de mensajes WM_LBUTTONDOWN en la posición correspondiente en la pantalla. Procese el mensaje LBUTTONUP y devuelva BitBlt.

8. La interfaz basada en Win32 se ejecuta de manera más eficiente que el CF basado en .Net, pero la eficiencia de desarrollo es baja. ¿Qué debo hacer?

La programación Win32 es muy antigua y "atrasada". Pero en dispositivos Windows Embedded que no procesan tan rápido como Ben3 a veces tienes que elegir. Para hacer esto, necesita crear una biblioteca (o biblioteca de clases) para encapsular el código de funciones de interfaz de uso común y acumular dichos recursos para mejorar la eficiencia del trabajo del equipo. La programación genérica de C++ sacrifica la eficiencia en tiempo de compilación por la reutilización de código, pero no sacrifica la eficiencia en tiempo de ejecución. Esto merece un estudio más profundo y existen algunas bibliotecas listas para usar, como STL.

Además, existen otras tecnologías disponibles: DirectDraw (que se describe más adelante), Windows Embedded Programming Language (WEPL) (que se describe más adelante), Direct3DM, OpenGL ES, etc. Pero son más difíciles de desarrollar.

9. ¿Cómo utilizar GDI+ (local/alojado)?

GDI+ es la próxima versión de GDI. Se ha mejorado mucho y es más cómodo de usar. Una de las ventajas de GDI es que no es necesario conocer ningún detalle sobre cómo se representarán los datos en el dispositivo, mientras que GDI+ hace un mejor trabajo para lograrlo, es decir, GDI es un nivel bajo a medio. API y probablemente tenga que conocer el dispositivo, mientras que GDI+ es una API de alto nivel, no tiene que saber nada sobre el dispositivo.

GDI+ en Windows CE/Windows Mobile es un pequeño subconjunto del escritorio de Windows, y GDI+ se ha encapsulado en OpenNETCF, lo que proporciona una manera conveniente para que los desarrolladores de componentes .COM también puedan llamar directamente a clases y métodos en gdiplus.dll. Ya existe una versión para Windows CE de GDI+ en Internet. No admite la integración de algunas funciones en la versión del sistema de escritorio de GDI+. Puede utilizar el desarrollo proporcionado por la biblioteca Libr y los archivos de encabezado. Pero puede que no sea estable.