|
sounds like a security problem : every single instance per launching user and winstation : check out DCOMCNFG
|
|
|
|
|
It looks like you want a system-wide singleton (accross process boundaries). You would indeed get funny results with this approach:
- different processes (in your example: IIS and the C++-application) instanciating your component would get a singleton *per process*.
- any static data you maintain dies when your dll goes out of memory: this happens if all interfaces are released: DLLCanUnload is called on a regular basis, and when it returns true (default ATL-implementation: when all reference counts are zero), the dll is unloaded.
You can solve this problem by leaving the COM-singleton for what it is,
designing your component as a multiply instantiatable component
and using either static data in a persistent, out-of-process server (take a look at ATL-service) or simply persist your data in a database.
|
|
|
|
|
Hello,
I'm writing a browser helper object (BHO). It seems that I cannot do this :
<br />
IGlobalInterfaceTable *g_pGIT = NULL;<br />
<br />
void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)<br />
{<br />
HRESULT hr;<br />
IDOMPeek* pIDOMPeek = NULL;<br />
hr = g_pGIT->GetInterfaceFromGlobal( <br />
dwUser, <br />
IID_IDOMPeek, <br />
(void**)&pIDOMPeek);<br />
<br />
I get hr == 0x800401f0
Why and how should i do it ?
Does I have to use ITimer, ITimerService, ... But i cannot find samples how to use that.
Thanks.
|
|
|
|
|
Oops, i forgot to call:
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
Next time i'll read the docs more deeply.
|
|
|
|
|
Hi,
I have been trying to get a result here for a couple of days and am now loosing hair at a rate which I am unable to sustain any longer
I have been experimenting with the VC demo ATLDRAW which includes a ATL DCOM server an ATL DCOM client and an ATL DOM Client as an ActiveX control.
I am trying to reduce the required Authorization such that someone can use it who is not a member of the same domain, so long as they have a login name and password on the client which matches the server. (I have seen this done with Windows Media Services remote management).
All is fine with the normal Client as I can use -
<br />
CoInitializeSecurity(NULL, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);<br />
However in the ActiveX control you can not call CoInitializeSecurity as you are too late. I have tried using CoSetProxyBlanket on m_pDrawServ but it has no effect. I have found some stuff at -
http://www.microsoft.com/msj/defaultframe.asp?page=/msj/1198/security/security1198.htm&nav=/msj/1198/newnav.htm[^]
Which says I need to call CoSetProxyBlanket on my interfaces but I don't see how to do it.
Has anyone ever managed to reduce the Authorization Level in a DCOM ATL ActiveX control and if so how.
Cheers
|
|
|
|
|
I am having some trouble with something that is probably very simple. I have a COM project (exe) and it does not use any ATL. It is fairly simple, a dialog box opens with 2 buttons, the first is to run MS Word. When pressed, word opens up and the user can enter some text. After a lot of research and trial-and-error, I was able to put a button on the Word toolbar. But I do not know how to know when the button has been pressed. This is my class:
/*----------------------------------------------------------------------------*/
const IID IID_IWordAppEventSink = __uuidof(Word::ApplicationEvents);
const IID IID_IWordDocEventSink = __uuidof(Word::DocumentEvents);
const IID IID_ISpecialSaveExit = __uuidof(Office::CommandBarButton);
/*----------------------------------------------------------------------------*/
class CWordEventSink : public CCmdTarget
{
DECLARE_DYNCREATE(CWordEventSink)
public:
CWordEventSink();
virtual ~CWordEventSink();
BOOL Advise(IUnknown* pSource, REFIID iid);
BOOL Unadvise(REFIID iid);
void SetLauncher(CTestDlg* pWordLauncher);
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWordEventSink)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
protected:
// Generated message map functions
//{{AFX_MSG(CWordEventSink)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CWordEventSink)
afx_msg void OnAppStartup();
afx_msg void OnAppQuit();
afx_msg void OnAppDocumentChange();
afx_msg void OnDocNew();
afx_msg void OnDocOpen();
afx_msg void OnDocClose();
afx_msg void PSISaveAndExit();
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
private:
CConnectionAdvisor m_AppEventsAdvisor;
CConnectionAdvisor m_DocEventsAdvisor;
CConnectionAdvisor m_BarEventsAdvisor;
CTestDlg* m_pWordLauncher;
};
I kind of cheated by using an example article written by Christian Staffe called Automating and Eventing in Word. But it never mentioned what to do to capture when the button has been pressed. Does anyone have any thoughts or suggestions? Examples would be great to, I am still trying to learn all this COM stuff..........
|
|
|
|
|
Please check out htis article :http://www.codeproject.com/com/outlookaddin.asp. Although this uses ATL, the basics still hold true.
You should use ConnectionPoints semantics to Advise and Unadvise to ICommandBarButtonEvents dispinterface which has a single method Click(dispid 0x00000001). Thus in your implementation of Invoke in your class, when the dispid = 1, check if the passed CommandBarButton* is the button you created and write the code for the handler.
First ofcourse somewhere in OnConnection() you must advise to ICommandBarButtonEvents like.
CComPtr<iconnectionpoint> spConPt;
hr = spMyButton->FindConnectionPoint(
DIID__CommandBarButtonEvents,
&spConPt);
DWORD dwCookie;
if (FAILED(hr))
return hr;
hr = spConPt->Advise(reinterpret_cast <idispatch*>(this),
&dwCookie4);
if (FAILED(hr))
return hr;
.......
similarly you should also Unadvise() when the connection is no longer needed.
'My capacity for happiness', he added, 'you could fit into a matchbox without taking out the matches first'.
- Marvin, the robot.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
I posted this on the Visual C++ board and the only response I got was "import them both". I am hoping that maybe someone in the COM board can help me with a little more info. I cannot import them both, it will not compile!
I was hoping someone could help me with a little problem I am having. I am new to COM and after a lot of research and helpful articles, I was finally able to write my first COM dll. One of the most suggested articles is the one about creating an outlook dll for office 2000. So I structed my dll around this. I used the #import for the type libs and was actually able to create my own button. I am not doing this for outlook but instead of word and excel. What I was wondering is if there is a way to know, programatically, what version of office the machine has? The #import statements are located in the stdafx.h. But is there a way to check if Office XP, then use the #import statements for Office XP and if not, use the ones for office 2000 libs? I have looked through a lot of code and I found a complete of alot ideas but with the way the dll is put together, since I am not using the msword.h and such, they don't work for me. Can anyone give me any suggestions!!!!!!
|
|
|
|
|
I have a bad answer for you, and then a question.
I have seen this type of question many other places and I have never seen an answer. My suggestion would be to simply use more than one version of your .dll. It would be nice to be able to use only one .dll for any system, but, as an example, check out the Microsoft Internet Explorer update page... there are different d/ls for different versions of windows. I think you have the same type of situation. It ain't pretty, but it may be the only solution. Hopefully someone can jump in and give a better answer...
And now my question: I was wondering what resources you used for your project, besides the article you referenced in your post. Specifically, I am getting ready to start a project using COM to automate Word and I am looking for a resource on this, objects, functions, etc. More specifically I want to be able to select document properties, search for and open templates, write text to the document, and print. I have gotten lost on wild goose chases in MSDN docs and I just need a nudge in the right direction.
Please let me know if you can help.
Thanks,
tym!
|
|
|
|
|
I am not sure if I am the best person to answer this. I tried to use MSDN and they have a wealth of information. Unfortunately, I understood about 1% of all the information. There are many articles out there, the one I reference in the above posting written by Amit Dey, there is another written by Christian Staffe, both are on this website. Plus, between this website and CodeGuru.com, you can pick up a lot of information. The bad thing is that it is not all straight forward, unless you are an experience COM/ATL programmer. Another bad thing is that many examples are written with ATL and many others are NOT. So it is a bad mix. If you keep digging, you can find a lot. If you are wanting to select document properties, open templates, print, etc, you can find basic functions/info on these websites. If you are wanting to add a button/toolbar/menu, that is a whole 'nother ballgame!
|
|
|
|
|
I think I understand DCOM, I know I understand COM, but marketing people have made some things tough on me to figure out.
For example, what is the difference between DCOM and CIS (COM Internet Services) ?
Where does COM+ fit in the picture, I know COM+ is MTS/COM packaged, but is DCOM and CIS still seperate from COM+?
COM+ is used for distributed computing, but I assume this is different than the distributed computing that DCOM implements?
Thanks in Advance.
Soliant | email
"the result is that VC7 is the only compiler to generate optimized MSIL" - Stanley Lippman
|
|
|
|
|
Hi all, I finally was able to get my Word Automation project to work, somewhat. I was never able to find a way with Office 97 but Office 2000 and XP, I was able to find a way. But I am having one problem. When I launch Word from my application, everything seems to work fine. Except when I decide to open an existing word document. It opens the document but it does it in an entirely new Word window, not in the existing window like it usually does. Any ideas what might be causing this? Any ideas how to get around this?????? I am stumped...
|
|
|
|
|
Hi, this is an uninformed, inexperienced answer, but maybe it will help.
Have you tried checking for an existing instance of word before opening the doc? I am brand new to COM, but it seems like there should be a way to check for this and then open a communication to the existing instance. I don't know what your code is like, but if you're just using system calls or something to open the doc and leave it up to windows file associations to do the right thing, that might be the problem.
Sorry if this is of no help, but no one else had an opinion...
tym!
|
|
|
|
|
If you used the Amit Dey article, I have had this problem as well. And I have not come up with a way to check for an existing instance, since it uses ATL...
|
|
|
|
|
The problem is:
How to handle dynamically in a C++ (ATL) CLIENT some
ActiveX control collection properties like in VB ?
(Item, Add, Remove, etc.)
Example:
A control is dynamically created from its ProgID.
COMCTL.ListViewCtrl.1 (common listview control)
We have access to its IUnknown & IDispatch pointers.
Automation approach, using ITypeInfo, TYPEATTR, etc., doesn't
seem to permit a correct access to the ListItems property
(ICollectionXXX like,I think)...
I found a PROPGET/PROPPUT ListItems property but I don't known
how to use them: these two functions take one argument and have
no result...
please help me !
|
|
|
|
|
ATL/WTL are way too cool:
In your header add:
1. #import "C:\WINNT\System32\MSCOMCTL.OCX" no_namespace, named_guids
2. IListViewPtr m_myListView; // new member
3. Access like this:
GetDlgControl(IDC_LISTVIEWCTRL1, __uuidof(IListView), (void**)&m_myListView);
IListItemsPtr IListPtr = m_myListView->GetListItems();
ÿVOTD: 1 "Now faith is being sure of what we hope for and certain of what we do not see."
2 "This is what the ancients were commended for" - Hebrews 11:1-2
|
|
|
|
|
Thanks Ernest
BUT... this is not exactly what I'm looking for...
ProgID is unknown at compile time. We have to read the type library at runtime...
So, is there an #import-like command that would do the job at runtime ?
|
|
|
|
|
Ok... I finally implemented a TLB browser and everything works.
But one strange thing: 'GetListItems' method definition changes !
something like:
in the Type Libray -> ListItems GetListItems( )
ITypeInfo from IDispatch -> GetListItems( arg )
Does somebody know why ?
|
|
|
|
|
Hello guys,
i have made a COM object called IJeremy it has a method called SetMsg which takes an IMessage* as an [in] param.
This object fails to compile - it tells me:
error MIDL2025 : syntax error : expecting a type specification near "IMessage"
What is the best way around to get it to work?
Could i sort of #include the IDL files of IMessage?
Thanks for the help,
Jeremy
Jeremy Pullicino
Professional C++ Developer
Amature COM developer
Done any hacking lately?
|
|
|
|
|
You need to define IMessage in the IDL file!
Jeremy Pullicino wrote:
Could i sort of #include the IDL files of IMessage?
yes, you can #import it!
ÿVOTD: 1 "Now faith is being sure of what we hope for and certain of what we do not see."
2 "This is what the ancients were commended for" - Hebrews 11:1-2
|
|
|
|
|
Hi, I have a Automation COM object which has one property, which is of type long. This works, and now I want to create another property, but not of type long, but of type IDispatch. Basically I want to return another COM object from a property. I've tried setting the property type from the IDL to LPDISPATCH and LPUNKNOWN, but I keep getting errors from VBScript.
Does anyone know how to have a property of type 'IDispatch' in a COM Automation Object?
Thanks,
James Pullicino
Drinking In The Sun
Forgot Password?
|
|
|
|
|
Hi!,
I'm far off a COM guru. I need my app to use the IShellLink interface... I have initialized both com (CoInitialize) and OLE (drag & drop works fine already). I followed the tutor I have and did it like
IShellLink* sl;
res = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&sl);
but this fails... Dunno why, none of the documented return values is returned (there are 3 of them).
Many Thanks for much help!
|
|
|
|
|
What OS are you running on? How are you checking the return value?
Todd Smith
|
|
|
|
|
|
We have an application consisting of any type of component available on the Windows platform :
* MFC ocx and dll,
* ATL DLL and EXE servers,
* some VB stuff and
* a MFC startup application.
Using the debug heap from Microsoft we have already found new/delete mem-leaks, but we have currently no choise to find those COM memory leaks.
I have began working on an IMallocSpy implementation to be registered in COM to show the amount of open leaks, but what I don't understand is how I could implement that kind of stuff to display the C-Class-Name, FunctionName and LineNumber where that open memory block will be allocated.
I tried to use the compiler macros __FILE__ and __LINE__ in my IMallocSpy implementation, but that shows - of course - the filename and the line of my IMallocSpy file....
Could somebody help me out ?!
Best regards
Andi
|
|
|
|
|