Reputation: 21
I am using WS_EX_NOACTIVATE, but form still can be activated by clicking on it. Testing under Windows 10, Delphi XE8. What am I doing wrong?
Main form (calling Form3.Show on button click):
unit Unit2;
...
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
...
procedure TForm2.Button1Click(Sender: TObject);
begin
form3.Show;
end;
end.
toolbar form (form3):
unit Unit3;
...
type
TForm3 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
protected
procedure CreateParams(var Params: TCreateParams); override;
public
...
procedure TForm3.CreateParams(var Params: TCreateParams);
const WS_EX_NOACTIVATE = $8000000;
begin
inherited;
Params.ExStyle := Params.ExStyle + WS_EX_NOACTIVATE;
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
FormStyle := fsStayOnTop;
end;
end.
Upvotes: 0
Views: 1119
Reputation: 68
I am not able to post comments yet so I have to post as an answer.
You can quite easily achieve it by setting the focus on any window you want. Just use EnumWindows to get all windows and then use SetForegroundWindow to loose focus. I did this in my implementation of an onscreen keyboard.
This means while you are clicking your window will have focus. In the OnClick method you call SetForegroundWindow with the Handle you want to have focussed an you will loose focus again. If you use the OnMouseDown method you will loose focus even faster.
Here is production code I made around 6 years ago. You will have to modify it but I hope it will give you the idea what I am talking about.
TWindowData = class(TObject)
private
FWDWindowHandle: HWND;
FWDWindowCaption: string;
FWDExeFileName: string;
procedure SetWDExeFileName(const Value: string);
procedure SetWDWindowCaption(const Value: string);
procedure SetWDWindowHandle(const Value: HWND);
public
property WDWindowCaption:string read FWDWindowCaption write SetWDWindowCaption;
property WDExeFileName:string read FWDExeFileName write SetWDExeFileName;
property WDWindowHandle: HWND read FWDWindowHandle write SetWDWindowHandle;
end;
function GetTitle (Hwnd: THandle; Param: Pointer): Boolean; stdcall;
{ get caption from every visible window }
var Text,TempString: string;
Buf : Array [0..100] of Char;
begin
result := True;
If (GetWindowLong(Hwnd,GWL_HWNDPARENT)=0) and (IsWindowVisible(Hwnd) or IsIconic(Hwnd))then
begin
TempString := GetWindowExeName(Hwnd);
SetLength (Text, 100);
GetModuleFileName( Hwnd,buf, 100 );
GetWindowText (Hwnd, PChar (Text), 100);
if NoSystemWindowOrSelf(TempString,Text) then
begin
MainForm.OneWindowData := TWindowData.create;
with MainForm.OneWindowData do
begin
WDWindowHandle := Hwnd;
WDWindowCaption := Text;
WDExeFileName := TempString;
end;
MainForm.WindowDataList.Add (MainForm.OneWindowData);
MainForm.lbWindowListMemo.Items.Add(text); { Show all Windows in this Memo }
end;
Result := True;
end;
end;
procedure TMainForm.bFillMemoClick(Sender: TObject);
var EWProc: EnumWindowsProc;
begin
WindowListMemo.Items.Clear;
WindowDataList.clear;
{ EnumWindows geht der Reihe nach alle offenen Fenster durch }
EWProc := GetTitle;
EnumWindows (@EWProc, 0);
end;
procedure TMainForm.FocusWindow;
{ Click on a Memo line to focus a window }
var TempWindowData : TWindowData;
begin
TempWindowData := TWindowData(WindowDataList[WindowListMemo.itemindex]);
SetForegroundWindow(TempWindowData.WDWindowHandle);
end;
Upvotes: 1