1

I'm sending a log message to the main form using this:

For send the message:

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;

And display it:

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;

This is for log the output from execute some python scripts.

However look like if the message string is too large, the process hang and is necesary kill the python process.

I was not aware that could exist a limit. PostMessage have a limit in the size of the data or could be something else?

This is with Delphi 2010.

EDIT: Sorry, I forget to show the type of msg. Is a String.

mamcx
  • 15,916
  • 26
  • 101
  • 189
  • 3
    PostMessage can only send integers, so it's definitively not that. – nos Jan 18 '10 at 17:50
  • 2
    Nos, you should post that as an answer because it's the correct answer. It doesn't solve Mamcx's problem, but he didn't ask for a solution; he merely asked whether message length could be the cause. – Rob Kennedy Jan 18 '10 at 18:22
  • One piece of information is missing - what is the type of the *Msg* variable whose data you are moving? The declaration of that variable may have a bearing on why the message receiver code is not behaving as expected. Also, what is "too large"? What length of Msg data works, and what length doesn't? Is this consistent, i.e. do messages of length N-1 always work and of length N always hang (where N is yet to be specified)? Finally [sic] that call to FreeMem(p) in the message handler should be duplicated in your exception handler or preferably be in a try..finally to ensure that p is freed. – Deltics Jan 18 '10 at 19:31

2 Answers2

0

I thought you shouldn't use Move. Are you sure all characters are from the same length ?

UPDATE:

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

I never have used pChar's too much, but don't you have to append a #0 character to the Msg string before you do this. Delphi 2010 does not zero out memory when using GetMem.

Edelcom
  • 5,038
  • 8
  • 44
  • 61
  • 1
    Although there are better ways to make a copy of a string, there's nothing wrong with the code that uses Move. Characters are obviously the same length because it's all in the same program, and he's copying exactly as many characters as he allocated memory for. (The better way is this: `var p: PString; New(p); p^ := Msg;` Then, in the message handler: `var p: PString; p := PString(Msg.LParam); EditLog.Add(p^); Dispose(p);`) – Rob Kennedy Jan 18 '10 at 18:28
  • SO, this is the answer, is not a limit on it. Also your code is more clean!. Please put as a answer so I can mark it. The problem with python is related to http://stackoverflow.com/questions/527197/intercepting-stdout-of-a-subprocess-while-it-is-running – mamcx Jan 19 '10 at 19:40
0

I'm taking the other route than mghie here (whoes answer just magically completely and utterly non-magically disappeared on me :P), looking at your code I can only deduce you ARE sending data from within the same process.

You are simply passing a pointer through PostMessage, so there is no limit on message size. When you debug your code (you are debugging that piece of code, right?), on what line does it break? The assignment of .text?

Try assigning the pchar to a string first, and writing that string to a file. If that works, you have a direction to look into.

If that doesn't work, verify using the debugger the pointer is indeed pointing towards a string, and if that string is zero-terminated. From the code you posted, it looks like it is.

Paul-Jan
  • 16,746
  • 1
  • 63
  • 95
  • @Paul-Jan: There's no magic in this disappearing act - on re-reading the question I came to the conclusion that this `PostMessage()` could indeed only be inside of the same application, so I deleted the answer. – mghie Jan 18 '10 at 18:32
  • Yes, is inside the same app. I need to do this because the code is on a multi-thread server (using RemObjects) that send log output to the main thread. – mamcx Jan 19 '10 at 19:00