Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Максимум минимума или оптимизация проги!


Автор: PSYx 21.9.2005, 12:20
Я хо4у загнать в трэй прогу, которая будет пинговать каждую минуту машину в сети(по IP-шнику), но при этом(та4ка у меня слабая Р2-233 smile ) потребляля минимум ресурсов! Так вот меня интересует: нельзя ли обойтись без таймера, а ,скажем, перехватывать системное изменение времени на минуту(скажем когда те-же часы сменяют время на минуту- ведь есть же системное сообщение совершающее это!?)???
Ну или по крайней мере подскажите ссыло4ку на статьи по оптимизации своего софта, плз.
Спасибо всем кто откликнулся!

Автор: _hunter 21.9.2005, 12:32
можеш смело использовать таймер. на загрузку системы он не сильно влияет.
+ можеш процесс пингования запустить в отдельном потоке и Sleep(1000) вписать...

Автор: PSYx 21.9.2005, 12:41
Угу, пасибо, а 4то нас4ёт оптимизации програм в ОБЩЕМ? Нет ссыло4ек? Заранее спасибо!

Автор: _hunter 21.9.2005, 12:53
http://www.google.com.ua/search?hl=ru&as_qdr=all&q=%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC+delphi&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&meta=

Автор: Snowy 21.9.2005, 13:55
Что тебе нужно:
1. Сократить потребление процессорного времени, при этом, чтобы программа откликалась на иконку в трее.
2. Сократить потребление оперативной памяти.
Соответственно тебе нужен минимальный размер программы, использование чистого WinAPI, реакция только на сообщения, без дополнительной самодеятельности.
Как этого добиться?
Берешь типовую заготовку минимальной программы на WinAPI, с иконкой в трее.
Качаешь с сайта KOL SysDcu7 (переписанные system.pas и sysinit.pas), кладешь dcu'шки в папку с программой.
Использовать в программе только модули Windows и Messages.
Вот тебе готовая заготовка:
Код

program TraySample;

uses
  Windows, Messages;

{$R tsample.res}

const
 WM_TIMER = $0113;
 TIMER_ID = $2BA3;
 WM_TRAYICON=WM_APP+1; // сообщение от трей иконки
 TRAY_ID=$A77E; // идентификатор иконки в трее
 MY_CLASS='MyTClass'; // класс для регистрации в системе
 MY_NAME='TraySample'; // так меня зовут 
 TIMER_INTERVAL_VALUE=60000; // период срабатывания в миллисекундах
var
 MainMsg: TMSG;      // для передачи сообщений

type
  PNotifyIconData = ^TNotifyIconData; // структура для работы с иконкой в трее
  TNotifyIconData = record
    cbSize: DWORD;
    Wnd: HWND;
    uID: UINT;
    uFlags: UINT;
    uCallbackMessage: UINT;
    hIcon: HICON;
    szTip: array [0..63] of AnsiChar;
  end;

 // Служебные функции -----------------------------------------

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

 // добавить иконку в трей
function TaskBarAddIcon(hWindow: HWND; ID: Cardinal; ICON: hIcon;
 CallbackMessage: Cardinal; Tip: PChar): Boolean;
var
  NID: TNotifyIconData;
begin
  FillChar(NID, SizeOf(TNotifyIconData), 0);
  with NID do begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd   := hWindow;
    uID    := ID;
    uFlags := 7; // MESSAGE or ICON or TIP
    uCallbackMessage := CallbackMessage;
    hIcon  := Icon;
    lstrcpyn(szTip, Tip, SizeOf(szTip));
  end;
  Result := Shell_NotifyIcon(0, @NID); // AddIcon
end;

 // удалить иконку из трея
function TaskBarDeleteIcon(hWindow: HWND; ID: Integer): Boolean;
var
  NID: TNotifyIconData;
begin
  FillChar(NID, SizeOf(TNotifyIconData), 0);
  with NID do begin
    cbSize := SizeOf(TNotifyIconData);
    Wnd    := hWindow;
    uID    := ID;
  end;
  Result := Shell_NotifyIcon(2, @NID); // DeleteIcon
end;

 // всплывалка менюшки
procedure PopupMenu(hWin: HWND);
var
 Menu: hMenu;
 Popup: hMenu;
 P: TPoint;
begin
 Menu := LoadMenu(hInstance, 'MAINMENU');
 Popup := GetSubMenu(Menu, 0);
 GetCursorPos(P);
 SetForegroundWindow(hWin);
 TrackPopupMenu(Popup, TPM_LEFTBUTTON, P.X, P.Y, 0, hWin, NIL);
 PostMessage(hWin, WM_NULL, 0, 0);
 DestroyMenu(Menu);
end;


 // Основные функции -------------------------------------------------

procedure OnTimer(hWin: hwnd);
begin
  // тут действие по таймеру
  MessageBox(0, 'Минута прошла','Таймер говорит:',0);
end;

procedure OnCreate(hWin: hwnd); // Вызывается при старте программы
begin
  // пихаем иконку в трей
  TaskBarAddIcon(hWin, TRAY_ID, LoadIcon(hInstance, 'MAINICON'),
  WM_TRAYICON, MY_NAME);
  SetTimer(hWin, TIMER_ID, TIMER_INTERVAL_VALUE, nil);
end;

procedure OnDestroy(hWin: hwnd); // Вызывается при выходе из программы
begin
  TaskBarDeleteIcon(hWin, TRAY_ID); // прибить иконку
  KillTimer(hWin, TIMER_ID); // остановить таймер
end;

// Обработка сообщений windows
function MainWndProc(hWin: HWND; uMsg: UINT; wp: WPARAM; lp: WPARAM): Integer; stdcall; export;
begin
  Result:=0;
  case uMsg of
    WM_CREATE: OnCreate(hWin); // при старте программы
    WM_TIMER: OnTimer(hWin);   // по таймеру
    WM_TRAYICON: if wp=TRAY_ID then // при клике по трей иконке
      case lp of
        WM_RBUTTONDOWN: PopupMenu(hWin); //всплыть менюшке
        WM_LBUTTONDBLCLK: PostMessage(hWin, WM_COMMAND, 29, 0); //def в меню
      end;
    WM_COMMAND: // вызов комманды меню
      case LoWord(wp) of
        29: MessageBox(hWin, 'Угу','Гугу',0);
        30: PostMessage(hWin, WM_DESTROY, 0, 0); // выход
      end;
    WM_DESTROY: begin // умираем
        OnDestroy(hWin);
        PostQuitMessage(0); // умереть
      end;
    else Result:=DefWindowProc(hWin, uMsg, wp, lp); // прочие события
  end;
end;

procedure RegMWindow; // создать главное окно
var WClass:  TWndClass; // описатель главного окна
begin
  FillChar(wClass, SizeOf(wClass), 0);
  wClass.lpfnWndProc:=@MainWndProc;
  wClass.hInstance:=HInstance;
  wClass.lpszClassName:=MY_CLASS;
  RegisterClass(wClass); // регестрируемся в системе
  CreateWindowEx(WS_EX_TOOLWINDOW,MY_CLASS,MY_NAME,
                 WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, nil); // создаем окно
  //SetPriorityClass(GetCurrentProcess, IDLE_PRIORITY_CLASS); // низкие приоритет
end;

BEGIN
  // тут проверяем, если уже запущены, то отваливаем
  if FindWindow(MY_CLASS,nil)<>0 then Halt;

  RegMWindow; // создать окно

  while GetMessage(MainMsg,0,0,0) do begin // цикл обработки сообщений
    TranslateMessage(MainMsg);
    DispatchMessage(MainMsg);
  end;
END.

Приаттачиваю полный проект.
В комплекте:
- данный код
- измененные dcu'шки system и sysinit (для уменьшения размера)
- иконка для трея, файл ресурсов, откомпиленный файл ресурсов с иконкой и попупкой
- батник, чтобы все это собрать в exe
- готовый exe размером 8.5 килобайт
Потребление системных ресурсов 0.000000000001%, кушает памяти 532кб (без учета kernel и user.dll)
Добавлено @ 14:00
P.S. заготовку писал и оптимизировал сам под минимальный размер. Реально проект весит 2.9кб, сверх пустого ехешника (5.6кб)

Автор: Snowy 21.9.2005, 14:57
Вот. К заготовке приделал ping.
Приклеиваю готовый вариант пинговалки.
Если пинг не проходит, то кричит страшными сообщениями (заменить на свой вариант).
Адрес пингуемого компутера прописан в начале кода. Можно заменить на любой или вообще перенести в var и заказывать из коммандной строки, реестра или файла.
Вобщем переделывай под себя как хочешь.
Добавлено @ 15:01
P.S. ехешник подрос до 10кб.

Автор: PSYx 22.9.2005, 12:32
У-у-у-ух пасибо! Snowy! Реально пасиба! В основном за совет по оптимизации!
Добавлено @ 12:34
Э-э-э-э-э, Хантер, а 4ё это за ссыло4ка такая весёлеькая? Никуда не ведущая?

Автор: _hunter 22.9.2005, 12:41
почему не ведущая? прекрасно ведет...

Автор: Snowy 22.9.2005, 13:26
Цитата(_hunter @ 22.9.2005, 12:41)
почему не ведущая? прекрасно ведет...

И ведет она на гугль и гугль рекомендует книгу "Дельфи глазами хакера".
А про эту книгу на форуме уже куча матов сложена.
Лучше я на пальцах расскажу, где и как можно уменьшить программу.

Автор: PSYx 23.9.2005, 11:57
Млин сори то у меня связь такая- глю4ит всё 4ё можно и нельзя!
Добавлено @ 11:59
Та не! Это у меня просто smile (ничего себе- просто) шрифты глю4ат! На каком язе ссылка?

Автор: Snowy 23.9.2005, 12:04
Ссылка просто ведет на гугль, автоматом введен запрос "Оптимизирование программ Delphi".
То же можешь сделать сам вручную с любым поисковиком.

Автор: _hunter 23.9.2005, 12:14
на русском была... ( utf-8, кажись... )

Автор: aalor 11.11.2005, 10:13
ну так вот продолжение - по этому способу у мя в проге всё нормально, но, мне нуна динамическое создание popupmenu а в том примере popup привязан статически

Автор: _hunter 11.11.2005, 12:18
menu: TPopupMenu в var' е
menu := TPopupMenu.Create() и menu.Popup(); там, где его создать нужно
у и про освобождение не забываем...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)