Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2008.11.02;
Скачать: [xml.tar.bz2];

Вниз

Прозрачность окна   Найти похожие ветки 

 
webpauk ©   (2008-01-29 17:09) [0]

Делаю окно полупрозрачным.
Как делаю - не понимаю.
Точнее понимаю как, но не понимаю почему это происходит.
Привожу код:


unit Unit1;

interface

uses
 Windows, Messages, Classes, Graphics, Forms;

type
 TRGB = record
   B, G, R: Byte;
 end;
 pRGB = ^TRGB;

 TForm1 = class(TForm)
   procedure FormPaint(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   fBmp: TBitmap;

   PrevParentWndProc: Pointer;
   procedure NewParentWndProc(var Msg: TMessage);
 end;

var
 Form1: TForm1;
 FTransparency: Integer;
 FTranspColor: TColor;

implementation

{$R *.dfm}

{Ñìåøèâàíèå öâåòîâ}
function MixBytes(FG, BG, TRANS: byte): byte;
 asm
   push bx
   push cx
   push dx
   mov DH,TRANS
   mov BL,FG
   mov AL,DH
   mov CL,BG
   xor AH,AH
   xor BH,BH
   xor CH,CH
   mul BL
   mov BX,AX
   xor AH,AH
   mov AL,DH
   xor AL,$FF
   mul CL
   add AX,BX
   shr AX,8
   pop dx
   pop cx
   pop bx      
end;

{Âûçîâ ïðîöåäóðû ñìåøèâàíèÿ öâåòîâ äëÿ êàæäîãî pixel}
procedure MixColors(Bitmap: TBitmap; Color: TColor);
var
 x, y: Integer;
 Dest: pRGB;
 fR, fG, fB: Byte;
begin
 fR:=GetRValue(FTranspColor);
 fG:=GetGValue(FTranspColor);
 fB:=GetBValue(FTranspColor);

 for y := 0 to Bitmap.Height - 1 do
 begin
   Dest := Bitmap.ScanLine[y];
   for x := 0 to Bitmap.Width - 1 do
   begin
     with Dest^ do
     begin
       R:=MixBytes(fR, R, FTransparency);
       G:=MixBytes(fG, G, FTransparency);
       B:=MixBytes(fB, B, FTransparency);
     end;
     Inc(Dest);
   end;
 end;
end;

{çàõâàò DC è îòðèñîâêà íà Canvas}
procedure TForm1.FormPaint(Sender: TObject);
var
 DC: hDC;
 P, A: Tpoint;
begin
 P:=Point(0, 0);
 A:=ClientToScreen(P);

 DC:=GetDC(0);
 BitBlt(fBmp.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, DC, A.X, A.Y, SrcCopy);
 ReleaseDC(0, DC);

 MixColors(fBmp, FTranspColor);
 BitBlt(Canvas.Handle, P.X, P.Y, fBmp.Width, fBmp.Height, fBmp.canvas.Handle, 0, 0, SRCCOPY);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 p: Pointer;
begin
 TransparentColorValue:=$00000001;
 TransparentColor:=True;

 FTransparency:=150;
 FTranspColor:=clBlue;

 fBmp:=TBitmap.Create;
 fBmp.Width:=ClientWidth;
 fBmp.Height:=ClientHeight;
 fBmp.PixelFormat := pf24Bit;

 PrevParentWndProc:=Pointer(GetWindowLong(Handle, GWL_WNDPROC));
 p:=MakeObjectInstance(NewParentWndProc);
 SetWindowLong(Handle, GWL_WNDPROC, LongInt(p));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 fBmp.Free;
 if HandleAllocated then SetWindowLong(Handle, GWL_WNDPROC, LongInt(PrevParentWndProc));
end;

procedure TForm1.NewParentWndProc(var Msg: TMessage);
begin
 Msg.Result:=CallWindowProc(PrevParentWndProc, Handle, Msg.Msg, Msg.WParam, Msg.LParam);

 case Msg.Msg of
   wm_Move, WM_ACTIVATE: Paint;
  end;
end;

end.


развивалось следующим образом:
1. сначала скрывалось окно, потом захватывался DC, потом окно отображалось и на нем рисовалась часть DC.
2. Возникла идея не скрывать окно, а вырезать его часть, захватывая DC.
3. Вырезать можно используя TransparentColor. Собственно говоря данный пример и должен был сначала Canvas заливать TransparentColorValue, захватывать DC, потом заливать не TransparentColorValue и рисовать часть контекста. Но в данном примере ничего не вырезается!!!! И всё работает!!!!
Может кто-нибудь поймет почему?


 
homm ©   (2008-01-29 17:11) [1]

> [0] webpauk ©   (29.01.08 17:09)
> Как делаю - не понимаю.

+1!


 
webpauk ©   (2008-01-29 17:14) [2]


> homm ©   (29.01.08 17:11) [1]

8(
сам того же мнения


 
webpauk ©   (2008-01-29 17:15) [3]

TransparentColor:=False;
тогда ничего не работает. Почему?


 
Dimaxx ©   (2008-01-29 17:35) [4]

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=30


 
webpauk ©   (2008-01-29 17:55) [5]


> Dimaxx ©   (29.01.08 17:35) [4]

цитата из ссылки: "При необходимости перерисовать полупрозрачное окно надо это окно ненадолго убрать с экрана"

Это не мой вариант!!!

> webpauk ©   (29.01.08 17:09)  
развивалось следующим образом:
1. сначала скрывалось окно, потом захватывался DC, потом окно отображалось и на нем рисовалась часть DC.
2. Возникла идея не скрывать окно, а вырезать его часть, захватывая DC.
3. Вырезать можно используя TransparentColor. Собственно говоря данный пример и должен был сначала Canvas заливать TransparentColorValue, захватывать DC, потом заливать не TransparentColorValue и рисовать часть контекста. Но в данном примере ничего не вырезается!!!! И всё работает!!!!
Может кто-нибудь поймет почему?


Вопрос не раскрыт: TransparentColor:=False/True - не работает/работает. Почему? Ведь нигде не производится заливка!


 
Dimaxx ©   (2008-01-29 17:57) [6]

Вот как реализовано в KOL:

procedure TControl.SetAlphaBlend(const Value: Integer);
const
 LWA_COLORKEY=$00000001;
 LWA_ALPHA=$00000002;
 ULW_COLORKEY=$00000001;
 ULW_ALPHA=$00000002;
 ULW_OPAQUE=$00000004;
 WS_EX_LAYERED=$00080000;
type
 TSetLayeredWindowAttributes=
   function( hwnd: Integer; crKey: TColor; bAlpha: Byte; dwFlags: DWORD )
   : Boolean; stdcall;
var
 SetLayeredWindowAttributes: TSetLayeredWindowAttributes;
 User32: THandle;
 dw: DWORD;
begin
 if Value = fAlphaBlend then Exit;
 fAlphaBlend := Value;
 User32 := GetModuleHandle( "User32" );
 SetLayeredWindowAttributes := GetProcAddress( User32,
                            "SetLayeredWindowAttributes" );
 if Assigned( SetLayeredWindowAttributes ) then
 begin
   dw := GetWindowLong( GetWindowHandle, GWL_EXSTYLE );
   if Byte( Value ) < 255 then
   begin
     SetWindowLong( fHandle, GWL_EXSTYLE, dw or WS_EX_LAYERED );
     SetLayeredWindowAttributes( fHandle, 0, Value and $FF, LWA_ALPHA);
   end
      else
     SetWindowLong( fHandle, GWL_EXSTYLE, dw and not WS_EX_LAYERED );
 end;
end;


Раз у тебя ХРюша - это как раз то.


 
webpauk ©   (2008-01-29 18:01) [7]


> Dimaxx ©   (29.01.08 17:57) [6]

AlphaBlend-устанавливает прозрачность для ВСЕЙ формы. Мне нужна часть!!!


 
webpauk ©   (2008-01-29 18:04) [8]

и еще непонятка.
если поместить прозрачную форму над другой прозрачной, то нижняя - вообще не отображается!!!


 
webpauk ©   (2008-01-29 18:11) [9]


> webpauk ©   (29.01.08 18:04) [8]

непонятка исчезла, когда изменил Form.ClassName


 
webpauk ©   (2008-01-29 18:58) [10]

а вот еще один метод прозрачности:
есть две формы одна со включенным alphablend, а вторая нет.
на одну из форм цепляем процедуры:

 private
   procedure WMPOCHANGE(var Msg: TMessage); message WM_WINDOWPOSCHANGED;
   procedure wmhittest(var Msg: TMessage); message WM_NCHITTEST;

procedure TForm1.WMPOCHANGE(var Msg: TMessage);
begin
 inherited;
 if Form2=nil then exit;

 Form2.Left:=Left+20;
 Form2.Top:=Top+20;
 form2.BringToFront;

end;

procedure TForm1.wmhittest(var Msg: TMessage);
var
 P: TPoint;
begin
 inherited;

 p := Point(msg.LParamLo, msg.LParamHi);
 p := ScreenToClient(p);
 if PtInRect(Rect(0, 0, Width, 20), P) then Msg.Result:=HTCAPTION;
end;


 
Fredy314 ©   (2008-01-29 20:32) [11]

Любители сложных решений, блин.
Вы ето
gif  с прозрачными областями,
png с переменной прозрачностью
или вообще psd со всеми наворотами для скинов не думали прикрутить?
Удачных вам подводных камней.


 
han_malign ©   (2008-01-31 12:20) [12]


> Ведь нигде не производится заливка!

WM_ERASEBKGND



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2008.11.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.007 c
2-1221985147
Вит__
2008-09-21 12:19
2008.11.02
Имена пользователей в Windows


11-1194706878
matroskin66
2007-11-10 18:01
2008.11.02
Несколько форм в dll


1-1201761034
mix
2008-01-31 09:30
2008.11.02
Вопрос по Drag&amp;Dock


15-1220713385
deadteachers
2008-09-06 19:03
2008.11.02
Хочу принять участие!


2-1222147865
vegarulez
2008-09-23 09:31
2008.11.02
Вопрос про хук.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский