Форум: "WinAPI";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];
ВнизМеханизм прорисовки скинов? Найти похожие ветки
← →
Hecker (2002-05-15 08:42) [0]Кто-нить знает как делают скины, типа как в ВинАмпе?
Как рисовать на кэпшене формы?
Если не трудно, киньте примерчик...
← →
Fellomena (2002-05-15 12:49) [1]Скины легко реализуются с помощью механизма "Серверов автоматизации".
См. COM и интерфейсы.
Так же в Королевстве есть статьи на эту тему.
← →
valery_f (2002-05-15 13:34) [2]2Fellomena - а не сложновато ли?
Все это делается обычной отрисовкой, к тому же - не очень-то сложной: битмапы в памяти, и по OnPaint "отплевывать" на Canvas формы через BitBlt - получается очень быстро. А если у формы отбить WM_ERASEBACKGROUND, то еще и мелькать не будет.
Вариант 2: на форме лежит TImage с фоном :)
Единственное "но" - скорее всего понадобятся кастомовые контролы, которые бы "вписывались" в скин, точнее - брали бы свое изображение из "заготовок".
А на кэпшене формы рисовать ничего не надо - его нужно вообще отключить, а на форме (и, соответственно, - в скине) предусмотреть область, которая будет использоваться как кэпшен.
← →
SPeller (2002-05-15 15:17) [3]2 valery_f (15.05.02 13:34)
На канве лучше не рисовать, а брать GetDC(Handle). При движении формы, могут быть косяки с рисованием. Канва и контекст формы это ж две разные вещи, никак не взаимосвязанные.
← →
valery_f (2002-05-15 16:26) [4]2 SPeller> Согласен. А еще лучше внедриться на уровень WM_PAINT / WM_ERASEBACKGROUND формы. Но начинающие могут пойти и от канваса (тоже ведь работает, а возни меньше), а кто поопытнее - сам догадается... ;)
← →
Игорь Шевченко (2002-05-15 16:32) [5]День добрый, valery_f,
И еще на уровень WM_NCPAINT, как у WinAmp"а.
С уважением,
← →
valery_f (2002-05-15 16:40) [6]2 Игорь Шевченко> Кажись, винампу WM_NCPAINT незачем - у него нет ни фрейма, ни капшна (ближайший аналог - BorderStyle формы = bsNone).
← →
SPeller (2002-05-15 16:47) [7]valery_f (15.05.02 16:40)
А мне кажется, у ВинАМПа есть заголовок. Я наблюдал такую картину, когда система была на грани умирания. Главное окно прорисовывалось как обычная виндовая форточка. С заголовком, кэпшином, границей. Там всё запутаннее чем кажется на первый взгляд.
← →
valery_f (2002-05-15 17:24) [8]2 SPeller> Это, скорее всего, был глюк. Ты ж наверное знаешь - перекрутить одной командой оконные флаги у TButton - и у кнопки появляется и бордюр, и капшин с кнопками minimize/maximize/close. Я не думаю, что они решили ТАК СИЛЬНО усложнить себе жизнь...
Во всяком случае, когда я делал скиновое окошко без бордюра и капшина - проблем вообще не испытывал, т.к. все делал сам и с виндой не торговался (это делаю я, это ты, тут я тебя перебью, а как мне тут через тебя пробиться и т.п.), тем более, что забот при этом не так уж много.
← →
Hecker (2002-05-15 21:57) [9]Спасибо за советы! Вроде всё понятно, но с кодом было бы лучше, может кто поделиться?
← →
SPeller (2002-05-16 00:53) [10]2Hecker ©
Вот пример из реальной жизни:
procedure TfrmOpen.FormCreate(Sender: TObject);
var imgdc,x,y:longint;i:integer;p:tutsettings;
begin
height:=460;
width:=510;
imgskin.top:=500;
hwnd:=frmopen.Handle;
fhdc:=getdc(hwnd);
hbmp:=createcompatiblebitmap(fhdc,510,460);
hdc:=createcompatibledc(fhdc);
oldobj:=selectobject(hdc,hbmp);
imgdc:=imgskin.Canvas.Handle;
bitblt(hdc,0,0,41,35,imgdc,0,0,srccopy);
for i:=1 to 8 do begin
x:=i*41;
y:=0;
bitblt(hdc,x,y,41,35,imgdc,42,0,srccopy);
end;
bitblt(hdc,369,0,141,35,imgdc,84,0,srccopy);
for i:=1 to 13 do begin
x:=0;
y:=i*30+5;
bitblt(hdc,x,y,41,30,imgdc,0,36,srccopy);
end;
bitblt(hdc,0,425,41,35,imgdc,0,67,srccopy);
for i:=1 to 8 do begin
x:=i*41;
y:=425;
bitblt(hdc,x,y,41,35,imgdc,42,67,srccopy);
end;
for i:=1 to 13 do begin
x:=369;
y:=i*30+5;
bitblt(hdc,x,y,141,30,imgdc,84,36,srccopy);
end;
bitblt(hdc,369,425,141,35,imgdc,84,67,srccopy);
timerlst.Enabled:=true;
srcdc:=imgdc;
selectobject(srcdc,imgskin.Picture.Bitmap.Handle);
end;
← →
Hecker (2002-05-16 02:39) [11]Огромное спасибо! А не знает ли кто, как делают рисунок на форме, а в некоторых местах (где рисунка нет) видно рабочий стол?
← →
Игорь Шевченко (2002-05-16 10:11) [12]День добрый, Hecker ©,
Работают с Region"ами. SetWindowRgn, CombineRgn и т.д.
С уважением,
← →
Игорь Шевченко (2002-05-16 10:15) [13]to valery_f (15.05.02 16:40)
Нас рассудит Spy++ :-)
У WinAmp"а есть в стилях окна и WS_CAPTION и WS_SYSMENU, следовательно, WM_NCPAINT он обрабатывает.
С уважением,
← →
valery_f (2002-05-16 11:58) [14]2 SPeller> fhdc:=getdc(hwnd) вижу, а где ReleaseDC?
2 Игорь Шевченко> Да, вижу, у главного окна винампа капшин есть, а вот у остальных - нет. Зачем-то он им понадобился именно в главном окне... Но вряд-ли для облегчения отрисовки :) Есть идеи?
← →
Игорь Шевченко (2002-05-16 12:12) [15]valery_f (16.05.02 11:58)
Для того, чтобы можно было на кнопки Minimize или Close нажать, к примеру. Как поступает любой неискушенный пользователь. :-)
С уважением,
← →
valery_f (2002-05-16 12:22) [16]Игорь Шевченко (16.05.02 12:12)
Minimize или Close можно сделать и самому (по одной строке кода). К тому же размер и положение этих кнопок у винампа уж никак не совпадают с виндовыми. Да и меню у них полностью свое...
← →
Игорь Шевченко (2002-05-16 12:51) [17]valery_f (16.05.02 12:22)
Дело не в коде, а в пользователе. Он привык жать на кнопки Close и Minimize у окна. У WinAmp"а (по крайней мере того, что стоит у меня) эти кнопки находятся на своих местах, неважно, что вид у них не совсем стандартный.
Затем и оставили :-)
С уважением,
← →
valery_f (2002-05-16 13:28) [18]Игорь Шевченко (16.05.02 12:51)
Да я не о логике оформления UI (окно должно иметь ХОТЬ КАКОЙ-ТО заголовок и ТАКИЕ-ТО кнопки на нем), а об имплементации. То, что и заголовок и кнопки они делают сами (без участия винды), я думаю, очевидно. Скорее всего - какие-то операции с окном требуют того, чтобы оно имело WS_CAPTION в атрибутах. Но к скинопроизводству это отношения уже не имеет.
← →
Hecker (2002-05-17 06:59) [19]Вот ещё вопрос по теме: КАК в ВинАмпе сделали такие настандартные кнопки?
← →
SPeller (2002-05-17 10:20) [20]2Hecker © (17.05.02 06:59)
procedure TfrmOpen.lblUpMouseEnter(Sender: TObject);
begin
if mupdowned then begin
bitblt(fhdc,lblup.Left,lblup.Top,24,15,imgskin.Canvas.Handle,154,119,srccopy);
uplimg:=true;
end
else if uplimg or (sender=frmopen) then begin
bitblt(fhdc,lblup.Left,lblup.Top,24,15,imgskin.Canvas.Handle,154,103,srccopy);
uplimg:=false;
end;
end;
procedure TfrmOpen.lblUpMouseLeave(Sender: TObject);
begin
if uplimg then begin
bitblt(fhdc,lblup.Left,lblup.Top,24,15,imgskin.Canvas.Handle,154,103,srccopy);
uplimg:=false;
end;
end;
procedure TfrmOpen.lblUpMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
todo:=-1;
//sleepex(100,false);
timerud.enabled:=true;
bitblt(fhdc,lblup.Left,lblup.Top,24,15,imgskin.Canvas.Handle,154,119,srccopy);
uplimg:=true;
mupdowned:=true;
end;
procedure TfrmOpen.lblUpMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
timerudoff:=true;
bitblt(fhdc,lblup.Left,lblup.Top,24,15,imgskin.Canvas.Handle,154,103,srccopy);
uplimg:=false;
mupdowned:=false;
end;
2valery_f (16.05.02 11:58)
А надо? И зачем? (
← →
valery_f (2002-05-17 14:39) [21]2 SPeller (17.05.02 10:20) Справка из хелпа по GetDC:
"After painting with a common device context, the ReleaseDC function must be called to release the device context. Class and private device contexts do not have to be released. The number of device contexts is limited only by available memory"
Во-первых - DC окна в процессе работы может меняться. Во всяком случае - при свертывании-развертывании окон - точно. Возможно, что винда не станет грохать DC, пока счетчик ссылок не обнулится релизами, но кто знает что у нее внутрях происходит?
Во вторых - ресурсы не резиновые. Разве тебе не случалось видеть, как в течение минуты GDI ресурсы уходят в ноль из-за того, что забываешь их освобождать?
В данном случае, может быть, ничего страшного не случится, но зачем этот "авось", когда разница - в одну-две строки кода? Тем более, что по хелпам - это нужно делать...
← →
Игорь Шевченко (2002-05-17 15:10) [22]valery_f (17.05.02 14:39)
> Во-первых - DC окна в процессе работы может меняться. Во
> всяком случае - при свертывании-развертывании окон - точно.
>
Далеко не всегда...
← →
Dorex (2002-05-18 18:57) [23]Прошу прощения, кто-нибудь может подсказать возможно ли добавить к кнопкам кэпшена свою, чтобы стиль у нее был, как и у стандартных? Стиль необходимо считывать и задавать "на лету", чтобы работа не зависела от системы и темы.
← →
Andrew_k (2002-05-18 23:42) [24]А сделать прозрачной часть формы, кстати, легко:
1) Устанавливаем Form1.TransparentColor в true
2) А Form1.TransparentColorValue в какое угодно значение, делаешь form1.color равным тому, чего ты захреначил в Form1.TransparentColorValue и теперь все куски формы, данного цвета, будут прозрачными.
← →
valery_f (2002-05-20 15:52) [25]Andrew_k (18.05.02 23:42)
Оч-чень хорошее и вкусное решение, но только для Windows XP :(
← →
Andrew_k (2002-05-21 15:47) [26]2Valery_f
А ни хрена :]
У меня под 9x/2k всё пашет!
Причем это не теория, я проверяю перед тем, как
посоветовать!
← →
XMan (2002-05-21 16:29) [27]Andrew_k (21.05.02 15:47)
Мил человек, попробуй еще раз под 9х... ;-)
А насчет 2к - не знаю, не пробовал...
← →
Zyv (2002-05-21 16:55) [28]2SPeller
Как-то с примером не очень получилось...
"Пример из жизни" работать должен, а не ругаться на необъявленные переменные, свойства и типы.
Если можно, с примером по-подробнее, плиз.
← →
SPeller (2002-05-21 19:23) [29]Zyv (21.05.02 16:55)
Не буду же я тебе сюда писать весь код модуля где эти переменные объявлены. Голова тебе для чего с руками? Разберись сам что к чему, объяви эти переменные, поработай и всё получится..
← →
Zyv (2002-05-22 11:53) [30]2SPeller
Спасибо, я вас тоже люблю.
С головой и руками все в порядке. Да и разобраться можно, конечно, если нужно.
Только вот писать на форумы "левые примеры" большого ума тоже не надо. Объявление p:tutsettings - это "хороший тон", если учесть, что переменная не используется вообще. Да и ReleaseDC тоже не помешало бы.
← →
SPeller (2002-05-22 12:28) [31]2Zyv (22.05.02 11:53)
Ну есть пара косячков. Переменную p забыл убрать, она для совершенно других целей используется. Главное что пример есть как чего делать. Я ведь не обещал полностью рабочего и отлаженного кода, а всего-лишь пример, как рисовать скины.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.007 c