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


Автор: Maestro 26.1.2006, 23:07
Как сделать безформенное приложение и использовать в нем компоненты к примеру Timer или Indy?

Автор: InfMag 26.1.2006, 23:12
Модульными средствами помоему
DataModule
Жми кароче New->Other и там это дело ищи, разберешся

Автор: bems 26.1.2006, 23:39
Никак. DataModule это формально без формы, но приимущества теряются. И малого размера не получится.

Автор: InfMag 26.1.2006, 23:44
bems
Ну а как ты еще хочешь безформенное приложение делать?

Автор: Poseidon 26.1.2006, 23:49
Maestro, удаляй все формы из проекта и модуль forms.
Компоненты создавай на Application

Автор: bems 26.1.2006, 23:52
Цитата(InfMag @ 26.1.2006, 23:44)
Ну а как ты еще хочешь безформенное приложение делать?

Только с модулем windows и все
Добавлено @ 23:54
Цитата(Poseidon @ 26.1.2006, 23:49 Найти цитируемый пост)

удаляй все формы из проекта и модуль forms.
Компоненты создавай на Application

а Application разве не в forms объявлен??

Автор: Демо 27.1.2006, 01:30
А зачем для использования Indy нужны формы?

Вот пример выполнения в потоке, делал для сорцов. Здесь Forms не используется.
Код

{
Модуль uGetHTTPThread
Выполнение запроса HTTP GET в отдельном потоке с
возможностью повторного использования.
Ведется учет количества потоков

Требования - установленный Indy10

 (c) Демо

Специально для Sources.ru (2005)

Пример использования:

procedure TForm1.Button1Click(Sender: TObject);
var
  s: String;
begin
  with TGetHTTP.Create do
  begin
    OnComplete := Complete;
    Get('http://www.sources.ru');
  end;
  with TGetHTTP.Create do
  begin
    OnComplete := Complete;
    Get('http://localhost');
  end;

procedure TForm1.Complete(Sender: TGetHTTP; var Action: TActionHTTPThread);
begin
  Memo1.Lines.Add('Complete');
  Memo1.Lines.Add(Sender.Result.RecvStr);
  Action := ahFree;
end;

}
unit uGetHttpThread;

interface

uses
  windows,classes, SysUtils, idHTTP, idLogDebug, idComponent, idGlobal,IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack,  IdIntercept,idException;

var
  ThrList: TThreadList;

type

//Состояние потока
  TStateHTTPThread=(shNone,shReady,shComplete,shWork);
//Действие при обработке OnComplete
  TActionHTTPThread=(ahNone,ahFree);
  TGetHTTP=class;
  TCompleteQuery=procedure(Sender: TGetHTTP; var Action:TActionHTTPThread) of Object;

//Структура, заполняемая в потоке.
  THTTPRec=record
    Query: String;              //Запрос в виде http://url
    ErrorMsg: String;           //Результатт в текстовом виде
    ErrorCode: Integer;         //Результат в числовом виде
    RecvStr: String;            //Принятая строка(полностью с заголовком)
    SendStr: String;            //Отосланная строка
    CountSend: Integer;         //Количество отосланных байт
    CountRcv: Integer;          //Количество принятых байт
    Page: String;               //Возвращенная страница(без заголовка)
  end;

//Собственно, сам поток
  TGetHTTP=class(TThread)
  private
    FH: TidHTTP;
    FL: TidLogDebug;
    FS: TIdIOHandlerStack;
    FTimeOut: Integer;
    FQuery: String;
    FResult: THTTPRec;
    FState: TStateHTTPThread;
    FOnComplete: TCompleteQuery;
    procedure FComplete;
    procedure FHWork(ASender: TObject; AWorkMode: TWorkMode;
      AWorkCount: Integer);
    procedure FLReceive(ASender: TIdConnectionIntercept;
      var ABuffer: TBytes);
    procedure FLSend(ASender: TIdConnectionIntercept;
      var ABuffer: TBytes);
    function GetTimeOut: Integer;
    procedure SetTimeOut(const Value: Integer);

  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Free;
    procedure Release;

    procedure Get(const Query: String);

    property OnComplete: TCompleteQuery read FOnComplete write FOnComplete;
    property Result: THTTPRec read FREsult;
    property State: TStateHTTPThread read FState;
    property TimeOut: Integer read GetTimeOut write SetTimeOut;
  end;

//Получение максимального количества потоков
function GetMaxThreads: Integer;

//Установка максимального количества потоков
procedure SetMaxThreads(aMaxThreads: Integer=10);

//завершение всех потоков и очистка списка
procedure TerminateAllThreads;

//Завершение конкретного потока
procedure ReleaseThread(Thread:TGetHTTP);

//Получение количества потоков в списке
function CheckCountThreads: Integer;

implementation

var
//Максимальное количество потоков - недоступно из других модулей напрямую
  MaxThreads: Integer;

{ TGetHTTP }

constructor TGetHTTP.Create;
begin
  if CheckCountThreads=GetMaxThreads then raise Exception.Create('Can''t create thread. MaxThreads='+IntToStr(MaxThreads));
  inherited Create(True);
  FreeOnTerminate := False;
  FState := shNone;             //Поток еще не готов принять запрос
  with ThrList.LockList do      //Добавляем поток в список
  try
    Add(Self);
  finally
    ThrList.UnlockList;
  end;
  TimeOut := 30000;
  Resume;
end;

destructor TGetHTTP.Destroy;
begin
  FH.Free;
  FS.Free;
  FL.Free;
end;

procedure TGetHTTP.Execute;
begin
  FH := TidHTTP.Create(nil);
  FL := TidLogDebug.Create(nil);
  FS := TIdIOHandlerStack.Create(nil);
  FS.Intercept := FL;
  FH.IOHandler := FS;
  FL.Active := True;
  FH.OnWork := FHWork;
  FL.OnReceive := FLReceive;
  FL.OnSend := FLSend;
  FState := shReady;
  if FQuery='' then Suspend;    //Запрос пустой - засыпаем
  try
    while not Terminated do
    begin
      FState := shWork;           //Поток занят
      FResult.Query := FQuery;
      FResult.ErrorMsg := '';
      FResult.ErrorCode := 0;
      FResult.RecvStr := '';
      FResult.SendStr := '';
      FResult.CountSend := 0;
      FResult.CountRcv := 0;
      FResult.Page := '';
      FQuery := '';

      try
        FH.ReadTimeout := TimeOut;       //Таймаут
        FResult.Page := FH.Get(FResult.Query);
        FResult.ErrorMsg := FH.ResponseText;
        FResult.ErrorCode := FH.ResponseCode;
      except
        on e: Exception do
        begin
          FResult.ErrorMsg := e.Message;
          FResult.ErrorCode := -1;
        end;
      end;
      FState := shComplete;       //Поток закончил выполнение запроса
      Synchronize(FComplete);     //Сообщаем пользователю
      if not Terminated then Suspend;
    end;
  finally
    ReleaseThread(Self);
  end;
end;

procedure TGetHTTP.FComplete;
var
  Action: TActionHTTPThread;
begin
  Action := ahNone;
  if Assigned(FOnComplete) then FOnComplete(Self,Action);
  if Action = ahFree
    then  Terminate;//ReleaseThread(Self)    //Завершаем поток
//    else Suspend;               //Засыпаем снова - до следующего запроса
end;

procedure TGetHTTP.FHWork(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Integer);
begin
//Увеличиваем соответствующий счетчик
  case AWorkMode of
    wmRead: FResult.CountRcv := FResult.CountRcv + AWorkCount;
    wmWrite: FResult.CountSend := FResult.CountSend + AWorkCount;
  end;
end;

procedure TGetHTTP.FLReceive(ASender: TIdConnectionIntercept;
  var ABuffer: TBytes);
var
  s: String;
begin
//  Добавляем в буфер полученную информацию
  SetLength(s,Length(ABuffer));
  Move(ABuffer[0],s[1],Length(ABuffer));
  FResult.RecvStr := FResult.RecvStr + s;
end;

procedure TGetHTTP.FLSend(ASender: TIdConnectionIntercept;
  var ABuffer: TBytes);
var
  s: String;
begin
//  Добавляем в буфер отправленную информацию
  SetLength(s,Length(ABuffer));
  Move(ABuffer[1],s[1],Length(ABuffer));
  FResult.SendStr := FResult.SendStr + s;
end;

procedure TGetHTTP.Free;
begin
//заменяем процедуру Free на нашу
  Release;
end;

procedure TGetHTTP.Get(const Query: String);
var
  i: Integer;
begin
//Проверяем, закончена ли предыдущая обработка.
  if (FState=shComplete) or (FState=shWork)
    then raise Exception.Create('Error state thread');

//Если поток еще толтько стартует - ожидаем.
  i := 100;
  while FState<>shReady do
  begin
    Sleep(10);
    //Слишком долго поток не переходит в статус shReady
    if i<0 then raise Exception.Create('Unknown error');
    Dec(i,10);
  end;
  FQuery := Query;
//Будим поток для выполнения запроса
  Resume;
end;

function TGetHTTP.GetTimeOut: Integer;
begin
  Result := InterlockedExchange(FTimeOut,FTimeOut);
end;

procedure TGetHTTP.SetTimeOut(const Value: Integer);
begin
  InterlockedExchange(FTimeOut,Value);
end;

procedure TGetHTTP.Release;
begin
  FreeOnTerminate := True;      //Переводим в состояние автоуничтожения
  Terminate;                    //Взводим флаг Terminated
  Resume;                       //Будим поток для завершения
end;

procedure TerminateAllThreads;
var
  i: Integer;
begin
  with ThrList.LockList do
  try
    for i := 0 to Count-1 do
    begin
      try
        TGetHTTP(Items[i]).Release;
      except
      end;
    end;
  finally
    ThrList.UnlockList;
  end;
end;

//Получить максимальное количество потоков.
function GetMaxThreads: Integer;
begin
  Result := InterlockedExchange(MaxThreads,MaxThreads);
end;

//Установить максимальное количество потоков.
procedure SetMaxThreads(aMaxThreads: Integer=10);
var
  CurrValue: Integer;
begin
  CurrValue := InterlockedExchange(MaxThreads,MaxThreads);
  if CurrValue>aMaxThreads then
  InterlockedExchange(MaxThreads,aMaxThreads);
end;

//Получить теккущее количество потоков
function CheckCountThreads: Integer;
begin
  with ThrList.LockList do
  try
    Result := Count;
  finally
    ThrList.UnlockList;
  end;
end;

//Завершить поток
procedure ReleaseThread(Thread:TGetHTTP);
var
  i:Integer;
begin
  with ThrList.LockList do
  try
    for i := 0 to Count-1 do
    begin
      try
        if TGetHTTP(Items[i])=Thread then
        begin
          TGetHTTP(Items[i]).Free;
          Delete(i);
          break;
        end;
      except
      end;
    end;
  finally
    ThrList.UnlockList;
  end;
end;

initialization
  MaxThreads := 10;
  ThrList := TThreadList.Create;
finalization
  TerminateAllThreads;
  ThrList.Free;
end.



Или вот:

Код

program SetTime;
uses
  Windows, SysUtils, IdTime;


var
  CurrTime: TDateTime;
  st: TSystemTime;
  YY,MM,DD,HH,NN,SS,MS: Word;
begin
    try
      with tIdTime.Create(nil) do
      begin
//        Host := 'ntps1-0.uni-erlangen.de';
        Host := '192.168.0.1';
        try
          CurrTime := DateTime;
        except
        end;
        Free;
      end;
    except
      Exit;
    end;
    GetLocalTime(st);
    DecodeDate(CurrTime,YY,MM,DD);
    DecodeTime(CurrTime,HH,NN,SS,MS);
    st.wYear := YY;
    st.wMonth := MM;
    st.wDay := DD;
    st.wHour := HH;
    st.wMinute := NN;
    st.wSecond := SS;
    st.wMilliseconds := MS;
    SetLocalTime(st);
end.


Автор: Maestro 27.1.2006, 16:31
...Как без формы посадить Timer сделать вызов события OnTimer?

Автор: _hunter 27.1.2006, 16:36
лепи на форму таймер. назначай ему обработчик.
потом перенеси этот метод в свое приложение и назная его таймеру
someTimer.OnTimer = method;

а создать таймер:
someTimer = TTimer.Create();

Автор: Maestro 27.1.2006, 17:14
Код

program test;

uses
  Windows, SysUtils;


begin

end.

Куда вписать метод?

Автор: devmstr 27.1.2006, 17:23
Timer вообще юзай стандартный(Win Api).
CreateTimer и погнал...,если надо, могу кинуть пример.

Автор: Romikgy 27.1.2006, 17:30
Код

program test;    
uses    
  Windows, SysUtils;    
procedure WorkTimer;
begin
//Сюда ложим то что надо
end;
var t1:Ttimer;
begin    
t1:=Ttimer.create();
t1.Interval:=время в мс;
t1.OnTimer:=WorkTimer;
//Ожидание завершения работы приложения
t1.Free;
end.

Только с процедурой для таймера в хелпе посмотри smile

Автор: Guedda 27.1.2006, 17:34
Код

program Test;

uses
  Windows, SysUtils;

var
  SomeTimer : Ttimer;

procedure TimerEnabled(Sender : TObject);
begin
  //здесь пишешь обработчик таймера
end;

begin
  SomeTimer := TTimer.Create(nil);
  SomeTimer.Interval := 1000;
  SomeTimer.OnTimer := TimerEnabled;
  SomeTimer.Enabled := true;
end.

Автор: Maestro 27.1.2006, 17:54
Guedda, говорит что не понимет тип метода, как TimerEnabled задикларировать?

Автор: Rennigth 27.1.2006, 18:02
Guedda Update...
Код

program Test;

uses
  Windows, SysUtils, ExtCtrls, Forms;

var
  SomeTimer : Ttimer;

procedure TimerEnabled(Sender : TObject);
begin
  //здесь пишешь обработчик таймера
end;

begin
  SomeTimer := TTimer.Create(nil);
  SomeTimer.Interval := 1000;
  SomeTimer.OnTimer := TimerEnabled;
  SomeTimer.Enabled := true;
  while not Application.Terminated do
      Application.HandleMessage;
end.


Выход из программы самому делать придеть как-нибудь.
Добавлено @ 18:11
т.е. ошибся: вот рабочий:
Код

unit Unit1;

interface

uses
  sysUtils, Dialogs, ExtCtrls, Controls, Classes;

type

  TSomeTimer = class(TTimer)
  protected
    procedure TimerEnabled(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;


  end;


var
  SomeTimer: TSomeTimer;

implementation

procedure TimerEnabled(Sender: TObject);
begin
  ShowMessage('');
end;


{ TSomeTimer }

constructor TSomeTimer.Create(AOwner: TComponent);
begin
  inherited;
  OnTimer := TimerEnabled;
end;

procedure TSomeTimer.TimerEnabled(Sender: TObject);
begin
  ShowMessage('');
end;

end.



Код

program Project2;

uses
  Windows,
  SysUtils,

  Forms, Classes,
  Unit1 in 'Unit1.pas';

begin
  SomeTimer := TSomeTimer.Create(nil);
  SomeTimer.Enabled := True;




  while not Application.Terminated do
      Application.HandleMessage;
end.



Автор: Maestro 27.1.2006, 18:41
Работает!, но можно как нить без цыкла обойтись, ато загрузка процесса до 90% доходит?
Код

  while not Application.Terminated do
      Application.HandleMessage;

Как ни будь что б работал один таймер?

Автор: Guedda 27.1.2006, 21:20
Тогда нужно пользоваться WinAPI-функциями и создавать отдельный процесс под таймер.
Для этого необходимо немного почитать инфы.

Автор: Демо 28.1.2006, 18:21
Цитата(Maestro @ 27.1.2006, 19:41 Найти цитируемый пост)

Работает!, но можно как нить без цыкла обойтись, ато загрузка процесса до 90% доходит?


Тебе шашечки ил иехать?
Вообще-то создание таймера не может быть самоцелью, для чего-то же программа предназначена?
Вот вместо цикла программа и должна что-то полезное делать.

Либо ставь конкретно задачу - что тебе нужно.

Автор: DragonFire 28.1.2006, 22:28
Господи, а вообще без всяких апликатионов не пробовали?
Вот прожка кружочки рисует цветные smile Прикольно smile
Код

program Paint;

uses
   Windows, Messages;

const
  AppName = 'WinPaint';
  id_Timer = 100; // èäåíòèôèêàòîð òàéìåðà

Var
  Window : HWnd;
  Message : TMsg;
  WindowClass : TWndClass;

function WindowProc (Window : HWnd; Message, WParam : Word;
         LParam : LongInt) : LongInt; stdcall;
Var
    dc : HDC;
    MyPaint : TPaintStruct;
    Brush : hBrush;
Begin
  WindowProc := 0;
  case Message of
   wm_Create  : dc := GetDC(Window);
   wm_Destroy : begin
                KillTimer (Window, id_Timer);
                DeleteDC (dc);
                PostQuitMessage (0);
                Exit;
                end;
   wm_Timer:    InvalidateRect(Window, nil, False);
   wm_Paint:    begin
                dc := BeginPaint (Window, MyPaint);
                Brush := CreateSolidBrush (RGB (random (255), random (255), random (255)));
                SelectObject (dc, Brush); 
                Ellipse (dc, 10, 10, 110, 110);
                DeleteObject (Brush);
                EndPaint (Window, MyPaint);
                ReleaseDC (Window, dc);
                end;
  end; // case
  WindowProc := DefWindowProc (Window, Message, WParam, LParam);
End;


begin
      With WindowClass do
        begin
        Style := cs_DblClks;
        lpfnWndProc := @WindowProc;
        cbClsExtra := 0;
        cbWndExtra := 0;
        hInstance := 0;
        hIcon := LoadIcon (0, idi_Application);
        hCursor := LoadCursor (0, idc_Arrow);
        hbrBackground := GetStockObject (White_Brush);
        lpszMenuName := '';
        lpszClassName := AppName;
        end;
       If RegisterClass (WindowClass) = 0 then
          Halt (255);
       Window := CreateWindow (AppName, 'Òàéìåð',
        ws_OverlappedWindow, 100, 100, 150, 150, 0, 0, HInstance, nil);
       ShowWindow (Window, CmdShow);
       UpdateWindow (Window);
       SetTimer (Window, id_Timer, 200, nil); // Óñòàíîâêà òàéìåðà
       Randomize;
       while GetMessage (Message, 0, 0, 0) do begin
         TranslateMessage (Message);
         DispatchMessage (Message);
        end;
      Halt (Message.wParam);
end.

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