Re: When CString doesn't work

Tech-Archive recommends: Fix windows errors by optimizing your registry



I very much appreciate the advice. Keep in mind that though I'm
somewhat proficient in C++ I'm still very new to Windows programming.
This is one of two self-imposed projects I'm starting out with. I
have a profusion of books to have to go through before I've even got
the most basic of the basics down. Uni-code, though not a new concept
to me is something I haven't worked with before at a programming
level. I wanted to get this code down to something that worked well
enough to help me learn the basics. The bells and whistles can come
later. But I could use a good tutorial on Uni-code so I can hopefully
avoid the pitfalls.

As for the inconsistencies? That's a by-product of my attempts to
make the code work. What I presented isn't what I started out with.
It's what I ended up with while trying to figure out why my CString
wasn't working as expected.

There are functions and methods I'm aware of, some I can guess at and
some I don't know a thing about. It's going to take some time before
I'm aware of, let alone familiar with, the most common of them so it's
going to take some time.

I appreciate the help I get from this newsgroup and hope that all of
y'all will bear with me as I get more and more water to cover my feet.
I do spend time trying to work out the problem and researching MSDN,
among other sources, before I put a question to this group.

And for the record, the responses I received to my essential question
resolved the problem. My thanks to all.

Lilith

On Sat, 04 Jun 2005 01:53:02 -0400, Joseph M. Newcomer
<newcomer@xxxxxxxxxxxx> wrote:

>See below...
>On Fri, 03 Jun 2005 15:06:42 -0500, Lilith <lilith@xxxxxxxxx> wrote:
>
>>I must seem like a totally ignorant progammer but when something
>>doesn't work as advertised I just have assume that I got the wrong
>>message from the advertisement.
>>
>>I'm writing a program with VC++ that requires I get a base directory
>>from the user then construct strings representing subdirectories two
>>levels under that. The directory below the main directory has a
>>consistent name but the next one down that's pertinent to this project
>>can be anything amongst a number of user named directories. The user
>>will need to select from the names of these. Initially I sought them
>>out and added them to a combo box for the user to select from but
>>changed my tactic to looking for a known subdirectory in the directory
>>designated for the functionality I'm looking at.
>>
>>The problem is that when I try to manipulate CString items with
>>concatenation, either with a string litteral or another CString, the
>>content of the string will not change. I'm following this through the
>>debugger with a watch view. The code in question is marked with "->"
>>in the code below.
>>
>>Hit me on the head if you think I'm being ignorant but I need to know
>>if there's something I simply am not understanding. Lilith
>>
>>void CGWLearnView::OnDomainBrowseBtn()
>>{
>> int i;
>>
>> CString DomainDirFile;
>> static CString WPGate = "WPGATE\\*";
>****
>First major error: if you use the word 'static', you must also prefix it with the word
>'const'. If you have a non-const CString, you have almost certainly made a serious
>programming error. I would suggest either of these changes, but as it stands right now, I
>consider the above statement erroneous.
>
>Never use literal strings like you did here. Use _T("WPGATE\\*"). Always program
>Unicode-aware
>****
>> static char FileFilter [] = "Domain Database (*.db)|*.db||";
>****
>const static. Why is this not a string resource? Why is char being used? First rule of
>successful Windows programming: 'char' as a datatype is used in very esoteric and
>restricted situations. This is not one of them.
>
>CString FileFilter;
>FileFilter.LoadString(IDS_FILE_FILTER);
>
>or is the phrase "Domain Database" recognized in every language in the world?
>****
>> WIN32_FIND_DATA FileInfo;
>>
>> CFileDialog oDomainDir(TRUE, "db", "wpdomain", OFN_FILEMUSTEXIST,
>> FileFilter);
>> oDomainDir.DoModal(); // open file dialog
>****
>And what happens if the user clicks "Cancel"?
>
>if(oDomainDir.DoModal() != IDOK)
> return;
>****
>> if ((oDomainDir.GetFileName()).IsEmpty()) return; // do nothing if
>> //no file name
>> DomainDirFile = oDomainDir.GetPathName(); // get the full path
>>
>>// display it
>> for (i=DomainDirFile.GetLength()-1; DomainDirFile[i] != '\\'; i--);
>> i++;
>> DomainDirFile.SetAt(i, '\0');
>> DomainDirectory = DomainDirFile;
>****
>What is this nonsense? Don't attempt to parse file names on your own.
>
>TCHAR drive[MAX_PATH];
>TCHAR path[MAX_PATH];
>
>_tsplitpath(DomainDirFile, drive, path, NULL, NULL);
>_tmakepath(DomainDirectory, drive, path, NULL, NULL);
>
>Typically, if I need a path ending in \, I make sure it is correct by doing
>
>if(DomainDirectory.Right(1) != (_T"\\") || DomainDirectory.Right(1) != _T("/"))
> DomainDirectory += _T("\\");
>*****
>
>> SetDlgItemText(IDC_DOMAIN_DIR, DomainDirectory);
>****
>What is this? Create a control variable
>
>c_DomainDir.SetWindowText(DomainDirectory);
>
>SetDlgItemText is used in non-MFC apps.
>****
>>-> DomainDirFile += WPGate;
>>
>> HANDLE FHandle = FindFirstFile (WPGate, &FileInfo);
>> if (FHandle != INVALID_HANDLE_VALUE) {
>> do {
>> if (FileInfo.cFileName[0] == '.') continue;
>***
>The above test is incorrect. It presumes that the only two items in the directory that
>start with "." are the two directory elements "." and "..". There is no reason to assume
>this is so. The correct test is
> if(FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
> (FileInfo.cFileName == CString(_T(",")) ||
> FileInfo.cFileName == CString(_T(".."))))
> continue;
>
>You really don't want code that will fail in real environments.
>
>Better still, use the MFC interator, which has operators that do this for you already.
>****
>> m_API_List.AddString (FileInfo.cFileName);
>> } while (FindNextFile (FHandle, &FileInfo));
>> FindClose (FHandle);
>> }
>> CFileFind finder;
>> CString API = "WPGATE\\API_*";
>>-> APIDirectory = DomainDirectory + API;
>****
>Why are you using a completely different method to store the string? In one case you
>declare a static CString and here you declare a non-static CString. By the way, in neither
>case do you need a variable. You could easily have done
>
>#define API _T("WPGATE\\API_*")
>CString APIDirectory = DomainDirectory + API;
>****
>> SetDlgItemText (IDC_API_DIR, APIDirectory);
>****
>Lose SetDlgItemText. Use control variables.
>****
>>}
>>
>>
>
>Joseph M. Newcomer [MVP]
>email: newcomer@xxxxxxxxxxxx
>Web: http://www.flounder.com
>MVP Tips: http://www.flounder.com/mvp_tips.htm

.



Relevant Pages

  • Re: CString Array to LPCTSTR *
    ... The point is CString is so suitable for windows programming. ... STL string would be a good choice for writting cross platform libraries. ... a const char *, GetBuffergets me LPTSTR which is not constant. ...
    (microsoft.public.vc.mfc)
  • Re: peer code review/advice needed for noob programmer
    ... There are lots of easy ways to transition from char to CString; ... Yes, except I am having to program to Microsoft FS's API, and the string is ... if any reason to allocate a buffer here. ...
    (microsoft.public.vc.mfc)
  • Re: CSocket/CAsyncSocket sending and receiving
    ... Stop experimenting with CSocket; it is losing. ... CString constructor will do a MultiByteToWideChar to convert the string. ... sequence of Receives will receive N bytes. ...
    (microsoft.public.vc.mfc)
  • Re: CFileDialog drives me insane. Handle Problem ?
    ... The basic type you care about is CString. ... This is the equivalent to the Java 'String' ... There are rare cases in which you need a LPTSTR pointer, ... const wchar_t * - const pointer to Unicode characters. ...
    (microsoft.public.vc.mfc)
  • Re: CFileDialog drives me insane. Handle Problem ?
    ... The basic type you care about is CString. ... This is the equivalent to the Java 'String' ... There are rare cases in which you need a LPTSTR pointer, ... const wchar_t * - const pointer to Unicode characters. ...
    (microsoft.public.vc.mfc)