In article <334b95b...@news.power.net.uk>,
Com...@lottery.powernet.co.uk (Matthew) wrote:
Quote
> I want to know why would anyone use StrPCopy when, apparently, #0 at
> the end seems to work just as well?
> Someone told me FindWindow was a pain in the backside. So I coded
> three illustrations to see what's going on.
> Example 1
> --------------
> procedure TForm2.Button1Click(Sender: TObject);
> var H1: longint;
> MwPChar: PChar;
> begin
> MwPChar:='';
> MwPChar:=strpcopy(MwPChar,'TMyForm1');
> H1 := FindWindow(MwPChar,nil) ;
> end;
> I find this works, but GPF's if the following line is omitted:
> MwPChar:=''; {for "initialisation" apparently, max length of PChar
> in Delphi 1?}
A PChar is a pointer - you need to allocate memory for it. The
MwPChar:='' is _not_ a valid way to "initialize" a PChar. It's
setting the pointer to some spot in memory that's already been
allocated - then the StrPCopy is _overwriting_ places in memory
that you don't want to overwrite. You allocate memory for your PChar
with StrAlloc. (Or you use an array[0..n] of char, or do any
number of things.) You get the GPF without that line because the
pointer is pointing to a totally random location in memory - it's
unfortunate that the "initialization" MyPChar:= '' appears to
work at first - it's wrong, it will eventually lead to a GPF
or much worse, some problem caused by the fact that you've overwritten
something.
Quote
> Example 2
> --------------
> procedure TForm2.Button1Click(Sender: TObject);
> var H1: longint;
> MwString: string;
> begin
> MwString:='TMyForm1'#0;
> H1 := FindWindow(@MwString[1],nil) ;
> end;
> I find this works, provided the #0 is put at the end of MwString.
> This is one line less code than Example 1, but I can see no
> disadvantages where this would not work as well as StrPCopy(). I have
> seen loads of code examples on newsgroups using StrPCopy(). Why do
> people use it.
Assuming you're using D2 then an even easier way is just to
say PChar(MyString) - a long string already has the #0 at the end.
In D1 you need to add the #0 as you did. For something exactly as
above there's no real reason to use StrPCopy - you want StrPCopy
if for some reason you want to copy a string into the space
allocated for a PChar, as opposed to just using the string as though
it were a PChar.
Quote
> I think it such a bother to specify the PChar twice in the same line
> of code:
> MwPChar:=strpcopy(MwPChar,'TMyForm1');
> First as a parameter, and then as the return value. What reason would
> there be for that? I don't understand why they design these functions
> like that.
You don't need to say it that way - the line above has exactly
the same effect as just saying
strpcopy(MwPChar,'TMyForm1');
They designed it the way they did so if you feel like "assigning" the
return value to a PChar you can.
Quote
> Why not:
> MwPChar:=strpcopy('TMyForm1');
> Wouldn't that be simpler to use in code?
Ah, but to set it up this way StrPCopy would have to automatically
allocate memory. It doesn't - if you're using PChars the idea is you
feel like allocating and freeing the memory yourself.
Quote
> Am I "wasting" memory in my Example 2 above? Apparently, Delphi 1
> allocates 256 bytes to the MwString by default. I see many people use
> this:
> Item : array[0..15] of char
> Then they point to that. I always wonder why. That seems a lot of
> typing to me. The length is fixed. Is it that this uses just 15 bytes,
> while my method in Example 2 above uses 256 for the string variable?
> The 256 bytes are released by Delphi when the function has executed
> anyway, or not? So why do so many programmers use these arrays of
> char?
It's not so they can use only 15 (um, 16!) bytes. You can do more
or less the same thing with StrAlloc(16). I think one reason for
using the array[0..15] of char has to do with the fact that the
memory's allocated [here] instead of [there] - I've never quite got
straight what [here] and [there] are. Another reason has to do with
the fact that people sometimes find it confusing to allocate and
free memory properly - using the array of char Delphi takes care
of all that. (Hmm, if it's an array[0..15] of char then the memory
is allocated once at startup - if you allocate it yourself at the
start of the procedure and free it at the end then you're doing
a lot more allocating and freeing.)
Quote
> Example 3
> --------------
> procedure TForm2.Button1Click(Sender: TObject);
> var H1: longint;
> begin
> H1 := FindWindow('TMyForm1'#0,nil) ;
> end;
> This is one line only, and I find it works. The class name is "hard
> coded", i.e. not in a variable reference.
> So it seems 'Hello'#0 is the same as 'Hello'+#0;
Yup.
Quote
> In haste I found #13 and #0 easily confused, where #13 is a carriage
> return in text strings, #0 the terminator for pointer strings.
> Email appreciated. I respond to every email.
> Matthew
-------------------==== Posted via Deja News ====-----------------------
http://www.dejanews.com/ Search, Read, Post to Usenet