|
open the dialog in the resource editor. Select the control. hold the contrl key down and double click. A wizard will appear asking for the name of the variable you want to associate with the control.
|
|
|
|
|
Full of glee I used an edit control to test it out. It didn't work.
I totally believe you; however, all I get is a messagebox saying "There are no data types for this kind of control." MB_OK.
I'm using a dialog interface, if that helps. It's also doing the same thing on my laptop and desktop PC. Does the installation of VC++ 6.0 and EVC++ 3.0 installed on the same machine hinder 3.0 for some reason? I would think not but one never truely knows.
Carl
|
|
|
|
|
Hmmmm. Maybe that's not it...
I tried it on my machine to verify. Hold control key. Double click control in dialog editor. Up comes small dialog asking for member variable name and type.
I don't know about EVC++ 3.0. What is it? Did the dialog editor build a class for the dialog? Can you see it in the Class Wizard?
Maybe the .clw file is hosed. You can try deleting it. Then run the Class Wizare. It will prompt and then rebuild it for you.
Good luck.
|
|
|
|
|
CTRL - click^2 works in VC++ 6.0.
I'm using Embedded Visual C++ 3.0 for WinCE.
I'll try deleting the .clw file and see what happens. ALthough I doubt that will fix it - this behaviour happens on all the PCs I try this with.
Added:
Oh, and thanks for your help.
|
|
|
|
|
Yeh, I expect that won't help either, just a desperate attempt to sound smart on my part. I did find this on Win CE development, however.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/apcguide/htm/appwzrd_5.asp
It may help. I notice they do NOT refer to the class wizard.
|
|
|
|
|
The CComVariant class in ATL has the following functions
CComVariant(LPCSTR lpszSrc)
{
vt = VT_EMPTY;
*this = lpszSrc;
}
CComVariant& operator=(LPCSTR lpszSrc)
{
USES_CONVERSION;
InternalClear();
vt = VT_BSTR;
bstrVal = ::SysAllocString(A2COLE(lpszSrc));
if (bstrVal == NULL && lpszSrc != NULL)
{
vt = VT_ERROR;
scode = E_OUTOFMEMORY;
}
return *this;
}
Which means the only way to get it to allocate memory for a new object is to use the assignment operator. The following code produces different results
char buf[256] = "test";
CComVariant result = buf;
char buf[256] = "test";
CComVariant result;
result = buf;
discuss!
Todd Smith
|
|
|
|
|
Yeah, that sounds pretty messed up.
---
Shog9
If I could sleep forever, I could forget about everything...
|
|
|
|
|
Those 2 code snips are equivilent. You can also use
CComVariant result("test");
for the same result.
Tsyntax
CComVariant result = buf;
compiles to the same object as
CComVariant result;
result = buf;
|
|
|
|
|
That's what I thought until my app was crashing and I stepped through the code and discovered otherwise.
this calls the constructor CComVariant(LPCSTR lpcStr)
CComVariant result = buf;
and this calls the assignment operator CComVariant& operator=(LPCSTR lpcStr)
CComVariant result;
result = buf;
I don't know what the C++ standard says about that.
Todd Smith
|
|
|
|
|
No. they all do the same thing. I stepped into them also and thought I saw what you said.
CComVariant result = buf;
executes
#ifndef OLE2ANSI
CComVariant(LPCSTR lpszSrc)
{
vt = VT_EMPTY;
*this = lpszSrc;
}
#endif
CComVariant result2(buf);
executes the same
CComVariant result3;
executes
CComVariant()
{
vt = VT_EMPTY;
}
result3 = buf;
executes
#ifndef OLE2ANSI
CComVariant& operator=(LPCSTR lpszSrc)
{
USES_CONVERSION;
InternalClear();
vt = VT_BSTR;
bstrVal = ::SysAllocString(A2COLE(lpszSrc));
if (bstrVal == NULL && lpszSrc != NULL)
{
vt = VT_ERROR;
scode = E_OUTOFMEMORY;
}
return *this;
}
#endif
Then I looked closer and stepped deeper and found they all ended up executing the = operator code! It does allocate memory.
This line of code from the constructor
*this = lpszSrc;
executes the = operator code shown above. So all come out the same.
The only caveat I see is that you may not have OLE2ANSI defined.
Make sense?
|
|
|
|
|
Ah that's true. The bug ended up being something else anyways
Todd Smith
|
|
|
|
|
No, it does not. These two are exactly equivalent:
CComVariant v ("foo");
CCOmVariant v = "foo"; The second line does not construct an object then call operator= .
--Mike--
Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
Guess again. If you trace through the code you will see it do it.
|
|
|
|
|
Please learn how the language works before making such bold and incorrect statments.
#include <iostream>
using std::cout;
using std::endl;
class C
{
public:
C(int x) : m_n(x) { cout << "in constructor" << endl; }
protected:
C(const C& rhs) : m_n(rhs.m_n) { cout << "in copy constructor" << endl; }
const C& operator = (int x)
{ cout << "in operator =" << endl;
m_n=x; return *this; }
int m_n;
};
int main()
{
C c1 (1);
C c2 = 2;
return 0;
} I even threw in a copy constructor in case you wanted to be a smartass about that. That wouldn't even compile if the c2 declaration were calling the assignment operator. Yet, somehow it does. Look, here's the output:
in constructor
in constructor Good night.
--Mike--
Just released - RightClick-Encrypt v1.3 - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
I'm not quite sure what your point is. It doesn't seem to have anything to do with my post. Did you post this in the wrong thread, or are you simply confused?
This thread was discussing the behaviour of a specific class and its constructors. If you look at the COleVariant class you will see a critical difference between its constructors and the one in your post.
"Please learn how the language works before making such bold and incorrect statments."
For someone who's posts seem to contradict even themselves, THAT is a bold statement. You seem to be both agreeing and disagreeing in the same post, while criticising the whole time. I suggest you re-read the thread more carefully; and learn to look before you leap.
"in case you wanted to be a smartass about that"
Calling me names just reinforces my opinion of your post and may even effect my opinion of you!
|
|
|
|
|
These two lines are not equivalent. Second line is considered equivalent to:
CComVariant v(CComVariant("foo"));
Thus it require that a copy constructor exists is accessible. The compiler was allowed to optimize away useless copy (I'm not sure if this is still allowed by the standard and under which condition --- I think that condition are now more strict).
Thus the first version will always call one constructor (which will in this case call assignment operator after initializing vt to VT_EMPTY to ensure that assignment won't try to destroy an unintialized VARIANT).
The second one may depend on the compiler, optimisations and possible minor changes in the standard. Thus it is preferable to uses the first one if it does mather.
Philippe Mori
|
|
|
|
|
There seems to be some confusion in this thread. I've seen several erroneous explanations based on theories about C++ language definition and VC++ compiler behavior. A simple look at the code shows what is going on.
There is no requirement for a copy constructor. It is needed for CComVariant because of this line in the constructor:
*this = lpszSrc;
That is the ONLY reason. If the coder had duplicated the logic of the = operator in the constructor, this line would not be present and the = operator would not be needed (for this constructor). This has nothing to do with compler optimization.
CComVariant v(CComVariant("foo")); // Uses a temporary object
is equivilent to
CComVariant vTemp("foo");
CComVariant v(vTemp);
not
CComVariant v = "foo";
|
|
|
|
|
My point is that the two lines are not strictly equivalent. Since most compilers does optimize the copy away, it makes no differences in practice but if you want to guarantee it, prefer the first version.
CComVariant probably define a copy constructor so one does exists and is public... Although it is not used, it is required that the copy-constructor is public. Please try sample code below or read the standard if you do not believe it!
I do not have VC installed on my computer but this simple code will show the point. I've test it with an old version of C++ Builder.
#include <iostream>
class A {
public:
A() { cout << "1"; }
A(const char *) { cout << "2"; }
A& operator=(const char *){ cout << "3"; }
A& operator=(const A &){ cout << "4"; }
private:
A(const A &) { cout << "5"; }
};
int main() {
A a = "allo";
}
If the copy constructor is private as this is the case here, the compiler will says that the copy constructor is not accessible (it has to be according to the standard).
C++ Builder 1.0 does not compile the code above but if the copy constructor is made public (or removed since if not defined the default copy constructor is public), the code will compile and display "2".
Thus the standard guarantees that CComVariant c("foo") will call only one constructor and makes no temporaries object but this is not the case for the second version...
So in practice CComVariant v = "foo"; is compiled as CComVariant v("foo"); but that optimisation is not required by the standard and the code must compile without the optimisation (i.e. CComVariant(CComVariant("foo")); must compile although that first construct will compile even if copy constructor is private).
I remember that I have read about it some time ago but I haven't found where. But I have found in Efficient C++ from Dov Bulka and David Mayhew (1999) that the suggest to uses the first version since it is always optimized (i.e. not compiler dependant).
Philippe Mori
|
|
|
|
|
|
Exact, so in pratice, both variations will generate similar code since VC does optimize away the useless temporary object (see my other replies above).
Prefered syntax for construction would be CComObject v("foo"); since it should typically be the most efficient one for many (similar) classes and that with any compilers.
Philippe Mori
|
|
|
|
|
Some of you helped me this morning with my vector question, I have run into another problem (surprised? ). Anyone have any ideas for this one?
#include <iostream.h>
#include <stack>
using namespace std;
void main()
{
cout << "Fun with stacks begins" << endl << endl;
stack<string> strStack;
strStack.push("Nick");
strStack.push("Megan");
while(!strStack.empty())
{
cout << strStack.top() << endl;
strStack.pop();
}
cout << "Fun with stacks is over." << endl;
}
Nick Parker
|
|
|
|
|
what's the problem?
-c
Conservative:
One who admires radicals centuries after they're dead.
-- Leo C. Rosten
|
|
|
|
|
Sorry, this is what the compiler spits back out at me.
<br />
--------------------Configuration: fun - Win32 Debug--------------------<br />
Compiling...<br />
fun.cpp<br />
C:\Documents and Settings\np0383\My Documents\C++\fun.cpp(66) : error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or the<br />
re is no acceptable conversion)<br />
Error executing cl.exe.<br />
<br />
fun.exe - 1 error(s), 0 warning(s)<br />
Which points to this line in the code:
cout << strStack.top() << endl;
Nick Parker
|
|
|
|
|
try
#include <iostream>
instead of
#include <iostream.h>
Conservative:
Make it possible for programmers to write programs in English and you will find that most programmers can't write English
|
|
|
|
|
That didn't work, I just tried it, what is the difference anyway?
Nick Parker
|
|
|
|