Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Свободное общение
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.08.2010, 13:08   #1
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию to Kotoff / полупрозрачность в Delphi

Добрый день.
По причине не далекой, я не смог отправить вам личное сообщение. Но не думаю что тема будет лишней и поможет другим интересующимся.

И так, как сделать окошко в дельфи прозрачным с красивыми тенями и другой мутью.

Перво наперво, качаем gdiplus.dll (если есть желание) с MS Official Site

Потом смотрим мои (DIB) и не мои (GdiPlus) модули в аттаче.

И так... Подготовим плацдарм для нашего окошка

Код:
implementation

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 и т.п. на прямую не ставятся. Как же это сделать?

Код:
var
  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 на с отрисованной картинкой. Осталось дело за малым, отобразить на окне.

Код:
var
  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();

Опять такие, это мануалчик, проверять не могу сейчас, да и думаю тут суть ясна, садитесь и пробуйте.
Вложения
Тип файла: rar DIB.rar (45.4 Кб, 174 просмотров)
BOBAH13 вне форума Ответить с цитированием
Старый 16.08.2010, 15:04   #2
docbrain
Заблокирован
 
Регистрация: 14.01.2010
Сообщений: 306
По умолчанию

А куда весь этот код писать? В какой модуль?
docbrain вне форума Ответить с цитированием
Старый 16.08.2010, 15:14   #3
Vikenty
Заслуженный флудер
Участник клуба
 
Аватар для Vikenty
 
Регистрация: 31.03.2010
Сообщений: 1,473
По умолчанию

Цитата:
Сообщение от docbrain Посмотреть сообщение
А куда весь этот код писать? В какой модуль?
Создаешь новый проект, удаляешь из него форму, Project->View Source, туда и пишешь
Vikenty вне форума Ответить с цитированием
Старый 16.08.2010, 15:32   #4
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

-9 это показательно . docbrain, ты случайно Coel не родственник? Вроде тоже Делфист или Паскалист...
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 16.08.2010, 18:27   #5
zumm
БохЪ
Форумчанин
 
Аватар для zumm
 
Регистрация: 30.09.2009
Сообщений: 724
По умолчанию

Цитата:
-9 это показательно . docbrain, ты случайно Coel не родственник? Вроде тоже Делфист или Паскалист...
Ага, они с DRAgon™ три брата...
В планах порабощение вселенной...
zumm вне форума Ответить с цитированием
Старый 16.08.2010, 23:15   #6
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Вован, в журнальчик статейку не хотите писануть?
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 17.08.2010, 02:29   #7
DomiNick
Студент, не
Старожил
 
Аватар для DomiNick
 
Регистрация: 29.01.2009
Сообщений: 2,067
Лампочка

Так уже же почти всё и написано...

Цитата:
// Rect := GetWindowRect(); / GetClientRect(); не помню как точно
Если у окна есть рамка (хотя для слоёных окон она и не нужна по сути) - то первое, а если как в примере (только WS_POPUP) - то без разницы...

Переменные LeftTop, Size, ZPoint и BlendFunc лучше объявить глобальными, причём LeftTop нужно обновлять при перемещении окна (а то после UpdateLayeredWindow оно окажется в старом месте)...

Область битмапа которая "используется" для окна должна быть в пределах битмапа - то есть размер окна (в Size) не может быть больше размера битмапа (с учётом ZPoint), а в сам ZPoint нельзя помещать отрицательные числа...

И слоёное окно нельзя делать дочерним - возможны жуткие баги...
I am the First of Cyber Evolution...
I am the First to Program your Future...
DomiNick вне форума Ответить с цитированием
Старый 17.08.2010, 09:16   #8
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от DomiNick Посмотреть сообщение
Так уже же почти всё и написано...


Если у окна есть рамка (хотя для слоёных окон она и не нужна по сути) - то первое, а если как в примере (только WS_POPUP) - то без разницы...

Переменные LeftTop, Size, ZPoint и BlendFunc лучше объявить глобальными, причём LeftTop нужно обновлять при перемещении окна (а то после UpdateLayeredWindow оно окажется в старом месте)...

Область битмапа которая "используется" для окна должна быть в пределах битмапа - то есть размер окна (в Size) не может быть больше размера битмапа (с учётом ZPoint), а в сам ZPoint нельзя помещать отрицательные числа...

И слоёное окно нельзя делать дочерним - возможны жуткие баги...
Я в курсе, просто описал как сделать основные моменты (линейно если хотите) да и дельфи уже подзабыл, а проверить ставить надо так что только так выдал. И еще, там в DIB.pas очень много вкусных функций типа бленда и блюра, да и сам класс очень вкусный, т.к. дает сразу связку HDC + Gdi+ Bitmap + HBITMAP + Scan0. Кто хочет, может оформит статью, я врятли смогу

Последний раз редактировалось BOBAH13; 17.08.2010 в 09:18.
BOBAH13 вне форума Ответить с цитированием
Старый 17.08.2010, 09:28   #9
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

эм... оформить-то можно, но это будет максимум где-то 2 странички, несолидно как-то ...тут бы скрины, рабочий проект-пример, заключение с точки зрения автора, ссылки на сопутствующую литературу и ресурсы...
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 18.08.2010, 01:41   #10
spamer
Software Developer
Старожил
 
Аватар для spamer
 
Регистрация: 19.12.2008
Сообщений: 2,070
По умолчанию

Цитата:
Вован, в журнальчик статейку не хотите писануть?
Да, действительно было бы хорошо...возможно все же BOBAH13 и напишет статейку...
Будь проще и люди к тебе потянутся
spamer вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
На Delphi 7 сделать игру кто хочет стать миллионером в delphi 7 666dart666 Помощь студентам 11 04.11.2010 17:57
Прозрачность и полупрозрачность Алкаш Мультимедиа в Delphi 4 25.11.2008 01:04
Delphi. Как нарисовать в Delphi два движущиеся шара с определенной скоростью? redred Общие вопросы Delphi 10 11.12.2007 10:43
Как открыть БД, написанную в Delphi если нf другой машине Delphi нет? dagarik БД в Delphi 7 22.10.2007 17:54
Полупрозрачность - как? t3ns0r Общие вопросы Delphi 13 10.08.2007 10:04