Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.16;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.025 c
15-1195199758
Ega23
2007-11-16 10:55
2007.12.16
Несколько фреймов в одном юните - никак не сделать?


2-1195547767
DDDeN
2007-11-20 11:36
2007.12.16
Вывод целых чисел в определенном формате


8-1170672615
bobus
2007-02-05 13:50
2007.12.16
Картинки для панели инструментов


15-1195183314
Slider007
2007-11-16 06:21
2007.12.16
С днем рождения ! 16 ноября 2007 пятница


15-1195174258
Германн
2007-11-16 03:50
2007.12.16
И про футбол, но и не только :)