Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[module, ahk & dotNet] IPC 2.6 


  • Please log in to reply
59 replies to this topic
majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
I will make modifications according to your analyses.

Thank you Lex.

PS:

(Also edit: "i.e. 64-bit on 64-bit Windows" was inaccurate.)

I like your kind of precision m8 :D
Posted Image

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
2 Lexikos

I have some questions:

1. What happens when 32bit AHK talks to 64 C# ? I guess system will do the marchaling ...

2. Original IPC.cs should work when compiled on 64bit. I realised I started 32bit app on 64 bit system.....

3. Do you think its possible and valuable to have single IPC.cs adjusting to changes in OS, no matter the how you compiled it, similar to what some people done here on AHK forum, when dealing with this stuff - i.e. checking the OS type and using appropriate NumGet. I don't know is there any technique in DotNet for mixing 32b and 64b.
Posted Image

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

1. What happens when 32bit AHK talks to 64 C# ? I guess system will do the marchaling ...

Yes, as it does between any two processes.

2. Original IPC.cs should work when compiled on 64bit. I realised I started 32bit app on 64 bit system.....

I would think it should be the opposite - assuming the "original" is the version which defines all members of COPYDATASTRUCT as 32-bit, it should only work as a 32-bit app. For instance, compiled as 64-bit the "dwData" and "cbData" C# fields would actually refer to two halves of the real dwData field, and "lpData" would actually refer to cbData.

3. Do you think its possible and valuable to have single IPC.cs adjusting to changes in OS, no matter the how you compiled it, similar to what some people done here on AHK forum, when dealing with this stuff - i.e. checking the OS type and using appropriate NumGet.

Do you mean IPC.ahk rather than IPC.cs? There shouldn't be any "adjusting" necessary in .NET, as long as you use the correct system-dependent types (i.e. IntPtr is sized depending on the OS).

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006

I would think it should be the opposite - assuming the "original" is the version which defines all members of COPYDATASTRUCT as 32-bit, it should only work as a 32-bit app

Fields of the structure are not defined as Int32 but as int. Somehow I thought that int is 64bit on 64bit systems....

There shouldn't be any "adjusting" necessary in .NET, as long as you use the correct system-dependent types (i.e. IntPtr is sized depending on the OS).

I see. Thanks.
Posted Image

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
version 2.6
- DotNet class fixes for 64b systems (made by Lexikos).
- Test apps for 32b and 64b systems.
- Docs update.
Posted Image

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Fields of the structure are not defined as Int32 but as int. Somehow I thought that int is 64bit on 64bit systems....

If int were 64-bit, the structure would still be incorrect since the second field is supposed to be 32-bit. I guess you now realise int is always an alias for Int32. :)

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Yes :)

This reveals my biggest mind bug: it refuses to think about small details .... Since the devil is in details, it often goes against me... :?

Ty 4 ur patience.

Posted Image
Posted Image

genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009
Thank you so much for making this module!

I have been trying to solve a problem with multiple midi inputs.
Unable to solve my problem one way, I have look for alternative.
I found this module. Since all I really need is data values coming back to the main script, I thought this module made sense.

I am trying to send the midi note number from script1 to script2.
Script2.ahk as well as IPC.ahk (from module archive) remain untouched and script2 is running. Once it gets to script2 I will do other stuff with the note number, like trigger keystrokes.


I confirm the following -
1. Edited Script1.ahk successfully sends the edit box to script 2.
2. Midi input is working and midi messages are being split up into bytes.
3. Midi note numbers are correct and show up in script1 gui box.

Can someone please take a look and help me route my data properly?

Script1.ahk edited as follows including the midi input.
;#SingleInstance, off	;allow multiple instances
	target := "Script2"
	stress := 1000,   x:=300
	;========================

	Gui, +LastFound	  +AlwaysOnTop
	hScript := WinExist() + 0

	Gui, Font, s10

	Gui, Add, Edit,	   vMyMsg  w200 , midiMsg
	 
	Gui, Add, Edit,  x+0 vMyPort w50, 100

	Gui, Font, s8
	Gui, Add, Button, x+5	gOnSend		  , Send
	Gui, Add, Button, x+5	gOnSendBinary , Send Binary
	Gui, Add, Button, x+5	gOnStress	  , Stress

	Gui, Add, ListBox,xm w440 h300 vMyLB,
	Gui, Show, x%x%	AutoSize
	
	GuiControl, , MyLB, This script HWND: %hScript%
	IPC_SetHandler("OnData")

; --------	inserted code ----------
/*
	I am trying to get the midi note number input passed to script 2.
	I currently have it showing the note number pressed in this scripts window
	Script1.
	
*/
; SET THIS DEVICEiD TO YOUR MIDI INPUT PORT, 0 IS THE FIRST MIDI PORT, 
; most of this code written by orbik.

DeviceID := 1 ; hardware keyboard
CALLBACK_WINDOW := 0x10000

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#Persistent

Gui, +LastFound
hWnd := WinExist()

OpenCloseMidiAPI()
OnExit, Sub_Exit

hMidiIn =
VarSetCapacity(hMidiIn, 4, 0)

result := DllCall("winmm.dll\midiInOpen", UInt,&hMidiIn, UInt,DeviceID, UInt,hWnd, UInt,0, UInt,CALLBACK_WINDOW, "UInt")

	If result
	{
		MsgBox, error, midiInOpen returned %result%`n
		GoSub, sub_exit
	}

hMidiIn := NumGet(hMidiIn) ; because midiInOpen writes the value in 32 bit binary number, AHK stores it as a string

result := DllCall("winmm.dll\midiInStart", UInt,hMidiIn)

If result
	{
		MsgBox, error, midiInStart returned %result%`n
		GoSub, sub_exit
	}

; for reference only
; #define MM_MIM_OPEN 0x3C1 /* MIDI input */
; #define MM_MIM_CLOSE 0x3C2
; #define MM_MIM_DATA 0x3C3
; #define MM_MIM_LONGDATA 0x3C4
; #define MM_MIM_ERROR 0x3C5
; #define MM_MIM_LONGERROR 0x3C6

OnMessage(0x3C1, "midiInHandler") ; calling the function below 
OnMessage(0x3C2, "midiInHandler")
OnMessage(0x3C3, "midiInHandler")
OnMessage(0x3C4, "midiInHandler")
OnMessage(0x3C5, "midiInHandler")
OnMessage(0x3C6, "midiInHandler")

return

;--------End of auto-execute section-----

OpenCloseMidiAPI() ; calls the winmm.dll to close midi port
	{
		Static hModule
		If hModule
		DllCall("FreeLibrary", UInt,hModule), hModule := ""
		If (0 = hModule := DllCall("LoadLibrary",Str,"winmm.dll")) 
		{
			MsgBox Cannot load library winmm.dll
			ExitApp
		}
	}

midiInHandler(hInput, midiMsg, wMsg) ; THIS IS THE MIDI IN FUNCTION WHERE THE MIDI MESSAGE IS BROKEN UP 
	{
		statusbyte 	:=  midiMsg & 0xFF			; EXTRACT THE STATUS BYTE (WHAT KIND OF MIDI MESSAGE IS IT)
		chan 		:= (statusbyte & 0x0f) + 1	; WHAT MIDI CHANNEL IS THE MESSAGE ON?
		byte1 		:= (midiMsg >> 8) & 0xFF	; THIS IS DATA1 VALUE = NOTE NUMBER OR CC NUMBER
		byte2 		:= (midiMsg >> 16) & 0xFF	; DATA2 VALUE IS NOTE VELEOCITY OR CC VALUE

    IfEqual, statusbyte, 144 ; test for noteOn message
		{ 

; how do I get byte1 "note number" sent to script2?

			Data := byte1 ; set var to the byte1 Midi note number
			OnData(Hwnd, Data, Port, Size)
			;IPC_Send( WinExist( target ), %byte1%, MyPort)
			;gosub, OnSend
        }
   Else
       {
       }
	}
;------ end of inserted code ---
return

OnData(Hwnd, Data, Port, Size) 	
	{
		global myLB

		if Size =
			 s = %Port%      Hwnd: %hwnd%      Message: %Data%
		else 
		{		  
			  x := NumGet(Data+0), y := NumGet(Data+4)
			  s = %Port%     Hwnd: %HWND%      Binary Data: POINT (%x%, %y%)      DataSize: %Size%
		}	
		GuiControl, , MyLB, %s%
	}

OnSend:
	Gui, Submit, NoHide
	if !IPC_Send( WinExist( target ), MyMsg, MyPort)
		MsgBox Sending failed
return

OnStress:
	Gui, Submit, NoHide
	if !(h := WinExist( target ))
		MsgBox Host doesn't exist
	loop, %stress%
	   IPC_Send(h, MyMsg " : " A_Index, MyPort)
return

OnSendBinary:
	Gui, Submit, NoHide
	VarSetCapacity(POINT, 8), NumPut(2000, POINT), NumPut(8000, POINT, 4)
	if !IPC_Send( WinExist( target ), &POINT, MyPort, 8)
		MsgBox Sending failed
return

GuiClose:
	ExitApp
return


; =============== this will exit the app when esc is pushed
Esc::GoSub, sub_exit

sub_exit:

	If (hMidiIn)
	DllCall("winmm.dll\midiInClose", UInt,hMidiIn)
	OpenCloseMidiAPI()
	ExitApp

#include ..\IPC.ahk

Thank you for looking!

KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk? links dead.. pm me


First Toy Lab
  • Members
  • 21 posts
  • Last active: Jan 09 2010 01:18 PM
  • Joined: 15 Nov 2009
When I read post like this I feel that I still have much to learn...

I found this webpage about IPC:

http://www.cs.cmu.edu/~IPC/

Does have anything to do with this script?

By the way... Well done script! I always appreciate look at the digital art of coding.

genmce
  • Members
  • 144 posts
  • Last active: May 21 2015 03:09 PM
  • Joined: 10 Jan 2009

When I read post like this I feel that I still have much to learn...

I found this webpage about IPC:

http://www.cs.cmu.edu/~IPC/

Does have anything to do with this script?

By the way... Well done script! I always appreciate look at the digital art of coding.



The IPC stuff is all majkinetor's code.
The midi in stuff is all orbik's code.


I am just a I guy who stumbled on some parts and employed a weak assembling force, to minimal success.

I have a lot to learn as well, I know just enough to get myself into trouble!
Like here.

KeyMce/GenMce - mackie emulator for pc keyboard/Convert your controller to mackie.
Midi I/O - Want to play with midi/ahk? links dead.. pm me


majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006

I found this webpage about IPC:

<!-- m -->http://www.cs.cmu.edu/~IPC/<!-- m -->

Does have anything to do with this script?

No.
That system uses TCP connections.
IPC uses WM_COPYDATA message (so its local only unlike TCP). The best way to learn about it is MSDN.
Posted Image

Jabobian
  • Guests
  • Last active:
  • Joined: --
Hi, all
I found on my Win XP which is a Chinese version, and the default encoding is in unicode (code page 936 for Chinese).

To let Script1.ahk and Script2.ahk run correctly, I have to change the following line in IPC.ahk

DataSize := StrLen(Data)+1, pData := &Data, Port := -Port
==>
DataSize := StrLen(Data)*2+2, pData := &Data, Port := -Port

Cheer!

Mystiq
  • Members
  • 83 posts
  • Last active: Nov 06 2011 07:07 PM
  • Joined: 08 Jan 2007

DataSize := StrLen(Data)+1, pData := &Data, Port := -Port
==>
DataSize := StrLen(Data)*2+2, pData := &Data, Port := -Port


Thanks for this, also you can use something like this to support both ANSI and Unicode builds (for Autohotkey_L).

DataSize := A_IsUnicode ? StrLen(Data)*2+2 : StrLen(Data)+1


fincs
  • Moderators
  • 1662 posts
  • Last active:
  • Joined: 05 May 2007
DataSize := (StrLen(Data)+1) * (!!A_IsUnicode + 1)


Mystiq
  • Members
  • 83 posts
  • Last active: Nov 06 2011 07:07 PM
  • Joined: 08 Jan 2007
There might be possible "bug" in the DotNet code. When the WM_COPYDATA is received it should return TRUE, which the AHK code appears to be doing but the DotNet one does not (test executables). I might be wrong but something i noticed different when testing.

DataSize := (StrLen(Data)+1) * (!!A_IsUnicode + 1)


Yoink! :p