Hola a todos, ¿es posible evitar que los componentes dentro de un formulario no asuma la transparencia de su padre?, me explico, necesito por ejemplo, tener un formulario con su alphablend a 175 y si tengo un button o panel éstas no asuman la transparencia, ahora mismo no encuentro alguna propiedad que evite eso, ¿es posible?.
Fleon xD
Evitar componentes asuman transparencia del formulario
#1
Escrito 05 septiembre 2016 - 11:27
#2
Escrito 08 septiembre 2016 - 12:34
¿No es posible lograr esto con delphi?.
#3
Escrito 08 septiembre 2016 - 01:02
¿No es posible lograr esto con delphi?.
De ser posible debe ser, http://stackoverflow...mponent-visible
Saludos
#4
Escrito 08 septiembre 2016 - 02:10
Gracias Egostar, pero no me sirve, requiero usar el alphablend y no la transparencia total, utilizando el alphablend los componentes que contiene el formulario también lo asumen, y eso es lo quiero, que el alphablend sólo se aplique al formulario.
Fleon xD.
#5
Escrito 08 septiembre 2016 - 03:06
El problema de alphablend es que afecta a la ventana y por tanto a todo su contenido. Puede hacerse alphablend parcial como mostré en el turorial Transparencias. Para ello tienes que manejar el alphablend de cada pixel, uno a uno y no el global de la ventana. Otra forma es aplicar regiones a los controles y hacer el Form transparente para después pegarlo sobre otra semitransparente con una técnica similar a la que use aquí y aquí, donde rgstuamigo y yo le dábamos forma de componente. Probablemente en Win8 y Win10 de anomalías ese código que se podrán subsanar.
Por defecto delphi no lo hace porque windows no lo hace, hay que hacer "trampas", nada es imposible.
Te pongo un ejemplo visual con aquellos ejemplos que hice, corriendo en Win10.
Se ve el ejemplo de la barra de títulos semitransparente y encima otra ventana con regiones que hace trasparente el área cliente pero no los componentes.
Saludos.
Archivos adjuntos
#6
Escrito 09 septiembre 2016 - 07:12
Muchas gracias Escafandra, estaré revisando los enlaces.
Fleon xD
#7
Escrito 09 septiembre 2016 - 09:45
Una prueba de concepto en Win10 con delphi 7:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Label1: TLabel; Button1: TButton; Panel1: TPanel; CheckBox1: TCheckBox; RadioButton1: TRadioButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); protected procedure WndProc(var Message: TMessage); override; private FForm: TForm; FullRgn, ClientRgn, CtlRgn: HRGN; procedure MakeFormTransparent; public end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.MakeFormTransparent; var AControl: TControl; A, Margin, X, Y, CtlX, CtlY: Integer; begin with FForm do begin Margin := (Width - ClientWidth) div 2; FullRgn := CreateRectRgn(0, 0, Width, Height); X := Margin; Y := Height - ClientHeight - Margin; ClientRgn := CreateRectRgn(X, Y, X + ClientWidth, Y + ClientHeight); CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF); for A := 0 to ControlCount - 1 do begin AControl := Controls[A]; if (AControl is TWinControl) or (AControl is TGraphicControl) then with AControl do begin if Visible then begin CtlX := X + Left; CtlY := Y + Top; CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height); CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR); end; end; end; SetWindowRgn(Handle, FullRgn, True); end; end; procedure TForm1.WndProc(var Message: TMessage); begin case Message.Msg of WM_SYSCOMMAND: case Message.WParam of SC_MAXIMIZE, SC_MINIMIZE, SC_RESTORE: SetWindowPos(FForm.Handle, 0, Left + GetSystemMetrics(SM_CXFRAME), Top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME), Width - 2*GetSystemMetrics(SM_CXFRAME), Height - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME), 0); end; WM_CLOSE: FForm.Close; WM_MOVING: SetWindowPos(FForm.Handle, 0, PRECT(Message.lParam).left + GetSystemMetrics(SM_CXFRAME), PRECT(Message.lParam).top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME), 0, 0, SWP_NOSIZE); WM_SIZING: SetWindowPos(FForm.Handle, 0, PRECT(Message.lParam).left + GetSystemMetrics(SM_CXFRAME), PRECT(Message.lParam).top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME), PRECT(Message.lParam).Right - PRECT(Message.lParam).Left - 2*GetSystemMetrics(SM_CXFRAME), PRECT(Message.lParam).Bottom - PRECT(Message.lParam).Top - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME), 0); WM_SIZE: if FForm <> nil then SetWindowPos(FForm.Handle, 0, Left + GetSystemMetrics(SM_CXFRAME), Top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME), Width - 2*GetSystemMetrics(SM_CXFRAME), Height - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME), 0); WM_SETFOCUS: PostMessage(FForm.Handle, WM_SETFOCUS, 0, 0); end; inherited WndProc(Message); end; procedure TForm1.FormCreate(Sender: TObject); begin FForm:= TForm.Create(self); FForm.Left:= Left + GetSystemMetrics(SM_CXFRAME); FForm.Top:= Top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); FForm.Width:= Width - 2 * GetSystemMetrics(SM_CXFRAME); FForm.Height:= Height - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME); FForm.BorderStyle:= bsNone; while ControlCount > 0 do Controls[0].Parent:= FForm; FForm.Show; end; procedure TForm1.Button1Click(Sender: TObject); begin AlphaBlend:= true; AlphaBlendValue:= 100; MakeFormTransparent; Windows.Beep(1000, 100); Label1.Caption:= 'Eureca'; end; end.
Saludos.
Archivos adjuntos
#8
Escrito 09 septiembre 2016 - 11:46
Ese mismo código funciona también en Windows 8.1 + Delphi Berlin 10.1
La única cosa que tuve que hacer es comentar Windows.Beep() o bien poner Beep solo. Los errores me decían que no se encontraba Windows, y que Beep no espera tantos parámetros.
Saludos,
#9
Escrito 09 septiembre 2016 - 12:18
Ese mismo código funciona también en Windows 8.1 + Delphi Berlin 10.1
La única cosa que tuve que hacer es comentar Windows.Beep() o bien poner Beep solo. Los errores me decían que no se encontraba Windows, y que Beep no espera tantos parámetros.
Saludos,
Excelente.
Beep es una API de Windows con esta declaración:
BOOL WINAPI Beep( _In_ DWORD dwFreq, _In_ DWORD dwDuration );
En delphi ponemos windows.Beep para evitar la ambigüedad con Beep de delphi, es extraño que Delphi Berlin 10.1 no compile, tendré que probar cuando pueda.
Saludos.
#10
Escrito 09 septiembre 2016 - 12:51
Para utilizar la API Beep de Windows debemos hacer esto:
Winapi.Windows.Beep(100,100);
Saludos,
#11
Escrito 09 septiembre 2016 - 01:02
Para utilizar la API Beep de Windows debemos hacer esto:
delphi
Winapi.Windows.Beep(100,100);
Saludos,
Bueno, con motivo de este tema he instalado Delphi Berlin 10.1 sobre mi Builder Berlin y ya puedo usar ambos.
Efectivamente es como dices, delphius. Hay otra forma que es cambiar en el uses Winapi.Windows por Windows, con lo que podremos usar Windows.Beep.
O también importar la API de forma dinámica:
type TWindowsBeep = function(dwFreq, dwDuration: DWORD): BOOL; stdcall; var WindowsBeep: TWindowsBeep; begin @WindowsBeep:= GetProcAddress(GetModuleHandle('Kernel32.dll'), 'Beep'); WindowsBeep(1000, 1000); end;
Saludos.
#12
Escrito 09 septiembre 2016 - 01:20
A mi me resultado raro que no aceptara el Beep de Windows... asi de simple con tu código...
Y me resultó más raro cuando puse Beep(100,100) sin anteponer Windows, y que de esa forma intentaba usar Beep de SysUtils.
Cargar dinámicamente era mi última posibilidad, sabiendo que en uses ya se estaba declarada, me decía que no debería ser necesario. Entonces fue que capté que para usar el Beep de Windows hay que poner todo.
Estas cosas de que para nombrar una unit haya que poner algo.unit todavía me sienta raro.
Saludos,
#13
Escrito 10 septiembre 2016 - 09:09
Si compilas el proyecto original de delphi7 en Rad Studio Berlin, Windows.Beep no da errores.
Saludos.
Archivos adjuntos
#14
Escrito 10 septiembre 2016 - 10:45
Yo no lo copié todo de cero. Simplemente empecé un nuevo proyecto y copie la implementación de los métodos y las variables.
Creo que el tema pasa por como está nombrado en el uses: Winapi.Windows vs Windows. Estimo que si los borrara andaría tal como tu prueba.
Lo que si noté al probarlo es que al momento de hacer clic en la barra de título para mover el form vuelve al estado normal por un milisegundo y después vuelve a adquirir transparencia.
Saludos,
#15
Escrito 10 septiembre 2016 - 06:29
Lo que si noté al probarlo es que al momento de hacer clic en la barra de título para mover el form vuelve al estado normal por un milisegundo y después vuelve a adquirir transparencia.
No es exactamente eso lo que sucede, La ventana principal pierde el foco cuando se posa sobre ella la ventana cortina que ocupa todo su área cliente, esto es así para que sus controles no pierdan el foco. Cuando "clickeas" la barra de título, es la ventana principal la que se vuelve activa por un instante para pasarle de nuevo la actividad a la cortina, esto genera un extraño visual. Se podría evitar controlando el color de la barra de títulos...
Esta es la causa:
WM_SETFOCUS: PostMessage(FForm.Handle, WM_SETFOCUS, 0, 0);
Saludos.