Re: strange behaviour

From: AlanGLLoyd (alanglloyd_at_aol.com)
Date: 10/24/03


Date: 24 Oct 2003 10:39:47 GMT

In article <d96764ff.0310232351.480fa9ab@posting.google.com>, nic@aub.dk
(Nicolai Hansen) writes:

>In an application I need to get the folder in which Windows are
>installed.
>
>My first attempt was:
>
>var
> p: PChar;
> s: String;
>begin
> GetWindowsDirectory(p, 256);
> s:=p;
> Showmessage(s); <---
> Showmessage('done');
>end;
>

The MSDN (Microsoft Developer Network) says of GetWindowsDirectory ...

"Parameters
lpBuffer
[out] Pointer to the buffer to receive the null-terminated string containing
the path. This path does not end with a backslash unless the Windows directory
is the root directory. For example, if the Windows directory is named Windows
on drive C, the path of the Windows directory retrieved by this function is
C:\Windows. If the system was installed in the root directory of drive C, the
path retrieved is C:\.
uSize
[in] Specifies the maximum size, in TCHARs, of the buffer specified by the
lpBuffer parameter. This value should be set to MAX_PATH+1 to allow sufficient
space for the path and the null terminator.
Return Values
If the function succeeds, the return value is the length, in TCHARs, of the
string copied to the buffer, not including the terminating null character.

If the length is greater than the size of the buffer, the return value is the
size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error
information, call GetLastError. "

This has some main points ...

1 You must supply memory for windows to put the directory into.
2 It returns the length it has used or needs.
3 If what it needs is more than what is supplied it will have failed.
4 You should start with MAXPATH + 1 (ie 261) bytes of memory
5 If it fails it returns 0

You can supply the memory either as a buffer you have allocated, or as an array
of char, or as string memory.

Personally I favour using string memory (because one is going to use it as a
string), and so I use SetLength() to allocate memory and to set the elength to
what is returned. One _could_ protect against future changes in MAX_PATH by
checking that one has provided enough memory, but I don't think that is
necessary.

So ...

var
  WinDir : string;
  LenWinDir : integer;
begin
  LenWinDir := MAX_PATH + 1; // never use "magic numbers"
  SetLength(WinDir. LenWinDir); // set some memory for the API
  LenWinDir := GetWindowsDirectory(PChar(WinDir), LenWinDir);
  SetLength(WinDir, LenWinDir); // set the string to the memory used;
  //
  ShowMessage('WinDir : ' + WinDir);

Failure of the API will end up with a null string.

Another way of pointing to string memory for an API is "@WinDir[1]".

The memory for WinDir will be released by Delphi when it goes out of scope.

Alan Lloyd
alanglloyd@aol.com
   



Relevant Pages

  • Re: Discovering variable types...
    ... >- but I suppose MS expect us to use wrappers ... memory allocations for your variables from disk as well. ... >They most certainly are of fixed size, changing the size of a String ... >>me to keep buffer size and current postion right in the memory block. ...
    (comp.lang.pascal.delphi.misc)
  • Re: Is this string input function safe?
    ... return a pointer to mallocated memory holding one input string, ... complains about use of deallocated pointers, ... mallocating an appropriate amount of memory. ... the contents of the buffer are indeterminate (for different ...
    (comp.lang.c)
  • Re: Buffer or Realloc?
    ... better to allocate memory and realloc it for the size of the what is ... between deciding to use a fixed size buffer or allocating memory ... so for the string I've got to prepare as part of a message to the UK Government gateway where the specification says the string has a maximum length of 10 characters I should not use a fixed size buffer but a reallocating buffer? ... with the realloc() approach -- obviously ...
    (comp.lang.c)
  • Re: Something wrong in my program
    ... what becomes of the memory block starting at this address is no ... our text buffer can contain 15 characters ... a string is a char array *terminated ...
    (comp.lang.c)
  • Re: Discovering variable types...
    ... >memory it points to is on the heap. ... sequentially reading data, if one is randomly reading records, then a ... >project is what's prompting me to improve disk access. ... from a memory buffer I can do it in about a second. ...
    (comp.lang.pascal.delphi.misc)