|
I'm trying to write a COM .exe server that creates a small modeless dialog box when properly called. Unfortunately, when I call the COM object from my application, it always returns E_NOINTERFACE from CoCreateInstance when given the correct IID of my COM interface (ICObject in this case, for test purposes). According to MFC documentation, this error occurs when the QueryInterface call does not support the requested interface. However, if I create the same exact COM project using an in-proc .dll file, without changing a single line of code in the calling application (except the CLSCTX_ string in CoCreateInstance), it works fine. I am using MFC's ATL/COM wizard to create both the .exe and the .dll projects. Both settings are for apartment model threading, custom interface, no aggregation and connection points. Here's my application code:
//////////////////////////////////////////////
#include "..\COMObject\COMObject.h"
#include "..\COMObject\COMObject_i.c"
...
HRESULT hr;
//instantiate it
hr = CoCreateInstance(CLSID_CObject, NULL, CLSCTX_LOCAL_SERVER /*CLSCTX_INPROC_SERVER for DLL*/, IID_ICObject, (void **) &m_pObject);
//do something with it
if(SUCCEEDED(hr))
{
m_pObject->StartDialog();
}
//////////////////////////////////////////////
Does anyone have any idea why it works with an in-proc .dll and not an out-of-proc .exe?
|
|
|
|
|
Are you sure CLSID_CObject and IID_ICObject are the same in .DLL and .EXE COM implementation? Check .IDL files they have to be the same for both types of projects (.EXE and .DLL) or just use one .IDL file for both projects.
soptest
|
|
|
|
|
I just tried creating a wholly other .exe server in a new directory with a new interface CLSID and IID. Still has the same methods as the previous attempts and the application still gave the E_NOINTERFACE error. For some reason it will not find the interface requested for an .exe server. I searched through the messages and there's one other one back in the annals describing the same exact problem (search for NOINTERFACE).
|
|
|
|
|
Your CLSID_CObject and IID_ICObject are different (EXE_Project::CLSID_CObject == DLL_Project::CLSID_CObject AND EXE_Project::IID_ICObject == DLL_Project::IID_ICObject). Read my previous post.
soptest
|
|
|
|
|
You should use (and register) the proxy/stub for your EXE server.
Or you should use the dual interfaces, derived from IDispatch, or/and oleautomation interfaces, derived from IUnknown, with standard OLE marshalling. For it, you should use the oleautomation compatible types of data, such as long, double, BSTR and so on.
In this case, you don't need any additional proxy/stub.
With best wishes,
Vita
|
|
|
|
|
Ahhh, thank you very much. I believe this is the answer I was looking for. I had started to suspect that it had something to do with the [oleautomation] tag, but I'm not knowledgeable yet enough to know what I'm doing. Thanks a lot!
|
|
|
|
|
Hi COM Expert.
I have a ms word automation, dos-based, application that support MFC.
The programming is running perfectly right now. and a few minues later i got " Couldn't create MS Word Application Object". at
<br />
app.CreateDispatch("Word.Application");<br />
But I restart the computer and the program works again. why is that? is it because of OLE did not get initialized? why i have to restart the computer in order to work fine. what is wrong with that?
here are my code
<br />
<br />
#include "stdafx.h"<br />
#include "PrintMSWord.h"<br />
#include <ole2.h>
#include <stdio.h><br />
#include "msword9.h"<br />
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
<br />
<br />
CWinApp theApp;<br />
<br />
using namespace std;<br />
<br />
<br />
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])<br />
{<br />
int nRetCode = 0;<br />
<br />
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))<br />
{<br />
cerr << _T("Fatal Error: MFC initialization failed") << endl;<br />
nRetCode = 1;<br />
}<br />
else<br />
{<br />
CString fileName;<br />
for (int i = 1; i < argc; i++)<br />
{ <br />
fileName += argv[i]; <br />
fileName += " ";<br />
}<br />
cout<<"Opening "<<(const char*)fileName<<" ..."<<endl;<br />
<br />
CoInitialize(NULL);<br />
<br />
_Application app;
if(!app.CreateDispatch("Word.Application"))<br />
{<br />
AfxMessageBox("Could not create MS Word Application Object.");<br />
return 1;<br />
}<br />
LPDISPATCH lpDisp;
COleVariant covTrue((short)TRUE),covFalse((short)FALSE),covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);<br />
<br />
lpDisp = app.GetDocuments();
Documents documents;<br />
documents.AttachDispatch(lpDisp);<br />
COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR);
<br />
_Document document = documents.Open(COleVariant((CString)fileName), vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt);<br />
app.SetVisible(TRUE);
<br />
cout<<"Formatting documents..."<<endl;<br />
PageSetup pagesetup = document.GetPageSetup();<br />
float bottomMargin = pagesetup.GetBottomMargin();
if(bottomMargin < 70 ) <br />
pagesetup.SetBottomMargin(bottomMargin+20);
<br />
float leftMargin = pagesetup.GetLeftMargin();<br />
if(leftMargin< 70)<br />
pagesetup.SetLeftMargin(leftMargin+20);<br />
float rightMargin = pagesetup.GetRightMargin();<br />
if(rightMargin < 70)<br />
pagesetup.SetRightMargin(rightMargin+20);<br />
<br />
float headerMargin = pagesetup.GetHeaderDistance();<br />
if(headerMargin < 60 )<br />
pagesetup.SetHeaderDistance(headerMargin+10);<br />
float topMargin = pagesetup.GetTopMargin();<br />
if(topMargin <60)<br />
pagesetup.SetTopMargin(topMargin +20);<br />
<br />
float footerDistance = pagesetup.GetFooterDistance();<br />
pagesetup.SetFooterDistance(footerDistance + 10);<br />
documents.ReleaseDispatch();<br />
cout<<"Printting document...";<br />
document.PrintOut(COleVariant((short)false), vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt);<br />
<br />
document.Close(COleVariant((short)false), vOpt, vOpt);<br />
<br />
VARIANT x;<br />
x.vt = VT_I4;<br />
x.lVal = 1;<br />
app.Quit(covFalse,covOptional,covOptional);<br />
CoUninitialize();<br />
<br />
}<br />
<br />
return nRetCode;<br />
}<br />
<br />
<br />
Thank you
|
|
|
|
|
I don't know MFC very well, but in VB you have to set all your office objects to nothing when you are done with them. Otherwise, the reference stays alive despite app.quit. Try to find a way to nullify or destroy all your reference objects rather than just letting them go out of scope. I see that you call CoUninitialize() and ReleaseDispatch(), but like I said I don't know enough about MFC to know how these work. Maybe try testing your objects before you return to see if they are fully destroyed.
Hope I helped.
|
|
|
|
|
what do you mean by saying
<br />
Try to find a way to nullify or destroy all your reference objects rather than just letting them go out of scope
I'm using network though. this program has been 4 days.. it works fine now and later it is not.. i have no clue at all coz this is my very first COM or Automation application.
I tried so hard to understand what is really going on within my application that sometimes works and mostly not. I couldn't find any book that's talk about why i can't get my word.application. I though it is because I couldn't initialize OLE libs. Anybody Anyone can tell me what is wrong with my code? what is causing my application not to app.createdispatch("Word.Applicaiton");
|
|
|
|
|
If it works at first and then suddenly stops working, then unreleased references are likely the cause. Try to set your Word.Application object to null or something of that sort. I wish I could help more, but I don't know MFC well enough.
Hopefully someone on CP can be more useful.
|
|
|
|
|
Thanks for your explaination. You are helping me and I don't know VB either but I think as long as the classes or functions is win32 API, both VB and C++ programmers can use in the same way, ofcourse the syntax will be different.
Anyway..Let's talk about my problem. Let me tell you one thing I just found out. As I told you, I'm using Network. I have
C:\,J:\,I:\,H:\,G:\...etc.
C:\ and G:\ drives is only I can access. It is private. but J:\, I:\ and H:\ are public. All the users can access to those drives. J:\ is a common one. All the users are on J:\ all the time.
My program give me a message "Couldn't create MS Word Application Object ",
<br />
_Application app<br />
if(!app.CreateDispatch("Word.Application"))<br />
{ <br />
AfxMessageBox("Couldn't create MS Word Application Object ");<br />
return 1;<br />
}<br />
but not from other running from C:\ and G:\. So can you give me any suggestion what do I need to change or do inorder to let my program run correctly on J:\?oh.. it is only works on my machine.. i mean even I copy my program and paste other users' c:\(machines). still it doesn't work.. the same message is giving me...
|
|
|
|
|
Make sure the other user's machine has Word 2000 or XP. If not, then it is a compatability issue. If you're using .NET then it could be something with the security permisions. Set everything to full trust and see if that works. Other than that, I don't know what could be causing it. Sorry.
|
|
|
|
|
yeah.. they all have office 2000. even on my machine, the program doesn't work everytime i restart the computer.. only sometimes. that's ok if you don't know , you do the best you can to help me. and I really appreciate it. Thank you Sharoz.
|
|
|
|
|
What is the error (HRESULT value)?
soptest
|
|
|
|
|
I'm trying to connect to IE events, and made quick & dirty demo ( it's here ). TROUBLE: when I'm getting document object of the IE frame, in which loaded document from another domain (not the same as top-level frame), an error occurs. And I can't to handle it correctly!! In debug mode message box with kernel exception popups...
Demo Usage:
1) Run IE
2) Type address of page with frames from different domains ( www.search.msn.com for ex. )
3) Press "Connect to OnMouseMove Button".
When connected, if you will track mouse hover the doc, you woll listen short beeps.
Help me to correctly handle an error in debug mode, when trying to access documents at search.msn.com and similar sites!!!
Thanks!
|
|
|
|
|
I run it, and nothing happens, just beeps.
Can you give me more details what to do?
P.S.
in void CIEEnumWindowsDlg::OnVs()
after you initialize smart pointer MSHTML::IHTMLDocument2Ptr spHtmlDocument(spDisp); add this line to check if wrapped pointer is vaid:
if(spHtmlDocument == NULL) return;
Samething is here
MSHTML::IHTMLWindow2Ptr spFrame;
spFrame = varFrame;
.
Make sure after you initialize typed smart pointers by assigning an interface pointer or in constructor check it fo NULL.
soptest
|
|
|
|
|
You got E_ACCESSDENIED COM exception, because of IE security design.
try{
spFrameDoc = spFrame->document;
} catch(_com_error e)
{
TRACE("Äîêóìåíò íåäîñòóïåí!\n");
}
Cross-Frame Scripting and Security
With Dynamic HTML (DHTML), content in different windows and frames can interact in powerful ways by scripting with the object model. However, since a browser can simultaneously display unrelated documents in its various windows and frames, certain rules must be enforced to protect data integrity and privacy of information. This article describes how and why these restrictions apply in the DHTML Object Model. All rules about script interaction apply equally to windows, dialog boxes, FRAMESETs, FRAMEs, and IFRAMEs. For most content, only interactions with content from the same domain are allowed. For example, a typical page on www.microsoft.com can freely script content on any other page on www.microsoft.com, but cannot script to pages that are located on a different Web domain. The DHTML Object Model uses the document.domain property to enforce this restriction: only pages with identical domain properties are allowed free interaction. The protocol of the URL must also match. For instance, an HTTP page cannot access HTTPS content. The range of permissible access for a page can be expanded when a script assigns the document.domain property to a suffix of the site name space, up to the second-level domain. For example, a page on www.microsoft.com can assign the document.domain property—initially www.microsoft.com—as microsoft.com to broaden access to include pages in home.microsoft.com or any other site, as long as the other pages also set the document.domain property to the identical value. Since only pages from a site whose name ends with microsoft.com will permit this domain to be set, it is assured that content from the same provider mutually agrees to interact and is free to do so. Domain suffixes shorter than the second-level domain (such as just "com") are not allowed, because they expose beyond a single provider. For international site names, such as www.microsoft.co.jp, the second-level domain for widest access would be "microsoft.co.jp" (not "co.jp"). Since it is important to be able to navigate windows or frames to any URL beyond the domain restriction, these types of accesses are always permitted. Only access that attempts to read out or modify content is restricted. For instance, the href property might be assigned to cause navigation to occur, but this property cannot be read if the URL is of a different domain. This would allow one page to learn where the user has been browsing, and to allow this is a breach of the user's privacy. Some restrictions that apply to pages of different domains include: window.location.href Property can be set to navigate, but cannot be read. Other window.location.href Functionality is blocked. document.location.href Property can be set to navigate, but cannot be read. Other document.location.href Functionality is blocked. IFRAME property can be set to navigate, but cannot be read.
Scripts that attempt to access parts of the object model to which they do not have access are blocked with a "permission denied" error. While domain security can prevent certain types of content interaction, it is important to understand that this restriction is necessary to ensure security. For example, without domain security, a rogue page could "snoop" on another page or, using DHTML, manipulate its content. <info><product rid="prod_IE" minver="4.0"><platform rid="plat_win" minver="95"><platform rid="plat_nt" minver="4.0">
soptest
|
|
|
|
|
Thanks. It's a strange thing occured. Yesterday, catch operator don't helped me (was Exception MessageBox). Today it works, both code:
try{spFrameDoc = spFrame->document; }
catch(_com_error e)
{
TRACE("Doc unavailable! %s\n", e.ErrorMessage());
}
try{spFrameDoc = spFrame->document; }
catch(...)
{
TRACE("Doc unavailable!\n");
}
And pair questions more.
1) Under debugger I saw
First-chance exception in IEEnumWindows.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception. Is it correct? (I handled it).
2) Is it means, that it's impossible to access certain documents for my app? Or there is any way to pass security troubles?
|
|
|
|
|
This kind of stuff happens all the time.. It looks scary, but I think it's stuff that either the kernel or link/loader is doing. Try debugging any application and you'll see tons of these messages (at least in VC 6)
FreeBSD is sexy.
<< This space for rent >>
|
|
|
|
|
I have two DLLs written in VB6. The one DLL is for data access, the other is an intermediary. Both are in COM+ Server applications. My application accesses the intermediary DLL, which in turn accesses the data-access DLL.
One of the classes in the intermediary has transaction support set to "Required". The rest of the classes have transaction support set to "Supported".
When my application accesses a function on this particular class, the application hangs. But if I start the data-access DLL in debug mode, the application accesses the function without a hitch.
Am I missing a setting or service somewhere? (I have Win2K Server.)
|
|
|
|
|
I have a Composite Control with a list control drawn in my resource. I created my own CListCtrl derived class, which adds sorting of columns.
Now I want to do some custom drawing, but I can get this to work. Some how I do not receive the NM_CUSTOMDRAW message. I used ON_NOTIFY_REFLECT and also tried the OnNotify method to catch this message, but here I only got the message from the header, not from the list itself.
How can I receive this message ? Must I do something else with the message map?
By the way, I used m_mylist.SubclassWindow(GetDlgItem(IDC_LIST)) to link the list control object to the list control.
|
|
|
|
|
Hello,
I have 2 questions.. I have researched this for a while and I am very frustrated, so any help will be greatly appreciated. I finally figured out that if your deskband inherits from IPersistStream, explorer won't release the dll when you close the deskband. Why is this??? Second question. Is there a way for a deskband to close itself? In other words, can a deskband tell it's owner that it wants to close?
Thanks
|
|
|
|
|
Man I would kill for an answer to these questions!
|
|
|
|
|
Hi all,
how can i open, format the margins and save a ms word document programmatically?
by the way, my applicating is dos-based application. I tried to put
<br />
if(!AfxOleInit())<br />
{<br />
AfxMessageBox("Could not initialize COM dll");<br />
return FALSE;<br />
}<br /> in my application. but it doesn't work. so i searched through microsoft.com.
and found Automate Excel from C++ withoud using mfc or # import (q216686)
|
|
|
|
|
I need to know the number of "printable" pages of any web site as I have it on the IE. (skip the settings of landscape/portrait) - this number serves me for my plugin which would be located on the toolbar and would be used for any
webpage opened at that moment.
|
|
|
|
|