|
Dear friends,
I am trying to convert 3 strings to BSTRs. But the method i am using is not working. It is giving me wrong results. Please tell me the reason why this is not wrking. Please see the code:
<br />
<br />
struct Student<br />
{<br />
BSTR firstName;<br />
<br />
BSTR lastName;<br />
<br />
BSTR fatherName;<br />
};<br />
<br />
<br />
int main(int argc, char* argv[])<br />
{<br />
std::string firstName = "Bob";<br />
<br />
std::string lastName = "Andrew";<br />
<br />
std::string fatherName = "Jones";<br />
<br />
Student s;<br />
<br />
s.firstName = _bstr_t(firstName.c_str());<br />
<br />
s.lastName = _bstr_t(lastName.c_str());<br />
<br />
s.fatherName = _bstr_t(fatherName.c_str());<br />
<br />
std::wcout << s.firstName << std::endl;<br />
<br />
std::wcout << s.lastName << std::endl;<br />
<br />
std::wcout << s.fatherName << std::endl;<br />
<br />
return 0;<br />
}<br />
The program is giving me following result:
Bob.
Jones.
Jones.
Please tell me the reason that why the second and third conversions created trouble. While debugging we can see the that the first two conversions were successful. But during third conversion, the previous one automatically changed to reflect the third.
I am using _bstr_t OR CComBSTR in order to avoid explicit call to SysFreeString()/SysAllocString() . Both _bstr_t and CComBSTR are behaving in the manner i described above.
|
|
|
|
|
What's actually happening is that the third BSTR is being created to point to the same memory as the first, and therefore the first now points to memory that has been assigned the value of the third. It makes no difference what order you do it in, the third _bstr_t returns a BSTR that points to the same memory as the first one did. If I add a fourth BSTR field, it happens again. It still happens if I avoid std::string and use constant fields. Basically, the only way I could avoid it was to turn the fields in the struct to be _bstr_t's.
I used to use _bstr_t a lot to convert strings, and I've never seen it do this before.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
It's happening because the temporary _bstr_t's get destroyed as soon as the assignment statement ends. The OP has raw BSTRs on the LHS of the assignment statement, so he essentially ends up with a dangling BSTR. When you have a _bstr_t or a CComBSTR on the LHS, the copy constructor (or the assignment operator) runs and makes a copy (using SysAllocString), so it runs fine.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Wow - that really sucks. As far as I can see, that's a bug in _bstr_t.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Not really. That's the only way _bstr_t can release memory held by it's internal member variable. If it didn't release it on destruction, then it becomes the responsibility of the user to call SysFreeString. Just
_bstr_t("Senthil");
will leak memory.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
The reason why this is happening is because you're not using _bstr_t correctly. When you say
s.firstName = _bstr_t(firstName.c_str());
what's happenings is, _bstr_t constructor gets called with firstname.c_str() as the argument. It does a SysAllocString and creates a BSTR internally (let's call it m_BSTR). Because you have the BSTR . on the LHS of the assignment statement, the conversion operator
operator BSTR()
{
return m_BSTR;
}
executes and you get a BSTR in s.firstName . What next happens is the reason why you're getting incorrect values. The destructor for _bstr_t runs (because it's lifetime ends after the assigment statement completes) and it does a SysFreeString on m_BSTR.
So what you have in s.firstName is essentially a dangling pointer, it's pointing to freed memory. You're just lucky that it didn't crash, it's reusing that freed memory and maybe that's why you're getting the same BSTR value.
The same case applies to CComBSTR also. The solution is simple, you just replace your plain BSTRs in the Student structure with a CComBSTR or _bstr_t . That way, the copy constructor (or the assignment operator) runs and does a SysAllocString for you, so you end up with a valid BSTR .
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
i want to know if anyone knows the algoritm of the argument of a bode diagram i have the "moludo"algoritm i dont know the word in english sorry anyone can help me thanks.
|
|
|
|
|
|
Hello all,
I'm currently encountering a frustrating nuance (bug?) when trying to use comboboxes in MFC applications in visual studio. Basically I do this:
- go through the project wizard, create a dialog application, using MFC in a static library
- create a combobox in the dialog view (I set sort to true) note: i use the style 'drop list'
- add combobox as a control variable to the dialog
- create a simple button which calls InsertString or AddString on the just-created combobox variable.
- Run app (debug or release, doesn't seem to matter)
- Combobox after having InsertString and/or AddString called looks empty like this:
http://img248.echo.cx/img248/530/brokencombobox2yj.jpg
Notice it appears empty even after calling AddString. However, interestingly if i call SetCurSel(0) after AddString the entry in index 0 appears, but none of the other added entries do.
So I'm quite interested and frustrated to find out what is going on here. I downloaded the demo project from:
http://codeproject.com/combobox/combobox_tut.asp, opened it in MSVS 2003 .NET, converted it, compiled, and lauched. Suprise, the droplist displays correctly.
See:
http://img248.echo.cx/img248/7476/workingdroplist4uh.jpg
However, if i modify the dialog of the combobox tutorial, create a new combobox, and a button that adds entries to it, it does not display correctly as previously shown.
Note that I do have MSVS 2002 and 2003 installed on my dev machine. However I'm not using an managed code so there is nothing being cross-referenced. I also have a laptop with only a copy of MSVS 2002 and all of this appears to be identical on there. Additionally on my brothers computer, which only has 2003 on it, it is the same.
Can anyone provide some insight as to what I'm missing, or what is going on here? I've tried everything from messing with project settings to manually editing resource files.
Please!
|
|
|
|
|
It looks from the first pic its a case of you not sizing the drop down list. Did you size it in the dialog editor?
Pssst. You see that little light on your monitor? That's actually a government installed spy camera. Smile and wave to big brother!
|
|
|
|
|
Not sure what you mean. I selected combobox from the form/dialog toolbar, and dragged a rectangle on the dialog in the dialog editor. Is that what you mean? Same way I create a button or any other control I would be using.
|
|
|
|
|
Select the combobox in the resource editor and resize the height of the dropdown part.
/ravi
My new year's resolution: 2048 x 1536
Home | Articles | Freeware | Music
ravib@ravib.com
|
|
|
|
|
Of the tens of thousands of MFC questions that I've seen since MFC was released in the early 90's, this has got to be the question I've seen posted most often.
You would think *someone* at MS would take note and make that interface a bit easier on such a trivial task
Cheers,
Tom Archer - Archer Consulting Group
"So look up ahead at times to come, despair is not for us. We have a world and more to see, while this remains behind." - James N. Rowe
|
|
|
|
|
|
Worse yet, a project including an XP manifest will automatically size the drop list for you, giving the false impression that you've already sized the drop list manually in the dialog editor...
You're reminded quickly of the problem when you give the program to someone using a Win98/2K machine, at which point they think you're playing some type of dirty psychological trick on them because they can't select anything from any of the combo boxes.
Pssst. You see that little light on your monitor? That's actually a government installed spy camera. Smile and wave to big brother!
|
|
|
|
|
Yes. This is part of what I was encountering. It just wasn't working on my work (win2k) machine. Grr!
|
|
|
|
|
Good lord I was hoping it was something as simple as that. Its weird though, it was working fine for a while.
Sheesh, thanks!
|
|
|
|
|
In what file is the display for a computer held?
|
|
|
|
|
What exact information are you looking for? As far as I know, the only way to retrieve various display information is via the Win32 API.
For example, DeviceCaps is used to determine screen resolution, number of supported colors and so on where as EnumDisplaySettings is used to enumerate all display modes. Therefore, it really depends on exactly what you need.
Cheers,
Tom Archer - Archer Consulting Group
"So look up ahead at times to come, despair is not for us. We have a world and more to see, while this remains behind." - James N. Rowe
|
|
|
|
|
how to crop an image in an application based on dialog? with thanks!(Cropping images)There is an image,which is 696*344, I want to put a box(200*150) on it, then i move the box to the right position with the mouse , at last,i can get a new image which is 200*150. Now I can't complete this , for help,With thanks.
thanks
|
|
|
|
|
The obvious thing to do is to create a new bitmap and use BitBlt to copy just the bit you need. The box part is easy, just draw the box at the mouse position, and keep track of the position in OnMouseMove.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
I have a dialog box where I want to do some initialization.
With visual studio 6.0, the wizard allowed me to choose OnInitDialog.
This would put in all the proper code so my class would get the base class OnInitDialog and inside the function there was a call to CDialog::OnInitDialog.
What is the “proper” way to do this in vs7.0?
Am I supposed to manually look at the parameter list of the base function, duplicate the parameters and also duplicate the return type?
Obviously the wizard was much more convenient, but if I have to manually do it in vs7.0, then at least I want to know this is my fate.
Thanks,
Ilan
|
|
|
|
|
1) Open the Properties pane for the dialog.
2) Click the Overrides button. (2 buttons right of the lightning bolt) OnInitDialog should be in the list
Pssst. You see that little light on your monitor? That's actually a government installed spy camera. Smile and wave to big brother!
|
|
|
|
|
Hi,
I'm working with Visual C++ 6.0 SP6 on Win98 and WinXP.
I have a problem with MFC CMonthCalCtrl. When I try get the current system tyme with GetCurSel this returns other date.
For example:
The CMonthCalCtrl is 2005 May 30 as current selected. But GetCurSel returns 2006 Jun 28. Why?
This problem is similar in both operative sistems.
some suggestion to solving this?
Ivan Cachicatari Blog[^]
www.latindevelopers.com
|
|
|
|
|
I´m trying to change the default behavior of the tree control regarding images (selected/nonselected) to state expanded/collapsed. I´ve created a CImageList and called CTreeCtrl.SetImageList with TVSIL_STATE instead of TVSIL_NORMAL. That was all I could find in VC++/MFC documentation, what else should I do ?
|
|
|
|