I am using the Windows MIDI interface for communicating with my MIDI devices.
Everything works fine, also with system-exclusive messages as long as a SYSEX message is framed with 0xF0 <data> 0xF7.
Well, I have an old Sampler (AKAI S900) which uses SYSEX without the 0xF7 at the end (common sample dump). My problem is, when the Sampler sends this string (0xF0 <some data>), I do not get it, because the Win32 API seems to wait for the trailing 0xF7 at the end of the SYSEX message.
How can I tell the MIDI interface to tell me immediately when a byte is available on the MIDI input, and not only when a complete message is received?
Currently, my code looks like this:
midiInOpen(&device_in,
selected_midi_in_interface(DWORD_PTR)midi_in_callback,
0, CALLBACK_FUNCTION);
...
midiHdr_in.lpData = temp_input;
midiHdr_in.dwBufferLength = (DWORD)input_len;
midiHdr_in.dwFlags = 0;
midiInPrepareHeader(device_in, &midiHdr_in, sizeof(MIDIHDR));
...
midiInAddBuffer(device_in, &midiHdr_in, sizeof(MIDIHDR));
midiInStart(device_in);
...
while (GetMessage(&Msg, NULL, 0, 0) > 0){
TranslateMessage(&Msg);
DispatchMessage(&Msg);
// Check if midiHdr_in.dwBytesRecorded has changed...
...
}
Related
I am creating application with win32 GUI and I tried blocking and ignoring some window messages of the message queue in my message loop. For it, I tried this following code:
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
if (msg.message != WM_... /*to complete with messages to block*/) DispatchMessage(&msg);
}
But it does not work and I can not understand why. Normally, except some particular messages, all messages pass by the message loop, so the messages that I block should be ignored! What is not wrong with my code? Mayby I shoud try to rethink my message loop?
Thanks for reading and your help.
I know lots of similar questions on this topic have been asked before but so far I have been unable to find a solution that actually works. I want to start a console program from my program and capture its output. My implementation should be in a way that is compatible with WaitForMultipleObjects(), i.e. I want to get notified whenever there is new data to read in the pipe.
My implementation is based on this example from MSDN. However, I had to modify it a little because I need overlapped I/O in order to be able to wait for ReadFile() to finish. So I'm using named pipes created using Dave Hart's MyCreatePipeEx() function from here.
This is my actual code. I have removed error checks for readability reasons.
HANDLE hReadEvent;
HANDLE hStdIn_Rd, hStdIn_Wr;
HANDLE hStdOut_Rd, hStdOut_Wr;
SECURITY_ATTRIBUTES saAttr;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
OVERLAPPED ovl;
HANDLE hEvt[2];
DWORD mask, gotbytes;
BYTE buf[4097];
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
MyCreatePipeEx(&hStdOut_Rd, &hStdOut_Wr, &saAttr, 0, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
MyCreatePipeEx(&hStdIn_Rd, &hStdIn_Wr, &saAttr, 0, FILE_FLAG_OVERLAPPED, FILE_FLAG_OVERLAPPED);
SetHandleInformation(hStdOut_Rd, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(hStdIn_Wr, HANDLE_FLAG_INHERIT, 0);
memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hStdOut_Wr;
siStartInfo.hStdOutput = hStdOut_Wr;
siStartInfo.hStdInput = hStdIn_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, "test.exe", NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);
hReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
for(;;) {
int i = 0;
hEvt[i++] = piProcInfo.hProcess;
memset(&ovl, 0, sizeof(OVERLAPPED));
ovl.hEvent = hReadEvent;
if(!ReadFile(hStdOut_Rd, buf, 4096, &gotbytes, &ovl)) {
if(GetLastError() == ERROR_IO_PENDING) hEvt[i++] = hReadEvent;
} else {
buf[gotbytes] = 0;
printf("%s", buf);
}
mask = WaitForMultipleObjects(i, hEvt, FALSE, INFINITE);
if(mask == WAIT_OBJECT_0 + 1) {
if(GetOverlappedResult(hStdOut_Rd, &ovl, &gotbytes, FALSE)) {
buf[gotbytes] = 0;
printf("%s", buf);
}
} else if(mask == WAIT_OBJECT_0) {
break;
}
}
The problem with this code is the following: As you can see, I'm reading in chunks of 4kb using ReadFile() because I obviously don't know how much data the external program test.exe will output. Doing it this way was suggested here:
To read a variable amount of data from the client process just issue
read requests of whatever size you find convenient and be prepared to
handle read events that are shorter than you requested. Don't
interpret a short but non-zero length as EOF. Keep issuing read
requests until you get a zero length read or an error.
However, this doesn't work. The event object passed to ReadFile() as part of the OVERLAPPED structure will only trigger once there are 4kb in the buffer. If the external program just prints "Hello", the event won't trigger at all. There need to be 4kb in the buffer for hReadEvent to actually trigger.
So I thought I should read byte by byte instead and modified my program to use ReadFile() like this:
if(!ReadFile(hStdOut_Rd, buf, 1, &gotbytes, &ovl)) {
However, this doesn't work either. If I do it like this, the read event is not triggered at all which is really confusing me. When using 4096 bytes, the event does indeed trigger as soon as there are 4096 bytes in the pipe, but when using 1 byte it doesn't work at all.
So how am I supposed to solve this? I'm pretty much out of ideas here. Is there no way to have the ReadFile() event trigger whenever there is some new data in the pipe? Can't be that difficult, can it?
Just for the record, while there are some problems with my code (see discussion in comments below the OP), the general problem is that it's not really possible to capture the output of arbitrary external programs because they will typically use block buffering when their output is redirected to a pipe, which means that output will only arrive at the capturing program once that buffer is flushed so real time capturing is not really possible.
Some workarounds have been suggested though:
1) (Windows) Here is a workaround that uses GetConsoleScreenBuffer() to capture the output from arbitrary console programs but it currently only supports one console page of output.
2) (Linux) On Linux, it's apparently possible to use pseudo-terminals to force the external program to use unbuffered output. Here is an example.
is there any documentation which messages are processed by DefWindowProc, and how?
I recently stumbled over WM_SETFONT/WM_GETFONT not being handled, I'm not sure if there's a mistake in my code, or if that's expected behavior, so I tried the following WinMain:
WNDCLASSEX wcx =
{
sizeof(WNDCLASSEX),
CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
DefWindowProc,
0, 0, // class/wnd extra bytes
hInstance,
0,
LoadCursor(0, IDC_ARROW),
0,
0,
_T("some class"),
0
};
ATOM a = RegisterClassEx(&wcx);
_ASSERTE(a != 0);
HWND wnd = CreateWindowEx(0, wcx.lpszClassName, NULL,
WS_POPUP, 0,0,0,0, GetDesktopWindow(), 0, hInstance, 0);
_ASSERTE(wnd != 0);
HFONT font = (HFONT) GetStockObject(ANSI_VAR_FONT);
_ASSERTE(font != 0);
SendMessage(wnd, WM_SETFONT, (WPARAM) font, 0);
HFONT font2 = (HFONT) SendMessage(wnd, WM_GETFONT, 0, 0);
_ASSERTE(font2 == font); // **FAILS**, font2 is 0
As far as I am aware - no.
Each window message is a rare and unique thing that can differ in one of MANY ways. Some messages are expected to be posted, other's sent.
Some messages are notifications to the users window proc, others are commands to the DefXXXWindowProc handler(s) - DefWindowProc, DefDlgProc, DefMDIChildProc etc.
Some are handled the same in dialog and window procs, some must be handled differently.
WM_SETTEXT and WM_SETREDRAW are actually commands that DefWindowProc uses to modify internal data structures in the WND struct.
WM_SIZE is just a notification - sent BY DefWindowProc to its own window - in response to WM_WINDOWPOSCHANGED.
WM_MOUSExxx messages NEED to be posted, never sent, as windows frequently enter modal states where messages are read with GetMessage/PeekMessage and handled directly and NOT posted.
A lot of messages look like notifications, but MUST always be passed on to DefWindowProc because they're "secretly" used to implement the window manager. (WM_ACTIVATE and friends).
Most messages can be handled in a dialog proc by returning FALSE (or TRUE), some, with meaningful results need to use SetDlgResult, others are automatically handled (WM_CTLCOLOR*) as the dialog proc knows that a non zero result from the DialogProc corresponds to the LRESULT to return.
Some (WM_SYSCOMMAND) are not really messages to the window at all, and are just handled by DefWindowProc to do window manager type things (tile the desktop etc.)
There is no real attempt in the official documentation to categorize these differences.
To specifically address the WM_SET/GETFONT issue, WM_SETFONT, while a defined message, is not handled by DefwindowProc, and hence not handled by window classes that do not explicitly support it. Controls (EDIT, STATIC, etc) and Dialogs support WM_SETFONT and WM_GETFONT. To support it in a application registered class would require supplying an actual custom WindowProc and handling the message there.
I'm developing for Windows Mobile in C++, and I'm running into a problem - I added my window
class, and in it I the keyboard input with my WndProc implementation. The problem is
that I'm getting the wrong codes, and identifying keys such as the func key incorrectly, and to make it worse, the values I'm getting (the wParam of the WM_KEYDOWN message) as different values between the two phones I have here for testing - who knows what will happen on other phones.
After playing around with it for ages, I found out that if I only create a window from the
predefined "EDIT" class, I actually do get the input correctly (in terms of letters/keys).
So the problem must not be in the phone, but rather the modes of getting messages (a bit of a newbie in win32, excuse me for lack of knowledge). I tried playing around with input modes, but sending a message to my window using EM_NUMBERS and the such, always failed.
So what I would want to do (though I'm open for suggestions), is somehow just get the characters from some hidden EDIT window, and forward them to my window. (Though I still need my window to have the focus so it would react correctly to messages different from WM_KEYDOWN and the like)
Is there any way to do this?
This is the 3'rd time I'm asking regarding this issue, i am eternally grateful to everyone who tried to help so far (though would be even more grateful if i had managed to solve my problem)
Here are the relevant code excerpts:
Class registration :
WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ROADMAP));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
window creation
if (width == -1) width = CW_USEDEFAULT;
if (height == -1) height = CW_USEDEFAULT;
RoadMapMainWindow = CreateWindow(g_szWindowClass, szTitle, OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
NULL, NULL, g_hInst, NULL);
MessageLoop
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
WNDPROC excerpt :
case WM_KEYDOWN:
{
WORD Code = (WORD)wParam;
int iRepeatTimes = (lParam & 0x0000FFFF);
int iScanCode = (lParam & 0x00FF0000) >> 16;
BOOL bALT_IsDown = (lParam & 0x20000000)? TRUE: FALSE;
BOOL bAlreadyPressed= (lParam & 0x40000000)? TRUE: FALSE;
BOOL bNowReleased = (lParam & 0x80000000)? TRUE: FALSE;
return DefWindowProc(hWnd, message, wParam, lParam);
}
The wParam of WM_KEYDOWN is a virtual key code that is not really constrained to be an ascii (or unicode) character - its simply a code that uniquely identifies the key on the platform.
If you want the 'text' - you want to wait for the WM_CHAR message - the wParam of WM_CHAR will be the actual character value that the user entered.
More Info - in your application loop - where you call TranslateMessage - it is actually the job of TranslateMessage to spot WM_KEYDOWN messages and synthesize and post the corresponding WM_CHAR messages.
TranslateAccelerator seems to be the only thing that can interfere with posted messages.
Of course, sometimes very unusual behaviour can manifest if the windows message proc is (or is not) handing messages to DefWindowProc at the wrong time. Why for example do you have an explicit call to DefWindowProc in your WM_KEYDOWN handler? The easiest way to handle that correctly is to have DefWindowProc as the last thing your window proc does so that all messages, handled and unhandled, go there by default. the exceptional case would be messages where you want to prevent DefWindowProc getting the message (WM_PAINT if you handle it for example).
You also keep mentioning trying to use Edit_SetInputMode - Edit_SetInputMode sends a message to the window: EM_SETINPUTMODE - which is a message only understood by EDIT controls. As you have registered your own window class, 'EM_SETINPUTMODE` is going to do nothing.
I've not had any problems like you describe, so I'd really like to see a bare-bones set of code that repros this. It is known that some phones get spurrious user-range messages but these shouldn't be affecting you at the level you're at. The fact that you're getting wrong codes for something so basic indicates to me that you must have something wrong in your window creation or message handling code.
I am just guessing, but maybe your app is an Ansi app? That could maybe explain that different codepages give you different keycodes. So have you tried to make it all Unicode in the project settings, and define the string constants accordingly? And did you try ctacke's suggestion to make a really basic app?
I want to debug a windows C++ application I've written to see why it isn't responding to WM_QUERYENDSESSION how I expect it to. Clearly it's a little tricky to do this by just shutting the system down. Is there any utility or code which I can use to send a fake WM_QUERYENDSESSION to my application windows myself?
I've used the Win32::GuiTest Perl module to do this kind of thing in the past.
The Windows API SendMessage can be used to do this.
http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
IS ti possible it's not responding because some other running process has responded with a zero (making the system wait on it.)
Yes of course, it possible. I faced a similar issue some months ago where some (unknown, but probably mine) app was preventing shutdown, so I wrote some quick code that used EnumWindows to enumerate all the top level windows, sent each one a WM_QUERYENDSESSION message, noted what the return value from SendMessage was and stopped the enumeration if anyone returned FALSE. Took about ten minutes in C++/MFC. This was the guts of it:
void CQes_testDlg::OnBtnTest()
{
// enumerate all the top-level windows.
m_ctrl_ListMsgs.ResetContent();
EnumWindows (EnumProc, 0);
}
BOOL CALLBACK EnumProc (HWND hTarget, LPARAM lParam)
{
CString csTitle;
CString csMsg;
CWnd * pWnd = CWnd::FromHandle (hTarget);
BOOL bRetVal = TRUE;
DWORD dwPID;
if (pWnd)
{
pWnd->GetWindowText (csTitle);
if (csTitle.GetLength() == 0)
{
GetWindowThreadProcessId (hTarget, &dwPID);
csTitle.Format ("<PID=%d>", dwPID);
}
if (pWnd->SendMessage (WM_QUERYENDSESSION, 0, ENDSESSION_LOGOFF))
{
csMsg.Format ("window 0x%X (%s) returned TRUE", hTarget, csTitle);
}
else
{
csMsg.Format ("window 0x%X (%s) returned FALSE", hTarget, csTitle);
bRetVal = FALSE;
}
mg_pThis->m_ctrl_ListMsgs.AddString (csMsg);
}
else
{
csMsg.Format ("Unable to resolve HWND 0x%X to a CWnd", hTarget);
mg_pThis->m_ctrl_ListMsgs.AddString (csMsg);
}
return bRetVal;
}
mg_pThis was just a local copy of the dialog's this pointer, so the helper callback could access it. I told you it was quick and dirty :-)
Yes. If you can get the window handle (maybe using FindWindow()), you can send/post any message to it as long as the WPARAM & LPARAM aren't pointers.