2010-01-18 4 views
0

Я посылаю сообщение журнала в основной форме с помощью этого:Предел размера сообщения PostMessage?

Для отправки сообщения:

procedure LogMsg(Msg: string; Kind:TMsgType=msgNormal); 
var 
    p: pChar; 
begin  
    case Kind of 
    msgError: Msg := '[Error] ' + Msg; 
    msgInformation: Msg := '# ' + Msg; 
    msgExternal: Msg := 'Plugin: ' + Msg; 
    end;//if 

    GetMem(p, (Length(Msg) + 1)*SizeOf(Char)); 
    Move(Msg[1], p^, (Length(Msg)+ 1)*SizeOf(Char)); 

    PostMessage(Application.MainForm.Handle, WM_LOG_MESSAGE, 0, integer(p)); 
end; 

И показать его:

procedure TfrmMain.WMLog(var Message: TMessage); 
var 
    p: pChar; 
    Lista:TStringList; 
begin 
    try 
    p := pChar(Message.LParam); 

    if EditLog.Lines.Count>100 then 
    begin 
     EditLog.Lines.Clear; 
    end;//if 

    Lista := TStringList.Create; 
    try 
     Lista.Delimiter := #10; 
     Lista.text := p; 
     EditLog.Lines.AddStrings(Lista); 
    finally 
     Lista.Free; 
    end;//try 

{$ifndef FPC} 
    EditLog.GotoLineAndCenter(EditLog.Lines.Count); 
{$endif} 

    Freemem(p); 
    except 
    on E: Exception do 
     EditLog.Lines.Add(E.Classname + ': ' + E.Message); 
    end;//try 
end; 

Это для журнала выходе из выполнить некоторые скрипты python.

Однако, если строка сообщения слишком велика, процесс зависает и, как следствие, убивает процесс python.

Я не знал, что может существовать предел. PostMessage имеет ограничение по размеру данных или может быть что-то еще?

Это с Delphi 2010.

EDIT: К сожалению, я забыл показать тип сообщ. Является String.

+3

PostMessage может отправлять целые числа, поэтому это окончательно не то. – nos

+2

Nos, вы должны опубликовать это как ответ, потому что это правильный ответ. Он не решает проблему Mamcx, но он не просил разрешения; он просто спросил, может ли быть причиной сообщения. –

+0

Отсутствует одна часть информации - каков тип переменной * Msg *, данные которой вы перемещаете? Объявление этой переменной может повлиять на то, почему код приемника сообщений не ведет себя так, как ожидалось. Кроме того, что «слишком велико»? Какая длина данных Msg работает, а какая длина нет? Является ли это последовательным, т. Е. Действительно ли сообщения длины N-1 всегда работают, а длина N всегда зависает (где N еще не указано)? Наконец [sic], что вызов FreeMem (p) в обработчике сообщения должен быть дублирован в вашем обработчике исключений или желательно быть в попытке. Наконец, чтобы гарантировать, что p освобожден. – Deltics

ответ

0

Я думал, что вы не должны использовать Move. Вы уверены, что все персонажи имеют одинаковую длину?

UPDATE:

GetMem(p, (Length(Msg) + 1)*SizeOf(Char)); 
Move(Msg[1], p^, (Length(Msg)+ 1)*SizeOf(Char)); 

Я никогда не использовал PChar слишком много, но вы не должны присоединять # 0 символ в Msg строку, прежде чем сделать это. Delphi 2010 не обнуляет память при использовании GetMem.

+1

Хотя есть лучшие способы сделать копию строки, нет ничего плохого в коде, который использует Move.Символы, очевидно, имеют одинаковую длину, потому что все они находятся в одной и той же программе, и он копирует ровно столько символов, сколько он выделил для памяти. (Лучше всего это: «var p: PString; New (p); p ^: = Msg;» Затем в обработчике сообщений: «var p: PString; p: = PString (Msg.LParam); EditLog. Добавить (p ^); Dispose (p); ') –

+0

SO, это ответ, не является для него предел. Также ваш код более чистый !. Пожалуйста, поставьте в качестве ответа, чтобы я мог отметить его. Проблема с python связана с http://stackoverflow.com/questions/527197/intercepting-stdout-of-a-subprocess-while-it-is-running – mamcx

0

Я беру другой маршрут, чем mghie здесь (whoes ответить только волшебно полностью и совершенно не-волшебно исчез на меня: P), глядя на свой код, я могу только вывести вы отправляете данные в пределах одного обработать.

Вы просто передаете указатель через PostMessage, поэтому нет ограничений на размер сообщения. Когда вы отлаживаете свой код (вы, , отлаживаете этот кусок кода, не так ли?), На какой строке он сломается? Назначение .text?

Попробуйте сначала назначить pchar строке и записать эту строку в файл. Если это работает, у вас есть направление для изучения.

Если это не сработает, проверьте, используя отладчик, указатель действительно указывает на строку, и если эта строка имеет нулевое завершение. Из кода, который вы опубликовали, похоже, что это так.

+0

@ Paul-Jan: В этом исчезающем акте нет волшебства - при повторном чтении вопроса я пришел к выводу, что этот 'PostMessage()' действительно может быть только внутри одного и того же приложения, поэтому я удалил ответ. – mghie

+0

Да, находится внутри того же приложения. Мне нужно сделать это, потому что код находится на многопоточном сервере (используя RemObjects), который отправляет вывод журнала в основной поток. – mamcx

Смежные вопросы