|
I think I found a bug in the MFC 7.1.
There is an error during assignment of a LPWSTR to a CString in an MBCS or ANSI application.
If you have something like this
LPWSTR pWStr; // contains an WideString
CString str;
str = pWStr; // <- here is the bug
In the third line the following member of CString is called:
CStringT& operator=( PCYSTR pszSrc ) [cstringt.h, line 988]
which calls GetBaseTypeLength [cstringt.h, line 429]
This member returns the size of the pWStr (via WideCharToMultiByte) - 1. That means that the terminating NULL-character is not counted.
So the reserved memory is too small to contain the whole pWStr including terminating NULL!
In the following call of StringTraits::ConvertToBaseType( pszBuffer, nDestLength, pszSrc ) in line 995 the destLengh doesn't include the NULL character. But ConvertToBaseType implicitly calls WideCharToMultiByte with the following parameters:
::WideCharToMultiByte( _AtlGetConversionACP(), 0, pszSrc, -1, pszDest, nDestLength, NULL, NULL );
This function returns the error code 0, because the reserved memory in pszDest is one byte to small.
To my mind this is an error in the MFCs. I only checked this in MFC 7.1. Please tell me, if you can reproduce the problem perhaps in other MFC version, too.
Thanks in advance
Konrad
|
|
|
|
|
This isn't really a bug, just the developers leveraging how the API works.
The string will come out correctly since WideCharToMultiByte will convert characters until the destination buffer fills up.
This behavior is actually desired since the length passed for the source string may be shorter than the string. The developers could have resolved nSrcLength before making the call, but chose not to since the failure is quite irrelevant.
The terminating null is taken care off by the GetBuffer() call, which reserves space for a terminating null.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
The same code was VC6.. It causes read out of bound warning in BoundChecker & Purify, but also pretty harmless.
Also note, if you change (via WideCharToMultiByte) - 1 to (via WideCharToMultiByte) you will break ATL CComBSTR, and may be some others.
|
|
|
|
|
I want to change a program id for a com project, so it will be different with the previous version.
Just change the .rgs file? or I need to change the uuid in idl files?
thanks
woody
|
|
|
|
|
What is a program ID? UUID corresponds to COM object.
Kuphryn
|
|
|
|
|
You have to change both the IDL and the .rgs script.
Safest is to do a global search voer all project files (but you can skip the MIDL generated ones)
oh... and oyu might want to unreigster the control before changing the ID - otherwise, if you do that often, your registry accumulates quitesome trash
"Vierteile den, der sie Hure schimpft mit einem türkischen Säbel."
mlog || Agile Programming | doxygen
|
|
|
|
|
How to send data(raw file,byte strem) to ethernet port. I know the mac address of the ethernet card.
Hemant.
|
|
|
|
|
Is send() what you are looking for? I don't do this type of development so I may be way off.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
you mean you have the MAC address of destination
machine? or you have multiple ethernet cards
on your machine and want to use the one that
maches that MAC address?
if your answer is the destination machine:
you have to use WinPcap(http://winpcap.polito.it/)
also take a look at here:
http://www.csee.usf.edu/~christen/tools/rawstuff.zip
but be carefull. you are going too low-level...
|
|
|
|
|
Hello,
How can I call a function each five minutes?
explanation:
WinMain{
...
Each5Minutes(MyFunction(...));
}
thanks in advance
christian
|
|
|
|
|
Create a one-minute timer with SetTimer() . Each time the timer procedure, or the WM_TIMER message handler, is called, increment a counter. Once that counter reaches five, you know that at least five minutes has elapsed. Be sure to reset the counter to zero!
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Create a one-minute timer with SetTimer()...
And why not just create 5-minute timer?
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
Last time I checked, the maximum value that could be passed to SetTimer() was 65536, which is about 65 seconds.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
DavidCrow wrote:
the maximum value that could be passed to SetTimer() was 65536
Correct me if I'm wrong:
UINT_PTR SetTimer(
...
UINT uElapse, // time-out value (milliseconds)
...
);
UINT is an unsigned 32 bit value (in Microsoft VC++ 6 at least). So it's max value is 2^32 - 1 = 4,294,967,295. These represent milliseconds. Which means over 4 million seconds, which means over 700,000 minutes, which means over 11,000 hours, which means over an year...
So 5 minutes is ok, I guess...
|
|
|
|
|
Anonymous wrote:
So it's max value is 2^32 - 1 = 4,294,967,295. These represent milliseconds. Which means over 4 million seconds, which means over 700,000 minutes, which means over 11,000 hours, which means over an year...
Close. It is actually over 4 billion seconds, which is roughly 49.7 years. Last I remember, anything over 65,536 would not work. I just tried it with 90,000 and it worked as expected. Go figure!
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
|
Another solution is a timer queue timer.
Kuphryn
|
|
|
|
|
Another solution is a timer queue timer.
Could you please explain what you mean here. Thnx
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
Check out CreateTimerQueue() and CreateTimerQueueTimer() . The timers are lightweight objects that enable you to specify a callback function to be called when the specified due time arrives.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
That's helpfull: supported only on 2000 and up...
Thnx
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
You can also use GetTickCount()
DWORD dwBeginOf5Secs = GetTickCount();
while (TRUE)
{
if (GetTickCount() - dwBeginOf5Secs > 5000)
{
dwBeginOf5Secs = GetTickCount();
}
else
Sleep(100);
}
Peter Molnar
|
|
|
|
|
I am reading in CString values from a file and atoi-ing them. Docs say it returns 0 if the string cant be converted to a number (though the example there says atoi("5 cars") returns 5 -- I thought it would return 0 ???) Confused about this.
The other thing is that I might have a CString "0". If atoi returns 0 in this case, then its not signalling an error. So would I treat the case of strings like "0" separately?
Thanks,
ns
|
|
|
|
|
atoi() would return 0 for "cars 5" since it found no numbers before it found a non-number. In other words, it converts all numbers up to the first non-number encountered.
Differentiating between the return values of atoi("0") and atoi("T") sounds like a design issue. What is the format of the incoming data?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
The data has been writeString--ed to a file with a %d format.
So I read it back in later and want to make sure someone didnt inadvertently change what should be a numerical entry in the input file, into a alphabetical entry.....so I was going to use atoi to check the readstring-ed CString......
Thanks,
ns
|
|
|
|
|
So your file should look like:
123
456
004
991
...
and you want to ensure that someone hasn't changed it to:
07b
1c8
004
3df
...
Is that an accurate assesment? If so, you'll need to employ ReadString() to read each line from the file and parse the data yourself, something like:
CString strLine;
while (...)
{
file.ReadString(strLine);
if (! IsAllNumbers(strLine))
AfxMessageBox(...);
}
bool IsAllNumbers( LPCSTR lpszData )
{
while ('\0' != *lpszData)
{
if (isdigit(*lpszData))
lpszData++;
else
return false;
}
return true;
}
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|