Последние записи
- Сделать авторизацию пользователя в программе
- Сделать границы компонента edit – жирными?
- Как настроить адрес без указания на index.php?
- Чтение из Excel и валидация. Можно ли как-то ускорить данный процесс?
- Загрузить файл из папки с программой
- Компьютеры для бухгалтера и дизайнера. В чём разница?
- Удалить все повторения в строке
- Как в treeview узнать индекс узла по которому был click?
- Исходник программы «азбука Морзе»
- Рассылка. Выпуск 139
21st
Авг
Полупрозрачность в Delphi
Posted by Chas under Статьи, Топик-обзор
И так, как сделать окошко в дельфи прозрачным с красивыми тенями и другой мутью.
Перво наперво, качаем gdiplus.dll (если есть желание) с MS Official Site
Потом смотрим мои (DIB) и не мои (GdiPlus) модули в аттаче.
И так… Подготовим плацдарм для нашего окошка
код:
const
WndClassName = ‘Trulyalya’;
var
WndClass: TWndClass = (
style: CS_DBLCLKS;
cbClsExtra: 0;
cbWndExtra: 0;
hbrBackground: 0;
lpszMenuName: NIL;
lpszClassName: WndClassName;
);
…
initialization
WndClass.lpfnWndProc := @DefWindowProc; // I hope…
WndClass.hInstance := HInstance;
WndClass.hIcon := LoadIcon(HInstance, ‘MAINICON’);
WndClass.hCursor := LoadCursor(0, IDC_ARROW);
Windows.RegisterClass(WndClass);
finalization
Windows.UnregisterClass(WndClassName, HInstance);
И так у нас есть зарегиный класс, вот ведь счастье ну мы не собираемся на этом останавливаться и пойдем до конца! Теперь давайте создадим окошко
Код:
hWnd := CreateWindowEx(WS_EX_TOOLWINDOW or WS_EX_LAYERED,
WndClass.lpszClassName, NIL, WS_POPUP or WS_VISIBLE, 0, 0, 0, 0, 0, 0, HInstance, NIL);
Думаю то что здесь, понять не составит труда. Теперь стоит понять, что у нас есть окошко со стилем WS_EX_LAYERED и это дает нам по сути установить и отобразить любое 32х битное изображение разумеется в формате ARGB никакие PNG и т.п. на прямую не ставятся. Как же это сделать?
Код:
Context: GpGraphics;
Tmp: TDIB;
Image: TDIB;
Rect: TRect;
begin
// Rect := GetWindowRect(); / GetClientRect(); не помню как точно, сами разберетесь
Tmp := TDIB.Create(Rect.right – Rect.left, Rect.bottom – Rect.top); // создаем битмап по размеру окна
Image := TDIB.Create(’my_image.png’); // загрузим какое то изображение
GdipCreateFromHDC(Tmp.DC, Context); // создадим контекст GDI+ c Tmp
GdipSetSmoothingMode(Context, SmoothingModeAntiAlias); // antialias включим
GdipSetCompositingMode(Context, CompositingModeSourceCopy); // рисование с перекрытием
GdipSetInterpolationMode(Context, InterpolationModeHighQualityBicubic); // качественно масштабировать изображения
GdipDrawImageRectRect(Context, Image.Bitmap,
0, 0, Tmp.Width, Tmp.Height, // покрываем все окно
0, 0, Image.Width, Image.Height, // берем все изображение
UnitPixel, NIL, NIL, NIL);
GdipDeleteGraphics(Context);
Image.Free();
И так, мы узнали размер окна, создали битпам для окна, загрузили картинку, связали GDI+ с Tmp и нарисовали с помощью GDI+ нашу картинку, потом все освободили. Теперь у нас есть Tmp на с отрисованной картинкой. Осталось дело за малым, отобразить на окне.
Код:
BlendFunc: TBlendFunction;
ZPoint: TPoint;
LeftTop: TPoint;
Size: TSize;
Rect: TRect;
begin
with BlendFunc do
begin
BlendOp := AC_SRC_OVER;
BlendFlags := 0;
AlphaFormat := AC_SRC_ALPHA;
SourceConstantAlpha := 255; // не желательно менять это, да станет прозрачней, но тормаза начнутся, лучше перерисовать сам битмап в более прозрачный.
end;
// Rect := GetWindowRect(); / GetClientRect(); не помню как точно, сами разберетесь
ZPoint := Point(0, 0);
LeftTop := Point(Rect.left, Rect.top);
Size.cx := Rect.right – Rect.left;
Size.cy := Rect.bottom – Rect.top;
UpdateLayeredWindow(hWnd, 0, @LeftTop, @Size, Tmp.DC, @ZPoint, 0, @BlendFunc, ULW_ALPHA);
Разумеется, не забудьте сделать это Tmp.Free();
Опять такие, это мануалчик, проверять не могу сейчас, да и думаю тут суть ясна, садитесь и пробуйте.
DIB.rar
Обсудить на форуме – Полупрозрачность в Delphi

