Ir al contenido


Foto

Evitar componentes asuman transparencia del formulario


  • Por favor identifícate para responder
14 respuestas en este tema

#1 Fleon

Fleon

    Advanced Member

  • Miembros
  • PipPipPip
  • 172 mensajes
  • LocationRepública Dominicana

Escrito 05 septiembre 2016 - 11:27

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


  • 0

#2 Fleon

Fleon

    Advanced Member

  • Miembros
  • PipPipPip
  • 172 mensajes
  • LocationRepública Dominicana

Escrito 08 septiembre 2016 - 12:34

¿No es posible lograr esto con delphi?.


  • 0

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 08 septiembre 2016 - 01:02

¿No es posible lograr esto con delphi?.


De ser posible debe ser, http://stackoverflow...mponent-visible

 

Saludos


  • 0

#4 Fleon

Fleon

    Advanced Member

  • Miembros
  • PipPipPip
  • 172 mensajes
  • LocationRepública Dominicana

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.


  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

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.

 

 

post-12294-0-33661900-1473369985.jpg

 

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


  • 1

#6 Fleon

Fleon

    Advanced Member

  • Miembros
  • PipPipPip
  • 172 mensajes
  • LocationRepública Dominicana

Escrito 09 septiembre 2016 - 07:12

Muchas gracias Escafandra, estaré revisando los enlaces.

 

Fleon xD


  • 0

#7 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 09 septiembre 2016 - 09:45

Una prueba de concepto en Win10 con delphi 7:


delphi
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, StdCtrls, ExtCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. Label1: TLabel;
  12. Button1: TButton;
  13. Panel1: TPanel;
  14. CheckBox1: TCheckBox;
  15. RadioButton1: TRadioButton;
  16. procedure FormCreate(Sender: TObject);
  17. procedure Button1Click(Sender: TObject);
  18. protected
  19. procedure WndProc(var Message: TMessage); override;
  20. private
  21. FForm: TForm;
  22. FullRgn, ClientRgn, CtlRgn: HRGN;
  23. procedure MakeFormTransparent;
  24. public
  25. end;
  26.  
  27. var
  28. Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. {$R *.dfm}
  33.  
  34. procedure TForm1.MakeFormTransparent;
  35. var
  36. AControl: TControl;
  37. A, Margin, X, Y, CtlX, CtlY: Integer;
  38. begin
  39. with FForm do
  40. begin
  41. Margin := (Width - ClientWidth) div 2;
  42. FullRgn := CreateRectRgn(0, 0, Width, Height);
  43. X := Margin;
  44. Y := Height - ClientHeight - Margin;
  45. ClientRgn := CreateRectRgn(X, Y, X + ClientWidth, Y + ClientHeight);
  46. CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);
  47. for A := 0 to ControlCount - 1 do
  48. begin
  49. AControl := Controls[A];
  50. if (AControl is TWinControl) or (AControl is TGraphicControl) then with AControl do
  51. begin
  52. if Visible then
  53. begin
  54. CtlX := X + Left;
  55. CtlY := Y + Top;
  56. CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height);
  57. CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
  58. end;
  59. end;
  60. end;
  61. SetWindowRgn(Handle, FullRgn, True);
  62. end;
  63. end;
  64.  
  65. procedure TForm1.WndProc(var Message: TMessage);
  66. begin
  67. case Message.Msg of
  68. WM_SYSCOMMAND:
  69. case Message.WParam of
  70. SC_MAXIMIZE, SC_MINIMIZE, SC_RESTORE:
  71. SetWindowPos(FForm.Handle, 0, Left + GetSystemMetrics(SM_CXFRAME),
  72. Top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME),
  73. Width - 2*GetSystemMetrics(SM_CXFRAME),
  74. Height - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME), 0);
  75. end;
  76. WM_CLOSE:
  77. FForm.Close;
  78. WM_MOVING:
  79. SetWindowPos(FForm.Handle, 0, PRECT(Message.lParam).left + GetSystemMetrics(SM_CXFRAME),
  80. PRECT(Message.lParam).top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME), 0, 0, SWP_NOSIZE);
  81. WM_SIZING:
  82. SetWindowPos(FForm.Handle, 0, PRECT(Message.lParam).left + GetSystemMetrics(SM_CXFRAME),
  83. PRECT(Message.lParam).top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME),
  84. PRECT(Message.lParam).Right - PRECT(Message.lParam).Left - 2*GetSystemMetrics(SM_CXFRAME),
  85. PRECT(Message.lParam).Bottom - PRECT(Message.lParam).Top - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME), 0);
  86. WM_SIZE:
  87. if FForm <> nil then
  88. SetWindowPos(FForm.Handle, 0, Left + GetSystemMetrics(SM_CXFRAME),
  89. Top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME),
  90. Width - 2*GetSystemMetrics(SM_CXFRAME),
  91. Height - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME), 0);
  92. WM_SETFOCUS:
  93. PostMessage(FForm.Handle, WM_SETFOCUS, 0, 0);
  94. end;
  95. inherited WndProc(Message);
  96. end;
  97.  
  98. procedure TForm1.FormCreate(Sender: TObject);
  99. begin
  100. FForm:= TForm.Create(self);
  101. FForm.Left:= Left + GetSystemMetrics(SM_CXFRAME);
  102. FForm.Top:= Top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
  103. FForm.Width:= Width - 2 * GetSystemMetrics(SM_CXFRAME);
  104. FForm.Height:= Height - GetSystemMetrics(SM_CYCAPTION) - 2*GetSystemMetrics(SM_CYFRAME);
  105. FForm.BorderStyle:= bsNone;
  106. while ControlCount > 0 do
  107. Controls[0].Parent:= FForm;
  108. FForm.Show;
  109. end;
  110.  
  111. procedure TForm1.Button1Click(Sender: TObject);
  112. begin
  113. AlphaBlend:= true;
  114. AlphaBlendValue:= 100;
  115. MakeFormTransparent;
  116. Windows.Beep(1000, 100);
  117. Label1.Caption:= 'Eureca';
  118. end;
  119.  
  120. end.

post-12294-0-45760300-1473435913.jpg

 

 

 

Saludos.

Archivos adjuntos


  • 1

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

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,


  • 0

#9 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

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:


cpp
  1. BOOL WINAPI Beep(
  2. _In_ DWORD dwFreq,
  3. _In_ DWORD dwDuration
  4. );

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.


  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 09 septiembre 2016 - 12:51

Para utilizar la API Beep de Windows debemos hacer esto:


delphi
  1. Winapi.Windows.Beep(100,100);

Saludos,


  • 0

#11 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 09 septiembre 2016 - 01:02

Para utilizar la API Beep de Windows debemos hacer esto:


delphi
  1. 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:

delphi
  1. type
  2. TWindowsBeep = function(dwFreq, dwDuration: DWORD): BOOL; stdcall;
  3.  
  4.  
  5.  
  6. var
  7. WindowsBeep: TWindowsBeep;
  8. begin
  9. @WindowsBeep:= GetProcAddress(GetModuleHandle('Kernel32.dll'), 'Beep');
  10. WindowsBeep(1000, 1000);
  11. end;

Saludos.
  • 0

#12 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

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,


  • 0

#13 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 10 septiembre 2016 - 09:09

Si compilas el proyecto original de delphi7 en Rad Studio Berlin, Windows.Beep no da errores.

 

post-12294-0-78873700-1473520167.jpg

 

 

Saludos.

Archivos adjuntos


  • 0

#14 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

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,


  • 0

#15 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

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:


delphi
  1. WM_SETFOCUS:
  2. PostMessage(FForm.Handle, WM_SETFOCUS, 0, 0);




Saludos.


  • 0




IP.Board spam blocked by CleanTalk.