我正在使用WS_EX_NOACTIVATE,但仍可以通过单击激活表单。 在Windows 10,Delphi XE8下进行测试。 我做错了什么?
主窗体(调用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.
工具栏表单(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.
答案 0 :(得分:0)
我无法发表评论,所以我必须发帖作为答案。
通过将焦点设置在您想要的任何窗口上,您可以轻松实现它。 只需使用EnumWindows获取所有窗口,然后使用SetForegroundWindow来放松焦点。 我在屏幕键盘的实现中做到了这一点。
这意味着当您点击窗口时会有焦点。 在OnClick方法中,使用您想要的句柄调用SetForegroundWindow 专注于你会再次失去焦点。 如果使用OnMouseDown方法,则会更快地失去焦点。
这是我6年前制作的生产代码。 你将不得不修改它,但我希望它会让你知道我在说什么。
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;