I create Toolbar button using TBBUTTON. To set tootip i set SendMessage(m_hWnd, TB_SETMAXTEXTROWS, 0, 0L), by doing this iString member of TBBUTTON is set as ToolTip, but i want both, ToolTip and Caption to Toolbar button.So how can i set this.
I refer http://msdn.microsoft.com/en-us/library/bb760446(VS.85).aspx#Displaying_Tooltips_for_Buttons link.
VariantClear( p );
VariantInit( p );
p->vt = VT_BSTR | VT_BYREF;
BSTR *pBSTR = new BSTR;
*pBSTR = SysAllocString( L"abc" );
p->pbstrVal = pBSTR;
And my client in VB is like this:
For i = 1 To 1000
Dim myInt As Integer
myInt = 3
ret = client.CallService(myInt)
As far as I know the COM engine is creating a VARIANT from my integer (which is received as VT_BYREF | VT_I2), and I change it to VT_BSTR.
The VB loop causes a huge memory leak.
Am I doing something wrong ? How the COM engine handles the new VARIANT/BSTR deallocation ?
It was my first guess, but I don't think so...each time I receive a call (from the loop) I receive the same integer VT_BYREF | VT_I2 (which is deallocated by VariantClear).
It seems that this BSTR is lost between calls, causing the leak (obviously myInt is an integer and can't reflect changes).
I can't change that interface, the real code is far more complicated, basically I need to receive a VARIANT* and change their value, and the new value comes from a c++ string.
I'm testing using VB 6.
How CallService is defined in IDL file? If it's "CallService([in] VARIANT *p1)", then you cannot change the parameter. If it's "CallService([in,out] VARIANT *p1), then you cannot receive the parameter in Integer.
IAC, VB passes myInt variable as VT_BYREF | VT_I2 to be possible to change the myInt value. It's made only during call some method. Inside VB don't store variant by this manner.
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.
STDMETHODIMP CDCSClient::CallService(/*[in,out]*/ VARIANT *p)
if (V_VT(p) == (VT_VARIANT | VT_BYREF))
// only here you can change the type of passed variable (see VB example below)
VARIANT *p2 = V_VARIANTREF(p);
p2->vt = VT_BSTR;
p2->bstrVal = SysAllocString( L"abc" );
Dim v As Variant
v = 1
Debug.Print TypeName(v) & " " & v
Debug.Print TypeName(v) & " " & v
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);
//Until here, it works finem_excelFIMAddInUtils.AddInEnablingEvent += addInEnablingEventHandler //Failes! --> InvalidCastException
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;
// create a Channel with port 0 --> otherwise an Exception will be//throwed: "This remoting proxy has no channel sink which means either //the server has no registered server channels that are listening, or //this application has no suitable client channel to talk to the server.
IpcChannel serverChannel = new IpcChannel("localhost:0");
//Use a second instance of the utility class. With the first instance provided by the COMAddIn.Object property, I //haven't found out how to marshal an event registering without throwing //an InvalidCastException
AddInFIMUtilities addInUtilClass = new AddInFIMUtilities();
//Register the second instance (CLR object) to the COM instance over the //provided utility interface
//Now the event registering works without cast exceptions
addInUtilClass.AddInSaveEvent += new AddInSaveEventHandler(addInUtilClass_OnFIMSaved);
The new delegate in Add-In class:
On the Add-In class I created a new IDispatch Interface:
//Service to register the CLR client object to COM observer list
void AddToSaveObserverList(IAddInUtilities addInUtils);
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.