iPad/iPhone CoreMidi - Mackie Control Emulation (stop, play buttons) - controls

I faced with very hard problem.
My task is to emulate Mackie Control Pro - Stop and Play buttons.
I know that Note93 (A5) - it is stop encoder. Note 94 (A5#) this is Play encoder.
Basically I'm sending Note On 93, 127 velocity then Note Off 93, 0 velocity, and Logic receive stop message, but after this he just went crazy, he sending many midi messages (note on,off 93) in loop, when I click play, it went more crazy. ((((
That how I'm sending message to Network Session:
Touch Down
UInt8 midiData[] = { 0x90, 93, 127};
[midi sendBytes:midiData size:sizeof(midiData)];
Touch Up
UInt8 midiData[] = { 0x80, 93, 0};
[midi sendBytes:midiData size:sizeof(midiData)];
The most interesting that when I play not A5, A5# in ThumbJam app (for iPad/iPhone), it works good. The same in eyoControl app, it works. But when I play A5, A5# key in TouchOSC or TB MIDI Stuff or Midi Designer, etc - then Logic went again to loop. And in the Midi Monitor messages the same in all applications. CRAZY... I can't understand this ((
What the difference, all applications connected and working seems via CoreMidi.
p.s. with Ableton Live, Reason everething ok. Buttons works.

Found solution. Instead of sending Note Off, application should send note on but with zero velocity.
instead {0x80, keynumber, 0} use {0x90, keynumber, 0}

Related

What has changed? Wake Windows and turn on monitor from Windows API

I have an old C program for displaying caller ID called YAC. Fortunately, the author Jensen Harris provided the source.
15 years ago, I modified the source to turn on the monitor if the computer was awake but the monitor was off. The code below worked well, turning on the monitor and making the caller ID message visible on the screen.
// TG - add a call to turn on the monitor if it is sleeping.....
SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
Recently the behavior has changed (presumably a Windows update changed something)
Now when a Caller ID message should be displayed, the monitor turns on (as evidenced by the LED), but the screen remains black. The monitor remains in the black-screen condition for a few seconds, then turns off again.
What additional or different call is now required to cause Windows to activate the display and show the desktop? Possibly this could be forced by sending a mouse move, but is there a better way?
EDIT:
I have implemented the following additional code to press and release ESC. I was unable to find a good example of a relative mouse move of 1 pixel, so I used an example for keyboard. I will test and see if it is effective.
INPUT inputs[2];
UINT uSent;
// reference: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_ESCAPE;
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_ESCAPE;
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
EDIT2 - I can confirm this approach does work to cause the monitor to display video, but of course has the potential for side-effects as any keyboard or mouse action would. I would still be interested in learning of a pure API function that works to fully wake the system like SC_MONITORPOWER used to.

How to distinguish WM_MOUSE*** messages generated by touch pad from generated by mouse device?

I've tried GetMessageExtraInfo() mentioned here:
Detect if WM_MOUSEMOVE is caused by touch/pen
but it does not work - GetMessageExtraInfo() returns 0 for all mouse events generated by touch pad.
Tried it on notebook with integral touchpad and on desktop PC with external touch pad attached.
I also tried to use WM_TOUCH event with RegisterTouchWindow() and WM_GESTURE but they do not work either - I am not receiving neither WM_TOUCH nor WM_GESTURE events on the window.
Essentially what I need is to detect when finger is on and off touch pad. But it seems that WM_TOUCH or WM_GESTURE work only for touch displays but not for touch pads, for unknown reasons.
Any advice?
If you require being able to distinguish the input source, consider using WM_POINTER* messages instead of the older WM_MOUSE* messages. Note that this will require calling EnableMouseInPointer() to receive messages about devices the system considers a mouse (which is true for many basic touch-pads).
Unlike the WM_MOUSE* messages, where the wParam tells you the state of certain virtual keys, the WM_POINTER messages includes enough information to be able to track the input source. It is somewhat more complicated in that pointer messages do not provide separate messages depending on which button was pressed, but that information is at least still available.

Injecting to a DX game and make game idle

I have a DLL that I am injecting to DX games. In the DLL, I am disabling XInput, raw input and also subclass WndProc to filter a bunch of input messages like WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_INPUT etc. Disabling XInput with XInputEnable(FALSE) and register raw devices with RIDEV_REMOVE flag.
While it works great for some games, it doesn't work for all. Certain games still have mouse move/hover input and I can see hover state for some UI when I move over.
My question is what did I miss? Could the game be capturing input some other ways?
Thank you.
I can think of these possible ways the application may still be receiving mouse input:
It re-enables Raw Input notifications
A window other than you one subclassed is receiving the messages
It's polling GetCursorPos
Using the Windows HID API or other user-mode interface to access the mouse device
Hooking mouse events or windows message using SetWindowsHookEx
The are probably others, but these are all I can think of at the moment.

GetAsyncKeyState() fails to return state of keyboard/mouse, while WM_KEYDOWN messages seem to work fine

I'm writing a game where I use GetAsyncKeyState() for character control like WASD and mouse buttons, and the windows messaging system for menu stuff like text input and cursor control.
Every once in a while, my computer seems to get into this weird state where GetAsyncKeyState() doesn't return anything. It seems to be related to times when my game crashes. Once the computer is in this state, I don't know how to get it out unless I restart the computer.
The windows messaging system still works fine in this case- if I type the 'W' key, I still get a WM_KEYDOWN message and the letter can show in my menu system, but the following method, which normally works, will fail:
bool result = (GetAsyncKeyState(vkey) & 0x8000) != 0;
For all I know, this is being caused by an external program (such as Synergy+, which I use to share mouse/keyboard input between computers), however I haven't been able to prove this yet.
Whatever the cause, I don't want this problem to occur to an end user. Are there any techniques to diagnose and repair a state like this?
EDIT: Perhaps this is some kind of driver issue? I just noticed that when my computer gets in this state, my mouse no longer processes the shortcuts I've assigned to its extra buttons. I don't know enough about how all this works to know what to blame in a case like this.

Using control send on windows live messenger For auto typing text

Hi i want to make a sort of a bot for WLM,
But the normal controlsend in autoit wont work
the basic question is how can i send a text to the windows live messenger window Without activating it?
Example:
There is someone in WLM with the window active called "Joop" I do:
ControlClick("Joop","","[CLASS:DirectUIHWND; INSTANCE:2]","Left",1,322,507)
ControlSend("Joop","","[CLASS:DirectUIHWND; INSTANCE:2]","Hi Joop")
this doesn't work however when I do this
WinActivate("Joop","")
ControlClick("Joop","","[CLASS:DirectUIHWND;INSTANCE:2]","Left",1,322,507)
ControlSend("Joop","","[CLASS:DirectUIHWND; INSTANCE:2]","Hi Joop")
it does work however now its activated what i dont want.
there is a problem with the window the whole msn talk window is one window so no extra control to type in thats why i tried the contolClick on the coordinates of the typing screen without succ6
this is the summary.
Text:
Position: 0, 28
Size: 882, 607
ControlClick Coords: 282, 180
Style: 0x56000000
ExStyle: 0x00010000
Handle: 0x00190916
>>>> Mouse <<<<
Position: 1885, 557
Cursor ID: 0
Color: 0xFFFFFF
>>>> StatusBar <<<<
>>>> Visible Text <<<<
>>>> Hidden Text <<<<
CVoiceVideoAvatarHostWindow
does anyone know how to get something in that textfield without activating it (so it can run on background) and using a lame function like send.
OR how can i send a text to the windows live messenger window Without activating it
Thanks
Matthy
MSN is purposefully resisting automation. It's not a limitation of the Windows API. If your goal is to automate a MSN chat, you can do so either by directly sending the TCP packets, or by automating another application which supports MSN (Digsby, Pidgin, etc.) and which works better with automation.
By directly sending the TCP packets you are writing your own program, from scratch, which to the outside world behaves just as MSN. There are user-made documentation about the protocol. One that I have used in the past is here: http://www.hypothetic.org/docs/msn/notification/authentication.php but I am entirely unsure whether it is still up-to-date. If you are familiar with networking, TCP, packet capturing and replaying, then I do suggest going this route as it's the most stable, long-term approach. (And I think: The most fun.)
However, not all projects demand a stable and long-term approach. It seems to me like you were just messing with automating some of the applications you happened to have on your computer, and MSN is of course one of the more interesting ones. Microsoft decided that when they built the MSN client it should not be made easy for anyone to try and automate the application. I think this was mostly done to prevent spam. In the early days it worked, because other people hadn't yet publically documented the protocol. And thus anyone who wanted to spam now had to make a costly investment.
If you do decide to continue with automating the official MSN client, or any other application that resists automation, there are a few tricks that you can try:
ControlSend without specifying the control parameter (use empty string "")
ControlClick on the window with specifying coordinates with using empty string for control parameter again
Eventually, simply Send/MouseClick with optional BlockInput
There are a lot more combinations that you can try (especially ControlX functions) that sometimes miraculously will work, but remember that in the end they are all just window messages. You can do everything in automation with the _SendMessage function, provided you know what you're doing.
Certain designs and interfaces make it very difficult, if not virtually impossible, for AutoIt to tap into the interface to read control information. I would suggest either using the WLM protocol manually via your own client, or utilize a client that doesn't make screen grabbing the text hard or impossible.
Ok, maybe finally an answer... at least this test app I coded works as following:
Somewhere in the beginning of your script you have to set the state of your WLM to #SW_HIDE. Later when you try to do ControlXxxx-stuff you first set a variable on your active window. Now you can optionally block your input and activate your hidden window. It now works as you described above and afterwards you reactivate your last active window. Optionally undo the input block again.
That should solve your question with the least breaktime... you could play with your Mouse Cursor Style in the meantime to simulate some CPU load, so the block input is not too offending. But the action is so fast you won't even recognise it... (maybe it will swallow some keypresses though)
Give it a try!
Opt("WinTitleMatchMode", 2)
#include <GuiConstantsEx.au3>
$GUI = GUICreate("Beispiel HiddenApp", 392, 323)
$ed = GUICtrlCreateEdit("nix", 1, 1, 390, 321)
GUISetState()
Sleep(1000)
GUISetState(#SW_HIDE, $GUI)
WinActivate("SciTE")
Sleep(1000)
BlockInput(1)
$act = WinActive("[ACTIVE]")
WinActivate($GUI)
ControlClick($GUI, "", $ed, "primary", 1, 50, 50)
ControlSend($GUI, "", $ed, "before{Alt}{Tab}after")
WinActivate($act)
BlockInput(0)
Sleep(1000)
GUISetState(#SW_SHOW, $GUI)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case Else
;;;
EndSwitch
WEnd

Resources