DirectInput console application - c++

I'm working in C++ in Windows and I need to deal with an input device with force feedback. I found out that one solution could be to use DirectInput and so I start looking at that.
FIRST QUESTION: any suggestions on other ways for dealing with force feedback devices? (Win32 app, not UWP)
Coming back to DirectInput
The reference starting point I have got in my mind is the DirectInput Samples, in particular the FFconst example where a constant feedback force is applied to the first device axis according to a value grabbed from a simple GUI. In my case what I want to achieve is having a simple console application where I set a constant force according to a value grabbed from the standard input.
The basic steps for using the DirectInput API, according to the samples and the documentation, are:
create direct input device calling DirectInput8Create;
look for devices calling EnumDevices filtering devices and limiting scope to the enumeration according to what you are looking for (in my case I'm filtering for looking only in DI8DEVCLASS_GAMECTRL devices and limiting the scope to DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK);
set data format for the selected device(s) calling SetDataFormat in order to be able to acquire the device;
set the cooperative level for the device(s) calling SetCooperativeLevel once again in order to acquire the device;
use the device...
Now, all goes well until we encounter the SetCooperativeLevel mehtod since it needs as input a HWND window handle "to be associate to the device" and which "must be a valid top-level window handle that belongs to the process". Since I'm writing a console application I need to find a valid HWND pointer: I sorted the problem out following this suggestion. Anyway, the HWND pointer I get in that way seems not to be a valid window handle since I get a E_HANDLE error, as I would specify nullptr as argument. I found out that specifying the argument through the call of GetTopWindow allows not to get the invalid handle error. However I'm not able to acquire the device and I get the DIERR_OTHERAPPHASPRIO error, which is nothing more than E_ACCESSDENIED. I found that it seems someone use to treat that error in the same way the DIERR_INPUTLOST error is treated, i.e. re-acquiring the device in a while loop as shown in the Joystick direct input sample in the UpdateInputState function. Anyway trying this I'm not able to exit that loop, i.e. the device device keep being denied.
That said I end up with the
SECOND QUESTION: how to use the DirectInput API in a console application or inside a DLL? (Win32) In case of a console application I'd like to understand why the steps I've done don't work, and in case of a DLL I'd like to know if anyone has an idea on which HWND pointer could be used.

Microsoft provides a function to get a console application's window for uses like this.
HWND WINAPI GetConsoleWindow(void);

Related

Associate HID Touch Device with Pnp Monitor

I am developing a tool that displays a status about various hardware components on a system we use at work. Currently, we have 16 touch screen monitors (all by 3M) plugged in to a Windows 10 box. I need to verify that any given monitor has an associated touch screen recognized by windows. This is to assess the system for any hardware malfunctions i.e. bad cable, bad USB port, bad Monitor, etc. We see this more than we would like to admit, usually where a monitor's display will be working fine but the USB controller on either end drops out and needs to be reset by unplugging/plugging back in
Unfortunately my code posting will be limited due to work constraints.
I can enumerate all of the monitors plugged in to the system via winapi's EnumDisplayDevices and EnumerateDisplayMonitors. I am able to build a list of all the HID touch screen devices using HIDApi.
From here I have no direction on where to go to link these two things together, if it is even possible. My first thought was the HID device information should have some sort of identifier shared by the results of calling the EnumDisplayDevices and EnumerateDisplayMonitors, but I have not found this to be the case. Another possibility would be to compare the coordinates/size of a monitor to a region that one of the touch controllers is responsible for. Again, not sure if that is possible.
In short, is there a way to associate a Touch device with it's corresponding monitor via c++?
I think you were just lucky that this driver suffix matched your monitor configuration. In my Windows 10 multi-monitor setup I get wrong displays when I look them up with this number in the driver entry as you described.
A reliable way for associating a HID device with a display seems to be:
Call GetRawInputDeviceList() to obtain the HID devices
Call GetRawInputDeviceInfo() with RIDI_DEVICEINFO to determine Usage and UsagePage
Call GetRawInputDeviceInfo() with RIDI_DEVICENAME to get a device string in the form \\\\?\\HID#VID_0EEF&PID_7200&Col01#6&152cc7f9&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Query the registry for the mapping table at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wisp\Pen\Digimon and look up the display device name. In my case the HID names are all prefixed with 20- there but the remaining part seems to match the name queried by GetRawInputDeviceInfo() exactly. As a fallback method in case there is no match, I also parse the middle part as Clay Brooks described in his answer.
Call EnumDisplayDevices() with a null pointer for lpDevice and 0 for dwFlags in a loop until the function returns zero.
Within each loop iteration, call EnumDisplayDevices() again with the current device as lpDevice and EDD_GET_DEVICE_INTERFACE_NAME for dwFlags and observe that it returns a DeviceID in the form \\\\?\\DISPLAY#ELO2243#5&607b301&0&UID24833#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
Loop until a HID <-> display match is found and take the DeviceName returned by the "outer" EnumDisplayDevices() call which should be something like \\.\DISPLAY3
After the suggestions in the comments and looking deeper into the registry, I've found a way to link Touch controllers to a monitor.
Using HIDApi, you can poll the system and find a list of all the Touch Controllers you need to monitor. I filtered by the VID of the monitors we are using. A sample return value for the path looks something like this:
"\\?\hid#vid_0596&pid_0520&col02#8&33d9e616&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
The bold part can be used to link to the entries in HKLM/Software/Microsoft/Wisp/Pen/Digimon. An example entry is this:
"\\?\HID#VID_0596&PID_0520&Col03#8&33d9e616&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}" "\\?\DISPLAY#MSY1C2B#7&1083071f&0&UID524#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}"
The first bold matches the data found through HIDApi and the second set of bolding, the monitor name and a UID, is listed in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY. Under here you can use the combination of monitor name and UID to find the Driver entry. Below is a sample driver entry:
{4d36e96e-e325-11ce-bfc1-08002be10318}\0010
The last bold number can then be used to match up with a DeviceID returned from EnumDisplayDevices(). Below is a sample DeviceID:
"MONITOR\MSY1C2B\{4d36e96e-e325-11ce-bfc1-08002be10318}\0010".
Then you can use this bolded section to match up to names of monitors returned from EnumDisplayMonitors().

Windows C++ - Need Ideas - Combining Mouse Input and Raw Input in the same app/window

I'll try to keep this as short as possible.
I have an app that has worked for years with a single mouse input. I am looking to incorporate the ability for my users to use other forms of input, such as interactive projectors, touch devices, or pretty much anything that provides WM_INPUT messages when you register for them.
The general idea I had was I would have a list of Vendor IDs and/or Product IDs that I would handle with Raw Input (which provides VID/PID, device handle and other information) for each message (WM_INPUT) received. Any devices that are not handled in the Raw Input code would be handled in the Mouse Input code (WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_RBUTTONDOWN, etc).
Ideally, I would be able to leave all of my Mouse Input code as is, or close to it. This way, if a user plugs in two mice, or a mouse and an unsupported pointing device (meaning my Raw Input code doesn't handle it based on VID/PID) the devices would both use the same system cursor. Any device that is known by my Raw Input code would be given separate cursors that exist only within my app.
The problem is simple: Mouse Input does not provide any information about the source of the message (such as WM_MOUSEMOVE, etc). Knowing that the message originated from touch helps (I have this implemented) but is definitely not enough. I need some kind of unique identifier. If I could know the source of the Mouse Input, I could only handle Mouse Input from devices that aren't on my list of known devices, and I could only handle Raw Input that are on my list of known devices.
Unfortunately, I cannot seem to find a way to achieve this.
Any ideas?
Thanks for your time sorry for the lengthy post.
TL;DR - Can you identify the source of Mouse Input (not Raw Input) in Windows? Determining whether or not the source is touch is not enough information, I need some kind of unique identifier.
Mouse Input - http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877(v=vs.85).aspx
Raw Input - http://msdn.microsoft.com/en-us/library/windows/desktop/ms645536(v=vs.85).aspx
I don't know of any API for getting some sort of device id after the fact.
You could use the fact that WM_INPUT messages come before all other input messages, and when you handle WM_INPUT you could use GetRawInputDeviceInfo and a hash of the name returned by RIDI_DEVICENAME to use as a unique id. Or, you might be able to use the hDevice member of the RAWINPUTHEADER structure.
edit2: The answer to this question is "Not possible", you can't do it. Don't bother trying, but if you do and I'm wrong please explain. The fact of the matter is you can't rely on Windows to provide messages in any particular order consistently, which is what I was attempting to do. This bit me big time. Either use raw input (WM_INPUT) or use mouse messages (wm_mouse) don't try to combine the two somehow.
I never really got the answer I wanted, but I got something that works so I thought it was worth sharing.
I am working on a huge assumption, as I can't find any documentation from Windows to support this assumption (and probably wouldn't really even trust it if I found documentation from windows). To my understanding, when a mouse event is generated at the lowest level it comes through the system as a raw input message first (WM_INPUT). After the WM_INPUT message is posted, the OS gets the message and applies the ballistics and whatever else it does before a WM_*MOUSE* message is posted. The huge assumption is that this process is serial in that it is always 1 WM_INPUT message followed by 1 WM_*MOUSE* message in the queue.
With this assumption I am working with the following:
When an input message is received, store all relevant information about the source device as the "current input information"
When a mouse message is received, process it using the "current input information" as the source of the mouse message
This allows me to use n inputs in my application independently.
I'd also like to add that per Brandon's suggestion I am using the hDevice member of the RAWINPUTHEADER structure to uniquely identify each input. Since a unique device can have multiple inputs, I have yet to come up with a good way of uniquely identifying each device. VID/PID doesn't work because you can have 2 of the exact same device with multiple inputs each plugged in. I'm still working on this, see Windows HID Device Name Format
Please let me know if anyone would like me to elaborate!
edit: not marking this as the answer since I believe the correct answer is "Not possible"

How to make windows media player go to previous song in playlist?

I am writing a simple Windows app in c++, that will be able to send commands to windows media player. My problem is that I want my app to move to the previous song in the playlist.
IWMPControls::previous() seems to do the job, but its behavior differs from what is written in msdn. In fact this function rewinds current media to the beginning and then (if current position is less than 2-3 seconds) it switches to the previous song.
I would like to implement two different buttons (please, don't ask me why :)) - one for rewinding to the beginning, and one - to moving to previous song. Is there any easy way to do this through IWMPControls (or any other WMP-related COM interface)?
p.s. I could handle this if I could get the position (index) of the current song in the list. But as far as I read MSDN, it seems to me that there is no easy way to get the current item index from playlist...
I think, the easiest way to control a WMP application from outside is by sending messages. So, you stick to basic WinAPI and you have to get your WMP window handle.
After you've retrieved it's handle, it's easy to transfer certain commands to it using plain Windows messages.
Basically, you just invoke SendMessage to retrieved earlier HWND wmp_windows_handle. The control messages are generally a WM_COMMAND messages where a wParam specifies what you want your player to do.
For example, Stop command can be transfered if you specify 0x00004979 as your wParam.
Stick to Google or Windows Media Player SDK for more specific information on these command codes and you'll definitely find what you are looking for.
Also to mention, I'm not proficient with that IWMPStuff you described above, so if I were you and I wanted a concrete answer about it, I would probably refer to it's SDK.
Well, I think I figured it out. You can force the previous song by 1) first calling IWMPControls::put_currentPosition(0.0), 2) then calling IWMPControls::previous().
There can be some problems, as it seems that some time must pass between 1) and 2). The obvious solution is to use ::PostMessage() inside your program (NOT ::PostMessage to WMP), so you make step 1), then PostMessage and, while processing your message, make step 2).

Access to external window handles

I am having a problem with the program I am currently working on. It is caused by the increased security in vista/Windows 7, specifically the UIPI which prevents a window with a lower integrity level 'talking' to a higher one.
In my case, i am wanting to tell the window with a high Integrity level to move into our application, It works flawlessly on XP or windows 7 with the security off.
I have tried setting the HWND of the higher IL window directly, rather than using the findwindow() function, this works fine but the program then fails when trying to move it or generally interact with it. The windowhandle is saved by the app to be embedded and read by the app running at a lower IL.
I have also tried setting UIaccess in the manifest to TRUE and digitally signing the program but no luck.
Any ideas on how to solve this problem?
thanks.
Just thought i would follow this up for anyone who also struggled as I have finally found a way to do this.
IL = Integrity Level.
I had 2 apps, highIL.exe and lowIL.exe, the highIL wanted to find the lowIL.exe window, set it as a child window and move it into a zone created for it on the highIL.exe. This was blocked by the UIPI in vista+.
In the end i used the ChangeWindowMessageFilter method in vista and the ChangeWindowMessageFilterEx in Windows7, both found in the user32.dll. These functions allow you to poke a hole in the UIPI to allow messages that you want through.
I created a few custom messages using RegisterWindowMessage function, I used this function to register the method in both highIL and lowIL applications, the line looked a little like this:
const UINT MY_MOVEINTWINDOW_MSG = RegisterWindowMessage(_T("MyMsg.MoveWindow"));
The lowIL.exe is then able to send these messages to the highIL.exe window without them being blocked. Then it was a case of just simply adding and writing message handlers.
This method will only work if you have access to both the high and low IL.
The MSDN also has a working example of the ChangeWindowMessageFilterEx function on there Website

Detecting multiple launches of a Windows application

What's the approved way to handle second, third, etc launches of application in Windows (C++) application? I need the running (first) instance to take some special action (pop up a dialog) in this case, but for the secondary instances to terminate.
On Mac, AppleEvents sends you a 're-open' message in this scenario. Mozilla on Windows uses DDE to check for an existing instance and pass the command line through. It feels like a pretty nasty solution, all the same.
The windows way is to open a named mutex and, if you can acquire it, it means you're the first instance, if not, there is another one. At this point you can register a windows message (the function is literally RegisterWindowsMessage) which gives you a WM_ msg you can send to all windows and only your app would know to catch it, which allows you to tell your initial copy to open a dialog box or w/e.
How to limit 32-bit applications to one instance in Visual C++
"The method that is used in this article is the one that is described in MSDN under the WinMain topic. It uses the CreateMutex function to create a named mutex that can be checked across processes. Instead of duplicating the same code for every application that you will use as a single instance, the code that you must have is in a C++ wrapper class that you can reuse across each application."
SendMessage Function
"Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message."
"Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication."
RegisterWindowMessage
"The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages."
On windows there is not really solution for that at least not out of the box.
You can use mutex to do such things, basically the app check for the mutex at startup create it if it doesn't exist.
There is one issue with CreateMutex method that you might need to consider - the named mutex might have been created by a third party. Now, most of the time, this won't be an issue, there would be no reason for someone else to block your application. However, if you're making a program that does something important, it may be an issue. Consider, if your program was a virus scanner, a virus could disable it by creating the mutex.
Usually, CreateMutex should do the job, but you should be aware of the limits of this method.