Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
15-1195221717
йцукенЫЧ
2007-11-16 17:01
2007.12.16
Как найти компонент?


15-1195223462
data
2007-11-16 17:31
2007.12.16
вопрос ораклистам:


2-1195666514
sydenis
2007-11-21 20:35
2007.12.16
TApplication.ProcessMessages в консоли ?


2-1195413147
fog
2007-11-18 22:12
2007.12.16
Использование ScrollBars


2-1195795328
Fraider
2007-11-23 08:22
2007.12.16
Можно ли писать в файл?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский