2013-05-27 5 views
2

В соответствии с этим question можно скрыть значок панели задач fmx, изменив стиль окна на WS_EX_TOOLWINDOW. В XE2 и XE3 этот код работает:Как скрыть кнопку приложения firemonkey с панели задач (XE4)?

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; процедура TForm2.Button1Click (отправитель: TObject); var h: THandle; начало h: = FmxHandleToHWND (ручка); 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, но эта переменная не назначается во время «OnCreate» Событие MainForm.

Так что в вашем "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.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, чтобы снова отобразить значок панели инструментов.

Смежные вопросы