Форум: "Начинающим";
Текущий архив: 2007.12.16;
Скачать: [xml.tar.bz2];
ВнизUpdateLayerWindow Найти похожие ветки
← →
Nightmare (2007-11-16 20:05) [0]Здравствуйте, я использую в своей программе для вывода интерфейса ULW и возникла такая проблема, как только в таймере начинает работать ULW и курсор не находится в области формы, то загрузка процессора составляет 0%, а как только я навожу курсор на форму то загрузка процессора увеличивается до 50%, хотя ничего по сути не меняется и обновление происходит точно также.
Может кто нибудь знает как это убрать?
P.S. для работы потребуется GDI+, и img я брал размером 1024Х768
var
pt1, pt2: TPoint;
sz: TSize;
bf: TBlendFunction;
DC: HDC;
Bmp: TBitmap;
procedure TFrm.FormCreate(Sender: TObject);
begin
Timer1.enabled:=False;
end;
procedure TFrm.Button1Click(Sender: TObject);
var
H: HBitmap;
Bitmap: TGPBitmap;
begin
Bitmap:=TGPBitmap.Create("Img.png");
Bmp:=TBitmap.Create;
Bitmap.GetHBITMAP(0,H);
Bmp.Handle:=H;
Timer1.Enabled:=true;
end;
procedure TFrm.Timer1Timer(Sender: TObject);
begin
if SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or
WS_EX_LAYERED) = 0 then ShowMessage(SysErrorMessage(GetLastError));
Width:=bmp.Width;
Height:=bmp.Height;
DC := GetDC(0);
sz.cx := Width;
sz.cy := Height;
pt1 := Point(Left, Top);
pt2 := Point(0,0);
with bf do begin
BlendOp := AC_SRC_OVER;
BlendFlags := 0;
SourceConstantAlpha := 255;
AlphaFormat := AC_SRC_ALPHA;
end;
UpdateLayeredWindow(Handle, DC, @pt1, @sz, bmp.Canvas.Handle, @pt2, 0, @bf, ULW_ALPHA);
ReleaseDC(0,DC);
end;
← →
Nightmare (2007-11-17 11:18) [1]Сообщение модератору:
Вы не могли могли бы переместить эту мету в раздел Media(или просто удалить), я случайно создал её не в том разделе.
Pleazeeeeeeeeeeee.
← →
sniknik © (2007-11-17 11:57) [2]ты ее правильно разместил, хоть и по ошибке, оформление темы как раз соответствует начинающим. читайте правила.
← →
antonn © (2007-11-17 11:59) [3]сохрани битмап 32бита от png на диск, удали все эти GDI+, загрузи битмап с диска и сразу выводи. Если будет виснуть - значит сам где то напортачил, понаставил каких нибудь компонент.
← →
Nightmare (2007-11-17 12:06) [4]На форме 1 кнопка и больше ничего.
сохрани битмап 32бита от png на диск, удали все эти GDI+, загрузи битмап с диска и сразу выводи
Это вы о чём?
← →
antonn © (2007-11-17 12:22) [5]код то разбирал? тот, что ты дал, использует GDI+ только для одного - вытаскивания png в tbitmap
http://desksoft.ru/index.php?forum=13&th=47
← →
Nightmare (2007-11-17 12:40) [6]antonn я видел твой пример уже давно, но проблема состоит в том что
если навести мышку на форму то она начинает есть 50% от процессора,
а если убрать мышку с формы то 0%, но обновление происходит точно также. И дело тут не в GDI, даже если убрать GDI и использовать обыкновенный битмар будет тоже самое.
← →
antonn © (2007-11-17 12:44) [7]и на моем примере тоже такое? значит дело в твоей дельфи (возможно компоненты левые) либо в системе стоят какие нибудь программы для "деланья прозрачных окон"
← →
Nightmare (2007-11-17 12:59) [8]В системе не стоит никаких левых программ.
Ненадо забывать что ULW происходит в таймере(мне это надо для анимации)
в твоём примере нет таймера и форма слишком маленькая, но добавив на твою форму таймер в котором выполняется процедура RenderForm, эффект получился аналогный(когда мышка на форме процессор загружен на 2-3% больше);
← →
antonn © (2007-11-17 13:06) [9]
if SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or
WS_EX_LAYERED) = 0 then ShowMessage(SysErrorMessage(GetLastError));
это можно делать один раз.
← →
homm © (2007-11-17 13:09) [10]> [0] Nightmare (16.11.07 20:05)
> Может кто нибудь знает как это убрать?
не использовать UpdateLayerWindow?
Отключи тень у указателя курсора.
Карточка какая, встроенная?
Ты хочешь нормальной работы функций, требующих аппаратное ускорение в оконной архитектуре виндовс, которая не менялась по сути 17 лет. В части полупрозрачных окон все держится на честном слове, об улучшениях в сторону увеличения производдительности и безключности даже не мечтай.
← →
Nightmare (2007-11-17 13:13) [11]
> if SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle,
> GWL_EXSTYLE) or
> WS_EX_LAYERED) = 0 then ShowMessage(SysErrorMessage(GetLastError));
>
> это можно делать один раз.
Не помогло
> об улучшениях в сторону увеличения производдительности и
> безключности даже не мечтай.
Веть в винампе как-то сделали.
← →
homm © (2007-11-17 13:16) [12]> [11] Nightmare (17.11.07 13:13)
> Веть в винампе как-то сделали.
что там сделали?
← →
antonn © (2007-11-17 13:18) [13]
> Веть в винампе как-то сделали.
странно, но насколько я понимаю, в винампе обычными регионами вырезается форма, на которой блитятся картинки...
какая версия дельфи?
← →
Nightmare (2007-11-17 13:21) [14]В винампе тоже ULW, с той же анимацией, и ест он столько же, как и моя форма если на неё не наводить мышку.
← →
Nightmare (2007-11-17 13:22) [15]BDS 2006
← →
homm © (2007-11-17 13:22) [16]> [14] Nightmare (17.11.07 13:21)
> В винампе тоже ULW, с той же анимацией,
Да ну? О_0 и как это чудо увидеть?
← →
homm © (2007-11-17 13:24) [17]Ты тень у мыши отключил? Какая карточка ответил?
← →
Nightmare (2007-11-17 13:28) [18]
> Да ну? О_0 и как это чудо увидеть?
В винампе есть скины с тенью, кроме как ULW тень на рабочий стол не сделать.
Тени у мыши нету, стандартный курсор Xp.
Карточка (не смейтесь) Radeon 9600
← →
homm © (2007-11-17 13:30) [19]> [18] Nightmare (17.11.07 13:28)
> В винампе есть скины с тенью,
И анимацией, ага?
Как часто твоя анимация обновляется.
> Карточка (не смейтесь) Radeon 9600
Здесь нет ничего смешного. Вполне достаточно для тебуемых тебе вещей, только не в виндовс.
← →
Nightmare (2007-11-17 13:33) [20]Alienware Invader и анимация и альфа канал(правда весит ~30мб).
← →
Nightmare (2007-11-17 14:00) [21]Ладно другой вопрос: Что происходит с формой если на нее навести мышку?
← →
antonn © (2007-11-17 14:02) [22]она много раз делает setcursor() :))
и еще маусмув посылает :)
← →
Nightmare (2007-11-17 14:07) [23]Ладно начнём с другого конца: ULW насколько я знаю недаёт компонентам перерисовываться перехватыя сообщение WM_Paint.Так Да?
← →
Nightmare (2007-11-17 15:08) [24]Я тут обнаружил ещё одну интересную вещь. Если запустить винамп(скин должен быть с альфа каналом) вместе с моим приложением и навести курсор на винамп, то моё приложение начинает ести 50% от процессора.
Странно, да.
← →
antonn © (2007-11-17 15:34) [25]DC := GetDC(0); вынеси из таймера
← →
Nightmare (2007-11-17 15:49) [26]Я уже давно вынес, но это всё равно не помогает.
antonn, а у тебя этот код разве нормально работает?
← →
antonn © (2007-11-17 16:03) [27]мой - нормально. и даже в таймере
← →
Nightmare (2007-11-17 16:34) [28]а мой код как работает, ну естественно если один раз делать
if SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or
WS_EX_LAYERED) = 0 then ShowMessage(SysErrorMessage(GetLastError));
и убратьDC := GetDC(0);
в таймере
и брать Img размером 1024Х768
← →
Nightmare (2007-11-17 16:36) [29]Или если у тебя нет GDI+ то сделай в своём коде Bitmap размером 1024Х768
← →
antonn © (2007-11-17 16:54) [30]работает, и даже 1152*864
← →
Nightmare (2007-11-17 17:00) [31]Напрашивается только один вывод - хреновый делфи. Это если учитывать что
винамп работает у меня нормально.
← →
Anatoly Podgoretsky © (2007-11-17 17:02) [32]> Nightmare (17.11.2007 17:00:31) [31]
Напрашивается совсем другой вывод, это не Дельфи хреновая.
← →
antonn © (2007-11-17 17:44) [33]уже бы давно скинул полный проект (исходники)...
← →
Nightmare (2007-11-17 18:22) [34]Ну свой исходник я выложить не смогу т.к. в нём много компонентов и кода, я доработал твой пример.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
ImageMain: TImage;
ImageMask: TImage;
Label1: TLabel;
Label2: TLabel;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var bmp,bmp2:TBitmap;
begin
bmp:=TBitmap.Create;
bmp2:=TBitmap.Create;
bmp.LoadFromFile("fon.bmp");
bmp2.LoadFromFile("mask.bmp");
Bmp.PixelFormat:=pf24bit;
Bmp2.PixelFormat:=pf24bit;
FormSplash.Show;
FormSplash.BuildCopy24to32( bmp,Bmp2, FormSplash.bt );
Timer1.Enabled:=true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Enabled:=False;
Timer1.Interval:=1;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
FormSplash.RenderForm;
end;
end.
{---------------------------------------------------------------------------------}
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TFormSplash = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
protected
procedure WMWINDOWPOSCHANGING(var Msg: TWMWINDOWPOSCHANGING); message WM_WINDOWPOSCHANGING;
public
BT:Tbitmap;
procedure RenderForm;
procedure BuildCopy24to32(_B_in,_B_mask:TBitmap; var _B_out: TBitmap);
end;
var
FormSplash: TFormSplash;
DC:HDC;
implementation
{$R *.dfm}
procedure TFormSplash.FormCreate(Sender: TObject);
begin
BT:=Tbitmap.Create;
BT.PixelFormat:=pf32bit;
end;
procedure TFormSplash.BuildCopy24to32(_B_in,_B_mask:TBitmap; var _B_out: TBitmap);
const
MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
PRGBArray = ^TRGBArray;
TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
PRGBAArray = ^TRGBAArray;
TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var x, y: Integer; RowOut: PRGBAArray; RowIn,RowInMask:PRGBArray;
begin
_B_out.Width:=_B_in.Width;
_B_out.Height:=_B_in.Height;
for y:=0 to _B_in.Height-1 do begin
RowOut:= _B_out.ScanLine[y];
RowIn:= _B_in.ScanLine[y];
RowInMask:= _B_mask.ScanLine[y];
for x:=0 to _B_in.Width-1 do begin
RowOut[x].rgbReserved:=trunc((RowInMask[x].rgbtBlue+RowInMask[x].rgbtGreen+RowInMask[x].rgbtRed)/3);
RowOut[x].rgbBlue:=byte(trunc(RowIn[x].rgbtBlue*RowOut[x].rgbReserved/255));
RowOut[x].rgbGreen:=byte(trunc(RowIn[x].rgbtGreen*RowOut[x].rgbReserved/255));
RowOut[x].rgbRed:=byte(trunc(RowIn[x].rgbtRed*RowOut[x].rgbReserved/255));
end;
end;
SetWindowLong(FormSplash.Handle,GWL_EXSTYLE, GetWindowLong(FormSplash.Handle,GWL_EXSTYLE) or WS_EX_LAYERED);
DC:= GetDC(0);
end;
procedure TFormSplash.RenderForm;
var zsize:TSize; zpoint:TPoint; zbf:TBlendFunction;
TopLeft: TPoint;
begin
width:=BT.Width;
height:=BT.Height;
zsize.cx := BT.Width;
zsize.cy := BT.Height;
zpoint := Point(0,0);
with zbf do begin
BlendOp := AC_SRC_OVER;
BlendFlags := 0;
AlphaFormat := AC_SRC_ALPHA;
SourceConstantAlpha := 255;
end;
TopLeft:=BoundsRect.TopLeft;
UpdateLayeredWindow(FormSplash.Handle,DC,@TopLeft,@zsize,BT.Canvas.Handle,@zpoin t,0,@zbf, ULW_ALPHA);
end;
procedure TFormSplash.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const SC_DRAGMOVE : Longint = $F012;
begin
if Button <> mbRight then begin
ReleaseCapture;
SendMessage(Handle, WM_SYSCOMMAND, SC_DRAGMOVE, 0);
end;
end;
procedure TFormSplash.WMWINDOWPOSCHANGING(var Msg: TWMWINDOWPOSCHANGING);
begin
SetWindowPos(Handle,HWND_TOPmost,Left,Top,Width,Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE );
end;
end.
← →
antonn © (2007-11-17 18:24) [35]
> Timer1.Interval:=1;
это чего такое? %)
← →
Anatoly Podgoretsky © (2007-11-17 18:29) [36]> antonn (17.11.2007 18:24:35) [35]
Это интервал, работать будет, но не так как думает автор
← →
Nightmare (2007-11-17 18:35) [37]а как он будет работать?
← →
Anatoly Podgoretsky © (2007-11-17 18:38) [38]Если повезет, то в лучшем случае раз в 10 мс, для платформы НТ
← →
Nightmare (2007-11-17 18:41) [39]ну это естественно, но суть не в таймере.
← →
Anatoly Podgoretsky © (2007-11-17 18:41) [40]> Nightmare (17.11.2007 18:41:39) [39]
Зачем же тогда спрашиваешь?
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.12.16;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.03 c