Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Вниз

использование статического метода   Найти похожие ветки 

 
msgipss   (2005-02-03 09:06) [0]

Вопрос ламерский конечно, сорри,
просто всегда считал что в delphi работает такая конструкция:
Ta=object
static procedure b;
end;
..
begin
Ta.b;
А оказалось
Ta=object
procedure b;
end;
var a:Ta;
begin
a.b;

чтож получается, перед тем как использовать статический метод, надо всё же создать экземпляр класса ?
меня можно бить ссылками всякими и др. литературой..


 
Александр Иванов ©   (2005-02-03 09:11) [1]

Заметь переменной типа TButton нет, а работает:
procedure TForm1.Button1Click(Sender: TObject);
begin
with TButton.Create(nil) do
 begin
   Parent:=Form1;
   Caption:="Hello";
 end;
end;


 
jack128 ©   (2005-02-03 09:15) [2]

msgipss   (03.02.05 9:06)
Ta=object
static procedure b;
end;

это у тебя даже не скомпилируется. В дельфи под статическими методами имеется в виду совсем не то, что в С++. Такая фишка в Дельфи называется классовыми методами. Замени object на класс(борланд забил на object очень давно и не развивает их) а static на class и тогда все заработает..


 
jack128 ©   (2005-02-03 09:16) [3]

jack128 ©   (03.02.05 9:15) [2]
Замени object на класс(борланд забил на object очень давно и не развивает их)  static на class и тогда все заработает..

короче так сделай
 Ta=class
   class procedure b;
 end;


 
Diabolik ©   (2005-02-03 09:20) [4]

>2Александр Иванов
>
>procedure TForm1.Button1Click(Sender: TObject);
>begin
>with TButton.Create(nil) do
> begin
>   Parent:=Form1;
>   Caption:="Hello";
> end;
>end;

Если не ошибаюсь то в начале формы, в описании TForm есть уже описание Button1: TButton

По этому и ошибки не выдает.

Обработчик событий procedure TForm1.Button1Click(Sender: TObject); же есть => есть и описание TButton


 
jack128 ©   (2005-02-03 09:24) [5]

Diabolik ©   (03.02.05 9:20) [4]
:-))  Круто :-)
А если я напишу так:

>procedure TForm1.Button1Click(Sender: TObject);
>begin
>with TMemo.Create(nil) do
> begin
>   Parent:=Form1;
>   Lines.Add("Hello");
> end;
>end;

Как объяснишь, что такой код работает??


 
Александр Иванов ©   (2005-02-03 09:28) [6]

Diabolik ©   (03.02.05 9:20) [4]
ОК, удаляем кнопку и пишем:

procedure TForm1.FormClick(Sender: TObject);
begin
 with TButton.Create(nil) do
 begin
   Parent:=Form1;
   Caption:="Hello";
 end;
end;


 
msgipss   (2005-02-03 09:32) [7]

Мне надо вот что:
1. существует класс,
2. создаю его экземпляр
3. существует множетство классов(порожденных от thread), из них я хочу вызывать статический метод этого класса 1.
Правда, в dlephi нет статических свойств, - да ? в 6 версии., т.е. даже из статического метода я не смогу обратиться  к динамическому его содержимому., мдааа тогда идея левая получается..


 
jack128 ©   (2005-02-03 09:41) [8]

msgipss   (03.02.05 9:32) [7]
из них я хочу вызывать статический метод этого класса 1.

Коли вы задаете вопрос по дельфи, давайте использовать дельфийскую терминалогию. Итак вам нужен статический метод или классовый?
msgipss   (03.02.05 9:32) [7]
Правда, в dlephi нет статических свойств, - да ?
Если имеются ввиду классовые свойства, то они появились только в Delphi9. В ранних версиях их можно заменнить классовыми процедурооми/функциями, как это делается в С++
msgipss   (03.02.05 9:32) [7]
т.е. даже из статического метода я не смогу обратиться  к динамическому его содержимому.

Что такое "динамическое содержание" ??


 
Александр Иванов ©   (2005-02-03 09:42) [9]

msgipss   (03.02.05 9:32) [7]
Что за динамическое содержимое статического метода? Что за чушь?


 
Verg ©   (2005-02-03 09:46) [10]

Ну так, явно передавай в "статический" метод (это не надо путать с C++, тут это переводится примерно, как метод класс-типа, хотя те же яйца - вид сбоку) указатель на динамически созданный экземпляр класса 1 и обращайся к его содержимому.


 
msgipss   (2005-02-03 09:47) [11]

Александр Иванов ©   (03.02.05 09:42) [9]
наверное не корректно выразился,
класс при своей работе работает с какими то динамическими объектами (создает и т.д). Имеет также статический метод, а насколько я помню из статического метода класса нельзя работать с динамическими объектами того же класса, да ?


 
jack128 ©   (2005-02-03 09:54) [12]

msgipss   (03.02.05 9:47) [11]
из статического метода класса нельзя работать с динамическими объектами того же класса, да ?


почему нельзя, все можно

 TTest=class
   class procedure ClassMethod(ATest: TTest);
   procedure SimpleMethod;
 end;
class procedure TTest.ClassMethod(ATest: TTest);
begin
 ATest.SimleMethod;
end;

procedure TTest.SimpleMethod;
begin
 ShowMessage("Test");
end;


 
Александр Иванов ©   (2005-02-03 09:54) [13]

См. [10. Передавай ссылку на объект и работай.


 
msgipss   (2005-02-03 09:58) [14]

Вопрос еще такой можно: по потокам.
У меня есть множество тредов(потоков), при создании потока ему передается ссылка на объект (тоже созданный от треда).
При работе своей это множество вызывает методы объекта (на который передана ссылка). В общем  то вопрос. Как будет работать многопотоковость если постоянно дергать поток (в смысле вызывать его свойства и методы) ?


 
msgipss   (2005-02-03 10:02) [15]

ведь для общения с внешним миром существует механизм синхронизации (Synchronize(proc)).. а мы несколько по другому работаем, правильно ли это ?


 
Verg ©   (2005-02-03 10:10) [16]


> в смысле вызывать его свойства и методы


У потока нет свойств или методов.
Свойства или методы есть у структур данных - классов.

> 15] msgipss   (03.02.05 10:02)


С внешним миром можно общаться не только посредством "пропросить что-то сделать другой поток" (Synchronize).

"Несколько по-другому, правильно ли это" - насколько по-другому сделано правильно, на столько правильно это и есть :)

P.S. Ощущение, как от электрика окончательно запутавшегося в проводах....


 
msgipss   (2005-02-03 10:40) [17]

Verg ©   (03.02.05 10:10) [16]

8)) не отрицаю, запутался.. или опять неверно объяснился.
1. пишу класс от TThread, добавляю свои property или опять не то говорю ?
2. создаю от него (от класса) объект (в приостановленном виде)
3. вызываю метод Resume, т.е. запускаю поток в работу

4. создаю группу других объектов (классы которых порождены тоже от TThread), при создании этих объектов, им передается ссылка на объект 1.
5. при своей работе группа объектов 4, вызывает property объекта 1.

Внимание вопрос: правильно ли так делать, потому как у каждого класса порожденного от TThread, есть Synchronize, для работы с др.потоками. И еще, если это возможно, что будет если множество потоков одновременно ломануться изменять property моего класса 1

По моему все понятно спросил...


 
Verg ©   (2005-02-03 10:51) [18]

Во многих случаях для совместного доступа нескольких потоков к сложным структурам данных, когда предпологается некое "нестабильное" по отношению к другим потокам их состояние в процессе этого доступа к ним, используют CriticalSection. Т.е. процедура (метод) доступа к некоему property класса 1 использует нечто типа

procedure TThreadOfClass1.SetMyProperty( Value : TPropertyValue );
begin
  CriticalSection.Enter;
  try
    MyProperty := Value; // Это абстрактный пример, здесь может быть какие-то
                                 // и довольно сложные манипуляции
  finally
    CriticalSection.Leave;
  end;
end;

Главное, чтобы все потоки "ходили" к этому property только через этот "шлюз".
CryticalSection - это private поле класса TThreadOfClass1, которое создается в его конструкторе ( убивается, соотв. в деструкторе).


 
Verg ©   (2005-02-03 11:00) [19]


> Synchronize


Это существет только для синхронизации действия потока с действиями потока его создавшего (назовем его главным), путем дачи указаний (постановки некоей заявки в его, для этого предназначенную очередь таких заявок) главному потоку выполнить некий код (метод) в тот момент, в который ему (главному) покажется, что это сделать он не проч.
Этот "главный" и выполняет заявки всех порожденных им потоков в порядке той самой очереди и только в определенные им самим "фазы" своего исполнения.
Эта фаза - как правило фаза выборки сообщений из своей системной очереди (перед/после PeekMessage).


 
Digitman ©   (2005-02-03 11:09) [20]


> что будет если множество потоков одновременно ломануться
> изменять property моего класса 1


это смотря что у тебя фактически творится в объекте при обращении к его св-ву для записи или чтения последнего ..


 
Erik1 ©   (2005-02-03 12:23) [21]

Да гремучея смесь у тебя в голове, все вместе WinApi для работы с тредами, обращение к VCL(Synchronize) и еще классы. Ты бы определился с чем работаеш, а то все сразу изучать, голова лопнет.


 
msgipss   (2005-02-03 12:31) [22]

Verg ©   (03.02.05 10:51) [18]
Спасибо.. так и буду делать, а то до этого передавал (через Synchronize) данные между порожденными потоками через основной поток 8)...

попытался на примере передать ссылку на объект потока в др. поток, что то не получается...
примерный код прилагаю:

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Button1: TButton;
   Button2: TButton;
   Edit1: TEdit;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
 public
 end;

    TSoftReport = class(TThread) // Объявление основного класса
     private
        fDetail:Byte;
        procedure SetDetail(value:byte);
     protected
        procedure ReadData;
        procedure Execute; override;
     public
      constructor Create;
      property Detail:byte read fDetail write SetDetail;
    end;

    TSoftReport1 = class(TThread) // Объявление класса (таких будет много)
     private
        fDetail:Byte;
        SoftReport:TSoftReport;
        procedure SetDetail(value:byte);
     protected
        procedure Execute; override;
     public
      constructor Create(p:Pointer);  // передаем ссылку на объект первого класса
      property Detail:byte read fDetail write SetDetail;
    end;

var   Form1: TForm1;
     SoftReport:TSoftReport;
     SoftReport1:TSoftReport1;
implementation
{$R *.dfm}

constructor TSoftReport.Create;
begin
fDetail:=0;
inherited Create(False);
end;

procedure TSoftReport.SetDetail(value:byte);
begin
  fDetail:=value;
end;

procedure TSoftReport.Execute;
begin
  while not Terminated do
  begin
     Synchronize(ReadData);
     sleep(5000);
  end;
end;

procedure TSoftReport.ReadData;  // показываем текущее состояние примера
begin
 Form1.Memo1.Lines.Add(intToStr(fDetail));
end;

//_____________________________________________________________________________________________

constructor TSoftReport1.Create(p:pointer);
begin
fDetail:=0;
SoftReport:=p;      // хочу так получить объект
inherited Create(False);
end;

procedure TSoftReport1.SetDetail(value:byte);
begin
  fDetail:=value;
end;

procedure TSoftReport1.Execute;
begin
  while not Terminated do
  begin
     SoftReport.Detail:=fDetail;   // записываем данные в другой поток
     sleep(5000);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SoftReport:=TSoftReport.Create;  // создаем поток 1
  SoftReport1:=TSoftReport1.Create(@SoftReport); // создаем поток 2 и передаем ссылку на второй
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  SoftReport1.Detail:=strToint(edit1.Text); // пытаемся проверить пример передачи данных по ссылке
end;

помогите пожалуйста с передачей параметра


 
msgipss   (2005-02-03 12:35) [23]

Erik1 ©   (03.02.05 12:23) [21]
да в общем у меня задача простая: хочу фиксировать все события в программе (эдакий логер), для этого создается поток, в который поступает инфа обо всех событиях, там она как то обрабатывается и где надо фиксируется. Может это можно сделать и по другому но я не видел.


 
Erik1 ©   (2005-02-03 12:50) [24]

Код полная ерунда, это кажется уже стандарт.
Synchronize(ReadData);
sleep(5000);
У тебя весь поток работает в основном потоке! Разберись с передачей данных, например PostMessage очень полезная вещь. Посмотри примеры в поставке delphi Demos\Threads\thrddemo.dpr

А ладно держи готовый пример:
{-----------------------------------------------------------------------------
Unit Name: DBThreadX
Author:    Erik Ivanov
Date:      07-май-2004
Purpose:
History:   1.0
-----------------------------------------------------------------------------}
unit ThreadBase;

interface
uses  classes, Windows;

type
 PRaiseFrame = ^TRaiseFrame;
 TRaiseFrame = record
   NextRaise: PRaiseFrame;
   ExceptAddr: Pointer;
   ExceptObject: TObject;
   ExceptionRecord: PExceptionRecord;
 end;

 TActiveEvent = (actExit, actSend);
 RAction = record
   Event: array[TActiveEvent] of THandle;
   Call: array[TActiveEvent] of TNotifyEvent;
 end;
 PAction = ^RAction;
 TNotifyEvent = procedure(Data: Pointer) of object;

 TCustomThread = class(TThread)
 private
   fID: Integer;
   fDescription: String;
   fActive: Boolean;
   fTimeOut: Integer;
   fFinished: TNotifyEvent;
   fCall: Integer;
   function  GetID: Integer;
   function  GetDescription: String;
   function  GetGrupp: String;
 protected
   tmEvent: RAction;
   fData: Pointer;
   procedure WaitTimeOut; virtual; abstract;
   procedure ShowMessage(Value: string); dynamic;
   procedure InternalException; dynamic;
   procedure BreakThread(Sender: TObject); dynamic;
   procedure InternalExec(Sender: TObject); virtual;
   procedure Execute; override;
   procedure CreateEvent; dynamic;
   procedure FreeEvent;   dynamic;
   procedure DoFinished;     virtual;
   procedure SetEvent(Value: TActiveEvent);
 public
   fLastException: TObject;
  constructor Create(TimeOut: Integer);
   destructor Destroy; override;
   procedure Start(const Data: Pointer); dynamic;
   procedure Stop; dynamic;
   function  Active: Boolean;

   property  ID: Integer read GetID write fID;
   property  Description: String read GetDescription;
   property  Group: string read GetGrupp;
   property  OnFinished: TNotifyEvent read fFinished write fFinished;
 end;

 TLogThread = class(TCustomThread)
 private
   fFileActive: Boolean;
   fLog: TextFile;
   fLogName: String;
 protected
   procedure WaitTimeOut; override; //virtual;
   procedure BreakThread(Sender: TObject); override;
 public
   constructor Create(FileName: String; TimeOut: Integer);
   destructor Destroy; override;
   procedure LogSave(const Buf: String);
   procedure LogClose;
 end;
 
const
 ActiveThread = MaxInt;

implementation
uses  Messages, sysutils;

procedure MsgWaitFor(Handle: THandle);
Var
   Msg: TMsg;
begin
 while MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT) = WAIT_OBJECT_0 + 1 do
 begin
   PeekMessage(Msg, 0, 0, 0, PM_Remove);
   if Msg.message <> WM_QUIT then  // GetMessage(Msg, 0, 0, 0)
     DispatchMessage(Msg);  //      TranslateMessage(Msg);
 end;
end;

{ TCustomThread }
constructor TCustomThread.Create(TimeOut: Integer);
begin
 inherited Create(True);
 fTimeOut := INFINITE;
   
 fID := Random(MaxInt);
//  New(tmEvent);
 fActive := False;

 tmEvent.Call[actSend] := InternalExec;
 tmEvent.Call[actExit] := BreakThread;

 CreateEvent;
end;

destructor TCustomThread.Destroy;
begin
//  Dispose(tmEvent);
 if Assigned(fLastException) then
   fLastException.Free;
 FreeEvent;
 inherited;
end;

procedure TCustomThread.BreakThread(Sender: TObject);
begin
 Terminate;
end;

procedure TCustomThread.InternalExec(Sender: TObject);
begin
 Inc(fCall);
end;

procedure TCustomThread.DoFinished;
begin
 if Assigned(fFinished) then
   fFinished(fData);
end;

procedure TCustomThread.InternalException;
begin
 if Assigned(fLastException) then
   fLastException.Free;

 if RaiseList <> nil then
 begin
   fLastException := PRaiseFrame(RaiseList)^.ExceptObject;
   PRaiseFrame(RaiseList)^.ExceptObject := nil;
 end
 else
   fLastException := nil;
end;

procedure TCustomThread.Execute;
var
 Status: DWord;
label
 Retry;
begin
 Retry:
 Status := WaitForMultipleObjects(Ord(High(tmEvent.Event)) + 1, @tmEvent.Event,
   false, fTimeOut); //INFINITE

 if fActive and (TActiveEvent(Status) <> actExit) then
   exit;

 fActive := True;
 try
   try
     case Status of
       Ord(Low(TActiveEvent))..Ord(High(TActiveEvent)):
       begin
         tmEvent.Call[TActiveEvent(Status)](Self);
         if (TActiveEvent(Status) <> actExit) then
           Synchronize(DoFinished);
       end;
       WAIT_TIMEOUT: WaitTimeOut;
     else
       OutputDebugString(PChar("Error WaitFor, status:"+IntToStr(Ord(Status))));
     end;
   except
     InternalException;
   end;
 finally
   FActive := False;
 end;

 if not Terminated then
   goto Retry;
end;

procedure TCustomThread.FreeEvent;
var
 i: TActiveEvent;
begin
 for i := Low(tmEvent.Event) to High(tmEvent.Event) do
 begin
   CloseHandle(tmEvent.Event[i]);
 end;
end;

procedure TCustomThread.CreateEvent;
var
 i: TActiveEvent;
begin
 for i := Low(tmEvent.Event) to High(tmEvent.Event) do
 begin
   tmEvent.Event[i] := Windows.CreateEvent(nil, false, false, nil);
 end;
end;

procedure TCustomThread.SetEvent(Value: TActiveEvent);
begin
 Windows.SetEvent(tmEvent.Event[Value]);
end;

procedure TCustomThread.Start(const Data: Pointer);
begin
 fData := Data;
 fCall := 0;
 SetEvent(actSend);
end;

procedure TCustomThread.Stop;
begin
 SetEvent(actExit);
 if Suspended then
   Resume;
 MsgWaitFor(Handle);
end;

function TCustomThread.Active: Boolean;
begin
 Result := fActive;
end;

procedure TCustomThread.ShowMessage(Value: string);
Const   Msg = "Starvara";
begin
 MessageBox(0, PChar(Msg), PChar(Value), MB_OK);
end;


 
Erik1 ©   (2005-02-03 12:50) [25]

function TCustomThread.GetDescription: String;
begin
 Result := fDescription;
end;

function TCustomThread.GetGrupp: String;
begin
 Result := IntToStr(ActiveThread);
end;

function TCustomThread.GetID: Integer;
begin
 Result := fID;
end;

{ TLogThread }

procedure TLogThread.BreakThread(Sender: TObject);
begin
 inherited;
 LogClose;
end;

constructor TLogThread.Create(FileName: String; TimeOut: Integer);
begin
 if TimeOut = 0 then
   TimeOut := 5000;
 inherited Create(TimeOut);
 fLogName := FileName;
end;

destructor TLogThread.Destroy;
begin
 LogClose;
 inherited;
end;

procedure TLogThread.LogClose;
begin
 fFileActive := False;
 {$I-}
 Flush(fLog);
 CloseFile(fLog);
 {$I+}
end;

procedure TLogThread.LogSave(const Buf: String);
begin
 if not fFileActive then
 begin
   AssignFile(fLog, fLogName);
   {$I-}
   Reset(fLog);
   {$I+}
   IOResult;
   if not FileExists(fLogName) then
     Rewrite(fLog);

   fFileActive := True;
 end;

 Append(fLog);
 Writeln(fLog, Buf);
end;

procedure TLogThread.WaitTimeOut;
begin
 LogClose;
end;

end.


 
msgipss   (2005-02-03 12:57) [26]

Erik1 ©   (03.02.05 12:50) [24]
код еще не смотрел, сразу скажу спасибо.
Насчет того что код ерунда и работает в основном потоке - согласен, но он только для того чтобы проверить передачу параметров по ссылке, вот и все - это не рабочий код.
Смотрю код...


 
Verg ©   (2005-02-03 12:58) [27]


> SoftReport1:=TSoftReport1.Create(@SoftReport);


Я не очень понял философской цели всего этого "проекта" :),
Но вот здесь, где @ - очень скверная, на мой взгляд ошибка.
Сам экземпляр класса - это уже ссылка на экземпляр (на участок памяти, где он находится), так что передавая адрес этой ссылки ты добиваешься интерпретации местарасположения SoftReport-ссылки, как собственно местарасположения самого экземпляра TSoftReport.
Что из этого может получится - одному черту известно.

Т.о,

SoftReport1:=TSoftReport1.Create(SoftReport);


 
msgipss   (2005-02-03 13:07) [28]

Verg ©   (03.02.05 12:58) [27]
>Я не очень понял философской цели всего этого "проекта" :),
не понял про что Вы 8), про логер (msgipss   (03.02.05 12:35) [23]) или про этот пример ?
Я тоже думаю что это ссылка, но в моем примере это не сработало и я попробовал так, как написал....
Пример демонстрирует следующее, если не понятно...
на форме 2 кнопки. button1 их создает. при вводе в Edit1 записываю во второй поток, который передает это значение первому по переданной ссылке, вот и все... - простая демонстрация...

предыдущий код смотрю...


 
Verg ©   (2005-02-03 13:24) [29]


> на форме 2 кнопки. button1 их создает. при вводе в Edit1
> записываю во второй поток, который передает это значение
> первому
по переданной ссылке, вот и все... - простая демонстрация...


Вот и непонятно - зачем?

Так ведь можно и третий и четвертый тред создать, и передавать от одного другому, пока последний не сделает то, что мог бы сделать и самый первый в этой надуманной цепочке....
Так почему же их у тебя всего два?  ;)) А не три или четыре?

Ты не в поток записываешь, пойми ты, это поток записывает значение в ячейку (переменную), другой поток ее от туда считывает (когда выспится) и т.д. Все это они делают независимо друг от друга с периодичностью в пять секунд. Почему пять, кстати? Если ты хочешь наладить обмен между потоками, то для этого предусмотрен хотя бы механизм обмена сообщениями (PostThreadMessage, GetMessage, PeekMessage и т.п.). Можно конечно и свой какой-то механизм "навыдумать", основанный на примитивах синхронизации ядра (Event, Mutex) и т.п.
Но, это отдельная тема....


> Я тоже думаю что это ссылка, но в моем примере это не сработало
> и я попробовал так, как написал....


Так ты ж не скзал самого главного:

> что то не получается...


что именно-то?

P.S. Всякие такие определения траблов: "не сработало", "не получается" - это не очень-то подходит для форума программистов.
Я вот тоже попробовал тут телевизор включить: не получается....
Долго разбирался, оказалось - здесь просто нет телевизора....


 
msgipss   (2005-02-03 14:46) [30]

Verg ©   (03.02.05 13:24) [29]
8), насчет PS cогласен, не программист я, и спасибо за Ваше терпение... теперь можно по вопросам ?
>Вот и непонятно - зачем?
Может я верную идеологию избрал, я хочу фиксировать все события, как штатные, нештатные, критические и т.д которые происходят во всех частях (классах) приложения. Для этой цели создал класс (пусть будет "логер") от треда и там обрабатываю все поступающие сообщения (под обработкой понимается какой то анализ сообщений и действия). Возник вопрос как поставлять сообщения в тред. Сначала я это делал через основной поток (Synchronize), работает нормально но понимаю что это не правильно. Потом попробовал вызывая статический метод логера записывать данные через него.
Затем, подсказали в этой ветке, передать всем классам ссылку на логер и писать с использованием TCriticalSection. Попробовал как Вы сказали - получилось, я просто не дождался вначале 5 сек.
Сейчас Вы сказали про PostThreadMessage, GetMessage, PeekMessage - сейчас буду смотреть.
Вот и всё.. Если есть какие ни будь другие решения самой задачи, хотелось юы услышать (Предыдущий код (от Erik1) не разобрался еще в нем), а по передачи данных между потоками, очень даже помогли спасибо. Если я опять говорю чушь, расскажите пожалуйста.
Заранее благодарен 8)


 
Erik1 ©   (2005-02-03 16:52) [31]

Ты о самом главном неподумал, как даные от формы помадут в поток? Недолжен поток сам считывать даные, форма сама должна посылать ему. А он в потоке кудато их сохранять. В моем случае в фаил, который закрывается через 5 сек неактивности(что очень удобно). Так происходит вызов:
Log := TLogThread.Create(LogFile, 5000);
Log.LogSave(Format("%d;%d;%d;Channels:%s; %s",[DecNoToInt(Params.Decoder),Params.Cmd,
   fContent, ByteToList(Params.Channels), Buf]));
Но ты хочеш сделать уневерсально для всех форм? Тогда сразу возникает вопрос зачем? Если хочется протоколировать ошибки, то это по другому делается.


 
Erik1 ©   (2005-02-03 17:02) [32]

Дополнительные поля и методы сделаны для менаджера потоков, который их показывает и может убить. У меня запись происходит без участия дополнительного потока и невидно передачи данных, но на основе TCustomThread можеш сделать, что тебе надо. Например записать с буфер с использованием критической секции , а в Excetute(InternalExec у меня) читать от туда, по мере записи очищать считаные данные. У меня есть более интересные примеры с использованием TMultiReadExclusiveWriteSynchronizer, но они сложнее.


 
msgipss   (2005-02-04 11:36) [33]

Спасибо всем участникам ветки.
Последний вопрос, помогите с поиском инфы по сообщениям потоку (PostThreadMessage, PeekMessage), может ламерский пример подкините 8)


 
Erik1 ©   (2005-02-04 12:12) [34]

А чем тебя моя procedure MsgWaitFor неустраивает в качестве примера?


 
JaDS ©   (2005-02-04 16:46) [35]

позвольте всё же вернуться к начальному вопросу, так как мне он тоже интересен, а именно:


Ta = object
 procedure a;
end;

procedure Ta.a;
begin
 MessageBox(0, "text", "caption", 64);
end;


Собственно вопрос, мне надо иметь возможность выполнить код метода без создания экземпляра класса, а именно Ta.b. Замечу что метод статический, к динамическим методам и структурам не обращается. Такое возможно???

PS:
пробовал описывать процедуру с дерективой class - не получилось, или я что-то не так делал. Объявление класса с дерективой class, вместо дерективы object - не предлагать



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.59 MB
Время: 0.039 c
1-1107928317
Gloomer
2005-02-09 08:51
2005.02.20
Ошибка при использовании DLL


3-1106207417
АМБ
2005-01-20 10:50
2005.02.20
DBGrid. Работа скролинга.


9-1100491033
ballack
2004-11-15 06:57
2005.02.20
Как избежать наезда спрайтов друг на друга...


1-1107834997
Аккум
2005-02-08 06:56
2005.02.20
Динамический array of record в памяти как располагается ?


3-1106110286
Janb
2005-01-19 07:51
2005.02.20
Как значения запросы правильно расположить в ДБГРИДЕ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский