pywinrt / python-winsdk

Python package with bindings for Windows SDK
https://python-winsdk.readthedocs.io
MIT License
77 stars 8 forks source link

Authoring COM components #25

Open DatGuy1 opened 1 year ago

DatGuy1 commented 1 year ago

I'm wondering if there's a python-winsdk alternative for https://learn.microsoft.com/windows/uwp/cpp-and-winrt-apis/author-coclasses ?

dlech commented 1 year ago

It is technically possible to write COM components in Python, but it would require some effort to implement the framework to do so and those components couldn't be used in non-Python apps (at least not without also bolting on a Python runtime).

DatGuy1 commented 1 year ago

Perhaps out of scope, but I've been trying my hand at implementing NotificationActivationCallback.h through various methods. Trying to implement it using comtypes/pywin32 stumps me due to it being created with winrt::make<winrt::implements<_, INotificationActivationCallback>>() and trying to use WinRT is confusing me with the C++ bindings, and I haven't had much luck with adding the header with cppwinrt.

dlech commented 1 year ago

If I'm remembering correctly that is used in conjunction with https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/toast-desktop-apps.

I think it would be useful to add a special helper to this library specifically for that class.

Perhaps we could adapt the code from https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast-desktop-cpp-wrl and write a Python wrapper for it.

DatGuy1 commented 1 year ago

That is indeed my use case for it. Doing a major revamp of my toasts module that uses your winsdk bindings, and activating notifications from the action center is the only TODO item remaining.

The other apps section is basically a barebones version of the WRL one, which is what I'm going off. I've managed to recreate the activator class with comtypes:

class NOTIFICATION_USER_INPUT_DATA(Structure):
    _fields_ = [("Key", LPCWSTR), ("Value", LPCWSTR)]

class INotificationActivationCallback(IUnknown):
    _iid_ = GUID("{53E31837-6600-4A81-9395-75CFFE746F94}")
    _methods_ = [
        COMMETHOD(HRESULT, "Activate", (LPCWSTR, LPCWSTR, POINTER(NOTIFICATION_USER_INPUT_DATA), ULONG))
    ]

class CallbackActivator(COMObject):
    _com_interfaces_ = [INotificationActivationCallback]
    _public_methods_ = ["Activate"]

    def Activate(self, *args, **kwargs):
        print(kwargs)
        print(args)

but I haven't managed to actually register and apply it using factories and whatever