1

Тема: Як згорнути в трей програму після того, як вона запустилась?

Хай. От дивіться, є одна прога, котру треба запускати кожен раз, як я запускаю комп. Ну я помістив ярлик цієї програми в папку "Автозагрузка". Коли ця прога запускаєтья, то її здорове вікно закриває мені весь робочий стіл, і якщо натиснути на червону кнопку з хрестиком, ну типу щоб закрити прогу, то вона згортається в трей. А як мені це все автоматизувати? Щоб при запуску вона сама згорталась в трей?

2

Re: Як згорнути в трей програму після того, як вона запустилась?

У властивостях ярлика є пункт "запускати згорнутим". А далі програма сама має розуміти, в трей їй чи не в трей.

3

Re: Як згорнути в трей програму після того, як вона запустилась?

koala написав:

У властивостях ярлика є пункт "запускати згорнутим". А далі програма сама має розуміти, в трей їй чи не в трей.

але воно не працює для цієї проги ┐(‘~` )┌

4

Re: Як згорнути в трей програму після того, як вона запустилась?

Ну то вже вибачте, "згортання в трей" - не стандартна операція, а за бажання програміста. Шукайте в налаштуваннях програми, пишіть скріпт autoit чи ще якось викручуйтеся

5

Re: Як згорнути в трей програму після того, як вона запустилась?

-_-

6

Re: Як згорнути в трей програму після того, як вона запустилась?

http://www.softpedia.com/get/System/OS- … Tray.shtml

Подякували: koala1

7

Re: Як згорнути в трей програму після того, як вона запустилась?

І взагалі, трей - це збочення. Все має бути в доку, з можливістю налаштування положення і розмірів :)

8

Re: Як згорнути в трей програму після того, як вона запустилась?

koala написав:

І взагалі, трей - це збочення. Все має бути в доку, з можливістю налаштування положення і розмірів :)

доку?

9

Re: Як згорнути в трей програму після того, як вона запустилась?

Не кажіть, що не знали про це

10

Re: Як згорнути в трей програму після того, як вона запустилась?

забув просто, та сама панель задач

11

Re: Як згорнути в трей програму після того, як вона запустилась?

В МакОС є і док і трей. У вінді, починаючи з сімки, також уже фактично док.
До речі, у мене також колись була подібна проблема, але треба було згортати усі програми, навіть ті, які самі згортатися не вміють. Це необхідно було для того, щоб звільняти таскбар від усяких архіваторів та перекодувальників, які довго виконують якісь дії. Накидав отаку програмку на паскалі + WinAPI:

Прихований текст
program ToTray;
{
  Copyright (c) 1996 by Charlie Calvert
  Modifications by Florian Klaempfl

  Standard Windows API application written in Object Pascal.
  No VCL code included. This is all done on the Windows API
  level.

  Last modifications by Torbins.
}

uses
  Messages, Windows;

const
  ClassName = 'ToTrayWindClass';
  WindowName = 'ToTray';

  NIM_ADD         = $00000000;
  NIM_MODIFY      = $00000001;
  NIM_DELETE      = $00000002;

  NIF_MESSAGE     = $00000001;
  NIF_ICON        = $00000002;
  NIF_TIP         = $00000004;

type
  TNotifyIconData = record
    cbSize: DWORD;
    Wnd: HWND;
    uID: UINT;
    uFlags: UINT;
    uCallbackMessage: UINT;
    hIcon: HICON;
    szTip: array [0..63] of Char;
  end;
  PNotifyIconData = ^TNotifyIconData;

  function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL;
    stdcall; external 'shell32.dll' name 'Shell_NotifyIconA';

var
  IconCapt: PChar;
  hWindow, hFWind: HWnd;
  hIcon: Windows.HICON;
  i: Integer;
  WndThread: Cardinal;
  TrayMes, TaskbarCreated: Cardinal;
  ThreadWindows: array of HWnd;
  AMessage: Msg;
  Param: String;

 { From SysUtils }
function StrComp(const Str1, Str2: PChar): Integer; assembler;
asm
        PUSH    EDI
        PUSH    ESI
        MOV     EDI,EDX
        MOV     ESI,EAX
        MOV     ECX,0FFFFFFFFH
        XOR     EAX,EAX
        REPNE   SCASB
        NOT     ECX
        MOV     EDI,EDX
        XOR     EDX,EDX
        REPE    CMPSB
        MOV     AL,[ESI-1]
        MOV     DL,[EDI-1]
        SUB     EAX,EDX
        POP     ESI
        POP     EDI
end;

function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
asm
        PUSH    EDI
        PUSH    ESI
        PUSH    EBX
        MOV     ESI,EAX
        MOV     EDI,EDX
        MOV     EBX,ECX
        XOR     AL,AL
        TEST    ECX,ECX
        JZ      @@1
        REPNE   SCASB
        JNE     @@1
        INC     ECX
@@1:    SUB     EBX,ECX
        MOV     EDI,ESI
        MOV     ESI,EDX
        MOV     EDX,EDI
        MOV     ECX,EBX
        SHR     ECX,2
        REP     MOVSD
        MOV     ECX,EBX
        AND     ECX,3
        REP     MOVSB
        STOSB
        MOV     EAX,EDX
        POP     EBX
        POP     ESI
        POP     EDI
end;

 { From JclSysInfo }
function GetWindowIcon(Wnd: HWND): Windows.HICON;
begin
  Result := GetClassLong(Wnd, GCL_HICON);
  if Result = 0 then
    Result := SendMessage(Wnd, WM_GETICON, ICON_BIG, 0);
  if Result = 0 then
    Result := LoadIcon(0, MakeIntResource(32512));
end;

 { Add Icon to Tray }
procedure AddIcon(h: HWND; m: Cardinal; hi: Windows.HICON; t: PChar);
var NIData: TNotifyIconData;
begin
  FillChar(NIData, SizeOf(TNotifyIconData), 0);

  with NIData do
  begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd := h;
    uID := 1;
    uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
    uCallBackMessage := m;
    hIcon := hi;
    CopyMemory(@szTip, t, 64);
  end;

  Shell_NotifyIcon(NIM_ADD, @nidata);
end;

procedure ModifyIcon(h: HWND; f: Cardinal; hi: Windows.HICON; t: PChar);
var NIData: TNotifyIconData;
begin
  FillChar(NIData, SizeOf(TNotifyIconData), 0);

  with NIData do
  begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd := h;
    uID := 1;
    uFlags := f;
    hIcon := hi;
    if f and NIF_TIP = NIF_TIP then
      CopyMemory(@szTip, t, 64);
  end;

  Shell_NotifyIcon(NIM_MODIFY, @nidata);
end;

 { Remove Icon from Tray }
procedure DelIcon(h: HWND);
var NIData: TNotifyIconData;
begin
  FillChar(NIData, SizeOf(TNotifyIconData), 0);

  with NIData do
  begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd := h;
    uID := 1;
  end;

  Shell_NotifyIcon(NIM_DELETE, @nidata);
end;

 { Process Window and Tray Massages }
function WindowProc(Window: HWnd; AMessage: UINT; WParam : WPARAM;
                    LParam: LPARAM): LRESULT; stdcall; export;
var
  twl, j: Integer;
  tmpIcon: Windows.HICON;
  tmpCapt: PChar;
  f: Cardinal;
begin
  WindowProc := 0;

  case AMessage of
    wm_Destroy:
      begin
        DelIcon(hWindow);
        twl := Length(ThreadWindows);
        if twl > 0 then
          for j := 0 to twl-1 do
            ShowWindow(ThreadWindows[j], SW_SHOW)
        else
          ShowWindow(hFWind, SW_SHOW);
        PostQuitMessage(0);
        Exit;
      end;
    wm_Timer:
      begin
        GetMem(tmpCapt, 64);
        try
          FillChar(tmpCapt^, 63, 0);
          GetWindowText(hFWind, tmpCapt, 63);
          tmpIcon := GetWindowIcon(hFWind);
          f := 0;
          if tmpIcon <> hIcon then
          begin
            f := NIF_ICON;
            hIcon := tmpIcon;
          end;

          if StrComp(tmpCapt, IconCapt) <> 0 then
          begin
            f := f or NIF_TIP;
            StrLCopy(IconCapt, tmpCapt, 63);
          end;
          if f <> 0 then
            ModifyIcon(hWindow, f, hIcon, IconCapt);
        finally
          FreeMem(tmpCapt);
        end;
      end;
  else
    if AMessage = TrayMes then
    begin
      if (lParam = WM_LBUTTONDOWN) or (lParam = WM_RBUTTONDOWN) or
        (lParam = WM_MBUTTONDOWN) then
      begin
        PostMessage(hWindow, WM_DESTROY, 0, 0);
      end;
    end
    else
      if AMessage = TaskbarCreated then
      begin
        DelIcon(hWindow);
        FillChar(IconCapt^, 63, 0);
        GetWindowText(hFWind, IconCapt, 63);
        AddIcon(hWindow, TrayMes, GetWindowIcon(hFWind), IconCapt);
      end;
  end;

  WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
end;

 { Register the Window Class }
function WinRegister: Boolean;
var
  WindowClass: WndClass;
begin
  WindowClass.Style := 0;
  WindowClass.lpfnWndProc := @WindowProc;
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := system.MainInstance;
  WindowClass.hIcon := LoadIcon(0, idi_Application);
  WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  WindowClass.hbrBackground := COLOR_WINDOW;
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := ClassName;

  Result := RegisterClass(WindowClass) <> 0;
end;

 { Create the Window Class }
function WinCreate: HWnd;
begin
  Result := CreateWindow(ClassName, WindowName, ws_Overlapped, -100, -100, 50,
    30, 0, 0, system.MainInstance, nil);

  {if Result <> 0 then begin
    ShowWindow(Result, SW_SHOWNA);
    ShowWindow(Result, SW_HIDE);
  end;}
end;

function GetErrorStr(code:Cardinal): string;
var
  MsgBuf: PChar;
begin
  Result:='';
  if FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or
       FORMAT_MESSAGE_FROM_SYSTEM, Nil, code, 0, @MsgBuf, 0, Nil)>0 then
  begin
    Result:=MsgBuf;
    LocalFree(Cardinal(MsgBuf));
  end;
end;

function OnTaskBar(Window: HWnd): Boolean;
begin
  Result := False;
  if (GetParent(Window) = 0) and (GetWindowLong(Window, GWL_EXSTYLE) and
    WS_EX_TOOLWINDOW = 0) and (GetWindowLong(Window, GWL_EXSTYLE) and
    WS_EX_NOACTIVATE = 0) then
    Result := True;
end;

function EnumThreadWndProc(Window: HWnd; LParam: LPARAM): BOOL; stdcall;
var
  twl: Integer;
  CName: PAnsiChar;
begin
  Result := True;

  if IsWindowVisible(Window) then
  begin
    twl := Length(ThreadWindows);
    SetLength(ThreadWindows, twl+1);
    ThreadWindows[twl] := Window;

    GetMem(CName, 256);
    try
      FillChar(CName^, 255, 0);
      if GetClassName(Window, CName, 255) = 0 then
        MessageBox(0, PChar('Can''t get Class Name'#13#10+
          GetErrorStr(GetLastError)), nil, mb_Ok);
      if (CName = 'TApplication') and OnTaskBar(Window) then
        hFWind := Window;
    finally
      FreeMem(CName);
    end;
  end;
end;

begin
  TrayMes := RegisterWindowMessage('WM_Tray');
  TaskbarCreated := RegisterWindowMessage('TaskbarCreated');

  hFWind := GetForegroundWindow;
  //hFWind := FindWindow('TTimerForm', nil);

  if (hFWind <> 0) and (hFWind <> GetDesktopWindow) and
    (hFWind <> FindWindow('Shell_TrayWnd', nil)) and
    (hFWind <> FindWindow('Progman', nil)) then
  begin
    if not WinRegister then
    begin
      MessageBox(0, PChar('Register failed'#13#10+GetErrorStr(GetLastError)),
        nil, mb_Ok);
      Exit;
    end;
    hWindow := WinCreate;
    if longint(hWindow) = 0 then
    begin
      MessageBox(0, PChar('WinCreate failed'#13#10+GetErrorStr(GetLastError)),
        nil, mb_Ok);
      Exit;
    end;

    GetMem(IconCapt, 64);
    try
      Param := ParamStr(1);
      if (Param = '/AllWnd') or (Param = '-AllWnd') then
      begin
        WndThread := GetWindowThreadProcessId(hFWind);
        EnumThreadWindows(WndThread, @EnumThreadWndProc, 0);
        FillChar(IconCapt^, 63, 0);
        GetWindowText(hFWind, IconCapt, 63);
        hIcon := GetWindowIcon(hFWind);
        AddIcon(hWindow, TrayMes, hIcon, IconCapt);
        if Length(ThreadWindows) > 0 then
          for i := 0 to Length(ThreadWindows)-1 do
            ShowWindow(ThreadWindows[i], SW_HIDE)
        else
          ShowWindow(hFWind, SW_HIDE);
      end
      else
      begin
        FillChar(IconCapt^, 63, 0);
        GetWindowText(hFWind, IconCapt, 63);
        hIcon := GetWindowIcon(hFWind);
        AddIcon(hWindow, TrayMes, hIcon, IconCapt);
        ShowWindow(hFWind, SW_HIDE);
      end;
      //Param := '';

      if SetTimer(hWindow, 1, 1000, nil) = 0 then
        MessageBox(0, PChar('SetTimer failed'#13#10+GetErrorStr(GetLastError)),
          nil, mb_Ok);

      while GetMessage(AMessage, 0, 0, 0) do
      begin
        TranslateMessage(AMessage);
        DispatchMessage(AMessage);
      end;
    finally
      FreeMem(IconCapt);
      KillTimer(hWindow, 1);
    end;
    Halt(AMessage.wParam);
  end;
end.

Коду могло б бути у п'ять разів менше, якби не бажання зробити виконуваний файл розміром усього 22Кб.

Подякували: koala, 0xDADA11C72