🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.delphi.vcl.components.using.general
10 messages
10 total messages Started by Sjors Sat, 26 Jul 2008 08:41
Is there someting like a non blocking 'ShowMessage'?
#248
Author: Sjors
Date: Sat, 26 Jul 2008 08:41
2 lines
1062 bytes
I want a batch process to continue, but I want a popup message window if it 
discovers an error. 
Re: Is there someting like a non blocking 'ShowMessage'?
#249
Author: Remy Lebeau (TeamB)
Date: Sun, 27 Jul 2008 05:20
11 lines
1190 bytes
"Sjors" <noreply@chello.nl> wrote in message 
news:488ae33b$1@newsgroups.borland.com...

> I want a batch process to continue, but I want a popup message window
> if it discovers an error.

Use a normal TForm for that.


Gambit 
Re: Is there someting like a non blocking 'ShowMessage'?
#250
Author: Peter Below (TeamB)
Date: Sun, 27 Jul 2008 08:22
25 lines
2034 bytes
Sjors wrote:

> I want a batch process to continue, but I want a popup message window
> if it discovers an error.

If the batch process is a console process just write a message to the
console window using WriteLn. If the console is supposed to be hidden
or you want something more visible for the user that does *not* block
further processing then you would have to create a message dialog (use
Windows.MessageBox) in a secondary thread. Using a normal form with
Show would not work if the program does not return to the message loop
afterwards. You could make it paint itself by calling its Update method
after the Show, but it would otherwise appear dead to the user (and the
OS).

An alternative method would be to collect the error messages in a
TStringlist first and only show a dialog with the collected messages
once the processing has completed.

-- 
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires), 
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
Re: Is there someting like a non blocking 'ShowMessage'?
#251
Author: Sjorsj DubbelJoe Boes
Date: Mon, 28 Jul 2008 12:37
45 lines
1855 bytes
"Peter Below (TeamB)" <none@nomail.please> wrote in


> Windows.MessageBox in a secondary thread.


Thanks, I've written this code below and that seems to work. :-)

type
  TMsgRecord = record
    thread : Integer;
    msg    : string[30];
  end;


var
   id : LongWord;
   threadhandle : Integer;
   msgrec : TMsgRecord;


ThreadVar  msgPtr : ^TMsgRecord;

function ShowMsg(Parameter : Pointer) : Integer;
begin
  // Set up a 0 return value
  Result := 0;

  msgPtr := Parameter;

  ShowMessage(msgPtr.msg);

  // End the thread
  EndThread(0);
end;

//.... blah die blah, etcetera

if TLogger.getInstance.GetWrittenError() then
begin
    msgrec.thread := 1;
    msgrec.msg    := 'Error in populate main dbf';
    threadhandle := BeginThread(nil, 0, Addr(ShowMsg), Addr(msgrec), 0, id);
end;
Re: Is there someting like a non blocking 'ShowMessage'?
#252
Author: Peter Below (TeamB)
Date: Mon, 28 Jul 2008 20:16
37 lines
2019 bytes
Sjorsj DubbelJoe Boes wrote:

> 
> "Peter Below (TeamB)" <none@nomail.please> wrote in
> 
> 
> > Windows.MessageBox in a secondary thread.
> 
> 
> Thanks, I've written this code below and that seems to work. :-)
> 
> var
>   id : LongWord;
>   threadhandle : Integer;
>   msgrec : TMsgRecord;
> ThreadVar  msgPtr : ^TMsgRecord;
> 
> function ShowMsg(Parameter : Pointer) : Integer;
> begin
>  // Set up a 0 return value
>  Result := 0;
> 
>  msgPtr := Parameter;
> 
>  ShowMessage(msgPtr.msg);

I said "Windows.Messagebox" for a reason, you know. The VCL is not
threadsafe, it is not a good idea to show a VCL form in a secondary
thread, and ShowMessage does exactly that.


-- 
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires), 
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
Re: Is there someting like a non blocking 'ShowMessage'?
#254
Author: Sjorsj DubbelJoe Boes
Date: Tue, 29 Jul 2008 08:06
9 lines
1470 bytes
"Peter Below (TeamB)" <none@nomail.please> wrote

> I said "Windows.Messagebox" for a reason, you know. The VCL is not
> threadsafe, it is not a good idea to show a VCL form in a secondary
> thread, and ShowMessage does exactly that.

Ok I'll look into it and change it. I made the mistake that I thought TForm 
was not the good option, but I could use ShowMessage. 
Re: Is there someting like a non blocking 'ShowMessage'?
#256
Author: Sjorsj DubbelJoe Boes
Date: Tue, 29 Jul 2008 08:55
23 lines
2064 bytes
"Peter Below (TeamB)" <none@nomail.please> wrote

> I said "Windows.Messagebox" for a reason, you know.

Ok I changed this:

  //ShowMessage(msgPtr.msg);
  Windows.MessageBox(0, Addr(msgPtr.msg[1]), 'Populate Main', 
MB_SETFOREGROUND );

Now the handle should be the handle of the calling form. But, it's a dll 
extern fuction with no GUI, so there is no calling form, hence I made it 0. 
Also the MessageBox seems to take a pointer to a null terminated string, but 
at msgPtr.msg[0] I think Delphi puts the length of the string. Also I am a 
bit surprised by the syntax string[128], I thought I should use char[128], 
but that's probably C++/Java syntax. I do hope string[128] produces a null 
terminated string like this then?

It seems to work though.

Oh yes, I do have more experience in C++, C# and Java then in Delphi, so I 
am a bit confused about the string syntax in Delphi. But this is ok then? 
Re: Is there someting like a non blocking 'ShowMessage'?
#257
Author: Peter Below (TeamB)
Date: Tue, 29 Jul 2008 13:25
87 lines
4223 bytes
Sjorsj DubbelJoe Boes wrote:

> 
> "Peter Below (TeamB)" <none@nomail.please> wrote
> 
> > I said "Windows.Messagebox" for a reason, you know.
> 
> Ok I changed this:
> 
>  //ShowMessage(msgPtr.msg);
> Windows.MessageBox(0, Addr(msgPtr.msg[1]), 'Populate Main',
> MB_SETFOREGROUND );

Argh, do not use Addr, especially not with strings. If msgPrt.msg is an
array of string or a TStringlist use a PChar cast:

Windows.MessageBox(0, PChar(msgPtr.msg[1]), 'Populate Main',
   MB_SETFOREGROUND );

A PChar cast on a string returns the address of the first character
(and Delphi strings are zero-terminated to be compatible with API
routines when needed). But it also does something extra: it calls
UniqueString on the string first to make sure the address resulting
from the PChar cast is for a string with a reference count of 1, in
case the API function needs to write to the string memory.

> Now the handle should be the handle of the calling form. But, it's a
> dll extern fuction with no GUI, so there is no calling form, hence I
> made it 0. 

Perfectly OK, but you could also pass the return value of
GetActiveWindow or GetForegroundWindow to it.

>Also the MessageBox seems to take a pointer to a null
> terminated string, but at msgPtr.msg[0] I think Delphi puts the
> length of the string. 

Only if you are using the old Shortstring or String[n] types. 

  S: Shortstring;  

as a variable declaration is the same as 

  S: String[255];

255 is the maximum size for a shortstring type, you can declare types
with smaller memory footprints by using lower number inside the square
brackets.

It gives you memory for a 256 byte array, the first element at index 0
stores the length of the string contained in the array (there is no #0
terminator for shortstrings), 1-byte characters are stored from index
1. If you need a #0 terminator you have to add it in code. To pass a
shortstring as a char* to an API function add a #0 and pass @S[1] (or
Addr(S[1])).

 S: String;

declares a variable of type AnsiString (at the moment, with Tiburon
that will change to UnicodeString). The Ansistring type is a dynamic
array of 1 byte characters, with memory mostly managed by the compiler.
The array can store up to Max(Longint)-8 characters theoretically and
it has an associated reference count managed by the compiler. The
compiler also makes sure the strings end in a #0 (which is not counted
by Length). Shortstrings are value types, Ansistrings are reference
types (the variable stores a pointer to a memory block on the heap). To
pass an ansistring as a char* you use Pchar(S).


Also I am a bit surprised by the syntax
> string[128], I thought I should use char[128], but that's probably
> C++/Java syntax. I do hope string[128] produces a null terminated
> string like this then?

No, see above. 

> It seems to work though.

Famous last words <g>.


-- 
Peter Below (TeamB)  
Don't be a vampire (http://slash7.com/pages/vampires), 
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
Re: Is there someting like a non blocking 'ShowMessage'?
#259
Author: Remy Lebeau (TeamB)
Date: Tue, 29 Jul 2008 16:59
41 lines
2660 bytes
"Sjorsj DubbelJoe Boes" <sales@ingcarlease.nl> wrote in message 
news:488edad2@newsgroups.borland.com...

> Now the handle should be the handle of the calling form. But, it's a
> dll extern fuction with no GUI, so there is no calling form, hence I
> made it 0.

That is fine.

> Also the MessageBox seems to take a pointer to a null terminated
> string, but at msgPtr.msg[0] I think Delphi puts the length of the string.

Only for short strings, not long strings.  Use a PChar() cast instead of 
Addr():

    Windows.MessageBox(0, PChar(msgPtr.msg), 'Populate Main', MB_OK);

> Also I am a bit surprised by the syntax string[128]

That creates a short string that has a maximum of 128 characters in it.  It 
takes up a fixed 129 bytes of memory - 1 byte for the length and 128 bytes 
for the characters..

> I thought I should use char[128], but that's probably C++/Java syntax.

You can do that, but you would have to manually ensure that a null character 
exists in the array.

> I do hope string[128] produces a null terminated string like this then?

It does not guarantee that.  However, the compiler knows how to convert a 
short string to a null-terminated long string, so you can do this:

    var
        msg: string[128];

    Windows.MessageBox(0, PChar(String(msg)), 'Populate Main', MB_OK);


Gambit 
Re: Is there someting like a non blocking 'ShowMessage'?
#261
Author: Sjorsj DubbelJoe Boes
Date: Wed, 30 Jul 2008 13:06
26 lines
2055 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote

>    Windows.MessageBox(0, PChar(String(msg)), 'Populate Main', MB_OK);

Hi guys,

Actually there is no reason why msg should no be a string itself, or you 
should say otherwise. I copied the code for a large part from

http://www.delphibasics.co.uk/RTL.asp?Name=ThreadVar

If I change msg its type from 'string[128]' to 'string', and call:

Windows.MessageBox(0, PChar(msgPtr.msg), 'Populate Main', 
MB_SETFOREGROUND );

It seems to work. (Although that could be my 'famous last words')

And thanks for the help with these Delphi questions. I am a quite 
experienced programmer, and I did C++, Java, C#, and my manager thinks that 
I then can do a little Delphi too if there is no-one else for the job. Which 
is of course correct, in principle, but you always run into the little 
detials you do not know that cost a lot of time.

:-)
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads