ZBar processor and delphi - delphi

Ok so I have been trying to get bar code scanning to work in a delphi application for the last 3 weeks now. Ive been directed to this example but that example uses other librarys like imagemagika and is a console application. I am looking for a vcl forms application.
Here is some code I have written to try and see if I can get the ZBar processor to work in delphi :
// Create Processor
processor := zbar_processor_create(0);
zbar_processor_set_config(processor, ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
// Initialize processor
zbar_processor_init(processor, {what do I put here ?}, 1);
// Setup a callback
{I dont know what do here}
// Enable preview window
zbar_processor_set_visible(processor, 1);
zbar_processor_set_active(processor, 1);
This code is based on a example in C that I found here : https://github.com/ZBar/ZBar/blob/master/examples/processor.c
as well as the documentation over here :
http://zbar.sourceforge.net/api/zbar_8h.html#c-processor
The zbar window opens but it does not show the video feed because I parsed nil as a paramater in the initialize step. In the example they have this C code but I have no idea what it means :
const char *device = "/dev/video0";
/* initialize the Processor */
if(argc > 1)
device = argv[1];
zbar_processor_init(proc, device, 1);
If I parse '/dev/video0' instead of nil the video feed still doesn't show. So I guess my question is what do I need to parse in zbar_processor_init() function ?
I also dont know how to set up a callback function that will be called once a result is found. How would I go about doing this ?
Thanks in advance,
Kobus

argc is the number of parameters passed in the command line and argv fetches them. dev/video is linux style device. Try con:
zbar_processor_init(processor, 'con:', 1)
Con: is the console. Com1: serial port 1, Aux: auxiliary port - probably usb, Prn: the printer Lpt: the line printer.

Related

Trying to read the contents from strstream causes access violation

I am trying to read the contents of an ostrstream using the str (). While trying to do so, i always come across access violations and my application crashes. Is there a way to read from strstream without causing stream errors?
I am working on a legacy project built on Borland C++. I am presently using Borland C++ v5.02 for building my project. Since the code is vast and scattered over a large number of files, I am unable to paste the code here. However, I will try to highlight my use case.
ps is the stream which is being used throughout the project to print receipts. I need to get the receipt data from this strstream without breaking the code.
string str = ps.pStr->str ();
ps.Pstr->rdbuf ()->freeze (0);
ps << EndJob;
The last line causes access violation
You missed set null in the end of the buffer.
Before any call to str() that uses the result as a C string, the buffer must be null-terminated, typically with std::ends.

MIDIYOKE in Delphi 2006

I am working with application in delphi. I need to use MIDIYOKE to send output from my application to another application. The second application is Virtual piano keyboard.
I installed all the packages and got MIDI components in the delphi.
I tried using MidiOutputPort1 and MidiInput1 components.
I tried playing one MIDI.The code is as follows:
procedure TForm3.Button1Click(Sender: TObject);
var
outputPort : TMidiOutputPort;
begin
outputPort := TMidiOutputPort.Create (Nil);
try
outputPort.PortId := -1;
outputPort.Active := True;
outputPort.PatchChange(0, 127, 0); // Gunshot
outputPort.NoteOn (1, 20, 127); // Play note at full volume
Sleep (1000);
outputPort.NoteOff (0, 60, 0);
finally
outputPort.Free
end
end;
I wanted to estalish connection between my application and Virtual piano keyboard.How to use MidiOutputPort1 and MidiInput1 for the connection between the two.
If both applications support MIDI sync you can use MIDI syncing. In that case MIDIYOKE is the master and Vpk is the slave. Syncing is handled by the following commands:
mc_MIDI_Timing_Clock = $F8;
mc_MIDI_Start = $FA;
mc_MIDI_Continue = $FB;
mc_MIDI_Stop = $FC;
I used it in the far past, so my knowledge is a bit rusty. What I can gather from my code is that it works as follows: Set the slave in the slave/sync receive/whatever it's called mode. Next send $FA to the channel of your choice. Some (not all) slaves require you to listen to specific channels.
At each clock tick send $F8 first. Next send the messages, preceded by the $FB message (both data bytes zero). When you're ready send $FC.
I think you should put the port number of one of your yoke ports in the portid property.
To know which id to use, you'll have to enumerate the available ports, because the id's can change if you add hardware, or if you change your midi yoke configuration.
Therefore, to remember which ports were chosen by the user, you need to store the device name, and hope that the user doesn't rename its devices :)
Let me know if this helps you enough to be able to continue your work; otherwise i'll dig up some old code that does what you're attempting to do.

Help embedding FSI

Starting here - Embedding F# interactive - I've been trying to embed FSI in my application.
However, I'm getting weird stuff back from StandardOutput.
for example, in standard FSI, if I send this:
let a = 3;;
I get this back:
[empty line here]
val a : int = 3
[empty line here]
> |
(with Pipe representing the input position)
But if I send let a = 3;; to StandardInput, I get this back on StandardOutput:
>
val a : int = 3
|
Has anyone else tried this? Is there something I'm doing wrong, and if not is there any way to work around this? None of the things I've tried so far work, and before I try the 'worse' thing I can think of (set a timer after sending stuff, add the > myself on timeout), I'd like to know if there is a better way!
When embedding F# Interactive, Visual Studio uses the --fsi-server:<some value> parameter.
As far as I know, this does two things:
Changes the way output is printed (instead of printing >, it prints SERVER-PROMPT> on a separate line, so it should be easier to remove it from the output and detect state when input is expected)
It also starts some .NET Remoting channel that you can use to stop execution of commands in F# Interactive (e.g. if it runs into an infinite loop) and it can also provide some completion information.
The F# Interactive pad in MonoDevelop F# plugin uses the flag (see source code on GitHub). I think it works mostly right, but I believe it sometimes prints additional \n in the output.

Sending the return key to an emulated console application

I'm using delphi to add an graphical interface to a console application.
The problem is when the console application asks for input.
I would normally type in my input and press enter to make it accept my string, but I don't know how to do this.
I'm using this library as a "wrapper" over the console application, it uses pipes for the input and output streams.
http://koders.com/delphi/fidDB05C6361540F62D532FC7C960D4111CE3AAEDB3.aspx?s=proxy
I've tried things like WriteToConsoleApp(#04); to send an EOT, which is Control-D. This would normally work but in this case it doesn't do anything.
I've also tried WriteToConsoleApp(#13); WriteToConsoleApp(#13#10);, but none of these solutions work.
If you have any advice I would be grateful.
You can use SendMessage or PostMessage function to send string/key to console application.
For example;
SendMessage(WindowHandle, WM_CHAR, Ord('A'), 0);//sends 'A' to the window
or
PostMessage(WindowHandle, WM_KEYDOWN, VK_RETURN, 0);//sends Return to the window

Find out what process registered a global hotkey? (Windows API)

As far as I've been able to find out, Windows doesn't offer an API function to tell what application has registered a global hotkey (via RegisterHotkey). I can only find out that a hotkey is registered if RegisterHotkey returns false, but not who "owns" the hotkey.
In the absence of a direct API, could there be a roundabout way? Windows maintains the handle associated with each registred hotkey - it's a little maddening that there should be no way of getting at this information.
Example of something that likely wouldn't work: send (simulate) a registered hotkey, then intercept the hotkey message Windows will send to the process that registered it. First, I don't think intercepting the message would reveal the destination window handle. Second, even if it were possible, it would be a bad thing to do, since sending hotkeys would trigger all sorts of potentially unwanted activity from various programs.
It's nothing critical, but I've seen frequent requests for such functionality, and have myself been a victim of applications that register hotkeys without even disclosing it anywhere in the UI or docs.
(Working in Delphi, and no more than an apprentice at WinAPI, please be kind.)
One possible way is to use the Visual Studio tool Spy++.
Give this a try:
Run the tool (for me, it's at C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\spyxx_amd64.exe or you can download it). Note: there is spyxx.exe (32-bit version) and spyxx_amd64.exe (64-bit version) - if you don't see anything in 64-bit use the 32-bit version (ie.catches messages only in same architecture)
In the menu bar, select Spy -> Log messages... (or hit Ctrl + M)
Check All Windows in System in the Additional Windows frame
Switch to the Messages tab
Click the Clear All button
Select WM_HOTKEY in the listbox, or check Keyboard in Message Groups (if you're OK with more potential noise)
Click the OK button
Press the hotkey in question (Win + R, for example)
Select the WM_HOTKEY line in the Messages (All Windows) window, right click, and select Properties... in the context menu
In the Message Properties dialog, click the Window Handle link (this will be the handle for the window that received the message)
Click the Synchronize button on the Window Properties dialog. This will show the window in the main Spy++ window treeview (if it's windows itself or some popup application it shows nothing).
On the Window Properties dialog, select the Process tab
Click the Process ID link. This will show you the process (In my Win + R case: EXPLORER)
Your question piqued my interest, so I've done a bit of digging and while, unfortunately I don't have a proper answer for you, I thought I'd share what I have.
I found this example of creating keyboard hook (in Delphi) written in 1998, but is compilable in Delphi 2007 with a couple of tweaks.
It's a DLL with a call to SetWindowsHookEx that passes through a callback function, which can then intercept key strokes: In this case, it's tinkering with them for fun, changing left cursor to right, etc. A simple app then calls the DLL and reports back its results based on a TTimer event. If you're interested I can post the Delphi 2007 based code.
It's well documented and commented and you potentially could use it as a basis of working out where a key press is going. If you could get the handle of the application that sent the key strokes, you could track it back that way. With that handle you'd be able to get the information you need quite easily.
Other apps have tried determining hotkeys by going through their Shortcuts since they can contain a Shortcut key, which is just another term for hotkey. However most applications don't tend to set this property so it might not return much. If you are interested in that route, Delphi has access to IShellLink COM interface which you could use to load a shortcut up from and get its hotkey:
uses ShlObj, ComObj, ShellAPI, ActiveX, CommCtrl;
procedure GetShellLinkHotKey;
var
LinkFile : WideString;
SL: IShellLink;
PF: IPersistFile;
HotKey : Word;
HotKeyMod: Byte;
HotKeyText : string;
begin
LinkFile := 'C:\Temp\Temp.lnk';
OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL));
// The IShellLink implementer must also support the IPersistFile
// interface. Get an interface pointer to it.
PF := SL as IPersistFile;
// Load file into IPersistFile object
OleCheck(PF.Load(PWideChar(LinkFile), STGM_READ));
// Resolve the link by calling the Resolve interface function.
OleCheck(SL.Resolve(0, SLR_ANY_MATCH or SLR_NO_UI));
// Get hotkey info
OleCheck(SL.GetHotKey(HotKey));
// Extract the HotKey and Modifier properties.
HotKeyText := '';
HotKeyMod := Hi(HotKey);
if (HotKeyMod and HOTKEYF_ALT) = HOTKEYF_ALT then
HotKeyText := 'ALT+';
if (HotKeyMod and HOTKEYF_CONTROL) = HOTKEYF_CONTROL then
HotKeyText := HotKeyText + 'CTRL+';
if (HotKeyMod and HOTKEYF_SHIFT) = HOTKEYF_SHIFT then
HotKeyText := HotKeyText + 'SHIFT+';
if (HotKeyMod and HOTKEYF_EXT) = HOTKEYF_EXT then
HotKeyText := HotKeyText + 'Extended+';
HotKeyText := HotKeyText + Char(Lo(HotKey));
if (HotKeyText = '') or (HotKeyText = #0) then
HotKeyText := 'None';
ShowMessage('Shortcut Key - ' + HotKeyText);
end;
If you've got access to Safari Books Online, there is a good section about working with shortcuts / shell links in the Borland Delphi 6 Developer's Guide by Steve Teixeira and Xavier Pacheco. My example above is a butchered version from there and this site.
Hope that helps!
After some research, it appears that you'd need to get access to the internal structure that MS uses to store the hotkeys. ReactOS has a clean room implementation that implements the GetHotKey call by iterating an internal list and extracting the hotkey that matches the parameters to the call.
Depending on how close ReactOS' implementation is to the MS implementation, you may be able to poke around in memory to find the structure, but that's over my head...
BOOL FASTCALL
GetHotKey (UINT fsModifiers,
UINT vk,
struct _ETHREAD **Thread,
HWND *hWnd,
int *id)
{
PHOT_KEY_ITEM HotKeyItem;
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
if (HotKeyItem->fsModifiers == fsModifiers &&
HotKeyItem->vk == vk)
{
if (Thread != NULL)
*Thread = HotKeyItem->Thread;
if (hWnd != NULL)
*hWnd = HotKeyItem->hWnd;
if (id != NULL)
*id = HotKeyItem->id;
return TRUE;
}
}
return FALSE;
}
I presume this thread on sysinternals was asked by someone related to this question, but I thought I'd link to it anyway to keep the two together. The thread looks very intriguing, but I suspect that some deep dive spelunking would need to happen to figure this out without access to the MS internals.
Off the top of my head, you might try enumerating all windows with EnumWindows, then in the callback, send WM_GETHOTKEY to each window.
Edit: Apparrently I was wrong about that. MSDN has more information:
WM_HOTKEY is unrelated to the WM_GETHOTKEY and WM_SETHOTKEY hot keys. The WM_HOTKEY message is sent for generic hot keys while the WM_SETHOTKEY and WM_GETHOTKEY messages relate to window activation hot keys.
Note: Here is a program purporting to have the functionality you are looking for. You could try decompiling it.
Another thread mentions a global NT level keyboard hook:
Re-assign/override hotkey (Win + L) to lock windows
maybe you can get the handle of the process that called the hook that way, which you can then resolve to the process name
(disclaimer: I had it in my bookmarks, haven't really tried/tested)
I know you can intercept the stream of messages in any window within your own process - what we used to call subclassing in VB6. (Though I do not remember the function, perhaps SetWindowLong?) I am unsure if you can do this for windows outside your own process. But for the sake of this post lets assume you find a way to do that. Then you can simply intercept the messages for all top level windows, monitor for the WM_HOTKEY message. You wouldn't be able to know all the keys right off the bat, but as they were pressed you could easily figure out what application was using them. If you persisted your results to disk and reloaded each time your monitor application was run you could increase the performance of your application over time.
This doesn't exactly answer the part of the question that is about the Windows API, but it answers the part of the question that is about a list of global hotkeys and the applications that "own" them.
The free Hotkey Explorer at http://hkcmdr.anymania.com/ shows a list of all global hotkeys and the applications that own them. This just has helped me figure out why an application-specific shortcut key stopped working and how to fix it (by reconfiguring the registered global hotkey in the app that had it registered), within a few seconds.

Resources