Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Передать PChar через PostMessage [D5, 2000]


Призрак ©   (2006-07-02 21:38:00) 

Один поток передаёт другому PostMessage(MyWnd.Handle, WM_USER, integer(PChar('Log Entry')), 0), а второй добавляет этот 'Log Entry'к Memo. Вопрос - это не приведёт к каким-нибудь проблемам с освобождением памяти? Я же передаю адрес на специально автоматически созданную переменную... она точно правильно автоматически освободится сразу после добавления в Memo? И то же самое - если я не явно укажу 'Log Entry', а через string-переменную... проблем не будет?..


begin...end   (2006-07-03 21:12:00) [1]

> Призрак ©   (03.07.06 20:48) [10]

Можно и так. Правда, не совсем понятно, откуда взялось число 255. Лучше выделять память именно в том количестве, в котором она нужна. Т.е. отправку я бы оформил так: PostMessage(LogForm.Handle, WM_USER, WParam(StrNew(PChar(s))), 0).


Призрак   (2006-07-03 21:10:00) [2]

ой... да. спасибо. ^_^


Leonid Troyanovsky   (2006-07-03 21:09:00) [3]


> Призрак ©   (03.07.06 20:48) [10]

> procedure AddLogMessage(s: string);
> var pch: PChar;
> begin
> pch:=StrAlloc(255);


Тогда уж pch := StrAlloc(Length(s) + 1)

--
Regards, LVT.


Призрак   (2006-07-03 20:48:00) [4]

Ммм... Так?

procedure AddLogMessage(s: string);
var pch: PChar;
begin
pch:=StrAlloc(255);
StrCopy(pch, PChar(s));
PostMessage(LogForm.Handle, WM_USER, integer(pch), 0);
end;

procedure TLogForm.ProcessLogReport(var Msg: TMessage); (message WM_USER)
var pch: PChar;
begin
pch := PChar(Msg.wParam);
Memo1.Lines.Add(pch);
StrDispose(pch);
end;


Leonid Troyanovsky   (2006-07-03 07:11:00) [5]


> Призрак ©   (03.07.06 04:09) [8]


> А как это надо делать? Я не хочу использовать SendMessage,
>  надо асинхронно... Что мне приходит в голову - это создать

Это ж почему асинхронно? Надо, как раз, синхронно, если,
конечно, это дейс-но, запись в лог.

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

Да так и делать - первый поток cделает GetMem/StrAlloc,
а второй, после обработки - FreeMem/StrDispose.

--
Regards, LVT.


Призрак   (2006-07-03 04:09:00) [6]

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

А как это надо делать? Я не хочу использовать SendMessage, надо асинхронно... Что мне приходит в голову - это создать динамическую переменную, то есть указатель, создать его в одном потоке, потом передать в другой и освободить после добавления в мему... но я с трудом представляю, как в винде работает вся эта система выделения переменных, освобождения... и вообще как PChar работает... может, просто сделать указатель на строку, и потом New(s) - s:=<что там мне надо> - Postmessage(...s...) и потом в другом потоке тоже описать указатель на строку, взять его из GetMessage и потом Dispose?..


Leonid Troyanovsky   (2006-07-02 23:19:00) [7]


> Призрак ©   (02.07.06 23:07) [6]


> а в принимающем потоке сделал перед отображением задержку
> на секунду, так чтобы сначала отправилось, потом строка
> изменилась, а потом уже отобразилось... и отобразилась первая
> строка :)

Эксперименты без подходящей теории - поиски в темноте.
Изучать же следует threads & synchronization (Delphi help & msdn).

> *перечитал несколько раз и не понял* ..."здесь тоже константа"?
> .. где?.. там же переменная...

Эта переменная string, которой присвоена константа.
В ее поле кол-во ссылок стоит -1, IMHO. (see system.pas also).

> а моя та приведённая большая штука работать нормально будет?

Нет.

--
Regards, LVT.


Призрак   (2006-07-02 23:07:00) [8]

ну, я написал для проверки так:
s:='A string';
PostMessage(....... integer(PChar(s)) .....);
s:='Another string!'


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

*перечитал несколько раз и не понял* ..."здесь тоже константа"?.. где?.. там же переменная...

а моя та приведённая большая штука работать нормально будет?
PostMessage(MyForm.Handle, WM_USER, integer(PChar('COM'+IntToStr(portNum)+': Error '+IntToStr(GetLastError)+' - '+SysErrorMessage(GetLastError))), 0)


Leonid Troyanovsky   (2006-07-02 22:25:00) [9]


> Призрак ©   (02.07.06 22:03) [3]

> А какие именно проблемы меня ждут если я буду переменную
> писать? ну,
> var s: string;
> s:='Magic!';
> PostMessage(MyWnd.Handle, WM_USER, integer(PChar(s)), 0);



Здесь снова константа, хотя уже String.
Но, делать это, в общем случае нельзя, т.к. string может освободится
раньше, чем сообщение будет обработано, бо ассинхронно,
а не через SendMessage.

--
Regards, LVT.


Leonid Troyanovsky   (2006-07-02 22:20:00) [10]


> Призрак ©   (02.07.06 22:03) [3]

> SendMessage(LogMemo.Handle, EM_REPLACESE, integer(PChar(s)),
>  0)
> так?.. а почему replace? что-то заменяется?..


Заменяется выделение. Т.е., сначала карет ставится в
в последнюю позицию (EM_SETSEL), затем
SendMessage(.., EM_REPLACESEL, 0, LParam(PChar(s))

--
Regards, LVT.


Призрак   (2006-07-02 22:03:00) [11]

> Хотя удобней не мемо, а листбокс, и LB_ADDSTRING со-сно.

Спасибо... хотя здесь мне нужна мемо...

> SendMessage(..EM_REPLACESE).

А как именно?..
var s: string;
s:='Log Entry';
SendMessage(LogMemo.Handle, EM_REPLACESE, integer(PChar(s)), 0)

так?.. а почему replace? что-то заменяется?..

Конкретно... Ну, например, вот такой:

PostMessage(MyForm.Handle, WM_USER, integer(PChar('COM'+IntToStr(portNum)+': Error '+IntToStr(GetLastError)+' - '+SysErrorMessage(GetLastError))), 0)

то есть - "COM1: Error xxx - error description"

А какие именно проблемы меня ждут если я буду переменную писать? ну,
var s: string;
s:='Magic!';
PostMessage(MyWnd.Handle, WM_USER, integer(PChar(s)), 0);


P. S. принимающая часть выглядит просто -
procedure TMonitorForm.ProcessReport(var Msg: TMessage); (она описана как message WM_USER);
begin
Memo1.Lines.Add(PChar(Msg.wParam));
end;


Leonid Troyanovsky   (2006-07-02 21:49:00) [12]



> Призрак ©   (02.07.06 21:38)  
> Один поток передаёт другому PostMessage(MyWnd.Handle, WM_USER,
>  integer(PChar('Log Entry')), 0), а второй добавляет этот
> 'Log Entry' к Memo. Вопрос - это не приведёт к каким-нибудь
> проблемам с освобождением памяти? Я же передаю адрес на
> специально автоматически созданную переменную... она точно
> правильно автоматически освободится сразу после добавления
> в Memo? И то же самое - если я не явно укажу 'Log Entry',
>  а через string-переменную... проблем не будет?..


Если это константа (PChar('Log Entry')) то не будет.
Если это переменная, то будут.

А, вообще-то, для того, чтобы добавить к Memo есть
SendMessage(..EM_REPLACESE).
Хотя удобней не мемо, а листбокс, и LB_ADDSTRING со-сно.

--
Regards, LVT.


begin...end   (2006-07-02 21:47:00) [13]

> Призрак ©   (02.07.06 21:38) [0]

> Я же передаю адрес на специально автоматически созданную
> переменную...

Никакой переменной автоматически не создаётся. Ваша строка -- это константа, записанная в исполняемом файле и отображённая в память. Адрес этой константы Вы и передаёте. А при добавлении в memo эта строка туда (в memo) скопируется.

> она точно правильно автоматически освободится сразу после
> добавления в Memo?

Нет, константа никуда не денется. И освобождать её не надо.

> И то же самое - если я не явно укажу 'Log Entry', а через
> string-переменную... проблем не будет?..

Нужен конкретный код.


Наверх

Титульная страница Поиск, карта сайта Написать письмо