El artículo anterior presenta la simple aplicación de sugerencia, y este artículo dará un ejemplo de personalización de Windows de sugerencias. Esta ventana de sugerencia personalizada tiene un buen efecto, con vidrio como borde y un efecto de sombra.
Sin embargo, antes de esto, debemos introducir cómo personalizarlo. Echemos un vistazo a varios métodos virtuales, CreateParams establece el estilo de la ventana, queremos sobrescribirlo para que no tenga fronteras. NCPaint dibuja el borde de la ventana, y también necesitamos cubrirlo, porque no necesitamos el borde. La pintura es más importante, por lo que debe estar cubierta en el contenido del área del cliente de la ventana de sugerencias. Pero lo más importante es ActivateHint, que establecerá el tamaño de la ventana y lo mostrará. La implementación de esta clase se proporciona a continuación:
unidad wdhintwnd;
interfaz
usos
Windows, clases, controles, gráficos, formularios, sysutils, extctrls;
tipo
Twdhintwnd = class (Thintwindow)
Privado
FWNDBMP: TBITMAP;
FHINTBMP: TBITMAP;
protegido
Procedimiento CreateParams (VAR Params: TCreateParams);
pintura de procedimiento;
procedimiento NCPaint (DC: HDC);
{Dibuja el indicador de la imagen}
procedimiento DrawHintimg (BMP: TBITMAP; Ahint: String);
{Obtenga la imagen del área de escritorio correspondiente a la ventana de inmediato}
procedimiento getDeskTopimg (BMP: TBITMAP; R: TRECT);
{Trate la imagen del área de escritorio para que parezca un trozo de vidrio con una pequeña sombra}
procedimiento efecthandle (wndbmp, hintbmp: tbitmap);
público
constructor create (downer: tcomponent);
Destructor destruir;
procedimiento activadoHint (rect: trect; const ahint: string);
fin;
Implementación
{Twdhintwnd}
procedimiento twdhintwnd.ActivateHint (rect: trect; const ahint: string);
varilla
P: TPOINT;
Comenzar
// Obtener un tamaño apropiado para mostrar el texto aquí
Fhintbmp.width: = rect.right - rect.left;
Fhintbmp.Height: = rect.bottom - rect.top + 4;
Drawhintimg (fhintbmp, ahint);
Fwndbmp.width: = rect.right - rect.left + 23;
Fwndbmp.height: = rect.bottom - rect.top + 27;
Inc (rect.right, 23);
Inc (rect.bottom, 27);
LímiteSrect: = rect;
Si se deja <screen.desktopleft entonces
Izquierda: = screen.desktopleft;
Si Top <Screen.desktoptop entonces
Superior: = screen.desktoptop;
Si izquierda + ancho> pantalla.desktopWidth entonces
Izquierda: = screen.DesktopWidth - ancho;
Si Top + Height> Screen.DeskTopheight entonces
Superior: = screen.desktopheight - altura;
GetDeskTopimg (fwndbmp, boundsrect);
Efecthandle (fwndbmp, fhintbmp);
P: = ClientTosCreen (punto (0, 0));
SetWindowPos (Handle, HWND_TOPMOST, PX, PY, 0, 0,
Swp_showwindow o swp_noactivate o swp_nosize);
fin;
constructor twdhintwnd.create (Awner: tComponent);
Comenzar
heredado;
Fwndbmp: = tbitmap.create;
Fwndbmp.pixeflaMat: = pf24bit;
Fhintbmp: = tbitmap.create;
fin;
Procedimiento twdhintwnd.createParams (params var: tcreateparams);
Comenzar
heredado;
// Retire el borde de la ventana
Params.style: = params.style y no ws_border;
fin;
destructor twdhintwnd.destroy;
Comenzar
Fwndbmp.free;
Fhintbmp.free;
heredado;
fin;
procedimiento twdhintwnd.getDeskTopimg (BMP: TBITMAP; R: TRECT);
varilla
C: tcanvas;
Comenzar
C: = tcanvas.create;
intentar
C.Handle: = getDC (0);
Bmp.canvas.copyrect (rect (0, 0, bmp.width, bmp.height), c, r);
Finalmente
C. libre;
fin;
fin;
procedimiento twdhintwnd.effecthandle (wndbmp, hintbmp: tbitmap);
varilla
R: Trect;
I, J: entero;
P: pbytearray;
Transst, transstangle: integer;
Comenzar
R: = rect (0, 0, wndbmp.width - 4, wndbmp.height - 4);
Frame3d (wndbmp.canvas, r, clmedgray, clbtnshadow, 1);
// ser un efecto de sombra debajo de la ventana
Transst: = 60;
para j: = wndbmp.Height - 4 a wndbmp.height - 1 do
Comenzar
P: = wndbmp.scanline [j];
Transstangle: = transst;
para i: = 3 a wndbmp.width - 1 hacer
Comenzar
// Si está en la esquina inferior derecha
Si i> wndbmp.width - 5 entonces
Comenzar
P [3*i]: = P [3*i]*Transstangle Div 100;
P [3*i + 1]: = P [3*i + 1]*Transstangle Div 100;
P [3*i + 2]: = P [3*i + 2]*Transstangle Div 100;
Transstangle: = transstangle + 10;
si se transfiere> 90, entonces transstangle: = 90;
fin
De lo contrario, comience
P [3*i]: = p [3*i]*transst div 100;
P [3*i + 1]: = P [3*i + 1]*transst div 100;
P [3*i + 2]: = P [3*i + 2]*transst div 100;
fin;
fin;
Transst: = transst + 10;
fin;
// ser un efecto de sombra en el lado derecho de la ventana
para j: = 3 a wndbmp.
Comenzar
P: = wndbmp.scanline [j];
Transst: = 60;
para i: = wndbmp.width - 4 a wndbmp.width -1 hacer
Comenzar
P [3*i]: = p [3*i]*transst div 100;
P [3*i + 1]: = P [3*i + 1]*transst div 100;
P [3*i + 2]: = P [3*i + 2]*transst div 100;
Transst: = transst + 10;
fin;
fin;
Wndbmp.canvas.draw (10, 10, hintbmp);
fin;
procedimiento twdhintwnd.ncPaint;
Comenzar
// Recargar no permitir el dibujo del borde
fin;
procedimiento twdhintwnd.Paint;
Comenzar
Canvas.CopyRect (ClientRect, fwndbmp.canvas, clientRect);
fin;
procedimiento twdhintwnd.drawhintimg (BMP: tbitmap; ahint: string);
varilla
R: Trect;
Comenzar
Bmp.canvas.brush.color: = application.hintcolor;
Bmp.canvas.pen.color: = application.hintcolor;
Bmp.canvas.rectangle (0, 0, bmp.width, bmp.height);
Bmp.canvas.font.color: = screen.hintfont.color;
R: = rect (0, 0, bmp.width, bmp.height);
Inc (r.left, 2);
Inc (r.top, 2);
DrawText (bmp.canvas.handle, pchar (ahint), -1, r, dt_left o dt_noprefix o
Dt_wordbreak o drawTextBidImodeFlagSreadingEnly);
fin;
Inicialización
Application.showHint: = false;
Hintwindowclass: = twdhintwnd;
Application.ShowHint: = True;
fin.
Simplemente agregue la unidad a su proyecto y ejecute el programa para ver el efecto.
Se han comentado las partes importantes del programa, y aquí hay solo unos pocos puntos importantes, en primer lugar, inicialización
En parte, aquí, configure el showhint de aplicación en False, mire el código fuente de VCL y sepa que la aplicación ha destruido una hintina, y la definición de HintWindowClass es la siguiente:
ThintWindowClass = Clase de ThintWindow;
Hintwindowclass: ThintWindowClass = Thintwindow;
Aquí lo reemplazamos con TwdhintWnd y finalmente establecemos showhint en verdad.
En el método ActivateHint, procesaremos el efecto. de la ventana rápida, de modo que hay transparencia el efecto es ahora. En segundo lugar, dibuje el borde del vidrio y finalmente haga un efecto de sombra en la derecha e inferior de la ventana.
Con respecto a la implementación de los efectos de la sombra, se utiliza la tecnología alfa de la imagen.
Dst.red = src.red * alfa + (1-alpha) * dst.red;
Dst.green = src.green * alfa + (1-alpha) * dst.green;
Dst.blue = src.blue * alfa + (1-alpha) * dst.blue;
El valor del alfa es entre 0 y 1, lo que significa completamente opaco cuando es 1, pero el color que usaremos para mezclar es negro, es decir, 0, por lo que lo que ve el código anterior es el siguiente:
P [3*i]: = P [3*i]*Transstangle Div 100;
El principio de la ventana rápida de vidrio es más o menos así. Pero como ventana rápida, creo que es suficiente.