Windows callback function in a plugin

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
User avatar
WharfRat
Experienced User
Posts: 159
Joined: Wed Dec 25, 2013 11:56 am

Windows callback function in a plugin

Post by WharfRat » Mon Dec 15, 2014 2:24 pm

I am writing a MIDI plugin.

The Windows Multimedia API sends messages to a callback function.

Currently, my callback function is implemented as a standalone function:

Code: Select all

import eg

eg.RegisterPlugin()

from ctypes import *
from ctypes.wintypes import *

# define the prototype for the MIDI Input callback function
MIDIINPUTCALLBACK = WINFUNCTYPE(None, HANDLE, UINT, LPVOID, LPVOID, LPVOID)

def MidiInputCallback (hMidiIn, wMsg, dwInstance, dwParam1, dwParam2):
    ...

class MidiInput (eg.PluginBase):
    def __init__ (self):
        ...
        self.Callback = MIDIINPUTCALLBACK(MidiInputCallback)
        ...
    def Configure (self, device_name=""):
        ...
I would prefer to have the callback function defined within the MidiInput class so that I can access the class members.

Code: Select all

import eg

eg.RegisterPlugin()

from ctypes import *
from ctypes.wintypes import *

# define the prototype for the MIDI Input callback function
MIDIINPUTCALLBACK = WINFUNCTYPE(None, HANDLE, UINT, LPVOID, LPVOID, LPVOID)

class MidiInput (eg.PluginBase):
    def __init__ (self):
        ...
    def Callback (self, ????): # <-- *** this is where I want it ***
        ...
    def Configure (self, device_name=""):
        ...
Any ideas on how it can be done?
EventGhost 0.4.1.r1640
PHX01RN plugin v3.0.1
Windows XP 32bit (v5.1 Build 2600 Service Pack 2)
Windows7 64bit (v6.1 Build 7601 Service Pack 1)

User avatar
WharfRat
Experienced User
Posts: 159
Joined: Wed Dec 25, 2013 11:56 am

Re: Windows callback function in a plugin

Post by WharfRat » Tue Dec 16, 2014 12:50 pm

Perhaps I need to ask a different question in order to accomplish what I need...

How can I access self from within MidiInput.Callback, which is actually MidiInputCallback after self.Callback = MIDIINPUTCALLBACK(MidiInputCallback)?

I hope what I am trying to achieve makes sense to you...
EventGhost 0.4.1.r1640
PHX01RN plugin v3.0.1
Windows XP 32bit (v5.1 Build 2600 Service Pack 2)
Windows7 64bit (v6.1 Build 7601 Service Pack 1)

User avatar
Pako
Plugin Developer
Posts: 2290
Joined: Sat Nov 11, 2006 1:31 pm
Location: Czech Republic
Contact:

Re: Windows callback function in a plugin

Post by Pako » Tue Dec 16, 2014 1:03 pm

I looked at it, but it is too complicated for me (because I can not test it).
Maybe you can create an analogous (generic but in principle identical) snipet (example), where I will have the opportunity to try it as well.

Pako

User avatar
WharfRat
Experienced User
Posts: 159
Joined: Wed Dec 25, 2013 11:56 am

Re: Windows callback function in a plugin

Post by WharfRat » Tue Dec 16, 2014 1:55 pm

Aah, thanks for the quick reply Pako...

I think I have solved it.
Currently I did not use the dwInstance parameter of the callback for anything, but I think I can pass self as the parameter for that, so that it will be accessible within the callback.
I hope that self is just a pointer, and not a deep copy of the object itself...
I will test it just now to see if it works.

By the way, the plugin will work without real MIDI devices.
I have also tested it with virtual MIDI devices like vmpk (Virtual MIDI Piano Keyboard - from SourceForge) by using a virtual MIDI port (MIDI Yoke).
More details about that will follow when I post the plugin (actually two plugins, MIDI input and MIDI output, plus a possible third one for MIDI file IO)...

These two plugins are much harder than the simple PHX01RN remote control plugin I wrote earlier...
EventGhost 0.4.1.r1640
PHX01RN plugin v3.0.1
Windows XP 32bit (v5.1 Build 2600 Service Pack 2)
Windows7 64bit (v6.1 Build 7601 Service Pack 1)

User avatar
WharfRat
Experienced User
Posts: 159
Joined: Wed Dec 25, 2013 11:56 am

Re: Windows callback function in a plugin

Post by WharfRat » Tue Dec 16, 2014 4:56 pm

Well, I struggled with using self as a parameter for dwInstance, and I couldn't get it to work.

Then I went back to Luse's Learning Python 5th Edition book.
Found something about function attributes on page 564.

This is what I do now:

Code: Select all

import eg

eg.RegisterPlugin()

from ctypes import *
from ctypes.wintypes import *

# define the prototype for the MIDI Input callback function
MIDIINPUTCALLBACK = WINFUNCTYPE(None, HANDLE, UINT, LPVOID, LPVOID, LPVOID)

def MidiInputCallback (hMidiIn, wMsg, dwInstance, dwParam1, dwParam2):
    ...
    print MidiInputCallback.parent.some_attribute
    ...
class MidiInput (eg.PluginBase):
    def __init__ (self):
        ...
        MidiInputCallback.parent = self
        self.Callback = MIDIINPUTCALLBACK(MidiInputCallback)
        ...
    def Configure (self, device_name=""):
        ...
The some_attribute in MidiInputCallback is an attribute of the MidiInput class.
EventGhost 0.4.1.r1640
PHX01RN plugin v3.0.1
Windows XP 32bit (v5.1 Build 2600 Service Pack 2)
Windows7 64bit (v6.1 Build 7601 Service Pack 1)

User avatar
WharfRat
Experienced User
Posts: 159
Joined: Wed Dec 25, 2013 11:56 am

Re: Windows callback function in a plugin

Post by WharfRat » Wed Dec 17, 2014 9:21 am

Pako...

Sorry, it took me a while to create a code snippet for you.
__init__.py
(6.27 KiB) Downloaded 149 times
I had to change the example to a MIDI Output Device.
Not everyone has MIDI input devices.
All motherboards have MIDI output devices.

It is as simple as I can make it for our purpose.
When the Open Device macro is executed, something should happen in the callback.
The same applies for the Close Device macro.

The solution I came up with yesterday using function attributes does not seem very elegant.
I think the best solution might be if I can pass self as an argument for dwCallbackInstance in the OpenMidiOutputDevice action.
EventGhost 0.4.1.r1640
PHX01RN plugin v3.0.1
Windows XP 32bit (v5.1 Build 2600 Service Pack 2)
Windows7 64bit (v6.1 Build 7601 Service Pack 1)

User avatar
Pako
Plugin Developer
Posts: 2290
Joined: Sat Nov 11, 2006 1:31 pm
Location: Czech Republic
Contact:

Re: Windows callback function in a plugin

Post by Pako » Wed Dec 17, 2014 3:35 pm

__init__.py
(6.88 KiB) Downloaded 164 times
If I understand correctly, so the solution is very simple.

Pako

User avatar
WharfRat
Experienced User
Posts: 159
Joined: Wed Dec 25, 2013 11:56 am

Re: Windows callback function in a plugin

Post by WharfRat » Wed Dec 17, 2014 6:20 pm

THANK YOU, THANK YOU, THANK YOU...

Simple?
Yes, but only after I studied it carefully...
I would never have arrived at your solution.
It is exactly what I wanted to achieve, and has tested correctly as well.
Thanks again...
EventGhost 0.4.1.r1640
PHX01RN plugin v3.0.1
Windows XP 32bit (v5.1 Build 2600 Service Pack 2)
Windows7 64bit (v6.1 Build 7601 Service Pack 1)

Post Reply