Skip to content

Commit

Permalink
feat: add Dispatcher.fromCLSID constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
halildurmus committed Oct 20, 2024
1 parent ca1c524 commit 38d2b7e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 13 deletions.
6 changes: 6 additions & 0 deletions packages/win32/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## 5.7.1-wip

- Add `Pointer<VARIANT>` optional parameter to `Dispatcher.invoke` method
- Add `Dispatcher.fromCLSID` constructor for creating a `Dispatcher` from a
CLSID

## [5.7.0] - 2024-10-19

- Add `UnregisterDeviceNotification` API (#916)
Expand Down
39 changes: 27 additions & 12 deletions packages/win32/lib/src/dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,16 @@ import 'win32/ole32.g.dart';
final class Dispatcher {
Dispatcher(this.dispatch) : _nilGuid = calloc<GUID>();

/// Creates a [Dispatcher] instance from a given programmatic identifier
/// (ProgID).
/// Creates a [Dispatcher] instance from a given class identifier (CLSID).
///
/// Throws a [WindowsException] if the COM object cannot be created or if an
/// error occurs during initialization.
factory Dispatcher.fromProgID(String progId) => using((arena) {
final lpszProgID = progId.toNativeUtf16(allocator: arena);
final lpclsid = arena<GUID>();
factory Dispatcher.fromCLSID(String clsid) => using((arena) {
final lpclsid = GUIDFromString(clsid, allocator: arena);
final riid = GUIDFromString(IID_IDispatch, allocator: arena);
final ppv = calloc<COMObject>();

var hr = CLSIDFromProgID(lpszProgID, lpclsid);
if (FAILED(hr)) throw WindowsException(hr);

hr = CoCreateInstance(
final hr = CoCreateInstance(
lpclsid,
nullptr,
CLSCTX.CLSCTX_INPROC_SERVER,
Expand All @@ -51,6 +46,21 @@ final class Dispatcher {
return Dispatcher(IDispatch(ppv));
});

/// Creates a [Dispatcher] instance from a given programmatic identifier
/// (ProgID).
///
/// Throws a [WindowsException] if the COM object cannot be created or if an
/// error occurs during initialization.
factory Dispatcher.fromProgID(String progID) => using((arena) {
final lpszProgID = progID.toNativeUtf16(allocator: arena);
final lpclsid = arena<GUID>();

var hr = CLSIDFromProgID(lpszProgID, lpclsid);
if (FAILED(hr)) throw WindowsException(hr);

return Dispatcher.fromCLSID(lpclsid.ref.toString());
});

/// Instance of [IDispatch] interface associated with the object.
final IDispatch dispatch;

Expand Down Expand Up @@ -135,10 +145,15 @@ final class Dispatcher {
///
/// The [method] parameter specifies the name of the method to be invoked.
/// The optional [args] parameter provides the arguments to pass to the
/// method, if any.
/// method, if any. The optional [result] parameter is used to store the
/// result of the method invocation, if any.
///
/// Throws a [WindowsException] if the invocation fails.
void invoke(String method, [Pointer<DISPPARAMS>? args]) {
void invoke(
String method, [
Pointer<DISPPARAMS>? args,
Pointer<VARIANT>? result,
]) {
if (_isDisposed) throw StateError('Dispatcher has been disposed.');

final pDispParams = args ?? calloc<DISPPARAMS>();
Expand All @@ -150,7 +165,7 @@ final class Dispatcher {
LOCALE_SYSTEM_DEFAULT,
DISPATCH_FLAGS.DISPATCH_METHOD,
pDispParams,
nullptr,
result ?? nullptr,
nullptr,
nullptr,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/win32/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: win32
description: >
Access common Win32 APIs directly from Dart using FFI — no C required!
version: 5.7.0
version: 5.7.1-wip
homepage: https://win32.pub
repository: https://github.com/halildurmus/win32
issue_tracker: https://github.com/halildurmus/win32/issues
Expand Down

0 comments on commit 38d2b7e

Please sign in to comment.