I'm making a gym management web app that handles sign-ins. Members have a barcode on a tag that they scan when they arrive to the gym.
I've heard that most barcode scanners simply act as a keyboard. This would require the scanning-in page to be open and in the foreground when a barcode is scanned.
If it's just a keyboard, how would I send the barcode scanner input to a single background process running on the computer, and have it ignore by all processes that may be in focus?
You're right that most scanner can support HID in keyboard emulation, but that's just the start.
If you want to have a bit more control over the data you can use a scanners that support the OPOS driver model.
Take a look at Zebra's Windows SDK to have a overview of the things that you can do. It may be a better solution than try to steal the barcode data coming in the OS as a keyboard entry to the foreground app.
Disclaimer: I work for Zebra Technologies
Other Barcode scanner vendor support a similar driver model.
I found an interesting post with a simple solution:
On the form constructor
InitializeComponent():
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form1_KeyPress);
Handler & supporting items:
DateTime _lastKeystroke = new DateTime(0);
List<char> _barcode = new List<char>(10);
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
// check timing (keystrokes within 100 ms)
TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
if (elapsed.TotalMilliseconds > 100)
_barcode.Clear();
// record keystroke & timestamp
_barcode.Add(e.KeyChar);
_lastKeystroke = DateTime.Now;
// process barcode
if (e.KeyChar == 13 && _barcode.Count > 0) {
string msg = new String(_barcode.ToArray());
MessageBox.Show(msg);
_barcode.Clear();
}
}
Credits: #ltiong_sh
Original post: Here
Use RawInput API (https://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard#_Toc156395975) and check device ID for incoming keystrokes. Different devices have different IDs. You can also block keystrokes from scanner from reaching your application and interfering with input fields.
One thing you might want to add is option for user to identity which device is used as a barcode scanner. I did it by asking user to test-scan barcode with scanner on first application startup or in settings.
Works with any barcode scanner which outputs keystrokes.
Related
I'm trying to support web-bluetooth to connect to my devices and perform a simple task (such as playing LED).
However, the device information showed on the scanning dialog when calling navigator.bluetooth.requestDevice is not so clear. It only shows the device name and a random (?) hex string.
The problem here is all my devices have the same name (AWESOME_LED), thus it's not easy for the user to select the correct LED if all scanning items show the same device name info. As far as I know, we can not custom to add more info showing on the scanning dialog.
I come up with a new solution that is changing the device name to unique for each LED with the format AWESOME_LED + [uniqueid] e.g AWESOME_LED1, AWESOME_LED2, AWESOME_LED3 so that the user can distinguish one from the others.
My question are:
Is there any alternative solution without making the device name unique?
If not, is there any problem / rejection / limitation from Apple or Google for my current app on App Store / Google Play by not using the same device name for all devices? I have been investigating it at Apple forums / Accessory Design Guidelines and looks like there are no problems, just to make sure if anyone has faced trouble from Apple / Google.
Thanks for your help.
Scanning dialog
My question are:
Is there any alternative solution without making the device name unique?
The browser prompt is not customisable yet. One solution you highlighted already is to make your LED device name unique. If you're able to control the device, why not having one AWESOME_DEVICE name and a GATT characteristic you can write to that controls individual LED colors. Maybe something like:
const device = await navigator.bluetooth.requestDevice({
filters: [{ name: "AWESOME_DEVICE" }],
});
const server = await device.gatt.connect();
const service = await server.getPrimaryService(0x1234); // Your service UUID
const characteristic = await service.getCharacteristic(0x5678); // Your characteristic UUID
// Set LED #1 to red color.
await characteristic.writeValue(
new Uint8Array(/*ledIndex=*/ 1, /*r=*/ 255, /*g=*/ 0, /*b=*/ 0)
);
If not, is there any problem / rejection / limitation from Apple or Google for my current app on App Store / Google Play by not using the
same device name for all devices? I have been investigating it at
[Apple forums][1] / [Accessory Design Guidelines][2] and looks like
there are no problems, just to make sure if anyone has faced trouble
from Apple / Google.
None that I'm aware of.
I am developing an WP8 app witch uses background audio agent. i have taken the background audio players sample. i have added the following method to audioplayer.cs
public static void playTrackAtIndex(int index)
{
currentTrackNumber = index;
BackgroundAudioPlayer.Instance.Track = _playList[currentTrackNumber];
}
after it is called the song at the specified index (let's say 5) will play, but when i pres skipnext in my ap or in the UVC currentTrackNumber is 0!. Please, any help is apreciated
it turns out you don't have any control over the lifecycle of the background audio agent, so at any time it may be killed and then instanced by the foreground app or the Background audio player. So the only whey to make the agent work is to design it as it will always be killed and instanced (use sql lite or files with a lock, or always check what backgoundaudioplayer is playing when your agent is called, so your agent will "remember" where it was before getting killed
I am making a race game in Unity with Unityscript and I made a steer with the lego mindstorms EV3 robot. I let te robot send information by bluetooth to the game, but I can't find how I can do that.
I already have the code for the bluetooth running and working a C#, but know I need to know how to translate it to unityscript.
I already tried to find it on google, but I only seem to get some software to hack the robot, but not to make code in unityscript for connecting the steer.
Under here stands the C# code:
// EV3: The EV3Messenger is used to communicate with the Lego EV3.
private EV3Messenger ev3Messenger;
// EV3: Create an EV3Messenger object which you can use to talk to the EV3.
ev3Messenger = new EV3Messenger();
// EV3: Connect to the EV3 serial port over Bluetooth.
// If the program 'hangs' on a call to ev3Messenger.Connect,
// then your EV3 is not paired with your PC yet/anymore.
// To pair: Remove the EV3 from the Windows Bluetooth device list and add it again.
ev3Messenger.Connect("COM3"); // Hardcoded serial port: put the serial port
// of the Bluetooth connection to your EV3 here!
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// Unload any non ContentManager content here
// EV3: Disconnect
if (ev3Messenger.IsConnected)
{
ev3Messenger.Disconnect();
}
}
// EV3: send Brake message to mailbox with name "MakeNoise"
if (ev3Messenger.IsConnected)
{
ev3Messenger.SendMessage("MakeNoise", "Brake");
}
// Game can be controlled by both the arrow keys and the Steer, gas and brake paddle of the connected EV3
UpdatePaddlePositionUsingKeys();
UpdatePaddlePositionUsingEV3();
base.Update(gameTime);
}
///Steer update
private void UpdatePaddlePositionUsingEV3()
{
if (ev3Messenger.IsConnected)
{
// EV3: Receive a new command from mailbox "COMMAND" of the EV3
// and use it to change the direction of the paddle or to exit the game.
EV3Message message = ev3Messenger.ReadMessage();
if (message != null
&& message.MailboxTitle == "Command")
{
if (message.ValueAsText == "")
{
}
{
ev3Messenger.Disconnect();
Exit();
}
}
}
}
I hope that you know where I can find how I can do this or even help me further.
If you want the original code for a small pong game where I got my inspiration from, just comment it.
I hope you can help me.
Here are some useful links with documentation on the EV3 firmware :
Firmware Documentation
LMS2012 Documentation
HDK/SDK
In particular, you need to learn how to send direct commands and then use that to read and write bluetooth mailboxes.
For communicating with the COM port itself using javascript, just do a little searching. For example, I found this SO question which has quite a few different ideas.
As part of c4ev3, We open-sourced our EV3 uploader, which can also be used to send connection-agnostic commands to the device.
Here is how you would move the motors in Perl (Complete version):
use IPC::Open2;
print open2(\*EV3OUT, \*EV3IN, "ev3 tunnel") or die "couldn't find: %!";
print EV3IN "0900xxxx8000 00 A3 00 09 00\n";
print EV3IN "0C00xxxx8000 00 A4 00 09 50 A6 00 09\n";
This would probe for an EV3 accessible over USB, Bluetooth or WiFi and connect to it, then send the direct messages associated with turning the motors. For more information on the direct commands protocol check out LEGO's Communication Developer Manual and David Lechner's answer.
Alternatively, you can write a C program for the EV3 with c4ev3 and communicate with that. That way you got a nicer looking C-API you can use.
I was wondering how I can select the output device for audio in directshow. I am able to get available audio output devices in directshow. But how can I make one of these to be audio output device. Its always going for the default audio device. I want to be able to output audio on my choice of device. I have been struggling through google but couldn't find anything useful. All I could get was this link but it doesn't really solve my problem.
Any help will be really helpful for me.
First off, if you're not using DirectShow .NET (DirectShowLib), get that here: It serves as a (very complete) interface between unmanaged DirectShow and C#
What follows is a pretty simple example of how to play an audio file, to the desired audio device
using DirectShowLib;
private IGraphBuilder m_objFilterGraph = null;
private IBasicAudio m_objBasicAudio = null;
private IMediaControl m_objMediaControl = null;
private void playAudioToDevice(string fName, int devIndex)
{
object source = null;
DsDevice[] devices;
devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory);
DsDevice device = (DsDevice)devices[devIndex];
Guid iid = typeof(IBaseFilter).GUID;
device.Mon.BindToObject(null, null, ref iid, out source);
m_objFilterGraph = (IGraphBuilder)new FilterGraph();
m_objFilterGraph.AddFilter((IBaseFilter)source, "Audio Render");
m_objFilterGraph.RenderFile(fName, "");
m_objBasicAudio = m_objFilterGraph as IBasicAudio;
m_objMediaControl = m_objFilterGraph as IMediaControl;
m_objMediaControl.Run();
}
It is up to user to manage audio devices and choose a primary device (such as via Control Panel applet). You can find ways to switch devices programmatically in Windows XP, however in Vista+ it is impossible without interactive user action by design.
See also Larry's answer here: How to change default sound playback device programmatically?
UPDATE: The mentioned above refers to modifying system configuration trying to alter default audio output device. An application is however not limited to default device only. Instead, it can enumerate available devices (see Using the System Device Enumerator + CLSID_AudioRendererCategory) and then create an instance of renderer for specific device with BindToObject call. From there on, it is a regular filter, just bound internally to device of interest.
I'm working on a online quiz client where we use a dedicated custom-made linux distro which contains only the quiz client software along with text editors and other utility software. When the user has started the quiz, I want to prevent him/her from minimizing the window/closing it/switching to the desktop or other windows. The quizzes can be attempted using only the mouse, so I need the keyboard to be completed disabled for the period of the quiz. How could I do this, using Qt or Mono? I'm ready to use any low-level libraries/drivers, if required.
You may use QWidget::grabKeyboard and QWidget::grabMouse, and please note the warning in comments:
Warning: Bugs in mouse-grabbing
applications very often lock the
terminal. Use this function with
extreme caution, and consider using
the -nograb command line option while
debugging.
Have you looked at XGrabKeyboard? That should do a global grab of the keyboard.
Did you try to use EventFilter ? You have the opportunity to block all the events related to, as instance, keypress...
More information here : http://qt.nokia.com/doc/4.6/eventsandfilters.html
Hope it helps !
Something like :
bool MyWidget::event(QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
return true;
}
return QWidget::event(event);
}