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
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 03:58 AM.
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.
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).
Bookmarks