![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Передача строки из доп.потока с основной [D7, WinXP]
GanibalLector © (2006-09-21 16:56:00)Господа, видел когда-то на форуме такой вот трюк для передачи строк из доп.потока в главный :
type
TForm1 = class(TForm)
...
private
procedure Priem (var Msg:TMessage); message WM_USER+2;
public
{ Public declarations }
end;
procedure TForm1.Priem(var Msg: TMessage);
begin
Memo2.Lines.Add(String(PChar(Msg.WParam)));
end;
где-то в потоке :
PostMessage(Handle,WM_USER+2,Integer(PChar('Hello,Word')),0);
Все КАК БЫ работает ;) Насколько такой подход верный?
ИМХО, не верный. Ибо при посылке ОДНОГО пробела( Integer(PChar(' ')) ) получаю AV !
Так все-же пользоваться WM_COPYDATA ?
DiamondShark (2006-09-21 21:44:00) [1]
> В пределах области видимости (string),
S := 'aaa';
P := PChar(S);
S := 'bbb'; // в P теперь невалидный адрес
А область видимости та же.
Даже если нет переприсваиваний, проще не морочиться пп того, где компилятору вздумается разместить финализацию, а пользоваться заведомо более строгим критерием.
Тем более, что при передаче м-у потоками от того, что строка доживёт до выхода из области видимости радости не шибко много ;)
Leonid Troyanovsky (2006-09-21 21:35:00) [2]
> DiamondShark © (21.09.06 21:32) [7]
> в PChar действителен только в пределах одного оператора.
В пределах области видимости (string), IMHO.
--
Regards, LVT.
DiamondShark (2006-09-21 21:32:00) [3]
> PostMessage(Handle,WM_USER+2,Integer(PChar('Hello,Word')), 0);
Нельзя так делать.
Возьмите за правило: адрес, полученный преобразованием строки в PChar действителен только в пределах одного оператора.
Leonid Troyanovsky (2006-09-21 18:47:00) [4]
> HanibalLector © (21.09.06 16:56)
> procedure TForm1.Priem(var Msg: TMessage);
> begin
> Memo2.Lines.Add(String(PChar(Msg.WParam)));
> end;
> где-то в потоке :
> PostMessage(Handle,WM_USER+2,Integer(PChar('Hello,Word')),
> Все КАК БЫ работает ;) Насколько такой подход верный?
Избыточность. Где-то в потоке :
//SendMessage(EditHandle, EM_SETSEL, dwStart, dwEnd);
SendMessage(EditHandle, EM_REPLACESEL, ..);
--
Regards, LVT.
GanibalLector (2006-09-21 18:00:00) [5]2 guav © (21.09.06 17:53) [4]
> WM_COPYDATA уже можно отправлять через PostMessage
А разве я это говорил? Через Send
> их уже используют в рамках одного процесса ?
А что мешает? Это кем-то запрещено?
guav (2006-09-21 17:53:00) [6]> При использовании WM_COPYDATA строка сначала копируется
> в память Windows, а программе передаётся адрес на копию
> строки.
А что, WM_COPYDATA уже можно отправлять через PostMessage и их уже используют в рамках одного процесса ?
> PostMessage(Handle,WM_USER+2,Integer(PChar(' ')),0); вызывает
> AV?
Потому, что к Pchar приводится не строка, а char.
Рассмотри всё же и [3] , такая проблема тоже может возникнуть при не-константных строках.
GanibalLector (2006-09-21 17:23:00) [7]2 Игорь Шевченко © (21.09.06 16:59) [1]
>Адрес передай и все (что, собственно и делается в приведенном коде). Потоки одного процесса разделяют общую память.
Вот и я так думал... Ну почему-же тогдаPostMessage(Handle,WM_USER+2,Integer(PChar(' ')),0);вызывает AV?
Наиль (2006-09-21 17:23:00) [8]
> при посылке ОДНОГО пробела( Integer(PChar(' ')) ) получаю
> AV !
Перед отсылкой пробела резервируется память под пробел.
Потом передаётся указатель на пробел.
При достижении End; память освобождается.
Т.к. отправка идёт через PostMessage, то программа не успевает воспользоваться адресом, вот и AV.
При использовании WM_COPYDATA строка сначала копируется в память Windows, а программе передаётся адрес на копию строки.
Игорь Шевченко (2006-09-21 16:59:00) [9]
> Господа, видел когда-то на форуме такой вот трюк для передачи
> строк из доп.потока в главный :
Адрес передай и все (что, собственно и делается в приведенном коде). Потоки одного процесса разделяют общую память.
А для указанного примера лучше использовать Synchronize или SendMessage.