com topic

COM-based APIs

Windows APIs that use the COM invocation model.

Since the Win32 package primarily focuses on providing a lightweight wrapper for the underlying Windows API primitives, you can use the same API calls as described in Microsoft documentation to create an manipulate objects (e.g. CoCreateInstance and IUnknown->QueryInterface). However, since this introduces a certain amount of boilerplate and non-idiomatic Dart code, the library also provides some helper functions that reduce the labor compared to a pure C-style calling convention.

Initializing the COM library

Before you call any COM functions, first initialize the COM library by calling the CoInitializeEx function. Details of the threading models are outside the scope of this document, but typically you should write something like:

final hr = CoInitializeEx(
    nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (FAILED(hr)) throw WindowsException(hr);

Creating a COM object

You can create COM objects using the C library:

hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, iid, ppv);

However, rather than manually allocate GUID structs for the clsid and iid values, checking the hr result code and deal with casting the ppv return object, it is easier to use the createFromID static helper function:

final fileDialog2 = IFileDialog2(
  COMObject.createFromID(CLSID_FileOpenDialog, IID_IFileDialog2));

createFromID returns a Pointer<COMObject> containing the requested object, which can then be cast into the appropriate interface as shown above. It is the caller's responsibility to free the returned pointer when all interfaces that derive from it are released.

Asking a COM object for an interface

COM allows objects to implement multiple interfaces, but it does not let you merely cast an object to a different interface. Instead, returned pointers are to a specific interface. However, every COM interface in the Dart Win32 package derives from IUnknown, so as in other language implementations of COM, you may call QueryInterface on any object to retrieve a pointer to a different supported interface.

More information on COM interfaces may be found in the Microsoft documentation.

The Dart Win32 package supplies a method that wraps QueryInterface. If you have an existing COM object, you can call it as follows:

  final modalWindow = IModalWindow(fileDialog2.toInterface(IID_IModalWindow));

Where createFromID creates a new COM object, toInterface casts an existing COM object to a new interface. Like createFromID, it returns a Pointer<COMObject>, which can be cast to the interface itself, and as with createFromID, it is the caller's responsibility to free the returned pointer when all interfaces that derive from it are released.

Calling a method on a COM object

No special considerations are needed here; however, it is wise to assign the return value to a variable and test it for success or failure. You can use the SUCCEEDED() or FAILED() top-level functions to do this, for example:

final hr = fileOpenDialog.Show(NULL);
if (SUCCEEDED(hr)) {
  // Do something with the returned dialog box values
}

Failures are reported as HRESULT values (e.g. E_ACCESSDENIED). Sometimes a Win32 error code is converted to an HRESULT, as in the case where a user cancels a common dialog box:

final hr = fileOpenDialog.Show(NULL);
if (FAILED(hr) && hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
  // User clicked cancel
}

Releasing COM objects

When you have finished using a COM interface, you should release it with the Release method:

fileOpenDialog.Release(); // Release the interface
free(fileOpenDialog.ptr); // Release the pointer to the interface

Often this will be called as part of a try / finally block, to guarantee that the object is released even if an exception is thrown.

Unloading COM support

When you have finished using COM, you should uninitialize it with the following call:

CoUninitialize();

A full example of these calls can be found in the com_demo.dart file in the example\ subfolder.

Classes

ApplicationActivationManager com
AppxFactory com
COMObject com Interface
A representation of a generic COM object. All Dart COM objects inherit from this class.
DesktopWallpaper com
FileOpenDialog com
FileSaveDialog com
IApplicationActivationManager com Interface
IAppxFactory com Interface
IAppxFile com Interface
IAppxFilesEnumerator com Interface
IAppxManifestApplication com Interface
IAppxManifestApplicationsEnumerator com Interface
IAppxManifestOSPackageDependency com Interface
IAppxManifestPackageDependenciesEnumerator com Interface
IAppxManifestPackageDependency com Interface
IAppxManifestPackageId com Interface
IAppxManifestProperties com Interface
IAppxManifestReader com Interface
IAppxManifestReader2 com Interface
IAppxManifestReader3 com Interface
IAppxManifestReader4 com Interface
IAppxManifestReader5 com Interface
IAppxManifestReader6 com Interface
IAppxManifestReader7 com Interface
IAppxPackageReader com Interface
IAudioCaptureClient com Interface
IAudioClient com Interface
IAudioClock com Interface
IAudioRenderClient com Interface
IAudioSessionControl com Interface
IAudioSessionManager com Interface
IAudioStreamVolume com Interface
IBindCtx com Interface
IChannelAudioVolume com Interface
IClassFactory com Interface
IConnectionPoint com Interface
IConnectionPointContainer com Interface
IDesktopWallpaper com Interface
IDispatch com Interface
IEnumIDList com Interface
IEnumMoniker com Interface
IEnumNetworkConnections com Interface
IEnumNetworks com Interface
IEnumResources com Interface
IEnumSpellingError com Interface
IEnumString com Interface
IEnumVARIANT com Interface
IEnumWbemClassObject com Interface
IErrorInfo com Interface
IFileDialog com Interface
IFileDialog2 com Interface
IFileDialogCustomize com Interface
IFileIsInUse com Interface
IFileOpenDialog com Interface
IFileSaveDialog com Interface
IInspectable com Interface
IKnownFolder com Interface
IKnownFolderManager com Interface
IMMDevice com Interface
IMMDeviceEnumerator com Interface
IModalWindow com Interface
IMoniker com Interface
INetwork com Interface
INetworkConnection com Interface
INetworkListManager com Interface
INetworkListManagerEvents com Interface
IPersist com Interface
IPersistFile com Interface
IPersistMemory com Interface
IPersistStream com Interface
IProvideClassInfo com Interface
IRunningObjectTable com Interface
ISequentialStream com Interface
IShellFolder com Interface
IShellItem com Interface
IShellItem2 com Interface
IShellItemArray com Interface
IShellItemFilter com Interface
IShellItemImageFactory com Interface
IShellItemResources com Interface
IShellLinkDataList com Interface
IShellLinkDual com Interface
IShellService com Interface
ISimpleAudioVolume com Interface
ISpeechObjectToken com Interface
ISpeechObjectTokens com Interface
ISpellChecker com Interface
ISpellChecker2 com Interface
ISpellCheckerChangedEventHandler com Interface
ISpellCheckerFactory com Interface
ISpellingError com Interface
ISpEventSource com Interface
ISpNotifySource com Interface
ISpVoice com Interface
IStream com Interface
ISupportErrorInfo com Interface
ITypeInfo com Interface
IUnknown com Interface
IUri com Interface
IVirtualDesktopManager com Interface
IWbemClassObject com Interface
IWbemConfigureRefresher com Interface
IWbemContext com Interface
IWbemHiPerfEnum com Interface
IWbemLocator com Interface
IWbemObjectAccess com Interface
IWbemRefresher com Interface
IWbemServices com Interface
KnownFolderManager com
MMDeviceEnumerator com
NetworkListManager com
ShellItem com
SpellCheckerFactory com
SpVoice com
VirtualDesktopManager com
WbemClassObject com
WbemContext com
WbemLocator com
WbemRefresher com

Functions

convertToCLSID(String strCLSID, {Allocator allocator = calloc}) Pointer<GUID> com
Converts a Dart string into an CLSID using the CLSIDFromString call.
convertToIID(String strIID, {Allocator allocator = calloc}) Pointer<GUID> com
Converts a Dart string into an IID using the IIDFromString call.