В предыдущей статье представлено простое применение подсказка, и эта статья приведет пример настройки Hint Windows. Это пользовательское окно подсказки имеет хороший эффект, со стеклом в качестве границы и теневого эффекта.
Однако до этого мы должны представить, как его настроить. Давайте посмотрим на несколько виртуальных методов, CreateParams устанавливает стиль окна, мы хотим перезаписать его, чтобы у него не было границ. Ncpaint рисует границу окна, и мы также должны покрыть ее, потому что нам не нужна граница. Краска более важна, поэтому она должна быть покрыта содержанием области клиента с подсказкой. Но самое важное-ActivateHint, который установит размер окна и отобразит его. Реализация этого класса приведена ниже:
единица wdhintwnd;
интерфейс
Использование
Windows, классы, управления, графика, формы, sysutils, extctrls;
тип
Twdhintwnd = class (thintwindow)
Частный
FWNDBMP: TBITMAP;
Fhintbmp: tbitmap;
защищен
Процедура CreateParams (var params: tcreateparams);
процедура краска;
процедура ncpaint (DC: HDC);
{Нарисуйте приглашение изображения}
Процедура DrawHintimg (BMP: TBITMAP; AHINT: String);
{Получите изображение области рабочего стола, соответствующего окну приглашения}
процедура getDesktopimg (bmp: tbitmap; r: trect);
{Обработайте изображение области рабочего стола, чтобы сделать его похожим на кусок стекла с маленькой тенью}
Процедура EffecThandle (wndbmp, hintbmp: tbitmap);
публичный
конструктор Create (AOHOWNER: TCOMPONT);
разрушитель разрушает;
Процедура ActivateHint (rect: trect; const ahint: string);
конец;
Выполнение
{Twdhintwnd}
Процедура twdhintwnd.ActivateHint (rect: troct; const ahint: string);
вар
P: Tpoint;
Начинать
// Получите подходящий размер, чтобы отобразить текст здесь
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);
Boundsrect: = rect;
Если оставить <screen.desktopleft, тогда
Слева: = screen.desktopleft;
Если top <screen.desktoptop, тогда
Top: = screen.desktoptop;
Если оставить + ширину> screen.desktopwidth тогда
Слева: = screen.desktopwidth - ширина;
Если вверху + высота> screen.desktopheight тогда
Top: = screen.desktopheight - высота;
GetDesktopimg (fwndbmp, boundsrect);
Effecthandle (fwndbmp, fhintbmp);
P: = ClientToscReen (точка (0, 0));
SetWindowpos (harder, hwnd_top, px, py, 0, 0,
SWP_SHOWWINDOW или SWP_NOACTIVATE или SWP_NOSIZE);
конец;
конструктор Twdhintwnd.create (Aowner: Tcomponent);
Начинать
унаследован;
Fwndbmp: = tbitmap.create;
Fwndbmp.pixelformat: = pf24bit;
Fhintbmp: = tbitmap.create;
конец;
Процедура twdhintwnd.createparams (var params: tcreateparams);
Начинать
унаследован;
// Удалить границу окна
Params.style: = params.style, а не ws_border;
конец;
Destructor twdhintwnd.destroy;
Начинать
Fwndbmp.free;
Fhintbmp.free;
унаследован;
конец;
Процедура twdhintwnd.getdesktopimg (bmp: tbitmap; r: trect);
вар
C: TCANVAS;
Начинать
C: = tcanvas.create;
пытаться
C.Handle: = getDC (0);
Bmp.canvas.copyrect (rect (0, 0, bmp.width, bmp.height), c, r);
Окончательно
C.free;
конец;
конец;
Процедура twdhintwnd.effecthandle (wndbmp, hintbmp: tbitmap);
вар
R: TRECT;
я, J: целое число;
P: PbyTearray;
Трансст, Транстангл: целое число;
Начинать
R: = rect (0, 0, wndbmp.width - 4, wndbmp.height - 4);
Frame3d (Wndbmp.canvas, R, Clmedgray, Clbtnshadow, 1);
// быть эффектом тени под окном
Трансст: = 60;
для j: = wndbmp.height - 4 до wndbmp.height - 1 do
Начинать
P: = wndbmp.scanline [j];
Transstangle: = Transst;
для i: = 3 до wndbmp.width - 1 do
Начинать
// Если это в правом нижнем углу
Если я> wndbmp.width - 5, тогда
Начинать
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;
Если трансстанге> 90, то трансстангл: = 90;
конец
иначе начинается
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;
конец;
// быть эффектом тени на правой стороне окна
для j: = 3 до wndbmp.height - 5
Начинать
P: = wndbmp.scanline [j];
Трансст: = 60;
для i: = wndbmp.width - 4 до wndbmp.width -1 do
Начинать
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;
конец;
конец;
Wndbmp.canvas.draw (10, 10, hintbmp);
конец;
Процедура twdhintwnd.ncpaint;
Начинать
// Перезагрузить не разрешать пограничный рисунок
конец;
Процедура twdhintwnd.paint;
Начинать
Canvas.copyrect (clientRect, fwndbmp.canvas, clientRect);
конец;
Процедура twdhintwnd.drawhintimg (bmp: tbitmap; ahint: string);
вар
R: TRECT;
Начинать
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 или dt_noprefix или
Dt_wordbreak или drawtextbidimodeflagsreadingonly);
конец;
Инициализация
Application.showhint: = false;
Hintwindowclass: = twdhintwnd;
Application.showhint: = true;
конец.
Просто добавьте устройство в свой проект и запустите программу, чтобы увидеть эффект.
Важные части программы были прокомментированы, и вот лишь несколько важных моментов, прежде всего, инициализации
Частично установите Showhint of Application в False, посмотрите на исходный код VCL и знайте, что приложение уничтожило оттенки, и определение HintwindowClass заключается в следующем:
Thintwindowclass = класс ThintWindow;
Hintwindowclass: thintwindowclass = thintwindow;
Здесь мы заменим его на Twdhintwnd, и, наконец, установил Showhint на True.
В методе ActivateHint мы обработаем эффект. из приглашенного окна, так что существует прозрачность, эффект сейчас. Во -вторых, нарисуйте край стекла и, наконец, сделайте эффект тени справа и нижней части окна.
Что касается реализации эффектов тени, используется Alpha Technology.
Dst.red = src.red * alpha + (1-alpha) * dst.red;
Dst.green = src.green * alpha + (1-alpha) * dst.green;
Dst.blue = src.blue * alpha + (1-alpha) * dst.blue;
Значение альфа составляет от 0 до 1, что означает совершенно непрозрачное, когда оно составляет 1, но цвет, который мы будем использовать для смешивания, черный, то есть 0, так что то, что видит вышеупомянутый код, выглядит следующим образом:
P [3*i]: = p [3*i]*Transstangle Div 100;
Принцип стеклянного окна примерно такой. Но как быстрое окно, я думаю, что этого достаточно.