-
January 24th, 2013, 09:10 PM
#16
Re: How to set a starting root directory for this code that selects a folder name?
ReleaseBuffer resets the length of the string so that functions like GetLength() work properly. The CSimpleStringT destructor does not call ReleaseBuffer, it's just calls an internal Release which frees up the memory if the string ref count is zero. No need to call ReleaseBuffer to reset the length of the string since the string object is going away.
ReleaseBuffer should be called after GetBuffer so you can use other string functions. Presumably you use GetBuffer to put data into the string from apis that take a string buffer. After putting the data in, call ReleaseBuffer to set the length of the string. I usually match up the calls and not worry about it further. I'd rather code this way than have to remember what ReleaseBuffer does and when I really need to call it.
Here's a snippet to ponder...
Code:
CString sTest(_T("I am a test string."));
int size = sTest.GetLength(); // 19 characters
LPTSTR wz = _tcscpy(sTest.GetBuffer(35), _T("I am a larger test string: 34 chars"));
size = sTest.GetLength(); // 19 characters - oops
sTest.ReleaseBuffer();
size = sTest.GetLength(); // 35 characters
-
January 25th, 2013, 04:52 AM
#17
Re: How to set a starting root directory for this code that selects a folder name?
Originally Posted by Mike Pliam
Code:
//bi.lParam = (LPARAM)(LPCTSTR)m_csMyLastDir; // this won't compile
I wonder how it would not.
Code:
#include <windows.h>
#include <tchar.h>
#include <atlstr.h>
int _tmain()
{
CString str = TEXT("text");
LPARAM lptr1 = (LPARAM)(LPCTSTR)str;
LPARAM lptr2 = (LPARAM)str.GetString();
LPARAM lptr3 = (LPARAM)str.GetBuffer();
_tprintf(TEXT("%x\n%x\n%x\n%s\n"), lptr1, lptr2, lptr3, lptr1);
return 0;
}
Code:
D:\Temp\75>cl 75.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
75.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:75.exe
75.obj
D:\Temp\75>75.exe
31a418
31a418
31a418
text
Last edited by Igor Vartanov; January 25th, 2013 at 04:58 AM.
Best regards,
Igor
-
January 25th, 2013, 05:37 AM
#18
Re: How to set a starting root directory for this code that selects a folder name?
Originally Posted by Mike Pliam
But what if one uses the same string source repeatedly in the same function (scope) ? I suspect it's safer to use ReleaseBuffer in each instance of GetBuffer(0) and let M$ worry about implementing the details of cleanup.
It's always safer to use GetString() in case when your code is not going to modify the string content (which I hope you're always aware of).
Typically it's very easy to tell if the string content may be modified by Win32 API. Non-modifiable will be of type LPC(T)STR. Modifiable will be LP(T)STR.
Code:
CString str;
typedef struct _RO
{
LPCTSTR readonly;
} RO;
RO ro;
ro.readonly = str; // casting to LPCTSTR is equivalent to calling GetString
typedef struct _RW
{
LPTSTR readwrite;
} RW;
RW rw;
rw.readwrite = str.GetBuffer(200);
. . .
str.ReleaseBuffer();
Though a special class of cases exists when the same structure type is used in WinAPI for both reading and modification. Good example would be LVITEM. The same field LPTSTR pszText is used for sending text to ListView as well as retrieving it from it. So, less restrictive type LPTSTR is used here. But when you just set the text to control, the control is never going to modify your string, so you are safe to do the following:
Code:
lvi.pszText = (LPTSTR)(LPCTSTR)str;
// here with second cast you just make compiler be happy
// but internal string still remains constant
But when you retrieve the string from control you have to provide a real writable buffer:
Code:
lvi.pszText = str.GetBuffer(200);
lvi.cchTextMax = 200;
. . . // calling API to retrieve the text
str.ReleaseBuffer();
In case of passing string via LPARAM again you must be aware if this is going to modify your string content or not. If it's not, you use GetString() or operator(LPCTSTR). If it is, you use GetBuffer(ANTICIPATED_SIZE).
Best regards,
Igor
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|