Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.133.96] |
|
Страницы: (3) 1 [2] 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
примерно так:
Synchronize(Self.Component.OnRead(Self.Component)); |
Сообщ.
#17
,
|
|
|
я так понял мне надо поток в компонент не впихивать?
|
Сообщ.
#18
,
|
|
|
почему же можешь впихивать, просто обращаться из потока к компоненту нужно с помощью Synchronize
|
Сообщ.
#19
,
|
|
|
приведи пример кода
потому что так не компилится да и не должно type vmUDPSocket = class(TComponent) private SActive : boolean; SPort : longint; SBufSize : longint; WSAData : TWSAData; UDPSock : TSocket; ToAddr : TSockAddr; FromAddr : TSockAddr; RecTh : RecThread; EventRead : TNotifyEvent; protected public procedure Startup; procedure Cleanup; published property Active : boolean read sActive write sActive; property Port : integer read SPort write SPort; property BufferSize : longint read SBufSize write SBufSize; property OnRead : TNotifyEvent read EventRead write EventRead; end; RecThread = class(TThread) public RecSocket : TSocket; ReadSize : longint; status : longint; Component : vmUDPSocket; private WSAData : TWSAData; procedure recvdata(sock:TSocket); protected procedure Execute; override; end; |
Сообщ.
#20
,
|
|
|
Цитата v1m @ потому что так не компилится да и не должно Не слышал про forward-объявления ? RecThread = class; //= forward vmUDPSocket = class(TComponent) ... end; RecThread = class(TThread) ... end; |
Сообщ.
#21
,
|
|
|
нет я до этого на паскале прогал))) да и сейчас прогаю ток в олимпиадном программировании))
|
Сообщ.
#22
,
|
|
|
я так ничего и непонял как мне синхронизировать
это vmUDPSocket = class(TComponent) private SActive : boolean; SPort : longint; SBufSize : longint; WSAData : TWSAData; UDPSock : TSocket; ToAddr : TSockAddr; FromAddr : TSockAddr; RecTh : RecThread; EventRead : TNotifyEvent; protected public procedure Startup; procedure Cleanup; published property Active : boolean read sActive write sActive; property Port : integer read SPort write SPort; property BufferSize : longint read SBufSize write SBufSize; property OnRead : TNotifyEvent read EventRead write EventRead; end; с этим RecThread = class(TThread) public RecSocket : TSocket; ReadSize : longint; status : longint; Component : vmUDPSocket; private WSAData : TWSAData; procedure recvdata(sock:TSocket); protected procedure Execute; override; end; я же тут как то Сomponent должен синхронизировать с компонентом иначе нету события я сделал таймер на форме и RecThread в компоненте поместил в public и запрашивал прием сразу из потока все кул но как синхронизировать мой компонент по нормальному? |
Сообщ.
#23
,
|
|
|
Вопрос с синхронизацией на самом деле спорный. Я уже ссылался на библиотеку Indy как пример. Вызов некоторых событий из доп. потоков может быть чертой компонента.
Однако, в данном конкретном случае я советую не использовать Synchronize, а посылать свое сообщение (назвать его можно было бы, например, CM_DATAREAD), вызывать обработчик соответствующего события из процедуры обработки сообщения (она будет вызвана из основного потока). В параметрах сообщения указатель на буфер с принятыми данными и размер. |
Сообщ.
#24
,
|
|
|
угу я уже это читал про посылку сообщения.
извиняюсь за тупой вопрос. ?: как сделать указатель на буфер в сообщении... |
Сообщ.
#25
,
|
|
|
Цитата v1m @ как сделать указатель на буфер в сообщении Просто приведением типов к типу параметров сообщения var Buff: array[0..1023] of Byte; FilledOn: Integer;//насколько конкретно заполнено begin //заполнение буфера и конкретного размера данных SendMessage(hComponent, CM_DATAREAD, Integer(@Buff), FilledOn); //... end; или вариант с динамическим распределением буфера, освобождение в этом же коде: var pBuff: PByte; DataSize: Integer;//сколько данных начитано begin //возможно выяснение размера данных... pBuff := GetMem(<SomeValue>);//конкретный размер может быть получен по разному: либо точное значение, либо "гарантированно" достаточный размер try //заполнение буфера и размера данных SendMessage(hComponent, CM_DATAREAD, Integer(pBuff), DataSize); //... finally FreeMem(pBuff); end; end; также с дин. распределением буфера, но освобождением на приемной стороне var pBuff: PByte; DataSize: Integer;//сколько данных начитано begin //возможно выяснение размера данных... pBuff := GetMem(<SomeValue>);//конкретный размер может быть получен по разному: либо точное значение, либо "гарантированно" достаточный размер //заполнение буфера и размера данных //если буфер выделялся с запасом, а реальных данных получено меньше, то нужно либо перераспределить его /ReallocMem/, либо передавать размер распределенный, //а реальный размер полезных данных как-то дополнительно /например, в начале буфера зарезервировать несколько байт под это/ PostMessage(hComponent, CM_DATAREAD, Integer(pBuff), DataSize); //дальше поток занимается своими делами, не ждет, память будет освобождена компонентом //*thread says*: пойду выпью какао с зефиром :) end; |
Сообщ.
#26
,
|
|
|
сейчас попробую)
|
Сообщ.
#27
,
|
|
|
а как в параметрах сообщения достать этот указатель?
|
Сообщ.
#28
,
|
|
|
ну дык обратным приведением ж
var pBuff: PByte; DataSize: Integer; begin pBuff := PByte(wParam); DataSize := lParam; |
Сообщ.
#29
,
|
|
|
PByte это тип array of integer ? или тот который стандартно задается?
и еще вопрос как handle взять? |
Сообщ.
#30
,
|
|
|
Тот который стандартно задается, но это только для примера. Ты можешь использовать любые указатели, какие тебе нравятся (только в данном не приводи к указателям дин. массивы и строки).
Handle должен передать сам компонент при запуске потока, удобнее всего параметром конструктора. |