|
Hi there,
I've got a program where I read the registry to get the path of an application - on XP.
Once I get that path as it is a dos formatted path I called the GetLongPathName(A) function to convert it to its long name value and I got the following error from GetLastError function:
"prescribed file doesn't exist"
In fact the folder exist but apparently XP doesn't recognize it's DOS name as a valid Windows name (?).
I scanned the "App Paths" registry and noticed that most recent application did have their path with long name form instead of the old fashioned DOS one.
So I am really confused my code is working fine on W98 but not on XP. How could I bypass the GetLongPathName function is there any substitute to convert a valid DOS name to its long name counterpart ?
Thanks,
Yarp
http://www.senosoft.com/
|
|
|
|
|
I use GetFullPathName() for this. Give it a try. From memory it doesn't check the disk and therefore doesn't complain if the file doesn't exist.
You might also want to look at AfxFullPath(). If you still have a problem let me know.
Neville Franks, Author of ED for Windows. www.getsoft.com
|
|
|
|
|
Thank you for your reply.
I Couldn't get GetFullPathName work properly too.
In fact I have a dual boot PC (a W2K boot and a XP one) and the application path I'm looking for was installed under XP on c:\program files (c: is the W2K drive). XP itself is located on d:.
So I get the following DOS name from the registry c:\progr~2\Poser\ and I would like the function to return c:\program files\Poser\.
I tried to type c:\progr~2 under DOS and Windows failed to go to the proper folder, but if I type d:\progr~1 it works fine. So I think this is a Windows bug. XP is unable to translate the DOS name from the other drive - because it is the W2K one ? The mistery remains.
Well, few people have dual boots like mine. If it works on another machine I'll just give up.
btw Your website is awsome
Yarp
http://www.senosoft.com/
|
|
|
|
|
I want to use ConvertSidToStringSid function in my MFC application.It is part of default libraries in MFC.VC editor show it to me but when I compile the program it tells me that it is not member of operator or global namespace!!!
Any Idea?
Mazy
"If I go crazy then will you still
Call me Superman
If I’m alive and well, will you be
There holding my hand
I’ll keep you by my side with
My superhuman might
Kryptonite"Kryptonite-3 Doors Down
|
|
|
|
|
You've got to include <sddl.h> and link with Advapi32.lib .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I did that but does not help.I used other functions of this library without any problem,there is error only for this one.
Mazy
"If I go crazy then will you still
Call me Superman
If I’m alive and well, will you be
There holding my hand
I’ll keep you by my side with
My superhuman might
Kryptonite"Kryptonite-3 Doors Down
|
|
|
|
|
This is probably a stupid question but is there any way to refresh a dialog so that all of the data and stuff that is in the dialog is destroyed and then recreated? Any help appreciated.
Brad Jennings
|
|
|
|
|
You can with DDX/DDV. Take a look in your docs at UpdateData and related stuff.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Hi all,
When I use IDiskQuotaUser->SetQuotaLimit() and ->SetQuotaThreadshold()there are always pop up an error dialog: like this:
//////////////////////////
Dubug Error
Program:**
Modlue:
File:i386\chkesp.c
Line 42
The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
Why?????????????????????????????????????
And How to resove this problem?
I tried to use static dll to build the project but failed for LNK2005 error.
also can not resolve the problem.
Thanks for help.
|
|
|
|
|
chkesp errors usually have their origins in passing around malicious pointers and/or wrong parameter sizes and counts. In this case it could be the LONGLONG value that's used in those calls. Happened to me once.
|
|
|
|
|
In code that I have, theres a T2W. MSDN and the web are not helpful.
char* strFile = new char[strFile0.GetLength() +1];
strcpy(strFile, strFile0);
_bstr_t b_strFile = T2W(strFile);
What exactly does T2W do?
Thanks,
ns
|
|
|
|
|
T2W converts from TCHAR strings to Unicode strings. Next obvious question is, what are TCHAR s? Well, TCHAR is a macro resolving either to char or wchar_t (Unicode character), depending on whether your app is being build in ANSI or Unicode mode. If in Unicode mode, T2W converts from Unicode to Unicode, i.e, it does nothing, but this apparent futility have some sense if you consider that this way the same source code can compile fine in either mode.
In your particular case, your source string is ANSI (char * ), which has the following implications:- This will only work in ANSI mode (in Unimode,
T2W will accept only Unimode strings).
- Taking into account the former, you could have used
A2W (ANSI to Unicode) instead So, I'd label this as a small flaw in the code. You'de be better off using TCHAR * as the type of strFile if pursuing Unicode compatibility.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I dont know how relevant this is, but this all started because I had to pass a CString (coming from GetWindowText) or char* into a VB com dll which had a parameter of type String. T2W fixes that. Should I replace it with A2W. I'm asking because I dont know about setting the mode in VC. I didnt even know I had a choice! Where in the IDE do I set the mode? Also whats the purpose of these two different modes - is it like one runs on Unix and one on windows or something? From your post the default mode my app is being built in must be ANSI. So can you please let me know where the mode setting is (I looked in some obvious places), and why a mode is chosen. Does A2W mean it will work in both modes?
Thanks,
ns
|
|
|
|
|
Well, writing code that compiles in both modes is a tedious task (specially when you didn't planned for it before) and IMHO it is not worth the effort if you don't really need it (which seems your case). If you renounce to compile in Unicode mode, then A2W and T2W are the same, but at least with A2W you are making it splicit that the code is intended for ANSI mode only.
To build your app in Unicode mode, go the project settings and define preprocessor macros UNICODE and _UNICODE . Although you might be able to succesfully build your project please be aware that Windows 9x OSs are not Unicode compliant, so the app won't just run (in Windows NT/2k/XP it should).
The difference between ANSI and Unicode modes is that the OS APIs you call are different in either mode, accepting char * or wchar_t * strings (for APIs not dealing with text, as for instance GetMessage there's no difference). Unicode is intended for apps in exotic languages, having often more characters than a single char can accommodate.
Apart from this, I think you can simplify your code a little:
USES_CONVERSION;
LPCOLESTR lpcostr=A2COLE((LPCSTR)fileString);
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thanks for the explanation. I think I'll stay ANSI for now.
Thanks,
ns
|
|
|
|
|
Hi.
I want to recognize a double click (right mouse button) in a DateTimePicker control, but don't know how to or aware of scenarios that might cause a problem with this.
What I have is grid of edit-able controls (CEdit, CDateTimePicker, CComboBox) and for a Date Time Picker, I want a double-click to capture the current time.
This is to help data entry by the user.
Any help/suggestions?
Thanks.
Johnny Pino
|
|
|
|
|
Sorry, I meant LEFT MOUSE BUTTON (double click), but either left/right should work.
JP
|
|
|
|
|
I have a CDialog derived class I want to use in two places, which differe in functionality. If I set a flag from the spawning
view class (which does a DoModal()), is it allowed to set a flag that will make OnInitDialog behave differently?
BOOL abc = TRUE;
myDlg.SetFlag( abc)
myDlg.DoModal();
and in the CDialog class, :
::OnInitDialog()
{
if (m_flag)
{
dosomething;
}
else
{
dosomethingelse;
}
Is this allowed? I cant really write two different OnInitDialogs, right? So in order to reuse it I am thinking of my flag idea.
Suggestions?
Thanks,
ns
|
|
|
|
|
Yes, you've got it right. Personally, I would make an enumeration variable in the dialog class and use that as the flag. That way, you can switch() on the flag and support future enhancements when you want more than two different behaviors. Just as soon as you've written all the code for two modes you'll find that you now want to have three The additional effort involved is very little.
<code>
class CMyDlg : public CDialog
{
public:
typedef enum
{
Mode1,
Mode2,
Mode3
} MyDlgModes;
private:
MyDlgModes m_Mode;
public:
SetDlgMode( MyDlgModes Mode )
{
m_Mode = Mode;
}
};
BOOL CMyDlg::OnInitDialog()
{
switch( m_Mode )
{
case Mode1:
... do stuff
case Mode2:
... etc
}
}
MyFunc()
{
CMyDlg dlg;
dlg.SetDlgMode( CMyDlg::MyDlgModes::Mode1 );
dlg.DoModal();
}
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Once again, a million thanks for your patiently detailed resolution. It helps tremendously! I thought I'd have to define the enum globally (can this even be done? like an extern enum)so using the enum declared in CMyDlg is pretty tricky! Appreciate your responses very much indeed!
Thanks,
ns
|
|
|
|
|
Hey no problem at all. It's fun to help out people. You can define the enum globally, although it is cleaner and more "object oriented" to only put the enums in the classes that actually need and use them. That said, if you want to use those same enum values all over the place in other unrelated classes, that's when you'd want to think about defining it in the global scope and putting it in some header. So long as your enum variables aren't global, a global enum typedef won't displease the OO fanatics out there
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
I did:
case Mode1:
int index = 0;
KeyValueMap & keyValueMap = *m_kVMap;
KeyValueMap::iterator it = keyValueMap.begin();
for(; it != keyValueMap.end(); it++)
{
m_listAddRecord.InsertItem(index, (*it).first);
index++;
}
CString temp = m_listAddRecord.GetItemText(0,0);
m_editAddedKW.SetWindowText(temp);
m_editAddedVal.SetWindowText("");
m_editAddedVal.SetFocus();
m_DoneAdd.EnableWindow(TRUE);
case Mode2:
The compiler errors said I was skipping initialization of "temp" and "it" with the case statement. Do I need a return or something somewhere?
I'm doing it with if m_Mode == Mode1 but yours was so cool...
Any idea what its not happy about and how to fix it?
Thanks,
ns
|
|
|
|
|
Yeah... with a case statement it is possible to jump over code that would otherwise be executed. It's almost like a goto statement. For instance, when case is Mode1, you're going to execute all of the code up to where Mode2 starts. What happens if you don't put a break in there, like you've got in your sample? Well in C++, unlike VB, you keep executing right through to the next case statement. This is one of those classic "gotcha" bugs. This by itself is not an error, however, because it is perfectly legal to want to keep executing the code in the next case section.
Someone doing this "case fall through" scenario on purpose might be thinking they can keep using the variables they declared in the previous case block for Mode1. Which might be true if you always executed the code for case Mode1. But you're not guaranteed that, since you might come in directly at case Mode2. Mode2 skips all of those variable declarations and initializations. Your variables don't exist there, so they can't be used nor referenced in that scope. This is a paradox between otherwise legal code and its run-time handling. As such, you have to give another layer of scope to declare any variables inside a case section. Here's some sample code:
std::vector< int > OuterVector;
switch( i )
{
std::vector< int > SwitchVector;
case 1:
{
std::vector< int > InnerVector;
std::vector< int >::iterator itInnerVector;
}
case 2:
{
}
break;
}
As you can see, I've added some block braces {} around the code for both case 1 and 2. This defines a new scope for those variables declared inside the block. They can only be used within that scope since they will be destroyed as soon as execution leaves that scope. If you tried to reference those variables in case 2, you'd get a compiler error because they don't exist.
If indeed you wanted to use the same variables in both case Mode1 and Mode2 when you fell through on purpose, you'd have to declare those variables either before the switch statement, as I've done above with OuterVector, or immediately after the switch but before any case statements are specified, as you see with SwitchVector. The former is a little clearer for other people to understand, but there might be scope issues that require the switch-level scope of the latter.
So, the long story short: wrap your case sections with curly braces. This should help to understand why it is considered an error, however. I've become so accustomed to adding braces to case blocks that I don't even think twice about it when they come out of my fingertips automatically. Here's your sample code tweaked a little bit:
case Mode1:
{
int index = 0;
KeyValueMap & keyValueMap = *m_kVMap;
KeyValueMap::iterator it = keyValueMap.begin();
for(; it != keyValueMap.end(); it++)
{
m_listAddRecord.InsertItem(index, (*it).first);
index++;
}
CString temp = m_listAddRecord.GetItemText(0,0);
m_editAddedKW.SetWindowText(temp);
m_editAddedVal.SetWindowText("");
m_editAddedVal.SetFocus();
m_DoneAdd.EnableWindow(TRUE);
}
break;
case Mode2:
I'm guessing from your previous posts that you don't really want to fall through from case Mode1 to Mode2. So remember to add that break statement before the case Mode2 code starts. That's one key difference between the VB syntax and VC
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
What a truly excellent explanation. Thank you so much. Indeed I need the 'break'. Have a good weekend!
Thanks,
ns
|
|
|
|
|
You bet, have a good weekend too!
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|