|
Did you install MSDN on your system and it doesnt work?
|
|
|
|
|
The most up-to-date docs for the feature pack are only available online
unfortunately. Hopefully they'll make them available for download in
the near future.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I've got a problem that I've tried to figure out, but can't.
Here's my code:
CString str = "C:\\Wells\\Program\\DataBases\\Drivers\\R and S\\OurDrivers.ddb";
CStdioFile myFile;
if(!myFile.Open(str, CFile::modeRead | CFile::typeText))
{
TRACE(_T("Unable to open file\n"));
}
DWORD dw = GetLastError();// error_path_not_found (3)
Here's the error with the CString str
ERROR:
error C2440: 'initializing' : cannot convert from 'const char [58]' to 'ATL::CStringT<BaseType,StringTraits>'
now I realize that this is correct:
CString str = _T("C:\\Wells\\Program\\DataBases\\Drivers\\R and S\\OurDrivers.ddb");
Here's the problem. I have to send "str" to the FileSave" function with the data already in it! I can't convert it like above (hard-coded) because I don't know what cchoices the User used to build the above string(str). I just hard-coded it for testing purposes.
Isn't there someway to use a CString as the filename/path in CStudioFile?
Help Please!
A C++ programming language novice, but striving to learn
|
|
|
|
|
Larry Mills Sr wrote: ...the FileSave" function...
What does its signature look like?
Larry Mills Sr wrote: I just hard-coded it for testing purposes.
So str will actually be populated by the user?
Larry Mills Sr wrote: Isn't there someway to use a CString as the filename/path in CStudioFile?
Yes, and it normally does not require anything special.
"Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
You can use the ATL and MFC String Conversion Macros[^] to convert from wide string to LPCTSTR. Note that it is normally not recommended to use CStringA directly. In addition it is also not recommended to call the GetBuffer() member when there are better alternatives. However with those disclaimers out of the way lets continue to hammer a square peg into a round hole.
An ugly dirty method would be:
CString str = _T("C:\\Wells\\Program\\DataBases\\Drivers\\R and S\\OurDrivers.ddb");
USES_CONVERSION;
myFile.Open((LPCTSTR)CStringA(T2A(str)).GetBuffer(),0,0);
A better way of doing this would be:
CString str = _T("C:\\Wells\\Program\\DataBases\\Drivers\\R and S\\OurDrivers.ddb");
char szPath[MAX_PATH + 1] = {0};
USES_CONVERSION;
strcpy(szPath,T2A(str));
myFile.Open((LPCTSTR)szPath,0,0);
An even better way of doing this might be:
#ifdef _UNICODE
char szPath2[MAX_PATH + 1] = {0};
WideCharToMultiByte(CP_ACP, 0, str, -1, szPath2, MAX_PATH, NULL, NULL);
myFile.Open((LPCTSTR)szPath,0,0);
#endif
Best Wishes,
-David Delaune
|
|
|
|
|
Larry Mills Sr wrote: I have to send "str" to the FileSave" function with the data already in it! I can't convert it like above (hard-coded) because I don't know what cchoices the User used to build the above string(str).
That seems FileSave functions takes CString as parameter, then why do you worry, it is the user who has to ensure proper data in str expected by FileSave method.
Answer DavidCrow's query, don't think about conversion unless you know what you are doing.
|
|
|
|
|
1. I'm using GDI+, when I press F1 to see the help of Pen , it'll try to find Gdiplus::Pen , but find nothing. If I typed Pen manually, it'll be found.
Any way to let F1 find it automatically?
2.
Pen pen(Color::Red);
When compiling with warning level 4, it reports a warning as below:
warning C4245: 'argument' : conversion from '' to 'Gdiplus::ARGB', signed/unsigned mismatch
What a type mismatch!
How to write it correctly?
|
|
|
|
|
hi to all
i am a new bie
i want to know usage of GetDetaitsOf() , NameSpace() , ParseName()
there are JScript , VBScript , Visual Basic examples
on MSDN[^] but i need a C++ example can you show me one
thanks
|
|
|
|
|
reteset wrote: hi to all
i am a new bie
Then you should be studying C++ fundamentals not trying to reproduce code from Javascript and other languages.
led mike
|
|
|
|
|
you probably need to use the IShellFolder2 Interface.
|
|
|
|
|
reteset wrote: i am a new bie
hope the following gives a start, assuming you are not c/c++ newbie but the shell interface newbie,
C++ example for the example[^],
#include <shlobj.h>
#include <shlwapi.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment (lib, "shlwapi.lib")
#define SAFE_RELEASE(_x) if (_x){_x->Release(); _x = NULL;}
int main()
{
LPMALLOC pMalloc = NULL;
IShellFolder *psfShell = NULL;
IShellFolder2 *psfWindowsFolder = NULL;
LPITEMIDLIST pidlWindowsFolder = NULL;
LPITEMIDLIST pidlFile = NULL;
TCHAR szDisplayName[MAX_PATH];
SHELLDETAILS shDetails;
HRESULT hr = E_FAIL;
hr = SHGetMalloc(&pMalloc);
if(FAILED(hr))
goto END;
hr = SHGetDesktopFolder(&psfShell);
if(FAILED(hr))
goto END;
hr = SHGetFolderLocation(NULL, CSIDL_WINDOWS, NULL, NULL,
&pidlWindowsFolder);
if(FAILED(hr))
goto END;
hr = psfShell->BindToObject(pidlWindowsFolder, NULL,
IID_IShellFolder2, (VOID **)&psfWindowsFolder);
if(FAILED(hr))
goto END;
hr = psfWindowsFolder->ParseDisplayName(NULL,
NULL,
_T("clock.avi"),
NULL,
&pidlFile,
NULL);
if(FAILED(hr))
goto END;
hr = psfWindowsFolder->GetDetailsOf(pidlFile, 2, &shDetails);
if(FAILED(hr))
goto END;
hr = StrRetToBuf(&shDetails.str, pidlFile, szDisplayName, sizeof(szDisplayName));
if(FAILED(hr))
goto END;
_tprintf(_T("Details at Column 2 : %s \n"), szDisplayName);
END:
if (pMalloc)
{
if (pidlFile) pMalloc->Free(pidlFile);
if (pidlWindowsFolder) pMalloc->Free(pidlWindowsFolder);
}
SAFE_RELEASE(psfWindowsFolder);
SAFE_RELEASE(psfShell);
SAFE_RELEASE(pMalloc);
return 0;
}
modified on Friday, May 2, 2008 1:31 AM
|
|
|
|
|
Just curious... do you actually use the goto statement that much in production code?
Best Wishes,
-David Delaune
|
|
|
|
|
It's a valid way of doing cleanup in this case; if you do not do that, you will have to copy the same "cleanup" code
all over the place.
|
|
|
|
|
Maximilien wrote: if you do not do that, you will have to copy the same "cleanup" code
all over the place.
No you don't. Just nest the if's and cleanup as you unnest, like so:
hr = SHGetMalloc(&pMalloc);
if(SUCCEEDED(hr))
{
hr = SHGetDesktopFolder(&psfShell);
if(SUCCEEDED(hr))
{
hr = SHGetFolderLocation(NULL, CSIDL_WINDOWS, NULL, NULL, &pidlWindowsFolder);
if(SUCCEEDED(hr))
{
hr = psfShell->BindToObject(pidlWindowsFolder, NULL, IID_IShellFolder2, (VOID **)&psfWindowsFolder);
if(SUCCEEDED(hr))
{
hr = psfWindowsFolder->ParseDisplayName(NULL, NULL, _T("clock.avi"), NULL, &pidlFile, NULL);
if(SUCCEEDED(hr))
{
hr = psfWindowsFolder->GetDetailsOf(pidlFile, 2, &shDetails);
if(SUCCEEDED(hr))
{
hr = StrRetToBuf(&shDetails.str, pidlFile, szDisplayName, sizeof(szDisplayName));
if(SUCCEEDED(hr))
_tprintf(_T("Details at Column 2 : %s \n"), szDisplayName);
}
}
pMalloc->Free(pidlFile);
}
psfWindowsFolder->Release ();
}
pMalloc->Free(pidlWindowsFolder);
}
psfShell->Release ();
}
pMalloc->Release ();
}
I prefer this way since it is obvious where the allocate / deallocate pairs are located.
Judy
|
|
|
|
|
|
I agree with you.
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
Maximilien wrote: It's ugly.
I agree whole-heartedly. However ... it was an example to refute your unqualified statement that "you will have to copy the same "cleanup" code all over the place" which is NOT true. There's no pretty way to deal with this kind of code. All alternatives are ugly when there are so many consecutive statements that both a) depend on the success of the preceding statement and b) each statement allocates something new.
Judy
|
|
|
|
|
JudyL_FL wrote: No you don't. Just nest the if's and cleanup as you unnest, like so:
Hi Judy,
That's a good point. However, the code readability decreases proportionally and it starts looking very ugly with an increased number of if conditions in this approach.
I would personally prefer the sinful goto way of doing it.
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
how wide you go (if i don't want the overhead of another function call)
|
|
|
|
|
The wider you go, the more the danger of your code being classified as horror.
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
Randor wrote: do you actually use the goto statement that much in production code?
never, not because of my interest but it is not in my control, i used to follow the organisation standards. some force to use the do..while(0) horrors, i personally not against it. but i never do the nested way for readability unless the number of statement is less or there is considerable need of inline function.
BTW, what's your opinion?
modified on Friday, May 2, 2008 3:13 AM
|
|
|
|
|
Rajkumar R wrote: BTW, what's your opinion?
The goto statement has always had a bad reputation. I can remember reading many arguments in the C++ usenet newsgroups debating these issues. And beyond the argument 'The goto statement causes spaghetti code' nobody ever gave a reason why the goto statement was bad.
I'm much older now and more experienced so I can now answer this question myself now. It is my opinion that the goto statement should be avoided. The code that Judy posted is a superior method of implementing the function regardless of how ugly it is. My reasoning is quite simple in that the compiler cannot perform optimizations with all of those unconditional jumps all over the place. So by placing all of those goto statements in your function it causes the compiler to produce very different code. You can confirm this by editing your project and enabling 'Assembly With Source Code (/FAs)' for producing the ASM file.
Now I will argue a point in favor of a well placed goto statement. An experienced programmer may have intimate knowledge of compiler optimizations and determine that a goto statement will be beneficial. For example:
for(int x =0; x < iLimit;++x)
{
for(int y =0; y < iAnotherLimit;++y)
{
for(int i =0;i< ilastlimit;++i))
{
if(FALSE == DoWork(SomeArray[x][y][i]))
{
goto critical_error;
}
}
}
}
critical_error:
CleanUp();
In this example the compiler output will greatly benefit from the goto statement. There is no faster way to exit the nested loops. So here is my final statement regarding the issue.
Randors Conjecture:
The only time at which a C++ programmer should use a goto statement is to escape a deep nested loop.
Best Wishes,
-Randor (David Delaune)
|
|
|
|
|
Randor wrote: My reasoning is quite simple in that the compiler cannot perform optimizations with all of those unconditional jumps all over the place.
That's incorrect. Gotos are hard for humans, not for computers. In fact, the way nearly all compilers work is to transform the code into an intermediate representation where "if (a) { then; } else { otherwise; } becomes
if (a) goto 1 else goto 2
1: then;
goto 3
2: otherwise;
3: ...
And then the optimizer runs on that representation, so it can surely understand gotos. Optimizers can perfectly work with arbitrary control flow graphs, they're not limited to "structured" control flow.
Different source code may cause different machine code to be generated, but there's absolutely no reason that gotos would be less efficient.
For an explanation why goto is bad, read
go-to statement considered harmful[^]
|
|
|
|
|
Rajkumar R
thank you
|
|
|
|
|
Hello friends,
I am using Win32 apllication on Vc6.0 IDE.
I am using 20 buttons.
I want to find out tab order dynamically.
I want change focus to next control if we select next button.
abhi
|
|
|
|
|