How to set a starting root directory for this code that selects a folder name? - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 18 of 18

Thread: How to set a starting root directory for this code that selects a folder name?

  1. #16
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,310

    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

  2. #17
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,990

    Re: How to set a starting root directory for this code that selects a folder name?

    Quote Originally Posted by Mike Pliam View Post
    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 03:58 AM.
    Best regards,
    Igor

  3. #18
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,990

    Re: How to set a starting root directory for this code that selects a folder name?

    Quote Originally Posted by Mike Pliam View Post
    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

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center