Lazarus

Programming => General => Topic started by: pcurtis on July 06, 2020, 11:48:50 pm

Title: Transparent form
Post by: pcurtis on July 06, 2020, 11:48:50 pm
Is it possible to make a form transparent, but keep the components solid?

Thanks in advance.
Title: Re: Transparent form
Post by: jamie on July 07, 2020, 12:58:15 am
Yes but there are two ways to do it, one that may work in all targets and one that works well that only works in Windows because of a couple API calls.

you need to be more specific on your requirements..
Title: Re: Transparent form
Post by: RAW on July 07, 2020, 02:26:28 am
On Windows you can use
Code: Pascal  [Select][+][-]
  1. CreatePolygonRgn, SetWindowRgn
  but this way the result is 100% transparent not semi transparent. Or you use a second window in the background with
Code: Pascal  [Select][+][-]
  1. AlphaBlend:= True; AlphaBlendValue:= 128;

In other words 1. cut out everything you don't need from window 1 and then create window 2 behind window 1 fully semi transparent ...
Trial and error ..  :)

Title: Re: Transparent form
Post by: Davo on July 07, 2020, 03:34:31 am
Some time ago I received guidance in this Forum to the same question. It works for me - Windows only. The relevant code insert into the FormShow event handler is :

Code: Pascal  [Select][+][-]
  1.   {make the form transparent - works only with Windows operating systems}
  2.   SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or
  3.     WS_EX_LAYERED);
  4.   SetLayeredWindowAttributes(Handle, clWhite, 255, LWA_COLORKEY);
  5.  
Title: Re: Transparent form
Post by: Handoko on July 07, 2020, 04:28:25 am
I remember there was a similar discussion, maybe helpful:
https://forum.lazarus.freepascal.org/index.php/topic,34038.msg222021.html
Title: Re: Transparent form
Post by: pcurtis on July 07, 2020, 04:35:12 am
@jamie - I use Win 10
@RAW - Any sample? (I'm not so advanced)
@Davo - I'm not quite sure what it does?
@Handoko - It's what I want but for "Any Component" not just TImage - Any ideas?

@All - Thanks for answering
Title: Re: Transparent form
Post by: Davo on July 07, 2020, 08:19:20 am
After including the code segment in the Form's OnShow procedure, the form itself will be transparent but any shapes created on the form or any lines drawn using a PaintBox component added to the form will show as floating over any background that is visible behind the form.

You will need to include unit Windows in the Form's uses clause.
Title: Re: Transparent form
Post by: pcurtis on July 07, 2020, 09:29:17 am
Davo - It works. I just had to set the forms colour to clWhite.

Cheers.
Title: Re: Transparent form
Post by: pcurtis on July 08, 2020, 12:17:40 pm
@DAVO - I have a small problem.

The code you suggested work, but there is one small problem.

On the form I display images, but if the image contains clWhite that part of the image also becomes see through  :(

Any ideas?
Title: Re: Transparent form
Post by: jamie on July 08, 2020, 12:42:32 pm
Use a different mask color for the form like a value 1 for example
Change the form color to 1 and the attribute settings to 1 also..

 The other way is to shift all white pixels down by 1 before displaying them

Other ways takes more. Code.
Title: Re: Transparent form
Post by: pcurtis on July 08, 2020, 01:25:14 pm
I haven't tried yet, but won't changing from clWhite to 1 just move the problem colour? I'm sure that the colour '1' also exists in the images.
Title: Re: Transparent form
Post by: pcurtis on July 08, 2020, 11:17:55 pm
Just as I thought. It just changes the problem colour  :(
Title: Re: Transparent form
Post by: RAW on July 09, 2020, 05:08:36 am
You can cut off everything you like from the form ...  :)

No colorkey necessary ...
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. interface
  5.  
  6. uses
  7.   Windows, Classes, SysUtils, Forms, Controls, Graphics, StdCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Memo1: TMemo;
  12.     Button1: TButton;
  13.     procedure FormCreate(Sender: TObject);
  14.     procedure Button1Click(Sender: TObject);
  15.     procedure Memo1MouseDown(Sender: TObject; Button: TMouseButton;
  16.       Shift: TShiftState; X, Y: integer);
  17.   private
  18.  
  19.   public
  20.  
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. procedure CutWnd(hForm: HWND);
  31. var
  32.   arrPts: array[0..12] of TPoint;
  33.   RGN: HRGN;
  34. begin
  35.   // cut off everything outside the polygon !!!
  36.  
  37.   // Point 1
  38.   arrPts[0].X := 0;
  39.   arrPts[0].Y := 0;
  40.   // Point 2
  41.   arrPts[1].X := 0;
  42.   arrPts[1].Y := 100;
  43.   // Point 3
  44.   arrPts[2].X := 350;
  45.   arrPts[2].Y := 100;
  46.  
  47.   arrPts[3].X := 350;
  48.   arrPts[3].Y := 200;
  49.  
  50.   arrPts[4].X := 50;
  51.   arrPts[4].Y := 200;
  52.  
  53.   arrPts[5].X := 50;
  54.   arrPts[5].Y := 100;
  55.  
  56.   arrPts[6].X := 0;
  57.   arrPts[6].Y := 100;
  58.  
  59.   arrPts[7].X := 0;
  60.   arrPts[7].Y := 220;
  61.  
  62.   arrPts[8].X := 250;
  63.   arrPts[8].Y := 220;
  64.  
  65.   arrPts[9].X := 250;
  66.   arrPts[9].Y := 260;
  67.  
  68.   arrPts[10].X := 150;
  69.   arrPts[10].Y := 260;
  70.  
  71.   arrPts[11].X := 150;
  72.   arrPts[11].Y := 220;
  73.  
  74.   arrPts[12].X := 0;
  75.   arrPts[12].Y := 220;
  76.  
  77.   // setup window
  78.   RGN := CreatePolygonRgn(arrPts, 13, Winding);
  79.   SetWindowRgn(hForm, RGN, True);
  80. end;
  81.  
  82. procedure TForm1.FormCreate(Sender: TObject);
  83. begin
  84.   BorderStyle := bsNone;
  85.   Width := 400;
  86.   Height := 300;
  87.   Position := poDesktopCenter;
  88.   Color := clGray; // only to see the difference !
  89.   Memo1.SetBounds(50, 100, 300, 100);
  90.   Memo1.Text := 'Move Window With MemoOnMouseDown';
  91.   Button1.SetBounds(150, 220, 100, 40);
  92.   // cut form
  93.   CutWnd(Handle);
  94. end;
  95.  
  96. procedure TForm1.Button1Click(Sender: TObject);
  97. begin
  98.   // reset form
  99.   SetWindowRgn(Handle, 0, True);
  100. end;
  101.  
  102. procedure TForm1.Memo1MouseDown(Sender: TObject; Button: TMouseButton;
  103.   Shift: TShiftState; X, Y: integer);
  104. begin
  105.   // move window with mouse over memo
  106.   ReleaseCapture;
  107.   SendMessage(Handle, WM_SYSCOMMAND, $F012, 0);
  108. end;
  109.  
  110. end.
Title: Re: Transparent form
Post by: pcurtis on July 09, 2020, 11:50:29 am
@RAW Looks good - Thanks
Title: Re: Transparent form
Post by: Mr.Madguy on July 09, 2020, 06:28:16 pm
I had my screensaver-like flying triangle OpenGL program long time ago, but I've lost it's code and it's very complex, so I don't have time to recreate it in a nearest future.
Title: Re: Transparent form
Post by: RAW on July 09, 2020, 10:16:36 pm
You can create a semi transparent background ... maybe like this ...
Just in case you don't want the mouse go through ... or set AlphaBlendValue to 1 ...  :)
Title: Re: Transparent form
Post by: madref on July 14, 2020, 10:04:33 am
In the first post or so it was said there are 2 ways to do this... On that works on Windows and the other????


Since I use a Mac I am curious to the other way?
Title: Re: Transparent form
Post by: Warfley on July 14, 2020, 02:16:19 pm
SetWindowRgn is actually available in the LCLIntf unit across platforms. Simply include "LCLIntf" and "LCLType" and the code by RAW should work...

Well at least it should compile. If it actually works depends on the Widgetset. With QT4 and QT5 it works. I think I remember that on MacOS it does not work with Carbon probably also doesn't work with cocoa.
BUT you can simply use QT5 on macOS. Back when I had a mac and I needed this I used QT4 (QT5 was unusable with lazarus back then) to archive this. (And with simply I mean it only took me around 10 hours to get it running and it looked pretty bad, like oldschool macos, but QT5 should look native)
Title: Re: Transparent form
Post by: madref on July 15, 2020, 11:52:13 pm
Nope does NOT work.... :(


Or can you make me a working example?
Title: Re: Transparent form
Post by: Warfley on July 16, 2020, 08:41:43 am
I dont have a mac anymore (St least none i do programming on), but it works with QT5 on linux and I remember that with QT4  this also worked on macos (even though it was 4 years ago, a lot has changed since then in macos)
Title: Re: Transparent form
Post by: madref on July 17, 2020, 12:20:51 am
I am not working with QT.... I am with Cocoa
Title: Re: Transparent form
Post by: Warfley on July 17, 2020, 01:57:32 am
If it actually works depends on the Widgetset. With QT4 and QT5 it works. I think I remember that on MacOS it does not work with Carbon probably also doesn't work with cocoa.
BUT you can simply use QT5 on macOS.

I never claimes it would work with cocoa (in fact i already doubted this when I made the post). But using qt for mac is (once it is setup) rather easy because you can ship the required dependencies within the AppBundle format.

Its a common problem (or at least it was when i used a mac) that both, carbon and cocoa had some quirks that made some LCL functionality inacessible. Back then neitger gtk nor qt where an alternative (gtk2 required x11 and looked absolutely terrible and qt4 looked like macos 10.4), but if I had to support macos now, i would probably go for qt5, looks native and has a much broader LCL support than cocoa.

But long story short, i already suspected this to not work with cocoa, so either use a different WS, or you simply cant do it (well maybe via raw api acess, but i know way to little about cocoa to answer this question)
Title: Re: Transparent form
Post by: madref on July 17, 2020, 05:01:11 am
to bad there is no other solution
Title: Re: Transparent form
Post by: skalogryz on July 17, 2020, 05:34:19 am
Nope does NOT work.... :(

could you please specify what exactly doesn't work on Cocoa.
otherwise it's hard to assist

https://www.dropbox.com/s/hbonwecvfcd6spr/windowblend.mov?dl=0
Title: Re: Transparent form
Post by: madref on July 17, 2020, 09:53:02 pm
The form just will not be transparant.
I have this full screen form that only has to be shown the top 235 pixels.
Title: Re: Transparent form
Post by: madref on July 19, 2020, 05:11:47 pm
and that will not happen as the windows version
Title: Re: Transparent form
Post by: madref on July 19, 2020, 05:28:38 pm
And this is what I want to achieve. But now it are two forms
TinyPortal © 2005-2018