根据此question,可以通过将窗口样式更改为 WS_EX_TOOLWINDOW 来隐藏fmx任务栏图标。 在XE2和XE3中,此代码有效:
uses FMX.Platform.Win, Winapi.Windows;
procedure TForm1.Button1Click(Sender: TObject);
var h:THandle;
begin
h := FmxHandleToHWND(Handle);
ShowWindow(h, SW_HIDE);
SetWindowLong(h, GWL_EXSTYLE, GetWindowLong(h, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
ShowWindow(h, SW_SHOW);
end;
在XE4中,此解决方案不起作用(应用程序按钮应该隐藏但没有任何反应)。任何人都有任何想法吗?
感谢。
答案 0 :(得分:3)
在XE7中试过这个,当然它没有用。然而,稍微了解FMX.PlatformWin显示应用程序句柄现在通过ApplicationHWND函数公开,因此适用于XE7的代码(不要忘记包含单元FMX.Platform.Win
和Winapi.Windows
)是...
procedure HideAppOnTaskbar (AMainForm : TForm);
var
AppHandle : HWND;
begin
AppHandle := ApplicationHWND;
ShowWindow(AppHandle, SW_HIDE);
SetWindowLong(AppHandle, GWL_EXSTYLE, GetWindowLong(AppHandle, GWL_EXSTYLE) and (not WS_EX_APPWINDOW) or WS_EX_TOOLWINDOW);
//ShowWindow(AppHandle, SW_SHOW);
end;
最后的ShowWindow是可选的 - 似乎没什么区别。您可以删除扩展样式并恢复WS_EX_APPWINDOW样式以再次显示工具栏图标。
答案 1 :(得分:2)
似乎在XE4 FM应用程序中没有应用程序对象的句柄。 所以我们需要获取主窗体的父级。 以下两种小方法可以在任务栏上隐藏/显示您的应用。
procedure HideAppOnTaskbar (AMainForm : TForm);
var
AppHandle : HWND;
begin
AppHandle := GetParent(FmxHandleToHWND(AMainForm.Handle));
ShowWindow(AppHandle, SW_HIDE);
SetWindowLong(AppHandle, GWL_EXSTYLE, GetWindowLong(AppHandle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
end;
procedure ShowAppOnTaskbar (AMainForm : TForm);
var
AppHandle : HWND;
begin
AppHandle := GetParent(FmxHandleToHWND(AMainForm.Handle));
ShowWindow(AppHandle, SW_HIDE);
SetWindowLong(AppHandle, GWL_EXSTYLE, GetWindowLong(AppHandle, GWL_EXSTYLE) and (not WS_EX_TOOLWINDOW));
ShowWindow(AppHandle, SW_SHOW);
end;
我们也可以使用“Application.MainForm”而不是传递mainform,但是在mainform的“OnCreate”事件期间没有分配这个变量。
因此,在您的主要形式的“OnCreate”事件中,您只需写下:
procedure TMyMainForm.FormCreate(Sender: TObject);
begin
HideAppOnTaskbar (self);
end;
答案 2 :(得分:0)
HWND hWnd = NULL;
DWORD pid, current_pid = GetCurrentProcessId();
do
{
hWnd = FindWindowExA(NULL, hWnd, "TFMAppClass", NULL);
if(hWnd)
{
GetWindowThreadProcessId(hWnd, &pid);
if(current_pid == pid)
break;
}
} while(hWnd);
::SetParent(FmxHandleToHWND(Handle), NULL);
::ShowWindow(hWnd, SW_HIDE);
答案 3 :(得分:0)
procedure HideAppOnTaskbar;
var
appHandle: HWND;
pid, current_pid: DWORD;
name: String;
begin
//ShowWindow(FindWindowA('TFMAppClass', nil), SW_HIDE);
name := ChangeFileExt(ExtractFileName(ParamStr(0)), '');
appHandle := 0;
pid := 0;
current_pid := GetCurrentProcessId();
repeat
begin
//appHandle := FindWindowExA(0, appHandle, 'TFMAppClass', nil);
appHandle := FindWindowExA(0, appHandle, 'TFMAppClass', PAnsiChar(AnsiString(name)));
if (appHandle>0) then
begin
GetWindowThreadProcessId(appHandle, pid);
if (current_pid = pid) then break;
end;
end
until (appHandle>0);
//SetParent(FmxHandleToHWND(Handle), nil);
ShowWindow(appHandle, SW_HIDE);
end;
答案 4 :(得分:0)
这适用于 Delphi 10.3,它可能也适用于其他版本。
我不知道您是否注意到,但是每当您的代码到达 FormCreate 过程时,您的 FMX 应用程序就已经创建了一个任务栏按钮,至少在 Delphi 10.3.3 Rio 上是这样的我们可能不喜欢。因此,如果您使用建议的方法,您的应用程序将在任务栏中快速显示其图标以隐藏它。
因此,如果您可以访问 Delphi 的 VCL/FMX 源代码文件,并且您不希望显示您的应用程序任务栏图标甚至一毫秒,您只需修改位于 {{ 1}} 目录,然后将其复制到您的项目目录,因此它将被选中而不是原始目录,并按照以下建议修改 FMX.Platform.Win.pas
函数:
c:\Program Files (x86)\Embarcadero\Studio\20.0\source\fmx\
就是这样,你不需要其他方法,注意它还有 CreateAppHandle
传递你窗口的样式,如果你也想从 Alt-Tab 列表中隐藏它,替换 function TPlatformWin.CreateAppHandle: HWND;
var
...
begin
...
Result := CreateWindowEx(WS_EX_WINDOWEDGE or WS_EX_APPWINDOW, FMAppClass.lpszClassName, PChar(FTitle),
WS_POPUP or WS_GROUP, 0, 0, 0, 0, GetDesktopWindow, 0, hInstance, nil);
if FApplicationHWND = 0 then // modified/added line
Winapi.Windows.ShowWindow(Result, SW_HIDE) // modified/added line
else // modified/added line
Winapi.Windows.ShowWindow(Result, SW_SHOWNORMAL);
end;
用 CreateWindowEx
代替。