Форум: "Начинающим";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
ВнизПередать PChar через PostMessage Найти похожие ветки
← →
Призрак © (2006-07-02 21:38) [0]Один поток передаёт другому
PostMessage(MyWnd.Handle, WM_USER, integer(PChar("Log Entry")), 0)
, а второй добавляет этот"Log Entry"
кMemo
. Вопрос - это не приведёт к каким-нибудь проблемам с освобождением памяти? Я же передаю адрес на специально автоматически созданную переменную... она точно правильно автоматически освободится сразу после добавления вMemo
? И то же самое - если я не явно укажу"Log Entry"
, а черезstring
-переменную... проблем не будет?..
← →
begin...end © (2006-07-02 21:47) [1]> Призрак © (02.07.06 21:38) [0]
> Я же передаю адрес на специально автоматически созданную
> переменную...
Никакой переменной автоматически не создаётся. Ваша строка -- это константа, записанная в исполняемом файле и отображённая в память. Адрес этой константы Вы и передаёте. А при добавлении в memo эта строка туда (в memo) скопируется.
> она точно правильно автоматически освободится сразу после
> добавления в Memo?
Нет, константа никуда не денется. И освобождать её не надо.
> И то же самое - если я не явно укажу "Log Entry", а через
> string-переменную... проблем не будет?..
Нужен конкретный код.
← →
Leonid Troyanovsky © (2006-07-02 21:49) [2]
> Призрак © (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.
← →
Призрак © (2006-07-02 22:03) [3]> Хотя удобней не мемо, а листбокс, и 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 22:20) [4]
> Призрак © (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.
← →
Leonid Troyanovsky © (2006-07-02 22:25) [5]
> Призрак © (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.
← →
Призрак © (2006-07-02 23:07) [6]ну, я написал для проверки так:
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 23:19) [7]
> Призрак © (02.07.06 23:07) [6]
> а в принимающем потоке сделал перед отображением задержку
> на секунду, так чтобы сначала отправилось, потом строка
> изменилась, а потом уже отобразилось... и отобразилась первая
> строка :)
Эксперименты без подходящей теории - поиски в темноте.
Изучать же следует threads & synchronization (Delphi help & msdn).
> *перечитал несколько раз и не понял* ..."здесь тоже константа"?
> .. где?.. там же переменная...
Эта переменная string, которой присвоена константа.
В ее поле кол-во ссылок стоит -1, IMHO. (see system.pas also).
> а моя та приведённая большая штука работать нормально будет?
Нет.
--
Regards, LVT.
← →
Призрак © (2006-07-03 04:09) [8]У меня была теория: я передаю "представление указателя на строку в виде целого", потом меняю строку, и когда в лог добавляется то что лежит там куда указывает указатель, то получится новая строка... Если нет - значит, PChar() не указатель на данную строку даёт, а копирует данную в другое место и возвращает указатель на это... А вот когда "это" разрушается - я не знаю...
А как это надо делать? Я не хочу использовать SendMessage, надо асинхронно... Что мне приходит в голову - это создать динамическую переменную, то есть указатель, создать его в одном потоке, потом передать в другой и освободить после добавления в мему... но я с трудом представляю, как в винде работает вся эта система выделения переменных, освобождения... и вообще как PChar работает... может, просто сделать указатель на строку, и потом New(s) - s:=<что там мне надо> - Postmessage(...s...) и потом в другом потоке тоже описать указатель на строку, взять его из GetMessage и потом Dispose?..
← →
Leonid Troyanovsky © (2006-07-03 07:11) [9]
> Призрак © (03.07.06 04:09) [8]
> А как это надо делать? Я не хочу использовать SendMessage,
> надо асинхронно... Что мне приходит в голову - это создать
Это ж почему асинхронно? Надо, как раз, синхронно, если,
конечно, это дейс-но, запись в лог.
> динамическую переменную, то есть указатель, создать его
> в одном потоке, потом передать в другой и освободить после
> добавления в мему... но я с трудом представляю, как в винде
Да так и делать - первый поток cделает GetMem/StrAlloc,
а второй, после обработки - FreeMem/StrDispose.
--
Regards, LVT.
← →
Призрак © (2006-07-03 20:48) [10]Ммм... Так?
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 21:09) [11]
> Призрак © (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 21:10) [12]ой... да. спасибо. ^_^
← →
begin...end © (2006-07-03 21:12) [13]> Призрак © (03.07.06 20:48) [10]
Можно и так. Правда, не совсем понятно, откуда взялось число 255. Лучше выделять память именно в том количестве, в котором она нужна. Т.е. отправку я бы оформил так: PostMessage(LogForm.Handle, WM_USER, WParam(StrNew(PChar(s))), 0).
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.016 c