|
I never tested this problem previous I think I must tell you thanks for your help.
|
|
|
|
|
It is ok, Hamid!
We are helping each other.
regards,
George
|
|
|
|
|
By the way I have a different question did you study in psychology?
|
|
|
|
|
Hi,
I'm seeing a strange problem; I learned to program in C and compiled with gcc, and back when I used to use character arrays all the time, I always needed to free memory. For instance:
char *a = new char(100);
Before the function was out, I would need to free it:
free(a);
Now I'm working on an MFC app (using VC++ .NET 2005) and it seems to crash when I try to free the memory (in this same situation; where I've created a character array, used it, then need to delete it a few lines later). Is allocation handled differently with the newer C++ compilers?
Thanks!
KR
|
|
|
|
|
One point I can say is when using new , you use delete . And when using malloc , use free . What was the message when the application crashed?
|
|
|
|
|
It does the same thing whether I use delete or free, and there's no message, it just crashes somewhere in free.c. If I set the char array to a static size then I see no issues, it's only when I allocate memory for it. Then, regardless of whether I delete or don't delete, my program starts showing very odd behavior.
Here's the actual code:
#ifdef _UNICODE
CString strText = (This piece of code returns a CStringA from the back-end of my program)
if (strText.GetLength() <= 0)
return false;
char *convertThis = new char(strText.GetLength());
sprintf(convertThis, "%s", strText);
int nLen = lstrlenA(convertThis);
BSTR unicodeStr = SysAllocStringLen(NULL, nLen);
MultiByteToWideChar(CP_ACP, 0, convertThis, nLen, unicodeStr, nLen);
m_EditControl.SetWindowText(unicodeStr);
SysFreeString(unicodeStr);
delete convertThis;
#else
Everything works fine if I set convertThis to a static size. If I allocate, everything goes haywire whether I free memory or not, but especially quickly if I free memory.
KR
|
|
|
|
|
I see a few problems here...
#ifdef _UNICODE
CString strText = (This piece of code returns a CStringA from the back-end of my program) <font color="Red"><-- assigning a CStringA to a CString shouldn't compile - mismatched types</font>
if (strText.GetLength() <= 0)
return false;
char *convertThis = new char(strText.GetLength()); <font color="Red"><-- what about +1 for the null terminator?</font>
sprintf(convertThis, "%s", strText); <font color="Red"><-- _UNICODE is defined, so strText is a wchar_t type string - this copy to char is invalid</font>
int nLen = lstrlenA(convertThis);
BSTR unicodeStr = SysAllocStringLen(NULL, nLen); <font color="Red"><-- why BSTR? A wchar_t array is the appropriate type for unicode - MultiByteToWideChar() takes a LPWSTR, not a BSTR</font>
MultiByteToWideChar(CP_ACP, 0, convertThis, nLen, unicodeStr, nLen); <font color="Red"><-- The original CString was already Unicode...this conversion is unnecessary</font>
m_EditControl.SetWindowText(unicodeStr);
SysFreeString(unicodeStr);
delete convertThis;
#else If you just need to convert a CStringA to a CString, you can just do this:
<font color="Green">
CStringA strText = (This piece of code returns a CStringA from the back-end of my program)
CString strTextGeneric(strText);
m_EditControl.SetWindowText(strTextGeneric);
<font color="Green"> Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Unfortunately it's not that simple, the string type is a CStringW yes but the characters are actually in CStringA format so the conversion is necessary. The compiler doesn't realize that it's a CStringA because the project settings for my front-end project define _UNICODE but my backend (a series of separate projects and libraries) is all in MBCS, which is where the function comes from (i.e. lots of text without the _T macro). I can't change that - the backend is going to return a multi-byte CString no matter what I do, but the program and compiler think it's of type CStringW because of my front-end project settings.
sprintf works correctly because of the above reason (even though CString type is a wide character array, the data inside is actually MBCS format).
I need the BSTR because MultiByteToWideChar will not compile if I define the type as wchar_t, and SetWindowText would require a conversion if I defined the type as LPWSTR. If I use BSTR I can do what I did and it works, if I don't use a BSTR additional steps are required.
I have tried:
CStringA strText = (CStringA)function();
CString strTextGeneric(strText);
m_EditControl.SetWindowText(strTextGeneric);
But that does not work, it just returns some garbled crud, probably because it thinks that the piece of code that returns CStringA is actually a CStringW.
But you're right about the +1 for null terminator, I did forget about that. However it doesn't help if I add that, it still crashes unless I define convertThis as a char array with a static length.
KR
|
|
|
|
|
KellyR wrote: I need the BSTR because MultiByteToWideChar will not compile if I define the type as wchar_t, and SetWindowText would require a conversion if I defined the type as LPWSTR
That doesn't make sense. A BSTR is a WCHAR*, which is a wchar_t*
Using a generic string type, implemented as a template no less, on a back end that could be used
by a front end with a different type....bummer. I don't know what to say about that
Regardless, I suppose using the square brackets and leaving room for null terminators should
help a lot.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: Using a generic string type, implemented as a template no less, on a back end that could be used
by a front end with a different type....bummer. I don't know what to say about that
It's horrible.
Mark Salsbery wrote: Regardless, I suppose using the square brackets and leaving room for null terminators should
help a lot.
Everything seems to work now with square brackets and with the +1 for null terminator. Thanks!
KR
|
|
|
|
|
KellyR wrote: It's horrible.
Heh - it's painful to think about
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
KellyR wrote: Now I'm working on an MFC app (using VC++ .NET 2005) and it seems to crash when I try to free the memory
Could it be that you changed a to point to a different address? For example:
char *a = new char[100];
a = a + 1;
a = "Hello";
delete [] a; Or that free() does not go with new ?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Use square brackets when allocating arrays with new , not round ones: it looks like you allocating a single char initialised to ASCII 100, then treating it as an array. This is a buffer overrun and you're probably corrupting the stack.
If you use new match it with a delete . If you use new ??[] match it with a delete [] . If you use malloc match it with a free . Don't mix and match.
Steve
|
|
|
|
|
|
There's also the problem that
char *a = new char(100); does not allocate an array. It allocates one char and initializes it to 100. You want
char *a = new char[100];
|
|
|
|
|
I am using Ultimate TCP/IP to ping an address. worked great until I put it into a seperate thread. I believe I have the pointers right to execute the class, but when the parent class gets the call from the return it is always OnTimout.
I must be doing something stupid here....
void CBinDlg::StartPinger(void)
{
CWinThread* pWThread = AfxBeginThread(PingAddress, this);
}
UINT PingAddress(LPVOID pParam)
{
CBinDlg* pDlg = (CBinDlg*)pParam;
pDlg->icmp.SetDoLookup(false);
pDlg->icmp.SetMaxTimeOuts(1);
pDlg->icmp.Ping( "10.0.2.60" , 1500, 32, 2);
return 0;
}
|
|
|
|
|
I don't know anything about Ultimate TCP/IP but you've passed a pointer to a dialog (based on the class name) to a worker thread. Worker threads don't have message pumps so your pDlg is not going to do anything.
Judy
|
|
|
|
|
Well phooey! back to the drawing board.
Thank you
|
|
|
|
|
Rhymhoont wrote: pDlg->icmp.SetDoLookup(false);
pDlg->icmp.SetMaxTimeOuts(1);
pDlg->icmp.Ping( "10.0.2.60" , 1500, 32, 2);
You need to put these three statements back in the primary thread (since they interact with the UI) and change PingAddress() to:
UINT PingAddress( LPVOID pParam )
{
CBinDlg *pDlg = (CBinDlg *) pParam;
return pDlg->PingAddress();
}
UINT CBinDlg::PingAddress( void )
{
PostMessage(some_user_defined_message);
return 0;
}
LRESULT CBinDlg::OnPostedMessage( WPARAM, LPARAM )
{
icmp.SetDoLookup(false);
icmp.SetMaxTimeOuts(1);
icmp.Ping("10.0.2.60" , 1500, 32, 2);
return 0;
}
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Simpler still is to call the PostMessage from inside the thread function
UINT PingAddress( LPVOID pParam )
{
CBinDlg *pDlg = (CBinDlg *) pParam;
pDlg->PostMessage(some_user_defined_message);
}
void CBinDlg::OnPostedMessage( WPARAM, LPARAM )
{
icmp.SetDoLookup(false);
icmp.SetMaxTimeOuts(1);
icmp.Ping("10.0.2.60" , 1500, 32, 2);
|
|
|
|
|
There appears to be two possible sorts of behaviour for selecting an item in a drop down combobox list:
1: Click once to get the list to drop down, then click on the selection.
2: Click and hold to get the list to drop down, move to selection, release to select it.
The default behaviour of comboboxes in MFC programs appears to be type 1. Is there any way to make them into type 2?
|
|
|
|
|
Wxffles wrote: There appears to be two possible sorts of behaviour for selecting an item in a drop down combobox list:
2: Click and hold to get the list to drop down, move to selection, release to select it.
How are you verifying this second method? I just opened one of my MFC apps, and the combobox does both (with no special coding on my part).
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Upon further investigation I've found that it works just as you say (and just as I want) when you use the old style common controls (version 4.7?). But when you use the new XP style (version 6.0), the behaviour changes. (And the extended user interface doesn't help). So I guess my question becomes, how do make them look new and work like they did in previous versions?
|
|
|
|
|
Wxffles wrote: There appears to be two possible sorts of behaviour for selecting an item in a drop down combobox list:
Nope, but that's a good guess. Continue guessing if you prefer, or the alternative I like to use to eliminate as much guessing as possible is to refer to the documentation[^]
The Extended User InterfaceDrop-down combo boxes and drop-down list boxes support an alternative keyboard interface called the extended user interface. By default, the F4 key opens or closes the list, and the DOWN ARROW changes the current selection. In a combo box with the extended user interface, however, the F4 key is disabled and pressing the DOWN ARROW key opens the drop-down list. In addition, the mouse wheel, which normally scrolls through the items in the list, does not have any function when the extended UI is set. To select the user interface for a combo box, an application can send the CB_SETEXTENDEDUI message to the combo box. A TRUE value for the wParam parameter enables the extended user interface; a FALSE value sets the default user interface. To determine whether a combo box uses the extended user interface, an application can send the CB_GETEXTENDEDUI message to the combo box.
|
|
|
|
|
I have a MFC application where I used to have menu items enabled /disabled whenever I want to. Later I added another menu item and tried to do the same with it. It works fine when I run the application from debug folder and it doesn't update that menu item running in release mode. This happens only to this new item that I added while the rest work fine as they do before.
Any suggestions are appreciated...
thanks,
PKNT
|
|
|
|
|