2013-05-27 128 views
2

根据此question,可以通过将窗口样式更改为WS_EX_TOOLWINDOW来隐藏fmx任务栏图标。 在XE2以及XE3此代码的工作:如何从任务栏(XE4)隐藏firemonkey应用程序按钮?

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此解决方案无效(应用程序按钮应该被隐藏,但没有任何反应)。任何机构有任何想法?

谢谢。

+3

这个工作适合我在XE3上(没有MainformOnTaskbar):使用FMX.Platform.Win; procedure TForm2.Button1Click(Sender:TObject); var h:THandle; 开始 h:= FmxHandleToHWND(Handle); ShowWindow(h,SW_HIDE); SetWindowLong(h,GWL_EXSTYLE,GetWindowLong(h,GWL_EXSTYLE)或 WS_EX_TOOLWINDOW); ShowWindow(h,SW_SHOW); 结束; – bummi

+0

MainformOnTaskbar决定主窗体是否为无主窗体。 FMX中的主要形式可能始终是无主的,可能没有意义。所以使用工具窗口样式就足够了。 –

+0

建议的代码在XE4上不起作用。 –

回答

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); 
+0

谢谢。 “TFMAppClass”指出我正确的方向。我用Spy ++寻找类似的东西,但显然错过了它。 – VGeorgiev

+0

尽管这段代码有一个问题。 'ShowWindow(FindWindowA(“TFMAppClass”,NULL),SW_HIDE)'将隐藏第一个窗口,它找到的这个类可能不适用于你的应用程序。如果你有两个Firemonkey应用程序正在运行,或者两个实例之一运行...最好使用类似于FindWindow('TFMAppClass',PChar(ChangeFileExt(ExtractFileName(ParamStr(0)),'')))'或者甚至更好地将它与'GetWindowThreadProcessId'和'FindWindowEx'结合起来检查ti是否属于你的进程。 – VGeorgiev

+0

你是对的,我更新了代码。 –

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” 事件把你的MainForm可以简单的写:

procedure TMyMainForm.FormCreate(Sender: TObject); 
begin 
    HideAppOnTaskbar (self); 
end; 
+0

我测试了建议的代码。它不起作用(没有效果)。我认为这个代码只适用于XE3;还要注意函数FmxHandleToHWND不再存在于XE4上。 –

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; 
3

在XE7只是尝试这样做,当然也没有工作。但是稍微留意一下到FMX.PlatformWin显示应用程序句柄现在通过ApplicationHWND功能暴露出来,以便在XE7工作的代码(不要忘了,包括单元FMX.Platform.WinWinapi.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样式以再次显示工具栏图标。

相关问题