How to hide firemonkey application button from Taskbar (XE4)?

后端 未结 4 858
天命终不由人
天命终不由人 2020-12-18 11:13

According to this question it is possible to hide fmx taskbar icon by changing window style to WS_EX_TOOLWINDOW. In XE2 and XE3 this code works:

<         


        
相关标签:
4条回答
  • 2020-12-18 11:49

    It seems that in XE4 FM apps there is no more handle for the application object. So we need to get the parent of the main form. Below two small methods to hide/show your app on the taskbar.

    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;
    

    We could also have used "Application.MainForm" instead of passing the mainform, but this variable is not assigned during the "OnCreate" Event of the mainform.

    So in your "OnCreate" Event off your mainform you can simply write:

    procedure TMyMainForm.FormCreate(Sender: TObject);
    begin
      HideAppOnTaskbar (self);
    end;
    
    0 讨论(0)
  • 2020-12-18 11:49
    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;
    
    0 讨论(0)
  • 2020-12-18 12:03

    Just tried this in XE7 and of course it didn't work. However a little look into FMX.PlatformWin shows the application handle is now exposed through the ApplicationHWND function, so the code that works on XE7 (don't forget to include unit FMX.Platform.Win and Winapi.Windows) is...

    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;
    

    The ShowWindow at the end is optional - it seems to make no difference. You can remove the extended styles and restore the WS_EX_APPWINDOW style to show the toolbar icon again.

    0 讨论(0)
  • 2020-12-18 12:07
    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 讨论(0)
提交回复
热议问题