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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.63 MB
Время: 0.008 c
1-95784
Magystr
2002-08-18 20:32
2002.08.29
Как сделать подсветку синтакса в RichEdit’е?


8-95911
Ivanov I
2002-04-19 15:29
2002.08.29
Как нарисовать дугу эллипса???


4-96027
Behemoth
2002-06-20 13:45
2002.08.29
Как заставить работать user.exe под WinXP


1-95777
-= Like =-
2002-08-19 17:26
2002.08.29
Запись, чтение, поиск строки.


3-95689
Kinder
2002-08-07 15:04
2002.08.29
Копирование баз





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский