Can I pass a HWND in a COM method? - windows

Is it possible to have a COM method which passes a HWND? With the following method in my object CoCreateInstance returns DISP_E_BADVARTYPE (0x80020008):
STDMETHODIMP ShowDialog(HWND hWndParent);
So far, I'm getting round this problem by passing an OLE_HANDLE then casting it but it feels like a cludge:
STDMETHODIMP ShowDialog(OLE_HANDLE hWndParent);

I think that HWND is a pointer to a struct thats why you can't use it in the IDL.
If you look at Microsoft Typelibs you will see all sort of variation on how to pass a handle (From int to long to HANDLE).

Your interface is probably registered as "dual", and HWND is not one of the types supported by OLE automation. Does your interface need to be IDispatch-compatible (do you need to call it from scripting or late-bound languages)? If not, deriving from IUnknown rather than IDispatch and not registering as dual will help you out.
NB: Casting is okay as long as you are only using the method in-process.

Related

What does all capitalized Function name means in WinAPI?

Informs the provider that a directory enumeration is starting
`
PRJ_START_DIRECTORY_ENUMERATION_CB PrjStartDirectoryEnumerationCb;
HRESULT PrjStartDirectoryEnumerationCb(
const PRJ_CALLBACK_DATA *callbackData,
const GUID *enumerationId
)
{...}
`
I am confused how to use this function.
You're looking at a callback (a generic programming concept, not specific to Win32), which is usually a reference to a function that you have to write yourself. In order to have the C/C++ compiler check that you've defined your callback function correctly, and to simplify usage of such callbacks, a typedef is often used. The Win32 API often uses all caps to define types of callbacks. In this case, PRJ_START_DIRECTORY_ENUMERATION_CB is the type of the function pointer (a pointer to the callback function that you have to write), and it is defined in projectedfslib.h as:
typedef
_Function_class_(PRJ_START_DIRECTORY_ENUMERATION_CB)
HRESULT
(CALLBACK PRJ_START_DIRECTORY_ENUMERATION_CB)(
_In_ const PRJ_CALLBACK_DATA* callbackData,
_In_ const GUID* enumerationId
);
This definition has a lot of excess stuff in it that helps the Microsoft toolset validate various things related to the usage of this type of function pointer. When writing your own function that works for this type of callback, you don't necessarily have to repeat a lot of the things that are used in the typedef. The MSDN documentation for callbacks often shows an example of how you would write the method signature for your callback, and that example is usually simplified to strip off the excess stuff that the toolset needs, leaving the stuff the developer needs to define when writing their callback.
In this case, the example function is called PrjStartDirectoryEnumerationCb, but there is no function defined with that name. It's up to you to define a function that looks like what you see on MSDN. It doesn't have to have the same name -- you can name it whatever you like, and then you use your function's name anywhere the callback is needed.
HRESULT MyCallback(const PRJ_CALLBACK_DATA *callbackData, const GUID* enumerationId)
{
// implement your callback here
}

What data type does HWND type belong to?

I'm trying to learn about the Win32api for Ruby, and I've come across the HWND type in different functions such as the MessageBox function. What does the HWND type do, and what data type does it belong to; pointer, integer, or long?
HWND represents a window to the operating system and is an opaque pointer value. That is you may know the value of a particular HWND but you know nothing about the data backing that value.
Handles refer to a resource that has been loaded into memory. This type is declared in WinNT.h as follows:
typedef PVOID HANDLE;
Best Regards,
Baron

How does CreateStdDispatch know what method to invoke?

i'm faced with implementing an IDispatch interface. There are four methods, and fortunately 3 of them are easy:
function TIEEventsSink.GetTypeInfoCount(...): HResult;
{
Result := E_NOTIMPL;
}
function TIEEventsSink.GetTypeInfo(...): HResult;
{
Result := E_NOTIMPL;
}
function TIEEventsSink.GetIDsOfNames(...): HResult;
{
Result := E_NOTIMPL;
}
It's the last method, Invoke that is difficult. Here i am faced with having to actually case the DispID, and call my appropriate method; unmarhsalling parameters from a variant array.
function Invoke(
dispIdMember: DISPID;
riid: REFIID;
lcid: LCID;
wFlags: WORD;
var pDispParams: DISPPARAMS;
var pVarResult: VARIANT;
var pExcepInfo: EXCEPINFO;
var puArgErr: DWORD
): HRESULT;
Not wanting to have to write all the tedious boilerplate code, that i'm sure will have bugs, i went googling - rather than doing any work.
i found this snippit on the MSDN Documentation of IDispatch.Invoke:
Generally, you should not implement Invoke directly.
Excellent! i didn't want to implement it anyway! Continuing reading:
Instead, use the dispatch interface to create functions CreateStdDispatch and DispInvoke. For details, refer to CreateStdDispatch, DispInvoke, Creating the IDispatch Interface and Exposing ActiveX Objects.
The Creating the IDispatch Interface link says:
You can implement IDispatch by any of the following means:
[snip]
Calling the CreateStdDispatch function. This approach is the simplest, but it does not provide for rich error handling or multiple national languages.
[snip]
Excellent, CreateStdDispatch it is:
Creates a standard implementation of the IDispatch interface through a single function call. This simplifies exposing objects through Automation.
HRESULT CreateStdDispatch(
IUnknown FAR* punkOuter,
void FAR* pvThis,
ITypeInfo FAR* ptinfo,
IUnknown FAR* FAR* ppunkStdDisp
);
i was going to call it as:
CreateStdDispatch(
myUnk, //Pointer to the object's IUnknown implementation.
anotherObject, //Pointer to the object to expose.
nil //Pointer to the type information that describes the exposed object (i has no type info)
dispInterface //the IUnknown of the object that implements IDispatch for me
);
What i cannot figure out is how the Windows API implemention of CreateStdDispatch knows what methods to call on my object - especially since CreateStdDispatch doesn't know what object-oriented language i'm using, or its calling conventions.
How will CreateStdDispatch know
what method to call for a given dispid?
the calling convention of my language?
how to handle exceptions from the language that my object oriented object is written in?
Note: i have no choice but to implement a dispinterface; i didn't define the interface. i wish it was a simple early bound IUnknown, but it tisn't.
Doesn't the ITypeInfo parameter passed into CreateStdDispatch expose all of the method information?
So you'd create type info first calling CreateDispTypeInfo and pass that through to CreateStdDispatch which can then use the type information to work out which method to call since CreateDispTypeInfo requires INTERFACEDATA which contains all this information
I could be way wrong since I don't have time to look into it but that would make sense to me.
I'll investigate this later and update the answer.
The short answer to your question is: neither CreateStdDispatch() nor the IDispatch implementation it creates knows anything at all about the methods to be called.
The object that you get back simply stores the parameters that you passed to CreateStdDispatch(), and for all IDispatch methods it only turns around and makes the corresponding calls on the ITypeInfo that you gave it. That is all.
If you pass nil for ptinfo as shown in your code then you only get E_INVALIDARG, since the implementing object cannot do anything at all without an ITypeInfo to which to delegate all the work.
If you inspect the code for CStdDisp in oleaut32.dll then you will find that it calls API functions like DispInvoke() (which also live in that DLL) instead of invoking the ITypeInfo methods directly, but these functions are all simple wrappers for calls to the ITypeInfo methods, without any further functionality.
In case anyone wonders: neither CreateStdDispatch() nor CStdDisp performs any additional magic; all they do is give you an IDispatch that does whatever the ITypeInfo that you passed in can do. Think of it as a kind of an adapter that allows you to plug an ITypeInfo into an IDispatch socket.
It is true that TAutoIntfObject.Create() needs a type library. However, all that the constructor does is call GetTypeInfoOfGuid() on it in order to get a type info pointer, to which the object then delegates most of the work related to dispatch things.
Borland in their wisdom made the member variable for the type info pointer private, which means that you really need to hand the constructor some type library or other that contains the interface in question, instead of simply writing another constructor or overriding some virtual function. On the other hand it shouldn't be too hard to load the type library via the registry or to dump parts of it to a TLB file. Inspecting a TLB with OleView gives you actual compilable IDL which is often also Borland-compilable RIDL.
CreateStdDispatch() does not know anything about exceptions either. The catching of exceptions thrown from COM methods and their conversion to HRESULT and/or IErrorInfo is compiler magic induced by Delphi's safecall keyword on the implementing method.
The same goes for the translation of HRESULTs to exceptions when calling COM methods specified as safecall in their interface declarations. The compiler simply inserts a call to #CheckAutoResult after every invocation of a safecall method; this function checks the HRESULT and throws EOleSysError if appropriate.
Simply switch the Delphi debugger to disassembly ('CPU view') to inspect all the magic that the compiler does for you!

How to create anonymous IDispatch functions with ATL?

Is there an easy way to create a class that is derived from IDispatch and that can be passed to API like this (this is C++ ):
pDOM2->attachEvent(CComBSTR("event"), new DispatchFunction);
I know how to create a C++ object that handle an invoke with a dispid of value 0 but it's always a bit painful to implement all IDispatch by hand. I was wondering if ATL has some standard way of doing it as it is fairly common.
By default ATL creates "auto-dual" COM classes. They support both early binding and IDispatch. You'll see IDispatchImpl<> in their inheritance list. You declare the dispid in the IDL. No extra work is required.

WCHAR array not properly marshalled

I have a COM interface with a following method definition (IDL notation):
SCODE GetText( [in, out] ULONG* pcwcBuffer,
[out, size_is(*pcwcBuffer)] WCHAR* awcBuffer );
Typelib marshaling is used for COM+, the type library is registered, other methods of the interface work allright when called through COM+, but not this method.
The server side copies an array of WCHARs into the awcBuffer and its length into pwcBuffer, no buffer overrun ever occurs.
static const wchar_t* Text = L"Sample";
STDMETHODIMP CImpl::GetText( ULONG* bufferLength, WCHAR* buffer )
{
const int length = wcslen( Text );
*bufferLength = length;
memcpy( buffer, Text, length * sizeof( WCHAR ) );
return S_OK;
}
When the client calls this method through COM+ the buffer contents gets lost. Specifically only the first wide char is preserved - if the server copies "Sample" wide character string, the client only receives "S" string. The return value on the client size is S_OK, the buffer length returned to the client is exactly the same as what the server copied.
I finally switched to BSTR to workaround this problem but it's really interesting why the whole valid looking construct doesn't work.
What's the possible reason of the described behaviour?
IIRC, the typelib marshaller ignores the size_is attribute -- thus, only 1 char is marshaled.
J. Passing is right. For the typelib marshaller to work, the COM interface must be OLE Automation compatible. The typelib marshaller is implemented in oleaut32.dll, so I guess there's a clue in the name.
[size_is] is perfectly valid IDL, and compiles into a valid typelib, but the typelib marshaler can only handle a subset of valid interfaces. That subset is usually referred to as OLE Automation. As an aside, VB6 clients can only speak OLE Automation, so they wouldn't be able to consume your interface either.
Try marking your interface with the [oleautomation] attribute in your IDL. It should give you a warning or error message that might point you to more information on the subject.
In "normal" COM, you could generate a proxy/stub DLL from your IDL to do the marshalling, but I'm afraid I don't remember whether COM+ would use your custom marshalling code even if you bothered to build it.
Update: in Juval Lowy's book "COM and .NET Component Services", I found this statement: "...configured components cannot use interfaces that require custom marshaling". So I guess that interface will never work in COM+. If you can, re-write to use a BSTR instead.
Couple of questions:
Why aren't you using BSTR?
Do you have the sources of the GetText function?
What is the size of the buffer returned by the function?

Resources