Board index » delphi » Newbie StrPCopy, FindWindow API, #0, PChar

Newbie StrPCopy, FindWindow API, #0, PChar

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?}

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.

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.

Why not:

    MwPChar:=strpcopy('TMyForm1');

Wouldn't that be simpler to use in code?

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?

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;

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

 

Re:Newbie StrPCopy, FindWindow API, #0, PChar


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.

- Show quoted text -

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

Re:Newbie StrPCopy, FindWindow API, #0, PChar


Quote
Matthew wrote:

> 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?}

> 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.

> 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.

> Why not:

>     MwPChar:=strpcopy('TMyForm1');

> Wouldn't that be simpler to use in code?

> 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?

> 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;

> 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

Yes, this is true in Win16. In Win32, it only works with Short Strings.

I wrote an article about this in the Windows Tech Journal -
"Pulling Pascal's Strings"

You might want to take a look at it.

I highly recommend using S+#0 if your going to go that direction.

Joe
--
Joe C. Hecht
(Borland Delphi Developer Support)
Join the Delphi Online Discussion Forum at
http://www.borland.com/techsupport/delphi/

Other Threads