|
I've written an OLE control using MFC. My control derives from COleControl. When I place the control into a VB container I am receiving only one WM_MOVE notification at the beginning. After that when ever I move the VB app around my control doesn't receive any notification.
Does anyone know what I am missing? Is there some interface I should call or support?
|
|
|
|
|
Dear all,
I have been trying to create COM object using ATL and VStudio 6.00 that will implement a TCP/IP client. The idea is as follows:
A COM object that Implements connectable interface is creating a thread that monitors the TCP/IP port. The thread has a pointer to the COM object so when it receives something from the TCP/IP port it "calls back" the Notify(BSTR msg) method of the COM object. The Notify method of the COM object performs a Fire_MessageReceived call to the event proxy class. Eventually the registered for events clients receive the message.
This mechanism works perfect till the point that the proxy class calls the Invoke method for each client. I get an Access violation on the Client.exe error 0xC0000005 ( I may have missed a 0 ). Stepping in the proxy class I can see that the connection counter is correct and that also the messages have been correctly assigned to VARIANTS. No out-of scope case... The funny thing is that this problem happens ALWAYS when the Clinet application is a VB programm and seldom when the client application is a C++ application.
Any help will be really appreciated
Kind regards
Giannis
|
|
|
|
|
In your worker thread you have to initialize the COM library for that thread, i.e. create an apartment, by matching calls to ::CoInitialize() and ::CoUninitialize(). I suspect that you haven't done so and that could explain why it works when the client is implemented in C++.
Given the above you are firing events from another apartment and you have to marshal the the sink interface since you are crossing apartment boundaries. Have a look at Michael Lindig's solution for one way of doing this through the GIT at
http://www.codeguru.com/Cpp/COM-Tech/atl/atl/article.php/c75/
I have used this solution and I've found it very useful.
If this doesn't help and if you are not using typelib-marshaling, try doing so by adding the keyword 'oleautomation' in the interface definition in the IDL file. If this helps you have a problem with your proxy-stub.
--
Roger
|
|
|
|
|
Roger,
I can only say that I am really thankfull for this answer of yours. Great info and just when I had started to get dissapointed.
I actually followed the solution proposed by the article in CodeGuru you pointed to and it worked perfectly. If I am not mistaken the first paragraph of your replay, to use CoInitialise() in my worker thread, could be a reason for my problems. But although I did so, it didn't short out anything. So only Michael Lindig's solution worked staigh out of the box!
I final note, it seems that VisulaStudio.NET is not very happy though with this solution (don't know why). Can't explain why the same code in VC6 is working while when compiled on VS.NEt C++ it behaves like I before (carsh the client regarless Michael Lindig's solution).
So thank you very much for one more time
Giannis
|
|
|
|
|
Giannis,
Thanks for your thanks!
I'm glad I was able to help you.
However, I didn't expect ::CoInitialize() in the worker thread to solve your problem. I just wanted to make sure you were initializing COM correctly in your thread since the rest of the steps won't work unless the apartment is properly set up.
Regarding VC7 and the .NET environment I cannot help you since I'm still running VC6. But I would expect it to work with VC7 as well.
Anyone else who has problems with GIT marshaling using VC7 / .NET?
--
Roger
|
|
|
|
|
I found also this [this] from Microsoft that documends the "feature"... I will give it a try with the message posting option
Regards
Giannis
|
|
|
|
|
I want to pass bit field union structures in DCOM but when i complie the same inside midl file, the compiler generates error & says bit fields cannot be sent in rpc. Is there any way to send bit fields across rpc in dcom or if it is not possible why is it a constraint.
Can anyone please help me to solve my problem
Thanks
Benny M Kurian
bkm@hcw.ltindia.com
|
|
|
|
|
Hi Dear...
I struck in a problem & I know you can help me..
I've a pro-merchant account in amazon..& I want to upload Inventory to amazon.. but getting problem..File Error..even from site upload...
Can you send me Execl file you used for that uploading...
+ if possible some coding snippet of uploading invenorty. I want to upload through coding.. send me at:
sumit_kapoor1980@hotmail.com
or chat with me at hotmail account or yahoo: sumit_kapoor1980@yahoo.com
I hope you will help me..
Thanks
Have a Nice Life..
Sumit Kapoor.
---Sumit Kapoor---
|
|
|
|
|
I'm having problems when I try to use a flash ActiveX control in a Win32 application (non-MFC)
I don't know why this exception is thrown:
First-chance exception at 0x10058561 in MM.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x10058561 in MM.exe: 0xC0000005: Access violation reading location 0x00000000.
Is something wrong with the code?
#import "c:\winxp\system32\macromed\flash\flash.ocx" named_guids<br />
<br />
...........................<br />
CoInitialize(0);<br />
<br />
IShockwaveFlash* pFlash;<br />
HRESULT hr=CoCreateInstance(CLSID_ShockwaveFlash,NULL,CLSCTX_INPROC_SERVER,IID_IShockwaveFlash,(void**)&pFlash);<br />
pFlash->LoadMovie(0,L"test.swf");
Thanks
Pablo Hernandez Valdes
|
|
|
|
|
Hi Pablo,
Sounds like the CoCreateInstance didn't work. Access violation was probably due to pFlash being NULL (in debug at least).
This is what I used to verify the code worked:
ShockwaveFlashObjects::IShockwaveFlashPtr pFlash = NULL;
try
{
HRESULT hr = pFlash.CreateInstance(__uuidof(ShockwaveFlashObjects::ShockwaveFlash));
if (SUCCEEDED(hr) && pFlash != NULL)
{
pFlash->LoadMovie(0,L"C:\\Inetpub\\wwwroot\\pds\\try1.swf");
}
}
catch(_com_error& e)
{
TRACE1("EXCEPTION: %s", e.Description());
}
NOTE: I've used the smart pointer implementation
Hope this helps,
Andy
|
|
|
|
|
Hello,
Does anyone know how to programmatically register a com component? I have written a simple component (a dll) in assembler and would like to programmatically register it. I'm not sure which windows api functions have to be called from DllRegisterServer and DllUnregisterServer which should be defined in my dll. Any help would be appreciated.
Robert
|
|
|
|
|
You could do the obvious and go for some form of shell excecute on regsvr32.exe /s mylib.dll should do the trick, where /s is for silent. /u to unregister. If you get the process handle when you do it, and wait on it you should be able to detect any errors as well.
"Je pense, donc je mange." - Rene Descartes 1689 - Just before his mother put his tea on the table.
Shameless Plug - Distributed Database Transactions in .NET using COM+
|
|
|
|
|
I don't have a problem using regsvr32.exe. What I am trying to do is write the two functions DllRegisterServer and DllUnregisterServer in my dll. These two functions will be called by regsvr32.exe. However I'm not sure just what should go into these two functions.
|
|
|
|
|
In the function DllRegisterServer (which is the function called by regsvr32.exe) you need to create registry entries for each of your "creatable" interfaces (those that you use IClassFactory to create). To do this you need to have the following string values:
* A string representation of the CLSID of the Interface (in the form {000209FF-0000-0000-C000-000000000046})
* A "Friendly" name for the interface
* A version independent program identifier i.e. Word.Application
* A version dependent program identifier i.e. Word.Application.11
* The file pathname of your DLL (you can get this by calling GetModuleFileName Win32 API)
All the enries that you need to create in the registry should be under HKEY_CLASSES_ROOT. In the following I have used "YOURCLSID" for the CLSID of your interface, "FRIENDLY" for the friendly name, "VIPROGID" for the Version Independant ProgID, "VDPROGID" for the Version Dependant ProgID and "PATHNAME" as the path to your DLL:
First create the key using the API call RegCreateKeyEx:
HKEY_CLASSES_ROOT\CLSID\YOURCLSID Default:= FRIENDLY
and then add the following values using the API RegSetValueEx:
HKEY_CLASSES_ROOT\CLSID\YOURCLSID\InProcServer Value := PATHNAME
HKEY_CLASSES_ROOT\CLSID\YOURCLSID\ProgID Value := VDPROGID
HKEY_CLASSES_ROOT\CLSID\YOURCLSID\VersionIndependentProgID Value := VIPROGID
Next create the following key:
HKEY_CLASSES_ROOT\VIPROGID Default := FRIENDLY
and add the following values:
HKEY_CLASSES_ROOT\VIPROGID\CLSID Value := YOURCLSID
HKEY_CLASSES_ROOT\VIPROGID\CurVer Value:= VDPROGID
Next create the following key:
HKEY_CLASSES_ROOT\VDPROGID Default := FRIENDLY
and add the following value:
HKEY_CLASSES_ROOT\VDPROGID\CLSID Value := YOURCLSID
DllUnregisterServer merely involves removing all the keys and values created above.
Hope this helps
|
|
|
|
|
Thanks for the detailed response!
|
|
|
|
|
Hello, I’m trying to call a managed COM object from an unmanaged c++ program. I get this one link error. Any ideas?
Compiling...
asam.cpp
Linking...
Creating library Debug/MyCPrj.lib and object Debug/MyCPrj.exp
asam.obj : error LNK2019: unresolved external symbol "void __stdcall _com_issue_errorex(long,struct IUnknown *,struct _GUID const &)" (?_com_issue_errorex@@YGXJPAUIUnknown@@ABU_GUID@@@Z) referenced in function "public: long __thiscall IClassfincom::print(void)" (?print@IClassfincom@@QAEJXZ)
Debug/MyCPrj.dll : fatal error LNK1120: 1 unresolved externals
The same c++ program, works well in a standalone c++ project.
The listing:
#include "stdafx.h"
#include "asam.h"
#pragma warning (disable: 4278)
#import <mscorlib.tlb> raw_interfaces_only
#import "D:\Documents and Settings\Sam\My Documents\Visual Studio Projects\finalCOM\finalCOM\bin\Debug\finalCOM.tlb" no_namespace named_guids
extern void sammain(void)
{
IClassfincom *cpi = NULL;
// Initialize COM and create an instance of the InterfaceImplementation class:
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(CLSID_Classfincom,
NULL,
CLSCTX_INPROC_SERVER,
IID_IClassfincom,
reinterpret_cast<void**>(&cpi));
if (FAILED(hr))
{
printf("Couldn't create the instance!... 0x%x\n", hr);
}
else
{
cpi->print();
cpi->Release();
cpi = NULL;
}
// Be a good citizen and clean up COM:
CoUninitialize();
}
|
|
|
|
|
Hi! my name is jinsoo. i am korean
after installing xp service pack 1 and latest windows update.
i cannot register activeX control on registry.
when in 2003. this job was good in windows 2000.
so though using regsvr32.exe not vc++ tool .the result was the same.
the error message is 0x80070715.
though i find the error message in msdn. i can not find that.
my system is windows xp.
tool is VC++(Serviced pack 6.0).
i hope you help me to solve this problem.
nice to meet u
nice to meet u
|
|
|
|
|
Hi Jinsoo,
Can you give more information? Is this your ActiveX object? Is it MFC/ATL ??
When I have issues like this then try debugging the registration of the control, for an ATL example:
Put a breakpoint in your DllRegisterServer function.
- Goto Project/Settings Menu in Visual Studio
- Click the Debug tab on the right-hand side.
- Type in "C:\WINDOWS\system32\regsvr32.exe" into the "Executable for debug session" text box
- Put the full path of the debug binary into the "Program Arguments" text box
Now run the debugger, you will get a dialog box asking if you want to continue (it is just informing you that regsvr32.exe you are running has no debug info.) Click OK and you should soon be put into the DllRegisterServer function, now just drill down until you come across the error.
Cheers,
Andy
|
|
|
|
|
Hi,
Could anybody explain why in QueryInterface()we use static_cast for casting pointers to interfaces to be returned by the functions, but inside the function in order to call AddRef() we call reintepret_cast like this:
reinterpret_cast<iunknown*>(*ppv)->AddRef();?
Why not just using static_cast as well?
Any input would be of great value and much appreciated.
Thanks.
skruss
|
|
|
|
|
if you find these words like static_cast,reintepret_cast and dynamic_cast
on msdn you will find the answer.
nice to meet u
|
|
|
|
|
Thanks very much. I looked their and found it very helpful indeed.
Nice to meet you too.
skruss
|
|
|
|
|
skruss wrote:
Why not just using static_cast as well?
It's a matter of taste really. They exist so that you can tell the compiler what it is that you want to accomplish. That way, the compiler can issue warnings/errors if what you want to do is illegal.
Of course, dynamic_cast is slightly different from the other casting operators in that it actually does the cast in runtime (it returns 0 if A is not assignable to B - B* b = dynamic_cast<A*>
reinterpret_cast should be avoided unless you really need it. Why? Because it basically tells the compiler to cast whatever into whatever. The compiler can thus not issue any warnings/errors.
--
Booohoo!
|
|
|
|
|
hi, i want to learn COM from vb. does anyone know any usefull document that teach COM or COM+ from the beginner. some document that i had could not make the beginner like me to understand. please provide me any tips or trick to solve that problem.
Roath Kanel
APO-CEDC
Save Children Norway-Cambodia Office
|
|
|
|
|
I'm trying to use the conversion macros (OLE2A, OLE2CA, etc) and I know I need to add the USES_CONVERSION macro, but where do I put it? I put it in my header file and I keep getting compiler errors that a bunch of the variables it declares are missing their type-specifiers and such. Am I doing something wrong? Thanks.
Also, this is off topic from the subject, but is there anything like CString for ATL?
- Aaron
|
|
|
|
|
Aaron,
In answer to the question of CString functionality for ATL, try looking at this (http://www.codeguru.com/Cpp/COM-Tech/atl/atl/article.php/c67/) I've used this in the past and worked a treat
- Andy
|
|
|
|