|
thanx this is done.
Bankey Khandelwal
Software Engineer
|
|
|
|
|
Hi,
How Do I implement late binding on a COM Addin which I created using ATL?
Thanks..
---
With best regards,
A Manchester United Fan
The Genius of a true fool is that he can mess up a foolproof plan!
|
|
|
|
|
Implement the IDispatch interface. Here's the IDL file for an AddIn I implemented for VC6
import "oaidl.idl";
import "ocidl.idl";
[
uuid(0c8dd9f0-2391-447a-b6dd-72aea4db9dc4),
version(1.0),
helpstring("Visual C++ Build Environment Loader Add-In 1.0 Type Library")
]
library DSWENVLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
importlib("devshl.dll");
importlib("ide\devdbg.pkg");
[
uuid(01b836c6-51c8-4476-bf15-ae91b0fe74f6),
oleautomation,
dual
]
interface ICommands : IDispatch
{
[id(1), helpstring("method RereadEnvironment")]
HRESULT RereadEnvironment();
};
[ hidden, uuid(0309A24D-B3E7-4C6A-8ACD-B3F0F8FAA483) ]
coclass ApplicationEvents
{
[default] dispinterface IDispApplicationEvents;
}
[
uuid(6c5658bc-946b-4bc7-94bf-5530cad3d654)
]
coclass Commands
{
[default] interface ICommands;
};
[
uuid(3d3eb2a1-8ce9-4555-89cd-d989a6b3009e)
]
coclass DswEnv
{
[default] interface IUnknown;
}
};
If you pick the correct options when creating the class, all the hard work gets done for you
|
|
|
|
|
Thanks a lot for your answer.
But if my Idl is smething like this then...
import "oaidl.idl";<br />
import "ocidl.idl";<br />
[<br />
object,<br />
uuid(23BB6C3D-AF30-4622-AE80-F19B29A964A7),<br />
dual,<br />
helpstring("IOutlookAddin Interface"),<br />
pointer_default(unique)<br />
]<br />
interface IOutlookAddin : IDispatch<br />
{<br />
<br />
};<br />
[<br />
uuid(B6AE2F8A-DA59-4371-8664-D4DEFCBE60C9),<br />
version(1.0),<br />
helpstring("EOutlookAddin 1.0 Type Library")<br />
]<br />
library EOUTLOOKADDINLib<br />
{<br />
importlib("stdole32.tlb");<br />
importlib("stdole2.tlb");<br />
<br />
[<br />
uuid(6228A6E9-3C8C-4E6C-8869-77631F65164A),<br />
helpstring("OutlookAddin Class")<br />
]<br />
coclass OutlookAddin<br />
{<br />
[default] interface IOutlookAddin;<br />
};<br />
};
Plus I also have
#import "C:\Program Files\Microsoft Office\Office\mso9.dll" rename_namespace("Office") named_guids <br />
using namespace Office;<br />
#import "C:\Program Files\Microsoft Office\Office\MSOUTL9.olb" rename_namespace("Outlook"), raw_interfaces_only, named_guids <br />
using namespace Outlook;
in my StdAfx.h file. I think the moment we use #import the dlls get early binded, isn't it?
I am creating an Outlook addin. So can you show me the way to create a late binded Outlook addin using ATL.
Thanks once again...
---
With best regards,
A Manchester United Fan
The Genius of a true fool is that he can mess up a foolproof plan!
|
|
|
|
|
Ah - you mean you want to late-bind to Outlook?
In that case, you're correct - the #imports early-bind. You need to access the relevant object through it's IDispatch interface. Not very much fun...You might find using a wrapper around an IDispatch pointer (like this[^]) makes things easier.
|
|
|
|
|
Why do you want to bind late? I tought the office components were dual, and can thus be called through the vtable.
|
|
|
|
|
Well, technically, it is said that to support multiple versions of any office application, late or dynamic binding must be used.
Can anyone help?
---
With best regards,
A Manchester United Fan
The Genius of a true fool is that he can mess up a foolproof plan!
|
|
|
|
|
Can you be more specific? I would just QueryInterface for the interface I need; If it succeeds the component supports it and I can call its methods; If it fails I can't so I try another approach. I can't see the need to "late bind" at the function level using IDispatch when you can negotiate at the interface level using QueryInterface (as is its function).
Steve
|
|
|
|
|
That's what I was thinking.
|
|
|
|
|
using VC++ 2005 Pro, I created an ATL/COM dll, added a simple object, then created a dialog control with a combo box and some other controls. Now I want to populate that combo box with some strings -- how do I do that? I use MFC a lot, so I know in MFC how to use ClassWizard to create a class name to the control, then call its AddString() method. But I don't see anything equilivant -- in VC++ 2005 I hold Ctrl key down and double click the control -- it brings up a window where I can assign class name, but only an integer. So I tried to call GetDlgItem(), but the compiler will not let me typecast its return value to CCombBox* as I can do in MFC.
Do I have to resort to sending normal win32 api messages to populate the combo box list?
Thanks
|
|
|
|
|
Stober wrote: Do I have to resort to sending normal win32 api messages to populate the combo box list?
Yes, if you stick with plain ATL. You can also use WTL, which has the control wrappers that you're looking for.
--Mike--
Visual C++ MVP
LINKS~! Ericahist | NEW!! PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
|
|
|
|
|
is it fine to contain other objects as data members of outer object in ATL. or we need to implement containment to do this.
Z.A
|
|
|
|
|
I am having problems with ATL and RichEdit controls.
I created an ActiveX (composite control using ATL that just contains a
RichEdit box (that was added with the Resource Editor). When the control is
displayed in IE5, the "backspace" key does not work properly in the RichEdit
box. Instead of deleting the chars in the box, pressing the "backspace" key
while in the RichEdit box causes the browser to go "Back" to the previous
URL. (Strange!)
|
|
|
|
|
I'm trying to figure out how exactly vector::push_back() creates objects.
Looks like vector::push_back() will create a lot of copies by copy constructor and destruct a lot. In other words, if I need to put a counter in the copy constructor to monitor how many copy of the objects are created during the run, I will get a number which I don't exactly understand why. Can anybody explain why push_back() keep making copies and deleting copies?
By running the following sample program, I supose to get 2,4,6,8,10 as output, but I get 21,22,23,24,25. Why is that?
Thanks!
class CVecTest
{
public:
CVecTest() {m_intCount = ++m_classNumber;}
CVecTest::CVecTest(const CVecTest &vec) {m_intCount = ++m_classNumber;}
~CVecTest(){};
static int m_classNumber;
int m_intCount;
};
int CVecTest::m_classNumber = 0;
int main(int argc, char* argv[])
{
vector<cvectest> vec;
for (int i=0; i<5; i++)
{
CVecTest p;
vec.push_back(p);
}
for (int i=0; i<5; i++)
cout << vec[i].m_intCount << endl;
return 0;
}
|
|
|
|
|
All STL containers have value semantics and as such copy or assign elements.
Steve
|
|
|
|
|
Stephen Hewitt wrote: All STL containers have value semantics
For the next version of C++ standard it is planned to add move semantics[^]. That would be
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
In the mean time you can get these semantics by butting smart pointers in the container - Boost has many such pointers.
Steve
|
|
|
|
|
std::vector and its friends in the C++ standard library will copy an added element and store the copy, not the original. std::vector doesn't destroy a contained object - it's the object destructor that handles destruction when the std::vector goes out of scope.
There's no container in the C++ standard library, which can share pointers that will be deleted when the last reference to them die. There are such alternatives in Boost[^] and Loki[^].
--
The Blog: Bits and Pieces
|
|
|
|
|
But what I expect is, when an object is inserted to a container, the container will call its copy constructor to make a copy and put into the container. Based on the result of my testing, looks like there are more than one copy of the object is created by copy constructor during the "push_back" process, and some of them got deleted, finnally only more copy remained and stored into the container. Looks like the insertion process is more complicated than just a value semantic.
|
|
|
|
|
Does this help? I suspect the additional copies may be the result of calling a function as in this example.
----------------
#include <iostream>
#include <vector>
using namespace std;
class CLogMe
{
public:
CLogMe()
{
cout << "CLogMe()" << endl;
}
CLogMe(const CLogMe &)
{
cout << "CLogMe(const CLogMe &)" << endl;
}
CLogMe& operator=(const CLogMe &)
{
cout << "operator=(const CLogMe &)" << endl;
return *this;
}
};
typedef vector<CLogMe> LogMes;
LogMes g_LogMes;
void Function(CLogMe me)
{
g_LogMes.push_back(me); // CLogMe copy constructor called here.
}
int main(int argc, char* argv[])
{
CLogMe me; // CLogMe constructor called here.
Function(me); // CLogMe copy constructor called here.
return 0;
}
Steve
|
|
|
|
|
This is exactly what I tried. I found the copy constructor get called a lot of time. After 5 push_back, copy constructor get called 20 times, and destroyed 15 times.
|
|
|
|
|
I'd say the additional copies comes from temporaries during the process of adding an element.
--
The Blog: Bits and Pieces
|
|
|
|
|
Ajax95 wrote: the container will call its copy constructor to make a copy and put into the container
The compiler, if any, makes the copy ctor call.
Ajax95 wrote: Based on the result of my testing, looks like there are more than one copy of the object is created by copy constructor during the "push_back" process
Not strange at all. The documented fact for a container with value semantics is that a copy of an element is added. It's not stipulated that one and only one copy will be made during the process and that that single copy is the one to be added. In fact, if you had taken the time to step into the push_back code while debugging, you would have noticed that lots of temporary copies are created during the process, which ensures that the original data is not tampered with.
Ajax95 wrote: some of them got deleted
Of course, that's the temporary ones that goes out of scope at each call return.
Ajax95 wrote: Looks like the insertion process is more complicated than just a value semantic.
No.
--
The Blog: Bits and Pieces
|
|
|
|
|
To avoid these extra copy constructor, call reserve function. like vec.reserve(5);
Everytime you calls push_back, vector has to expand the memory block and copies the elements from the original to new memory block. Here comes the copy constructor in picture. As the size of vector increases, the number of calls of copy constuctor keeps on increasing(directly proportional to number of elements in vector).
|
|
|
|
|
hi all
Following error occur in my atl com project.this project is using both the atl and mfc classes.Tool is visual studio 2003.
d:\Microsoft Visual Studio .NET\Vc7\atlmfc\include\atlcom.h(1759): error C2259: 'ATL::CComObject<base />' : cannot instantiate abstract class
with
[
Base=CMakeBarcode
]
Tasleem arif
|
|
|
|