|
The parameter is defined as [in,out,optional].
And yes, now I understand, as I suspected, I can't reallocate the VT_BYREF | VT_I2 inside my ATL code.
The only thing still not 100% clear which confused me is that I can define a VB procedure receiving a byref variant, do the same thing receiving my int, and changing it to String and no leak happens. That was my first test.
But the difference is: there's no COM in this scenario, and the pure VB allocation\dellocation mechanisms are not the same.
Thanks a lot !
|
|
|
|
|
STDMETHODIMP CDCSClient::CallService( VARIANT *p)
{
if (V_VT(p) == (VT_VARIANT | VT_BYREF))
{
VARIANT *p2 = V_VARIANTREF(p);
p2->vt = VT_BSTR;
p2->bstrVal = SysAllocString( L"abc" );
return S_OK;
}
}
Dim v As Variant
v = 1
Debug.Print TypeName(v) & " " & v
Call obj.CallService(v)
Debug.Print TypeName(v) & " " & v
With best wishes,
Vita
|
|
|
|
|
About memory leaks. VB allocation\dellocation mechanisms are the same with COM.
p->vt = VT_BSTR | VT_BYREF;
BSTR *pBSTR = new BSTR;
*pBSTR = SysAllocString( L"abc" );
p->pbstrVal = pBSTR;
There are 2 memory allocations in statements "= new BSTR" and "= SysAllocString".
The VARIANT with VT_BYREF|VT_BSTR isn't an owner of its values, so freeing of the VARIANT doesn't free neither pbstrVal nor *pbstrVal. And finally you have memory leaks.
The VARIANT with VT_BSTR (without VT_BYREF) is an owner of its values, so freeing of the VARIANT frees bstrVal.
p->vt = VT_BSTR;
p->bstrVal = SysAllocString( L"abc" );
And there are no memory leaks.
With best wishes,
Vita
|
|
|
|
|
Hi,
I am trying to call the Win 32 API messagebox function from c#.
However, i finding my code not working:
could you please help me correct it:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ConsoleApplication5
{
class Program
{
public const String UserReference = "user32.dll";
[DllImport(UserReference, SetLastError = true)]
private static extern Int32 MessageBox(IntPtr hWnd, String pText,
String pCaption, Int32 uType);
static void Main(string[] args)
{
IntPtr ProblemCauser = (IntPtr)(-100);
MessageBox(ProblemCauser, "hello", "check", 0);
Int32 ErrorCode = Marshal.GetLastWin32Error();
Console.WriteLine("Error Code: " + ErrorCode.ToString());
Console.ReadLine();
}
}
}
|
|
|
|
|
Your arguments are invalid!
nicetohaveyou wrote: IntPtr ProblemCauser = (IntPtr)(-100) .
-100 is a number not pointer to valid window.
Call it like that
MessageBox(this.Handle,"hello", "check", 0)
into Form body or
MessageBox(IntPtr.Zero,"hello", "check", 0)
|
|
|
|
|
On one side I have a C# application (WPF) from which I want to call an Office Add-In class. On my Office Add-In project I've exposed a class and an interface to COM. I'm able to call functions from my exposed Add-In object, but I'm not able to register an event, which should by fired by the exposed Add-In project.
My C# code:
officeAddIn = excel.COMAddIns.Item(ref addinName);
object obj = officeAddIn.Object;
IAddInUtilities m_excelFIMAddInUtils = (IAddInUtilities)obj;
AddInEnablingEventHandler addInEnablingEventHandler = new AddInEnablingEventHandler(m_excelFIMAddInUtils_AddInEnablingEvent);
m_excelFIMAddInUtils.EnableAddIn(true);
m_excelFIMAddInUtils.AddInEnablingEvent += addInEnablingEventHandler
My AddIn Project:
[ComVisible(false)]
[Serializable()]
public delegate void AddInEnablingEventHandler();
public partial class ExcelFIMAddIn
{
private AddInFIMUtilities m_utilities;
private Office.IRibbonExtensibility m_ribbon;
protected override object RequestComAddInAutomationService()
{
if (m_utilities == null)
{
m_utilities = new AddInFIMUtilities();
}
return m_utilities;
}
protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
RibbonExcelFIM ribbon = new RibbonExcelFIM();
ribbon.FIMSaveEvent += new FIMSaveEventHandler(ribbon_FIMSaveEvent);
return ribbon;
}
}
[Guid("6CA66587-1A1E-4cd6-B55A-20F07F18C343")]
[ComVisibleAttribute(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddInUtilities
{
void EnableAddIn(bool isAddInEnabled);
event AddInEnablingEventHandler AddInEnablingEvent;
}
[ComVisibleAttribute(true)]
[Guid("F2FA4759-AEA0-4f4e-838B-3BBBC77837AB")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("AddInFIMUtilites")]
[Serializable()]
public class AddInFIMUtilities : StandardOleMarshalObject, IAddInUtilities
{
public event AddInEnablingEventHandler AddInEnablingEvent;
public void EnableAddIn(bool isAddInEnabled)
{
m_isAddInEnabled = isAddInEnabled;
if (isAddInEnabled)
{
if (AddInEnablingEvent != null)
{
AddInEnablingEvent();
}
else
{
}
}
}
}
What I'm doing wrong? Is there a solution which someone can provide me?
Thanks in advance
Marcel
|
|
|
|
|
I found out a solution that works. If someone has a better working solution, please post it
The code snippet of my new code in C#:
m_excelAddInUtils = (IAddInUtilities)obj;
IpcChannel serverChannel = new IpcChannel("localhost:0");
ChannelServices.RegisterChannel(serverChannel);
AddInFIMUtilities addInUtilClass = new AddInFIMUtilities();
m_excelAddInUtils.AddToSaveObserverList(addInUtilClass);
addInUtilClass.AddInSaveEvent += new AddInSaveEventHandler(addInUtilClass_OnFIMSaved);
The new delegate in Add-In class:
public delegate void AddInSaveEventHandler();
On the Add-In class I created a new IDispatch Interface:
[Guid("69075652-6A6D-442c-B534-5816D5046F04")]
[ComVisibleAttribute(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IAddInEvents
{
void AddInSaveEventHandler();
}
And extended the Main method interface:
[Guid("6CA66587-1A1E-4cd6-B55A-20F07F18C343")]
[ComVisibleAttribute(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddInUtilities
{
[DispId(1)]
void AddToSaveObserverList(IAddInUtilities addInUtils);
[DispId(2)]
void FireSaveEvent();
}
The new methods in the Utility class:
public void AddToSaveObserverList(IAddInUtilities addInUtils)
{
Globals.ExcelFIMAddIn.SaveObserverList.Add(addInUtils);
}
public void FireSaveEvent()
{
AddInSaveEvent();
}
On the Add-In class itself, these extensions are required:
<pre>private List<IAddInUtilities> m_saveObserverList = new List<IAddInUtilities>();
public List<IAddInUtilities> SaveObserverList
{
get { return m_saveObserverList; }
}
And eventually firing the event:
foreach (IAddInUtilities addInFIMUtil in this.SaveObserverList)
{
try
{
((AddInFIMUtilities)addInUtil).FireSaveEvent();
}
catch
{
}
}
modified on Monday, August 10, 2009 6:52 AM
|
|
|
|
|
Hi,
I am new to COM Component development. I dont have that much idea. So plz give me sample code or sample program. Thanks in Advance..
regards,
kannak....
kannak
|
|
|
|
|
|
Hi David...
Thanks for responding..i will go through ....
Regards,
kannak......
kannak
|
|
|
|
|
When I try to play an .avi file in a Windows Media Player component, it is like 1 second black between each new play. It says 'Media has been found' (a translation of myswlf of the Dutch version). Is this solvable? The avi file is a copy of the Vista copy file dialog which musn't be black between every loop.
Thanks.
|
|
|
|
|
Sorry for asking this question too fast - I found out that this component can play without any black pause in between!
Thanks.
|
|
|
|
|
How to set output parameter value to javascript use invoke function's pDispParams.
in javascript
<script type="text/javascript"><br />
var fVal;
external.GetFloat(fVal);<br />
</script>
How do it in Invoke function???
STDMETHODIMP CImpIDispatch::Invoke(<br />
DISPID dispIdMember,<br />
REFIID ,<br />
LCID ,<br />
WORD wFlags,<br />
DISPPARAMS* pDispParams,<br />
VARIANT* pVarResult,<br />
EXCEPINFO* ,<br />
UINT* puArgErr)<br />
{<br />
return S_OK;<br />
}
Hongjun Ge
|
|
|
|
|
You have no chance to transmit any value to javascript by parameter in parameter's list of GetFloat function. Only by [out,retval] parameter of one. I.e. by syntax "fVal = external.GetFloat();". For this action, you should assign right value to pVarResult parameter of CImpIDispatch::Invoke.
With best wishes,
Vita
|
|
|
|
|
Thanks for your reply.
In msdn document descriptions like below.Why they can implement the oCustCalenderObj parameter as out.
http://msdn.microsoft.com/en-us/library/aa770041(VS.85).aspx[^]
<SCRIPT language="JScript"><br />
function MyFunc(iSomeData)<br />
{<br />
var oCustCalendarObj;<br />
external.GetCustomCalender(oCustCalenderObj);<br />
oCustCalerdarObj.doStuffWithIt();<br />
.<br />
.<br />
.<br />
}<br />
</SCRIPT>
Hongjun Ge
|
|
|
|
|
I don't know, but all I said is correct. I didn't meet with GetCustomCalender declaration, but "Get" prefix requires [out,retval] parameter.
AFAIK JScript passes all arguments by value, so server doesn't have a way to modify them. And there is only one case - VARIANT* pVarResult parameter of Invoke.
You can assign some value to this parameter and view the result.
With best wishes,
Vita
|
|
|
|
|
Thanks for your reply. My be there have some way to implement it that we didn't find, But thanks again.
Hongjun Ge
|
|
|
|
|
I'm automating MS Word and so far I've found out that the easiest way to do it is to put as much of the code as possible in VBA macros (in a *.dot file loaded through COM automation), and call those macros.
m_Application.CreateDispatch(_T("Word.Application"));
...............
m_AddIns.AttachDispatch(m_Application.get_AddIns());
m_AddIn.AttachDispatch(m_AddIns.Add(_T("MyMacros.dot"), &vtOptional));
...............
m_Application.Run("MyMacro1");
The problem is I can't pass arguments to MyMacro1, and I need to in some cases. CApplication::Run accepts only 1 parameter and that's the macro name. But how can I pass additional arguments to the macro?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Hello,
I am trying to call an activeX method from JScript in IE6. The method we are trying to call takes two arguments: one long which is the dimension of the array (of bytes) passed as the second parameter. In some cases the size can be zero and the array undefined and we are in that case.
How can I call this method from my JScript code? I tried obj."method(0, null);" but I get an incompatible type error. I also tried using Scripting.Dictionary object but to no avail. Has anyone a tip for this ?
Thanks,
|
|
|
|
|
I'm building .NET application that uses DirectX API for web camera device rendering.
I'm using DirectShowNet Library as wrapper for more info see here DirectShow.NET[^]
When I create instance of for ICaptureGraphBuilder2 interface and call RenderStream like bellow
<br />
Guid cat = PinCategory.Capture;<br />
Guid med = MediaType.Video;<br />
<br />
hr = capGraph.RenderStream(ref cat, ref med, capFilter, null,null)<br />
where capFilter is my source filter,everything is OK.
But after releasing the resources and recreating the graph and the ICaptureGraphBuilder2 instance when I call the method RenderStream it failes with return code -2147024809 or HRESULT E_INVALIDARG.I've tried to call it like
<br />
hr =capGraph.RenderStream(ref cat, ref med, capFilter, null,target) <br />
,where target is my target filter,but this failes again with the same return code.When I change the category to PinCategory.Preview I'm also getting the same result.
I can't avoid using ICaptureGraphBuilder2,because I need to control the resolution of the device.
Do you know how to fix it?
Thank you very much!
|
|
|
|
|
I have solved the problem with using DirectShowLib ,newer version of the API.
Now everything works fine!

|
|
|
|
|
Hi guys,
working with some closed-code client/server application - the client reaches the server using a COM object thats defined by a InprocServer32 DLL - I would like to split client and server to different machines.
DCOM at first sight cannot do it - as the COM is a InprocServer32 DLL (for remoting a LocalServer32 COM - EXE seems to be necessary - Racmgr32 only lists these COM class entries).
My first thought was to code a InprocServer32 COM EXE that provides the same classes like the InprocServer32 DLL does. After I would generate the TLB of the DLL an generate a InprocServer32 DLL that has the same classes and interfaces, but just calls the LocalServer32 EXE - which after could be remotely used by help of DCOM. I guess this has do be done because if I just deleted the InprocServer32 class entry, the current creating method in my client-EXE would not be able to deal with the LocalServer32 COM class anymore.
My question now is - would You guys do it the same way? Does anyone know a way how to make a InprocServer32 DLL being usable remotely - for example by hooking up CreateDispatch? If I would do it the way I described - does anyone see problems or shortcomings? I am thankful for every articles and informations You drop!
Thank You very much for Your ideas, thoughts and replies!
Tiger
|
|
|
|
|
A good online reference for COM programming is: Inside COM+[^], it covers alot of the same information as does Don Box's "Essential COM".
After reading your post several times (I found it a little confusing), I'm wondering: what your logic is for wanting to have your COM objects remoted from another machine, to a Local out-of-process server, and then to an in-process DLL server? Is this some kind of security scheme, or is it just not understanding the basic architecture of COM?
Also, this wasn't clear from your post: are you writing all three COM components yourself? Or, is the InprocServer32 DLL already compiled, and is a dependency for your client project?
An In-Proc server ALWAYS must be a DLL. The COM Library uses the registry entries for the COM CoClass along with the parameters the client provides when instantiating, using either CoCreateInstanceEx, or DllGetClassObject, as the case may be, to determine exactly how to configure the COM Server. It's actually more complicated than that.
Here are some of the relavant chapters from the above cited book:
Chapter Two, The Client, CoCreateInstanceEx[^]
Chapter Four: Apartments[^]
Chapter Thirteen, Executable Components[^]
Chapter Fifteen, Standard Marshaling[^]
And, of course, the one aspect of COM that mystifies everyone, Chapter Eighteen, Security[^]
Chapter Ninteen, The Network Protocol[^], is also very informative.
In answer to your original question, though, I would start out configuring my COM server to be as simple as possible, unless you have overriding security concerns. If you read Chapter Thirteen, you will see that much of the reason for creating an Out-of-Process Server instead of an In-Proc Server, is to control the actual number of COM objects being accessed simultaneously by separate client applications.
|
|
|
|
|
Hi Baltoro,
thank You for all that useful information - I am sure these links will push my project forward.
As I re-read my article, I agree with You that it's not written that clear - so I'd like to explain it more straight:
A company that quit business a while ago sold us some server application together with a client and an API to also write Your own clients to that server. All programs are compiled and I have no source - the only thing I got is a very detailed API documentation, a InProc32 COM DLL and it's includes for C++ projects. All was provided for use with Visual C++ 6.0.
The current situation is, that the server app runs together with the provided client app on workstation machines, and at night a client appwritten by me (using their API) queries the data and stores it in a central server with raid structure.
The provided server app accepts as many connections as I want (through the API-DLL-COM-Inproc32). Our bottleneck is currently the sync of all databases at night, we would like this to happen realtime. Instead of doing syncs several times a day, I would like to split the provided client and server from running together on one workstation. After the client should run on the desktop PC till API inproc32. There I would like to put sth. in between to lead the API calls through DCOM or TCP to a RAID server running the provided server app that would respond.
With DCOM it could be done like this:
-------------- Workstation ---------------------------
Client app -> Inproc32-FakerDLL -> DCOM |
------------------------------------------------------
Machine-boundary
------------- Server -------------------------------------------
| DCOM -> ActiveX-Exe -> Inproc32-DLL -> Server app
----------------------------------------------------------------
As I got no sources, I would create a fake Inproc32 COM DLL from the original API's ILD file.
Then a ActiveX exe providing DCOM support encapsulation the Inproc32 DLL running on server machine.
Now the fake Inproc32 DLL would forward through DCOM to that ActiveX-Exe-DCOM provider which would do the real calls to Inproc32-real-API-DLL on our RAID-server.
Again in other words:
What I try to do is split on a known COM-Inproc32-API and put client app and server app on different machines. Problem is - I got a ready-to-use client app that I cannot modify (compiled) and a server app that is compiled, too.
The question remaining is - is there a more elegant way without the need to writing a ActiveX-Exe that provides the COM-class of the inproc32-API for DCOM on the server machine - and a kind of fake/proxy DLL that forwards to this DCOM-ActiveX-Exe from client machines (to leave all clients-apps loading their Inproc32 DLL)? All is just for splitting server app and client app to different machines...
Let me add that we already verified - there is no license problem by doing what I try to.
Thank You very much for all Your support - I am reading the articles already!
Have a good time!
modified on Monday, August 3, 2009 9:53 AM
|
|
|
|
|
sdk_tiger,
(I'm assuming you have a sense of humor.)
See, now that second post makes it all clear,...and, by the way, I would never have suspected all that from your original post, except that you were leaving out some important details. WOW!
This sounds like something right out of SWORDFISH (2001 movie)[^]. Had you actually posted that last post originally, my response would have been:
DYH 6GJY!! BGOOC265RTG, HEY DFWQAQ!! LL8U YHJ IIRFDB, OK POQQVC47. !W! KKL: FGTMVX KPSSV QQFYHC!! 4547.0058875
(Warning, this repsonse is encrytped. By Extra-Terrestrials. It just looks like gibberish!)
OK, all kidding aside,...why would you even run this software? You have NO IDEA what it really does. Always require that the source code be availiable. Otherwise, how do you verify it's operation? What are your security requirements? I'm assuming there aren't any.
I REALLY don't know what to suggest. To me, the entire concept is implausible. I would start over and write the entire component suite from the beginning, so that I had the complete source, so that I could (1) configure diagnostic routines, if necessary, and (2) verify that it operates correctly and securily, or, can be conveniently upgraded.
|
|
|
|
|