1313interface
1414
1515uses
16- classes, sysutils, controls, forms, graphics,
17- simba.base;
16+ Classes, SysUtils, Controls, Forms, Graphics,
17+ simba.base,
18+ simba.ide_events;
1819
19- function ShowWindowSelector : TWindowHandle;
20+ type
21+ TSimbaWindowSelector = class (TObject)
22+ public
23+ constructor Create;
24+ destructor Destroy; override;
25+
26+ procedure Pick ;
27+ end ;
28+
29+ var
30+ SimbaWindowSelector: TSimbaWindowSelector;
2031
2132implementation
2233
@@ -27,81 +38,40 @@ implementation
2738 { $IFDEF DARWIN}
2839 CocoaAll, CocoaWSForms, CocoaUtils,
2940 { $ENDIF}
30- simba.baseclass, simba.vartype_windowhandle, simba.nativeinterface;
41+ simba.ide_maintoolbar,
42+ simba.vartype_windowhandle,
43+ simba.vartype_box,
44+ simba.process,
45+ simba.dialog,
46+ simba.nativeinterface,
47+ simba.initializations;
3148
3249type
33- TSimbaWindowSelectorBase = class (TSimbaBaseClass)
34- protected
35- FExcludeWindows: TWindowHandleArray;
36-
37- procedure HighlightWindow (Window: TWindowHandle); virtual ; abstract ;
38- public
39- function Select : TWindowHandle;
40- end ;
41-
42- // 4 forms to create a box around the window
43- TSimbaWindowSelectorSimple = class (TSimbaWindowSelectorBase)
44- protected
45- const
46- BORDER_SIZE = 4 ;
47- protected
48- FLeftForm, FRightForm, FTopForm, FBottomForm: TForm;
49-
50- procedure HighlightWindow (Window: TWindowHandle); override;
51- public
52- constructor Create;
53- destructor Destroy; override;
54- end ;
55-
56- // overlay a transparent form
57- TSimbaWindowSelectorFancy = class (TSimbaWindowSelectorBase)
50+ TWindowHighlighter = class
51+ protected const
52+ BORDER_SIZE = 3 ;
5853 protected
5954 FForm: TForm;
60-
61- procedure HighlightWindow (Window: TWindowHandle); override ;
55+ FLeftForm, FRightForm, FTopForm, FBottomForm: TForm;
56+ FExcludeWindows: TWindowHandleArray ;
6257 public
6358 constructor Create;
6459 destructor Destroy; override;
65- end ;
6660
67- function ShowWindowSelector : TWindowHandle;
68- begin
69- // Linux (xlib) does support transparent windows but display managers may or may not perform.
70- { $IF DEFINED(WINDOWS) or DEFINED(DARWIN)}
71- with TSimbaWindowSelectorFancy.Create() do
72- { $ELSE}
73- with TSimbaWindowSelectorSimple.Create() do
74- { $ENDIF}
75- try
76- Result := Select();
77- finally
78- Free();
61+ function GetWindowAtCursor : TWindowHandle;
62+ procedure Highlight (Window: TWindowHandle);
7963 end ;
80- end ;
8164
82- function TSimbaWindowSelectorBase.Select : TWindowHandle;
83- var
84- Window: TWindowHandle;
85- begin
86- Result := 0 ;
65+ constructor TWindowHighlighter.Create;
8766
88- while SimbaNativeInterface.MousePressed(EMouseButton.LEFT) do
67+ function FormToWindowHandle (Form: TForm): TWindowHandle;
8968 begin
90- Window := GetWindowAtCursor(FExcludeWindows);
91- if (Window <> 0 ) and (Window <> Result) then
92- begin
93- HighlightWindow(Window);
94-
95- Result := Window;
96- end ;
97-
98- Application.ProcessMessages();
99-
100- Sleep(25 );
69+ { $IFDEF DARWIN}
70+ Result := TCocoaWSCustomForm.GetWindowContentFromHandle(Form).window.windowNumber;
71+ { $ELSE}
72+ Result := Form.Handle;
73+ { $ENDIF}
10174 end ;
102- end ;
103-
104- constructor TSimbaWindowSelectorSimple.Create;
10575
10676 function CreateEdgeForm : TForm;
10777 begin
@@ -114,20 +84,49 @@ constructor TSimbaWindowSelectorSimple.Create;
11484 Result.SetBounds(0 , 0 , 0 , 0 );
11585 Result.Show();
11686
117- FExcludeWindows := FExcludeWindows + [Result.Handle];
87+ FExcludeWindows := FExcludeWindows + [FormToWindowHandle(Result)];
88+ end ;
89+
90+ function CreateTransparentForm : TForm;
91+ begin
92+ Result := TForm.CreateNew(nil );
93+ Result.FormStyle := fsSystemStayOnTop;
94+ Result.BorderStyle := bsNone;
95+ Result.Scaled := False;
96+ Result.SetBounds(0 , 0 , 0 , 0 );
97+ Result.Color := clGreen;
98+ Result.AlphaBlend := True;
99+ Result.AlphaBlendValue := 100 ;
100+ Result.Show();
101+
102+ { $IFDEF DARWIN}
103+ with TCocoaWSCustomForm.GetWindowContentFromHandle(Result) do
104+ window.setBackgroundColor(ColorToNSColor(Result.Color));
105+ { $ENDIF}
106+
107+ { $IFDEF WINDOWS}
108+ SetWindowLong(Result.Handle, GWL_EXSTYLE, GetWindowLong(Result.Handle, GWL_EXSTYLE) or WS_EX_LAYERED or WS_EX_TRANSPARENT);
109+ { $ENDIF}
110+
111+ FExcludeWindows := FExcludeWindows + [FormToWindowHandle(Result)];
118112 end ;
119113
120114begin
121115 inherited Create();
122116
117+ { $IF DEFINED(WINDOWS) or DEFINED(DARWIN)}
118+ FForm := CreateTransparentForm();
119+ { $ELSE}
123120 FLeftForm := CreateEdgeForm();
124121 FRightForm := CreateEdgeForm();
125122 FTopForm := CreateEdgeForm();
126123 FBottomForm := CreateEdgeForm();
124+ { $ENDIF}
127125end ;
128126
129- destructor TSimbaWindowSelectorSimple .Destroy;
127+ destructor TWindowHighlighter .Destroy;
130128begin
129+ FreeAndNil(FForm);
131130 FreeAndNil(FLeftForm);
132131 FreeAndNil(FRightForm);
133132 FreeAndNil(FTopForm);
@@ -136,57 +135,98 @@ destructor TSimbaWindowSelectorSimple.Destroy;
136135 inherited Destroy();
137136end ;
138137
139- procedure TSimbaWindowSelectorSimple.HighlightWindow (Window: TWindowHandle);
138+ function TWindowHighlighter.GetWindowAtCursor : TWindowHandle;
139+ begin
140+ Result := SimbaNativeInterface.GetWindowAtCursor(FExcludeWindows);
141+ end ;
142+
143+ procedure TWindowHighlighter.Highlight (Window: TWindowHandle);
140144begin
141145 with Window.GetBounds() do
142146 begin
143- FLeftForm.SetBounds(X1 - BORDER_SIZE, Y1 - BORDER_SIZE, BORDER_SIZE, Y2 - Y1 + (BORDER_SIZE * 2 ));
144- FRightForm.SetBounds(X2, Y1 - BORDER_SIZE, BORDER_SIZE, Y2 - Y1 + (BORDER_SIZE * 2 ));
145- FTopForm.SetBounds(X1, Y1 - BORDER_SIZE, X2 - X1, BORDER_SIZE);
146- FBottomForm.SetBounds(X1, Y2, X2 - X1, BORDER_SIZE);
147+ if (FForm <> nil ) then FForm.SetBounds(X1, Y1, X2 - X1, Y2 - Y1);
148+ if (FLeftForm <> nil ) then FLeftForm.SetBounds(X1 - BORDER_SIZE, Y1 - BORDER_SIZE, BORDER_SIZE, Y2 - Y1 + (BORDER_SIZE * 2 ));
149+ if (FRightForm <> nil ) then FRightForm.SetBounds(X2, Y1 - BORDER_SIZE, BORDER_SIZE, Y2 - Y1 + (BORDER_SIZE * 2 ));
150+ if (FTopForm <> nil ) then FTopForm.SetBounds(X1, Y1 - BORDER_SIZE, X2 - X1, BORDER_SIZE);
151+ if (FBottomForm <> nil ) then FBottomForm.SetBounds(X1, Y2, X2 - X1, BORDER_SIZE);
147152 end ;
148153end ;
149154
150- procedure TSimbaWindowSelectorFancy.HighlightWindow (Window: TWindowHandle) ;
155+ constructor TSimbaWindowSelector.Create ;
151156begin
152- with Window.GetBounds() do
153- FForm.SetBounds(X1, Y1, X2-X1, Y2-Y1);
157+ inherited Create();
154158end ;
155159
156- constructor TSimbaWindowSelectorFancy.Create ;
160+ destructor TSimbaWindowSelector.Destroy ;
157161begin
158- FForm := TForm.CreateNew(nil );
159- FForm.FormStyle := fsSystemStayOnTop;
160- FForm.BorderStyle := bsNone;
161- FForm.Scaled := False;
162- FForm.SetBounds(0 , 0 , 0 , 0 );
163- FForm.Color := clGreen;
164- FForm.AlphaBlend := True;
165- FForm.AlphaBlendValue := 100 ;
166- FForm.Show();
162+ inherited Destroy();
163+ end ;
167164
168- { $IFDEF DARWIN}
169- with TCocoaWSCustomForm.GetWindowContentFromHandle(FForm) do
170- begin
171- window.setBackgroundColor(ColorToNSColor(FForm.Color));
165+ procedure TSimbaWindowSelector.Pick ;
166+ var
167+ Selected, WinAtCursor: TWindowHandle;
168+ Highlighter: TWindowHighlighter;
169+ Pid: TProcessID;
170+ Bounds: TBox;
171+ begin
172+ Selected := 0 ;
173+ Highlighter := nil ;
174+ try
175+ Highlighter := TWindowHighlighter.Create();
172176
173- FExcludeWindows := [window.windowNumber];
174- end ;
175- { $ENDIF}
177+ while SimbaNativeInterface.MousePressed(EMouseButton.LEFT) do
178+ begin
179+ WinAtCursor := Highlighter.GetWindowAtCursor();
180+ if (WinAtCursor <> 0 ) and (WinAtCursor <> Selected) then
181+ begin
182+ Highlighter.Highlight(WinAtCursor);
183+ Selected := WinAtCursor;
184+ end ;
185+
186+ Application.ProcessMessages();
187+ Sleep(25 );
188+ end ;
176189
177- { $IFDEF WINDOWS}
178- SetWindowLong(FForm.Handle, GWL_EXSTYLE, GetWindowLong(FForm.Handle, GWL_EXSTYLE) or WS_EX_LAYERED or WS_EX_TRANSPARENT);
190+ if (Selected <> 0 ) and Selected.IsValid() then
191+ begin
192+ Pid := Selected.GetPID();
193+ Bounds := Selected.GetBounds();
179194
180- FExcludeWindows := [FForm.Handle];
181- { $ENDIF}
195+ DebugLn([EDebugLn.FOCUS], ' Window Selected: %d' , [Selected]);
196+ DebugLn([EDebugLn.FOCUS], ' - Dimensions: %dx%d' , [Bounds.Width - 1 , Bounds.Height - 1 ]);
197+ DebugLn([EDebugLn.FOCUS], ' - PID: %d (%s)' , [PID, IfThen(IsProcess64Bit(PID), ' 64 bit' , ' 32 bit' )]);
198+ DebugLn([EDebugLn.FOCUS], ' - Title: "%s"' , [Selected.GetTitle()]);
199+ DebugLn([EDebugLn.FOCUS], ' - ClassName: "%s"' , [Selected.GetClassName()]);
200+ DebugLn([EDebugLn.FOCUS], ' - Executable: "%s"' , [GetProcessPath(PID)]);
201+
202+ SimbaMainToolBar.WindowSelection := Selected;
203+ SimbaMainToolBar.ProcessSelection := Pid;
204+
205+ SimbaIDEEvents.Notify(SimbaIDEEvent.WINDOW_SELECTED, nil );
206+ end ;
207+ except
208+ on E: Exception do
209+ ShowErrorDialog(' Target Selector' , ' Exception occurred while selecting target %s' , [E.Message]);
210+ end ;
211+
212+ if (Highlighter <> nil ) then
213+ Highlighter.Free();
182214end ;
183215
184- destructor TSimbaWindowSelectorFancy.Destroy ;
216+ procedure DoCreate ;
185217begin
186- FreeAndNil(FForm);
218+ SimbaWindowSelector := TSimbaWindowSelector.Create();
219+ end ;
187220
188- inherited Destroy();
221+ procedure DoDestroy ;
222+ begin
223+ FreeAndNil(SimbaWindowSelector);
189224end ;
190225
226+ initialization
227+ SimbaInitialization_Add(ESimbaInit.IDE_BEFORE_SHOW, @DoCreate, ' SimbaWindowSelector' );
228+ SimbaInitialization_Add(ESimbaInit.IDE_DESTROY, @DoDestroy, ' SimbaWindowSelector' );
229+
191230end .
192231
232+
0 commit comments