Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.08.29;
Скачать: CL | DM;

Вниз

Как треду перед запуском передать/установить параметры/флаги?   Найти похожие ветки 

 
Olorin ©   (2002-08-15 11:44) [0]

Вот и вопрос собственно!


 
Skier ©   (2002-08-15 11:53) [1]

>Olorin
создать свой конструктор с параметрами, которые необходимы.


 
Olorin ©   (2002-08-15 12:15) [2]

Скиер можно поподробнее.... скажем я создаю тип:

type
TbtnMouseStart = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;

.........................

var
MouseStart1: TbtnMouseStart;
MouseStart2: TbtnMouseStart;


Как каждому потоку передать свои параметры?


 
Skier ©   (2002-08-15 12:23) [3]

>Olorin


TbtnMouseStart = class(TThread)
private
FYourParam1 : Integer;
FYourParam2 : String;
protected
procedure Execute; override;
public
constructor CreateWithParams(CreateSuspended: Boolean;
const AYourParam1 : Integer; const AYourParam2 : String);
end; //TbtnMouseStart


{ TbtnMouseStart }

constructor TbtnMouseStart.CreateWithParams(CreateSuspended: Boolean; const AYourParam1: Integer; const AYourParam2: String);
begin
inherited Create(CreateSuspended);
FYourParam1 := AYourParam1;
FYourParam2 := AYourParam2;
end;

procedure TbtnMouseStart.Execute;
begin
inherited Execute;
end;


Создание :


var
MouseStart1: TbtnMouseStart;
MouseStart2: TbtnMouseStart;
begin
MouseStart1 := TbtnMouseStart.CreateWithParams(False, 0, "This
is my own parameter");
MouseStart2 := TbtnMouseStart.CreateWithParams(False, 0, "This
is my own parameter too");
//............
end;


 
Ученик ©   (2002-08-15 12:26) [4]

>Skier © (15.08.02 12:23)
Извиняюсь, чуть поправлю

constructor TbtnMouseStart.CreateWithParams(CreateSuspended: Boolean; const AYourParam1: Integer; const AYourParam2: String);
begin
FYourParam1 := AYourParam1;
FYourParam2 := AYourParam2;
inherited Create(CreateSuspended);
end;


 
Skier ©   (2002-08-15 12:27) [5]

>Ученик
Валяй...:)))


 
Skier ©   (2002-08-15 12:30) [6]

>Ученик
Я тут подумал - если создавать Thread с параметром
CreateSuspended = False, то твоя поправка очень существенна...Приступ невнимательности... :)


 
Olorin ©   (2002-08-15 12:37) [7]

Ок огромное спасибо пока разобирался с примером из дельфи вы тут разжевали... уряяя..... а еще вопрос... если у меня может запускаться МНОГО потоков неужели на каждый создавать переменную флаг?


 
Skier ©   (2002-08-15 12:40) [8]

>Olorin
Если флаг для каждого потока должен быть свой, то да...


 
Ученик ©   (2002-08-15 12:50) [9]

>Olorin © (15.08.02 12:37)
Есть еще threadvar


 
Olorin ©   (2002-08-15 13:00) [10]

>Ученик ©
Хм и чем отличается применение threadvar от просто глобальной??
>Skier ©
Угу флаг нужен различный для каждого треда...


 
Ученик ©   (2002-08-15 13:02) [11]

>Olorin © (15.08.02 13:00)
Для каждого треда она своя


 
Olorin ©   (2002-08-15 13:39) [12]

Хм тоесть я ее могу перед стартом в задаче иннициализировать и потом проверять ее значение при работе из потока?
Чего то я не допер... может пример... на пару строк? :o)


 
Ученик ©   (2002-08-15 13:45) [13]

Source\Internet\Sockets.pas
ThreadObject: TClientSocketThread;


 
Olorin ©   (2002-08-15 13:53) [14]

>Ученик ©
Хм не понял как оно пашет:

implementation

threadvar
ThreadObject: TClientSocketThread;

Мне же для каждого запускаемого треда нужен свой экземпляр... тоесть писать из задачи и читать из процессов... тоесть просто останавливать процессы по флагу не все, а только те которым укажу...


 
Ученик ©   (2002-08-15 14:16) [15]

Флаг можно организовать как список тредов (глобальная переменная), которым нужно выполнить задание, треды проверяют наличие себя в списке


 
Olorin ©   (2002-08-15 14:24) [16]

А подробнее сильно много писать? :o)


 
Ученик ©   (2002-08-15 14:39) [17]

>Olorin © (15.08.02 14:24)
Подробнее прийдется мастеров ждать :)))


 
Olorin ©   (2002-08-15 14:52) [18]

>Ученик ©
Эхх пока они прийдут топ улетит в дальние дали :o(


 
Ученик ©   (2002-08-15 15:01) [19]

>Olorin © (15.08.02 14:52)
Какая часть реализации вызывает вопросы ?


 
Olorin ©   (2002-08-15 15:26) [20]

>Ученик ©
Именно как использовать threadvar как флаг остановки потоков... не всех сразу а только того что нужно...


 
Ученик ©   (2002-08-15 15:32) [21]

>Olorin © (15.08.02 15:26)
Ученик © (15.08.02 14:16)
threadvar там уже не было


 
Digitman ©   (2002-08-15 15:33) [22]

Кто должен взводить этот флаг ? Другой поток ?


 
Olorin ©   (2002-08-15 15:36) [23]

>Digitman ©
Задача запускает потоки много либо по одному либо несколько сразу... так вто не удобно создавать 10-15 глобальных переменных чтобы рулить остановкой процессов :o(


 
Olorin ©   (2002-08-15 15:37) [24]

>Ученик ©
Упс сорри я не внимателен... ок я просто не понял как организовать список тредов на которые указывает глобальная переменная :o/


 
panov ©   (2002-08-15 15:43) [25]

Ты бы написал, что ты получить хочешь.
Может и флаги не понадобятся.


 
Digitman ©   (2002-08-15 15:48) [26]

так, стоп.

Нет понятия "задача", ушло оно вместе в небытие. Есть "процесс" - ОС-объект, создаваемый системой как реакция на старт приложения.

В контексте процесса существует как минимум один кодовый поток - основной. В контексте осн.код.потока процесса ты создаешь N дополнительных, фиксируя ссылки на них где-то в отдельных переменных или в массиве. И хочешь в произвольный момент времени в контексте осн.код.потока взвести некий флаг, в результате чего соответствующий этому флагу некий доп.код.поток из созданных тобой и работающих в дан.момент времени был приостановлен на время.

Так или не так ?


 
Olorin ©   (2002-08-16 06:48) [27]

>Digitman ©
В общем так но что вы имели ввиду под фразой:
"фиксируя ссылки на них где-то в отдельных переменных или в массиве."????


 
Olorin ©   (2002-08-16 06:51) [28]

>panov ©
Да в общем все уже конкретно описанно выше...
Я запускаю из своего процесса потоки могу штук 20 за раз могу по одному... иак как у них нет завершения по коду я должен их останавливать сам... типа скажем установил глобальную переменную fDone в True и процесс остановился... НО держать 20 и более глобальных переменных IMHO чудовищно... вот и спрашиваю может есть другие пути??


 
Digitman ©   (2002-08-16 08:04) [29]

>Olorin

Самые обычные действия имел ввиду :

var

MyThread1, MyThread2: TMyThread;
MyThreads: array[..] of TMyThread;
...

// фиксация ссылки в именованой переменной
MyThread1 := TMyThread.Create(..);
MyThread2 := TMyThread.Create(..);

//взведение флага, индивидуального для соответствующего
//кодового потока,
//ссылка на который хранится в именованой переменной

MyThread1.SomeFlag := True;
MyThread2.SomeFlag := True;

//////////////////////////////////////////////

// фиксация ссылки в элементе массива
MyThreads[i] := TMyThread.Create(..);

//взведение флага, индивидуального для i-го кодового потока
MyThreads[i].SomeFlag := True;


 
Olorin ©   (2002-08-16 08:26) [30]

Хм примерно понял идею... попробую реализовать... тут еще вопрос... не будет ли этот способ ресурсоемким :o)


 
Digitman ©   (2002-08-16 08:36) [31]

>Olorin

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


 
Olorin ©   (2002-08-16 08:39) [32]

Я имелл виду разницу с просто создание глобальных переменных... ок так получается красивей... :o)


 
Olorin ©   (2002-08-16 10:23) [33]

>Digitman ©
Хм немного не понял... вот кусок кода:

unit uothreads;

interface

uses
Classes, Windows, Messages;

type

TClickType = (MDOUBLE, MSINGLE);
TButtonType = (MLEFT, MRIGHT);

TbtnMouseStart = class(TThread)
private
FClickType: TClickType;
FButtonType: TButtonType;
FIterval: Integer;
FProcHWND: HWND;
FX: Integer;
FY: Integer;
protected
procedure Execute; override;
public
constructor Create(Sender: TObject; AClickType: TClickType; AButtonType: TButtonType; AIterval: Integer; AProcHWND: HWND; AX: Integer; AY: Integer);
end;

implementation

constructor TbtnMouseStart.Create(Sender: TObject; AClickType: TClickType; AButtonType: TButtonType; AIterval: Integer; AProcHWND: HWND; AX: Integer; AY: Integer);
begin
FClickType := AClickType;
FButtonType := AButtonType;
FIterval := AIterval;
FProcHWND := AProcHWND;
FX := AX;
FY := AY;
FreeOnTerminate := True;
inherited Create(False);
end;

procedure TbtnMouseStart.Execute;
begin
// какой-то код
end;

end.


Далее в основном юните:


procedure TfrmMain.btnMouseStartClick(Sender: TObject);
var
MouseStart1: TbtnMouseStart;
ThreadsTerminated: array[..] of TbtnMouseStart; //массив!?
AComboBox : TComboBox;
AEdit : TEdit;
AIndex : String;
begin
// запуск потока
MouseStart1 := TbtnMouseStart.Create(Sender, MDOUBLE, MLEFT, 1000, ProcHWND, 0, 0);

и далее ниччего не понимаю... как проверять состояние флага в процедуре Execute самого потока и что делать при запуске оного... :o(


 
Digitman ©   (2002-08-16 10:41) [34]

А какое поле класса TbtnMouseStart у тебя есть некий флаг ?
Что-то не вижу я, где и какой флаг взводится : ни в процедуре btnMouseStartClick() ни в методе-конструкторе TbtnMouseStart.Create()

Что ты подразумеваешь под понятием "флаг" ? Флаг имеет два состояния - установлен (или взведен, или "1", или TRUE - как угодно) и сброшен ("0", FALSE и т.д.) ... Т.е. флаг - логическое понятие и, соответственно, логический тип данных в коде. У тебя нет ни одного логического поля в классе TbtnMouseStart. Что проверять-то ?




 
Olorin ©   (2002-08-16 10:48) [35]

Вопрос в том как его создать... если определить в классе TbtnMouseStart то этот флаг не будет виден и его нельзя будет использовать, хм взводить его при запуске процесса... а как потом его менять из основного кода??
Я выше написал то что у меня сейчас есть... тот пример который вы постили ДО этого вверг меня в непонятки... может вы сможете мне на готовом(тот что я привел) объяснить?


 
Digitman ©   (2002-08-16 11:20) [36]

ну, вот, скажем, самый простой вариант :

TbtnMouseStart = class(TThread)
public
MyFlag: Boolean;
constructor Create(...; MyFlagInitialState: Boolean);
end;

constructor TbtnMouseStart.Create(...; MyFlagInitialState: Boolean);
begin
...
MyFlag:= MyFlagInitialState;
inherited Create(False);
end;


procedure TbtnMouseStart.Execute;
begin
...
if MyFlag then...
else ...
...
end;

procedure TfrmMain.btnMouseStartClick(Sender: TObject);
var
...
begin
...
// создаем код.поток с изначально сброшенным флагом
MouseStart1 := TbtnMouseStart.Create(..., False);
...
end;

...
//где-то далее по тексту, пока код.поток работает еще,
//меняем состояние флага, управляя тем самым ходом выполнения
//метода Execute()
...
MouseStart1.MyFlag := True;
...
MouseStart1.MyFlag := False;
...
и т.д. ....


 
Olorin ©   (2002-08-16 12:16) [37]

//где-то далее по тексту, пока код.поток работает еще,
//меняем состояние флага, управляя тем самым ходом выполнения
//метода Execute()
...
MouseStart1.MyFlag := True;
...
MouseStart1.MyFlag := False;

Этот флаг не доступен! Не понял почему.... :o(


 
Olorin ©   (2002-08-16 13:14) [38]

Хм ну вот... подкинули НЕрабочий пример... в общем то идея даже не рабочая... так как я таким же способом хотел параметры передавать ан нет не вышло... не ужели никто не поможет из Мастеров? :o)


 
Digitman ©   (2002-08-16 14:16) [39]

>Olorin

Что значит "флаг недоступен" ? Поясни.


 
Olorin ©   (2002-08-16 14:22) [40]

Нет его в доступных функциях, методах, параметрах... он вообще не виден! :o)


 
Olorin ©   (2002-08-16 14:24) [41]

>Digitman ©
В принципе могу выложить исходники не такие они большие 2 экрана примерно...


 
Digitman ©   (2002-08-16 14:33) [42]

ты флаговое поле-то хоть в разделе PUBLIC объявил ? или - куда кривая выведет ? Раздел объявления поля (равно как и любого иного члена класса) имеет оч.важное значение ! В данном примере флаговое поле д.б. объявлено как минимум в PUBLIC (но никак не в PROTECTED и уж тем более - в PRIVATE). Надеюсь, ты это понимаешь и выполнил эти условия ..


 
panov ©   (2002-08-16 14:38) [43]

Вот пример тебе:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ThrList: TList;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
index: Integer;
begin
ThrList := TList.Create;
for index := 0 to 99 do ThrList.Add(TMyThread.Create(False));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
index: Integer;
begin
ThrList := TList.Create;
for index := ThrList.Count-1 downto 0 do
begin
TMyThread(ThrList[index]).Terminate;
end;
ThrList.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
index: Integer;
begin
for index := 0 to 10 do
begin
if ThrList.Count>0 then
begin
TMyThread(ThrList[0]).Flag := True;
ThrList.Delete(0);
end;
end;
end;

end.


unit Unit2;

interface

uses
Classes,windows;

type
TMyThread = class(TThread)
private
FFlag: Boolean;
procedure SetFlag(aFlag: Boolean);
protected
procedure Execute; override;
public
property Flag: Boolean read FFlag write SetFlag;
constructor Create(aFlag: Boolean);
end;

implementation

constructor TMyThread.Create(aFlag: Boolean);
begin
inherited Create(True);
FFlag := aFlag;
FreeOnTerminate := True;
Resume;
end;

procedure TMyThread.SetFlag(aFlag: Boolean);
begin
FFlag := aFlag;
end;

procedure TMyThread.Execute;
begin
while not Terminated do
begin
if Terminated then break;
if FFlag then Break;
Sleep(1);
end;
end;

end.



 
lenin ©   (2002-08-16 14:39) [44]

Вместо флага используй указатель на этот флаг, тогда все будет работать:
MyFlag: ^Boolean;
constructor Create(...; MyFlagInitialState: ^Boolean);


procedure TbtnMouseStart.Execute;
begin
...
if MyFlag^ then...
else ...
...
end;


TfrmMain:

private
MyFlg: ^Boolean;
...
procedure TfrmMain.btnMouseStartClick(Sender: TObject);
var
...
begin
...
// создаем код.поток с изначально сброшенным флагом
New(MyFlg);
MyFlg^:=false;
MouseStart1 := TbtnMouseStart.Create(..., MyFlg);
...
end;

...
//где-то далее по тексту, пока код.поток работает еще,
//меняем состояние флага, управляя тем самым ходом выполнения
//метода Execute()
...
MyFlg^ := True;
...
MyFlg^ := False;
...
и т.д. ....

Что то вроде этого.



 
Digitman ©   (2002-08-16 14:44) [45]

>lenin

Это зачем еще по ссылке-то передавать параметр ? Да еще и - глобальную переменную (об отказе от которой, собссно, и речь идет) ? Будь так любезен, объясни ...


 
Esu ©   (2002-08-16 16:30) [46]

panov: Может быть я чего-то не понимаю...


> procedure TForm1.FormCreate(Sender: TObject);
> var
> index: Integer;
> begin
> ThrList := TList.Create;

Тут создается список, нигде в коде не освобождается.


> procedure TForm1.FormClose(Sender: TObject; var Action:
> TCloseAction);
> var
> index: Integer;
> begin
> ThrList := TList.Create;
> for index := ThrList.Count-1 downto 0 do
> begin
> TMyThread(ThrList[index]).Terminate;
> end;
> ThrList.Free;

Тут список снова создается, тот не освободился - утечка. Count у этого явно 0. Зато освобождается.

Видимо опечатся :)


 
Olorin ©   (2002-08-19 06:04) [47]

>Digitman ©
Естественно в PUBLIC ну нету его в списке и все тут... может все же выложить код полностью он не так и велик.. экран примерно...


 
Olorin ©   (2002-08-19 06:09) [48]

Мдее все больше и больше убеждаюсь в неработоспособности предложенных методов... хотя идеи и не плохие :-)
Неужели нет других гибких путей? :-)


 
Digitman ©   (2002-08-19 08:48) [49]

>Olorin

желательно , конечно, целиком видеть код


 
Olorin ©   (2002-08-19 10:14) [50]

Вот главный модуль main.pas:

unit main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ExtCtrls, Menus, StdCtrls, RxMenus, RXSpin, Placemnt,
HotKeyManager, Buttons;

type
TfrmMain = class(TForm)
mmMain: TMainMenu;
mmiScript: TMenuItem;
mmiOptions: TMenuItem;
mmiHelp: TMenuItem;
mmiNew: TMenuItem;
mmiSave: TMenuItem;
mmiSaveAs: TMenuItem;
mmiExit: TMenuItem;
pnlMain: TPanel;
pctrlMain: TPageControl;
tshMain: TTabSheet;
tshScript: TTabSheet;
gbxChMainW: TGroupBox;
cbxMMouse1: TComboBox;
cbxMKey1: TComboBox;
cbxMKey2: TComboBox;
cbxMKey3: TComboBox;
edtIMouse1: TEdit;
edtIKey1: TEdit;
edtIKey2: TEdit;
edtIKey3: TEdit;
gbxChOtherW: TGroupBox;
cbxMMouse2: TComboBox;
cbxMKey4: TComboBox;
cbxMKey5: TComboBox;
cbxMKey6: TComboBox;
edtIMouse2: TEdit;
edtIKey4: TEdit;
edtIKey5: TEdit;
edtIKey6: TEdit;
gbxSShot: TGroupBox;
mmiMacros: TMenuItem;
tshOther: TTabSheet;
tshSettings: TTabSheet;
cbxSSDate: TCheckBox;
rbtnSSbmp: TRadioButton;
rbtnSSjpg: TRadioButton;
RxSpnSSjpgPerc: TRxSpinEdit;
edtSSpath: TEdit;
frmPlacement: TFormPlacement;
hkmMain: THotKeyManager;
btnMouseStart1: TSpeedButton;
btnMStart1: TSpeedButton;
btnMStart2: TSpeedButton;
btnMStart3: TSpeedButton;
btnMouseStart2: TSpeedButton;
btnMStart4: TSpeedButton;
btnMStart5: TSpeedButton;
btnMStart6: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure btnMouseStartClick(Sender: TObject);
procedure MouseStop(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
ProcHWND: HWND;
const
KeyCodes: array[0..27] of Integer = (
VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12,
VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_ESCAPE, VK_TAB, VK_INSERT, VK_DELETE,
VK_HOME, VK_END, VK_PRIOR, VK_NEXT, VK_BACK, VK_RETURN, VK_PAUSE, VK_SCROLL );

KeyLabels: array[0..27] of string = (
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
"Up", "Down", "Left", "Right", "Escape", "Tab", "Insert", "Delete",
"Home", "End", "PageUp", "PageDown","Backspace","Enter","Pause", "ScrolLsock");

implementation

uses uothreads;

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
var
i : Integer;
begin
cbxMKey1.Clear;
for i := 0 to High(KeyLabels) do
cbxMKey1.Items.Add(KeyLabels[i]);
cbxMKey2.Items := cbxMKey1.Items;
cbxMKey3.Items := cbxMKey1.Items;
cbxMKey4.Items := cbxMKey1.Items;
cbxMKey5.Items := cbxMKey1.Items;
cbxMKey6.Items := cbxMKey1.Items;
end;

procedure TfrmMain.btnMouseStartClick(Sender: TObject);

function GetIndexFromName(const AName : String) : String;
var
ii : Integer;
begin
Result := EmptyStr;
if AName = EmptyStr then Exit;
for ii := Length(AName) downto 1 do begin
if AName[ii] in ["A".."Z", "a".."z"] then Exit;
Result := AName[ii] + Result;
end;
end;

var
MouseStart1: TbtnMouseStart;
AComboBox : TComboBox;
AEdit : TEdit;
AIndex : String;
begin
//------------------------
if TSpeedButton(Sender).Down then begin
AIndex := GetIndexFromName(TSpeedButton(Sender).Name);
if AIndex <> EmptyStr then begin
AComboBox := TComboBox(FindComponent("cbxMMouse"+ AIndex));
AEdit := TEdit(FindComponent("edtIMouse"+ AIndex));
// if (AComboBox <> nil) and (AEdit = nil) then ShowMessage("0");
if (AEdit.Text = "") or (StrToInt(AEdit.Text) = 0) then begin
ShowMessage("


 
Olorin ©   (2002-08-19 10:15) [51]

Вот модуль с определениями потоков:

unit uothreads;

interface

uses
Classes, Windows, Messages;

type

TClickType = (MDOUBLE, MSINGLE);
TButtonType = (MLEFT, MRIGHT);

TbtnMouseStart = class(TThread)
private
FClickType: TClickType;
FButtonType: TButtonType;
FIterval: Integer;
FProcHWND: HWND;
FX: Integer;
FY: Integer;
protected
FTerminate: Boolean;
procedure Execute; override;
public
constructor Create(Sender: TObject; AClickType: TClickType;
AButtonType: TButtonType; AIterval: Integer;
AProcHWND: HWND; AX: Integer; AY: Integer;
ATerminate: Boolean);
end;

implementation

constructor TbtnMouseStart.Create(Sender: TObject; AClickType: TClickType;
AButtonType: TButtonType; AIterval: Integer;
AProcHWND: HWND; AX: Integer; AY: Integer;
ATerminate: Boolean);
begin
FClickType := AClickType;
FButtonType := AButtonType;
FIterval := AIterval;
FProcHWND := AProcHWND;
FX := AX;
FY := AY;
FTerminate := ATerminate;
FreeOnTerminate := True;
inherited Create(False);
end;

procedure TbtnMouseStart.Execute;
begin
while not FTerminate do
case FClickType of
MDOUBLE: begin
case FButtonType of
MLEFT: begin
PostMessage(FProcHWND, WM_LBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONDOWN));
PostMessage(FProcHWND, WM_LBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONUP));

PostMessage(FProcHWND, WM_LBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONDOWN));
PostMessage(FProcHWND, WM_LBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONUP));

PostMessage(FProcHWND, WM_LBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONDBLCLK));
PostMessage(FProcHWND, WM_LBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONUP));
end;
MRIGHT: begin
PostMessage(FProcHWND, WM_RBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONDOWN));
PostMessage(FProcHWND, WM_RBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONUP));

PostMessage(FProcHWND, WM_RBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONDOWN));
PostMessage(FProcHWND, WM_RBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONUP));

PostMessage(FProcHWND, WM_RBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONDBLCLK));
PostMessage(FProcHWND, WM_RBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONUP));
end;
end;
end;
MSINGLE: begin
case FButtonType of
MLEFT: begin
PostMessage(FProcHWND, WM_LBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONDOWN));
PostMessage(FProcHWND, WM_LBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_LBUTTONUP));
end;
MRIGHT: begin
PostMessage(FProcHWND, WM_RBUTTONDOWN, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONDOWN));
PostMessage(FProcHWND, WM_RBUTTONUP, 0, MakeLong(FX, FY));
PostMessage(FProcHWND, WM_SETCURSOR, FProcHWND, MakeLong(HTCLIENT, WM_RBUTTONUP));
end;
end;
end;
end;

end;

end.


 
Olorin ©   (2002-08-19 10:16) [52]

поправка:

protected
FTerminate: Boolean;

Вписал щас в ручную и промазал в реале оно было в секции public


 
Digitman ©   (2002-08-19 10:41) [53]

ну так - а где у тебя обращение к public-полю FTerminate по записи ? Оно закомментарено в вызывающем коде

Это раз.
Во-вторых, велосипед ты изобретаешь. Класс TThread уже имеет защищенное флаговое свойство Terminated и public-метод Terminate, взводящий флаг Terminated (при старте потока флаг всегда сброшен по-умолчанию).

Все , что от тебя требуется - стартовать код.поток и в нужный момент времении вызвать метод Terminate, в рез-те чего выполняющийся метод Execute() (периодически опрашивающий св-во Terminated на равенство True) получает возможность корректно прервать свое выполнение, если обнаружено данное условие.


 
Olorin ©   (2002-08-19 10:54) [54]


> Digitman © (19.08.02 10:41)
> ну так - а где у тебя обращение к public-полю FTerminate
> по записи ? Оно закомментарено в вызывающем коде

Потому и закоментированно что вызывает ошибку :o)

> Это раз.
> Во-вторых, велосипед ты изобретаешь. Класс TThread уже имеет
> защищенное флаговое свойство Terminated и public-метод Terminate,
> взводящий флаг Terminated (при старте потока флаг всегда
> сброшен по-умолчанию).
> Все , что от тебя требуется - стартовать код.поток и в нужный
> момент времении вызвать метод Terminate, в рез-те чего выполняющийся
> метод Execute() (периодически опрашивающий св-во Terminated
> на равенство True) получает возможность корректно прервать
> свое выполнение, если обнаружено данное условие.

Хм я думал об этом... но при вызове:
MouseStart1.Terminate
Поток просто прервется как я понял и проверка в методе Executed флага Terminated не спасет... я не прав?


 
Digitman ©   (2002-08-19 11:14) [55]


> Потому и закоментированно что вызывает ошибку :o)


Ты модуль-то uothreads объяви на всякий случай в разделе USES модуля main). Модуль Main ничего не знает о существовании в проекте модуля uothreads, отсюда и ошибка.

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


> Поток просто прервется как я понял и проверка в методе Executed
> флага Terminated не спасет... я не прав?


Не прав. С какой стати он прервется-то ? Мало ли какое состояние имеет некая переменная или поле класса ! Тело метода Execute() вправе вообще не обращать на это внимание и выполняться до тех пор, пока того потребует внутренняя его логика, а не требование "завершиться" внешнего по отношению к нему кода. Св-во Terminated, установленное в True - лишь признак, указывающий заинтересованному в нем методу Execute(), что внешний по отн. к нему код ожидает с этого момента, что тело метода должно плавненько "закруглиться", корректно освободив все занятые им ресурсы


 
Olorin ©   (2002-08-19 11:21) [56]

>Digitman ©
Стоп мы походу о несколько разных вещах :o)
Я о методе:
MouseStart1.Terminate
А вы о встроенном флаге:
MouseStart1.Terminated:=true

Кстати щас почитал внимательно первое как раз ОНО.... СПАСИБА АГРОМНОЕ... хоть я и сам докопался практически... главное внимание... :o)


 
Digitman ©   (2002-08-19 11:32) [57]

Извини, я проглядел USES uothreads в Main.pas IMPLEMENTATION.
Знаешь, перенеси-ка ты USES uothreads в Main.pas INTERFACE-секцию - оно не помешает для коррекной работы инспектора объектов : область видимости INTERFACE USES не дает повода для сомнений в видимости любого public-идентификатора в любом подключенном именнго таким образом модуле

Тем не менее : интересует-таки, что же за ошибку ты получаешь от компилятора и на какой строке , если убрать комментарии... разумеется, если FTerminate - это действительно public-поле


 
Digitman ©   (2002-08-19 11:41) [58]

>Olorin

Единственное, что делает тело метода Terminate при вызове, это:
FTerminated := True;

поле FTerminated - приватное и недоступно для непосредственной записи со стороны любого кода вне модуля classes.pas

св-во же Terminated - публичное (и недоступное), при его вызове просто считывается тек.значение поля FTerminated. Как раз то, что тебе и нужно делать теле Execute() (while/if Terminated ...) , дабы как можно оперативней реагировать на требование внешнего кода к корректному завершению данного кодового потока


 
Olorin ©   (2002-08-19 11:43) [59]


> Знаешь, перенеси-ка ты USES uothreads в Main.pas INTERFACE-секцию
> - оно не помешает для коррекной работы инспектора объектов
> : область видимости INTERFACE USES не дает повода для сомнений
> в видимости любого public-идентификатора в любом подключенном
> именнго таким образом модуле

Перенес, флаг FTerminate стал доступен :o)


> Тем не менее : интересует-таки, что же за ошибку ты получаешь
> от компилятора и на какой строке , если убрать комментарии...
> разумеется, если FTerminate - это действительно public-поле

Если не переносить ругается на неопределенный идентификатор FTerminate...

И решил я таки воспользоваться связкой ...Terminate .... & if Terminated then
:o)


 
Digitman ©   (2002-08-19 11:49) [60]

>Olorin

> решил я таки воспользоваться связкой ...Terminate .... &
> if Terminated


И правильно поступил. Ни к чему "захламлять" класс и память, занятую его экземплярами, лишними полями, назначение которых дублирует уже реализованную Борландом функц-ть класса.



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

Текущий архив: 2002.08.29;
Скачать: CL | DM;

Наверх




Память: 0.66 MB
Время: 0.011 c
6-95925
yps12
2002-06-18 13:55
2002.08.29
NMPOP3 (получить attachment s )


3-95645
perov
2002-08-07 14:19
2002.08.29
Блокировка


1-95763
Olorin
2002-08-19 13:59
2002.08.29
Как реагировать на хот кей только при активной форме?


3-95646
masanovetc
2002-08-06 11:40
2002.08.29
Как сделать запрос при помощи временных таблиц?


1-95761
CrazyHackers
2002-08-19 13:47
2002.08.29
Изменять порядок элементов treeview