Recent

Author Topic: Placing selection box on windows desktop?  (Read 2509 times)

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Placing selection box on windows desktop?
« on: November 16, 2020, 10:39:51 am »
I want to create a Windows only application which will operate on data at a specific region on the desktop. I have seen similar programs where one gets to place a rectangle on the desktop to define the region to work with.

How is that done?

I don't think by writing to the desktop because then there will be a permanent change to it...
What I want is to have a way to fairly accurately place a rectangle on the screen, which can be adjusted by the user (by mouse dragging) to accurately fit a specific region of the desktop inside it.
Then my new application will operate on that region while keeping its boundaries visible to the user.

I have seen a proposal to create an application with a form that is transparent and then draw to that using a different color. But then the operations will be to that application form while I want to use the desktop (or rather another application window on the desktop).

EDIT:
Forgot to say also that with the suggested code from the link above the created form is transparent also to the mouse so when clicking on some background item position one actually clicks on that and not on the now transparent form...

Any suggestions?
« Last Edit: November 16, 2020, 11:02:07 am by BosseB »
--
Bo Berglund
Sweden

winni

  • Hero Member
  • *****
  • Posts: 2117
Re: Placing selection box on windows desktop?
« Reply #1 on: November 16, 2020, 11:28:07 am »
Hi!

Put a panel on the first form.
Take a second Form.

If you drag the second form to the first form
you can do

Code: Pascal  [Select][+][-]
  1. Form2.Parent := Form1.Panel1;

Winni

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Re: Placing selection box on windows desktop?
« Reply #2 on: November 16, 2020, 12:18:24 pm »
Hi!

Put a panel on the first form.
Take a second Form.

If you drag the second form to the first form
you can do

Code: Pascal  [Select][+][-]
  1. Form2.Parent := Form1.Panel1;

Winni
I don't quite follow...
Do you mean to make a separate form to handle the transparency and use the main form to control the operations?
And the main form would be a normal application form and the second form the transparent one?

I have now tested the proposed transparent form code and it does make the form internals transparent.

Then I placed a panel at the bottom of that form and set it NOT to inherit the colors. Here I placed a "Close" button too.
But now the mouse clicks get eaten up somewhere else so buttons on that panel do not receive mouse clicks at all.
Breakpoints inside the OnClick of the button do not trigger...

There is actually no way to close the application except by the X button in upper right corner of the main form....
--
Bo Berglund
Sweden

GetMem

  • Hero Member
  • *****
  • Posts: 3807
Re: Placing selection box on windows desktop?
« Reply #3 on: November 16, 2020, 01:03:34 pm »
@BosseB

Please test attached project.

GetMem

  • Hero Member
  • *****
  • Posts: 3807
Re: Placing selection box on windows desktop?
« Reply #4 on: November 16, 2020, 06:47:13 pm »
@BosseB

As an alternative solution you can also test the following project.
« Last Edit: November 16, 2020, 07:02:05 pm by GetMem »

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Re: Placing selection box on windows desktop?
« Reply #5 on: November 16, 2020, 09:20:45 pm »
I cannot open any of these projects, or should I say when I open the projects there is no code editor shown and if I activate the code editor it is empty.
If I try to compile it states that there is no main project file.
Seems like these zip files are not complete or else that they reference files outside of the zip...

I am using Lazarus 2.0.10 and FPC 3.2.0
Is that what these are made for?
--
Bo Berglund
Sweden

GetMem

  • Hero Member
  • *****
  • Posts: 3807
Re: Placing selection box on windows desktop?
« Reply #6 on: November 16, 2020, 09:27:24 pm »
Quote
I cannot open any of these projects, or should I say when I open the projects there is no code editor shown and if I activate the code editor it is empty.
If I try to compile it states that there is no main project file.
Seems like these zip files are not complete or else that they reference files outside of the zip...

I am using Lazarus 2.0.10 and FPC 3.2.0
Is that what these are made for?
It was made with Lazarus trunk. I will convert them to Lazarus 2.0.10 soon.

GetMem

  • Hero Member
  • *****
  • Posts: 3807
Re: Placing selection box on windows desktop?
« Reply #7 on: November 16, 2020, 09:45:35 pm »
The following attachment contains the converted version for Lazarus 2.0.10.

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Re: Placing selection box on windows desktop?
« Reply #8 on: November 16, 2020, 10:28:06 pm »
Meanwhile I created a new project in Lazarus and manually copied the code in from your zip project (the last one) and made it compile.
So this is a rectangle I can place over some area on the desktop.
Resize and move by using the red square at the lower right and close via the pop menu at the square. Fine.

Thanks for the code, I will start looking at how it works now and try to adapt to my use case. But first some evening tea....
--
Bo Berglund
Sweden

GetMem

  • Hero Member
  • *****
  • Posts: 3807
Re: Placing selection box on windows desktop?
« Reply #9 on: November 17, 2020, 04:28:33 am »
@BosseB
You're welcome! In the converted version, I forgot to set FormStyle to fsSystemStayOnTop. This is needed for obvious reasons.

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Re: Placing selection box on windows desktop?
« Reply #10 on: November 28, 2020, 09:51:38 am »
@BosseB
You're welcome! In the converted version, I forgot to set FormStyle to fsSystemStayOnTop. This is needed for obvious reasons.
Back again after some ffmpeg investigations.
I have checked that I can use ffmpeg to capture the video in a defined rect area of the desktop.
It seems to work fine for the image part of the video, not yet solved: how to get the corresponding audio.
But that is for another thread..

Now I need the rectangle to create a selection function so the user (me) can place a video grabbing region on screen and get the coordinates for ffmpeg to use.
So I want to have a "select window" function in my app which should create the rectangle form and let the user place it and then when it is closed grab the rect coordinates for use with ffmpeg.

Concerning your comment above:
How exactly am I supposed to set this FormStyle property?
In code or using the Object Inspector on the form?
Any preference on which to use?
And can the entire thing be created in code without having a form unit included in the project?

It would be nice to have a function "SelectCaptureRegion" which when called creates the rectangular frame form all in code so only the pas file is needed...
Or is that overkill?
--
Bo Berglund
Sweden

lucamar

  • Hero Member
  • *****
  • Posts: 3436
Re: Placing selection box on windows desktop?
« Reply #11 on: November 28, 2020, 10:27:31 am »
And can the entire thing be created in code without having a form unit included in the project?

It would be nice to have a function "SelectCaptureRegion" which when called creates the rectangular frame form all in code so only the pas file is needed...
Or is that overkill?

Yes, it can be, and any property that can be set in the object inspector can also be set in code. That's how most non-standard dialogs work. As for it being overkill ... well, it depends but for a simple "selection rectangle" kind of form it migth even be the preferred way to do it.

The advantage of designing a form in the IDE, setting properties in the OI, etc. is that the LCL can then load/create the form from a resource in the executable which is quite nice for "normal" forms with lots of controls of some set size, set in some defined position, with properties set to some non-default values; but for a bare form set at some size and in such position in the screen? You might as well do it in code.

Do note that for a well behaved form you might want to override/overload its Create() method and set the needed properties in it. That way you can be sure that however you create it, it'll always have those propeties set as you want (in this case BorderStyle, FormStyle, etc.). That is, you would make kind of a custom "dialog" from which you could set/read the values you need for your app without worrying about how it will work internally. Basically, how one works with, say, a TOpenDialog, etc.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Re: Placing selection box on windows desktop?
« Reply #12 on: November 28, 2020, 02:48:47 pm »
And can the entire thing be created in code without having a form unit included in the project?

It would be nice to have a function "SelectCaptureRegion" which when called creates the rectangular frame form all in code so only the pas file is needed...
Or is that overkill?

Do note that for a well behaved form you might want to override/overload its Create() method and set the needed properties in it. That way you can be sure that however you create it, it'll always have those properties set as you want (in this case BorderStyle, FormStyle, etc.). That is, you would make kind of a custom "dialog" from which you could set/read the values you need for your app without worrying about how it will work internally. Basically, how one works with, say, a TOpenDialog, etc.
OK thanks!
I started doing a unit that I could then use in other programs and when I let Lazarus autocreate the methods I defined in my class (same as in your program) I did not get what I expected for the Create method...
Here is what I entered and the framework created by Lazarus:

Code: Pascal  [Select][+][-]
  1. type
  2.  
  3. { TfrmSelectScreenRect }
  4.  
  5. TfrmSelectScreenRect = class(TForm)
  6.   miClose : TMenuItem;
  7.   pm : TPopupMenu;
  8.   procedure FormCreate(Sender : TObject); override; // <== override to add stuff
  9.   procedure FormResize(Sender : TObject);
  10.   procedure miCloseClick(Sender : TObject);
  11. protected
  12.   procedure CreateParams(var Params: TCreateParams); override;
  13. private
  14.   FIsBusy: Boolean;
  15.   procedure CreateTransparentForm;
  16. public
  17.  
  18. end;
  19.  
  20. function SelectCaptureRegion(var PosX, PosY, Width, Height: integer): boolean;
  21.  
  22. implementation
  23.  
  24. function SelectCaptureRegion(var PosX, PosY, Width, Height : integer) : boolean;
  25. begin
  26.  
  27. end;
  28.  
  29.  
  30. { TfrmSelectScreenRect }
  31.  
  32. procedure TfrmSelectScreenRect.FormCreate(Sender : TObject);
  33. begin
  34. // <== No inherited here! Why?
  35. end;
  36.  
  37. procedure TfrmSelectScreenRect.FormResize(Sender : TObject);
  38. begin
  39.  
  40. end;
  41.  
  42. procedure TfrmSelectScreenRect.miCloseClick(Sender : TObject);
  43. begin
  44.  
  45. end;
  46.  
  47. procedure TfrmSelectScreenRect.CreateParams(var Params : TCreateParams);
  48. begin
  49.   inherited CreateParams(Params);
  50. end;
  51.  
  52. procedure TfrmSelectScreenRect.CreateTransparentForm;
  53. begin
  54.  
  55. end;

Can I just add inherited there or is that not even needed?
Maybe I can assume it has been done when this event triggers so I can access the form and adjust its properties?
--
Bo Berglund
Sweden

lucamar

  • Hero Member
  • *****
  • Posts: 3436
Re: Placing selection box on windows desktop?
« Reply #13 on: November 28, 2020, 04:15:39 pm »
What I meant was that yo would you something like, for example:

Code: Pascal  [Select][+][-]
  1. type
  2.   TfrmSelectScreenRect = class(TForm)
  3.     {... other things here ...}
  4.   public
  5.     constructor Create(TheOwner: TComponent): overrride;
  6.   end;
  7.  
  8. function SelectCaptureRegion(var PosX, PosY, Width, Height: integer): boolean;
  9.  
  10. implementation
  11.  
  12. { TfrmSelectScreenRect }
  13.  
  14. constructor TForm1.Create(TheOwner: TComponent);
  15. begin
  16.   inherited Create(TheOwner);
  17.   {Now set properties of the form,
  18.    connect event handlers,
  19.    setup and add controls,
  20.    etc ...}
  21. end;
  22.  
  23. {... more code here ...}
  24.  
  25. end;

That allows you to setup a whole form entirely in code but if you have many controls with several properties changed from default it can result in a really huge constructor, which is (among other things) why Delphi introduced the mechanism for loading and setting up forms from a form resource.

In your case, if your form really must contain main and popup menus with several menu items (each of which, remember, is a component by itself) I would forget about doing all that in code and would use a "normal" form: it will look more "clean" and will be easier to maintain.

And, if for nothing else, pure laziness :D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

BosseB

  • Sr. Member
  • ****
  • Posts: 311
Re: Placing selection box on windows desktop?
« Reply #14 on: November 28, 2020, 05:51:44 pm »
But this form really contains the popup menu item just as a way to exit the form, since buttons and such are not clickable on the transparent form.
I noted that the little red square at the bottom right is where the popmenu activates and that it results in exiting the form altogether.
In the example the popup menu exits the application altogether using Application.Terminate...

I guess I might as well create my rectselect form as a complete form and skip this "create in code" idea...
After all the example application using only this form works.
I just have to replace Application.Terminate with a Form.Close.

EDIT
I ended up modifying the polygon statements so I increased the size of the bottom right little square to include an exit button (actually a TStaticText item with its OnClick hooked to the popup menu event). This way it is obvious how to close the selector.
I also added another TStaticText container there into which I write the current size of the selection box in pixels as feedback. And I set the initial size of the box to the most commonly used video I make (860x480).

Finally I added a clipboard output on exit where I put the correct ffmpeg arguments for selecting the area to record from:
-offset_x 995 -offset_y 355 -video_size 860x480
so it is ready to be pasted into the ffmpeg command.
« Last Edit: November 29, 2020, 10:23:07 am by BosseB »
--
Bo Berglund
Sweden

 

TinyPortal © 2005-2018