Terms and conditions of applicability of `AttachThreadInput` - c++

This is a simple modification of a win32 initial code - generated from base template:
if (!InitInstance(hInstance,true)
{
return false;
}
std::thread{ [hInstance,main_thread= GetCurrentThreadId()] {
MSG msg{};
if (!InitInstance(hInstance,true)
{
return;
}
auto const current_thread{ GetCurrentThreadId() };
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32APP));
if (!AttachThreadInput(main_thread, current_thread, true))
return;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
AttachThreadInput(main_thread, current_thread, false);
} }.join();
Two windows are created and shown. But obviously, messages sent to the window created in main thread are not processed. What is missing? I couldn't find anything in tones of msdn docs and lots of forum posts. All I can find in forums is lots of complains about SetFocus and modal dialogs - which is not what I am looking for.
Thanks in Advance.

Ok. I had to go back and focus on the exact wording of the original dock. The term Input refers to HID. My confusion was due to the need for existence of message queues for both threads. So on the event of an input, different messages (pseudo) simultaneously get sent to both threads. Both threads will observe HID events; their perception of evets will be different, due different sequences recieved messages.
Thanks everyone for the hints.

Related

WinAPI What happens if I don't Translate and Dispatch unhandled message

On GetMessage reference from microsoft we have the next example:
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
What if I just ignore unhandled messages in the main loop of my program and move on?
Is there any risk to it? Will Windows complain/leak memory/hold resources for longer than necessary if I don't translate+dispatch this message if I don't actually need/want to handle it?
According The Message Loop,
The TranslateMessage function is related to keyboard input. It
translates keystrokes (key down, key up) into characters. You do not
really have to know how this function works; just remember to call it
before DispatchMessage. The link to the MSDN documentation will give
you more information, if you are curious.
The DispatchMessage function tells the operating system to call the
window procedure of the window that is the target of the message. In
other words, the operating system looks up the window handle in its
table of windows, finds the function pointer associated with the
window, and invokes the function.
If I don't translate+dispatch, loop will not be able to handle keyboard input and window messages. For example, the window cannot be moved, cannot be redrawn or closed. This has nothing to do with memory leaks
Having said that, a standard Message loop should be:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Accelerators are what matters here, otherwise known as "short-cut keys". Your program wants to respond to them regardless of which window has the focus. Like F1 shows the program's help file, regardless which control has the focus. You don't want to have to write code that subclasses every control window to recognize F1.
Refer: why exactly TranslateMessage

Standard if(PeekMessage) else update&render-loop creates delay in message handling

Following a Direct2D tuturial I've created a realtime update&render-loop like below. But when the update&render-loop takes long (eg when I have a Sleep(5000) somewhere in the Update()), normal messages handling like clicking the close window, can have to wait up to 5s.
So what is the proper way to split the message handling and realtime update&render-loop in two separate threads?
while (message.message != WM_QUIT)
{
if (PeekMessage(&message, windowHandle, 0, 0, PM_REMOVE)) // check for events and pass them to WindowProc, otherwise
DispatchMessage(&message);
else // run the realtime update&render loop
{
GameController::Update();
graphics->BeginDraw();
GameController::Render();
graphics->EndDraw();
}
}

Forcing a ListBox to Update

I am using C++ with MFC, and I have a ListBox tied to a variable that I'm updating as I run through a function:
void CFileSelection::OnBnClickedFiletousb()
{
m_LogC.AddString(_T("Starting move to USB, Please Wait..."));
UpdateData(FALSE);
// Code to move files from disk to USB
m_LogC.AddString(_T("Move to USB Successful."));
}
However, despite the UpdateData, the ListBox doesn't populate with either string until it has completed it's task. Is there a way to make it update the screen before the rest of the code is executed?
Use this function after changing the text on the listbox. Your issue is that the other calls are blocking the MessageThread, but you can force an update with this.
void ProcessWindowMessages()
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // let them see the message before we go into longer term wait
{
TranslateMessage(&msg); // translate it
DispatchMessage(&msg); // and let windows dispatch it to WinProc
}
}
Alternatively you can also call
yourlistboxVariable->UpdateWindow();

C++ Microsoft SAPI: Speak with event and Pump Message asynchronously

To better understand this question, refer to my earlier question:
C++ MSAPI 5: SetNotifyCallbackFunction not working
In Microsoft SAPI, in order to deliver the text-to-speech events when you are using the SetNotifyCallbackFunction you need to create a message pump, below is the code.
Now my problem is that I need the message pump to be done asynchronously. I have tried the std::thread, pthread and the boost library. But whenever I put the message pump in another thread. The pump failed. It is also the case whenever I tried calling the Speak in another thread. How can I solve this? Again my goal is to make the MSAPI speak asynchronously with events.
to call the message pump:
HANDLE hWait = pV->SpeakCompleteEvent();
WaitAndPumpMessagesWithTimeout(hWait, INFINITE);
the actual message pump code:
HRESULT WaitAndPumpMessagesWithTimeout(HANDLE hWaitHandle, DWORD dwMilliseconds)
{
HRESULT hr = S_OK;
BOOL fContinue = TRUE;
while (fContinue)
{
DWORD dwWaitId = ::MsgWaitForMultipleObjectsEx(1, &hWaitHandle, dwMilliseconds, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
switch (dwWaitId)
{
case WAIT_OBJECT_0:
{
fContinue = FALSE;
}
break;
case WAIT_OBJECT_0 + 1:
{
MSG Msg;
while (::PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&Msg);
::DispatchMessage(&Msg);
}
}
break;
case WAIT_TIMEOUT:
{
hr = S_FALSE;
fContinue = FALSE;
}
break;
default:// Unexpected error
{
fContinue = FALSE;
hr = E_FAIL;
}
break;
}
}
return hr;
}
I suspect you need to create the message queue before calling WaitAndPumpMessagesWithTimeout.
There are a couple of ways of doing this:
call ::PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE)
Create a window (message-only windows are useful here)
When you call Speak() on a separate thread, you should create the SAPI objects on that thread, as well.
I forgot to answer my own question yesterday. But I'll give credit to Eric Brow
First off, my purpose in doing the asynch event is it will be used as a library for other language.
What I have researched yesterday was like what Eric said, all SAPI interaction must occur on the same thread. Therefore, I solve this by creating a class that is derive from CWinThread which also has the SAPI functionalities. Then I let the wrapper functions interact with the derived CWinThread class.
Source: http://www.codeproject.com/Articles/551/Using-User-Interface-Threads

PostMessage() succeeds but my message processing code never receives the message

In my C++ application's GUI object I have the following in the main window procedure:
case WM_SIZE:
{
OutputDebugString(L"WM_SIZE received.\n");
RECT rect = {0};
GetWindowRect(hwnd, &rect);
if (!PostMessage(0, GUI_MSG_SIZECHANGED, w, MAKELONG(rect.bottom - rect.top, rect.right - rect.left))) {
OutputDebugString(L"PostMessage failed.\n"); // <--- never called
}
}
return 0; // break;
The GUI object also has the following getMessage() method:
int GUI::getMessage(MSG & msg) {
BOOL result = 0;
while ((result = GetMessage(&msg, 0, 0, 0)) > 0) {
if (msg.message > (GUI_MSG_BASE-1) && msg.message < (GUI_MSG_LAST+1)) {
OutputDebugString(L"GUI message received.\n");
break;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return result;
}
The application object calls this method in the following way:
while ((result = _gui.getMessage(msg)) > 0) {
switch (msg.message) {
// TODO: Add gui message handlers
case GUI_MSG_SIZECHANGED:
OutputDebugString(L"GUI_MSG_SIZECHANGED received.\n");
_cfg.setWndWidth(HIWORD(msg.lParam));
_cfg.setWndHeight(LOWORD(msg.lParam));
if (msg.wParam == SIZE_MAXIMIZED)
_cfg.setWndShow(SW_MAXIMIZE);
else if (msg.wParam == SIZE_MINIMIZED)
_cfg.setWndShow(SW_MINIMIZE);
else if (msg.wParam == SIZE_RESTORED)
_cfg.setWndShow(SW_SHOWNORMAL);
break;
}
}
The application object is interested in the window size because it stores this information in a configuration file.
When I run this in Visual Studio's debugger, the output window looks like this after resizing the window:
WM_SIZE received.
GUI message received.
GUI_MSG_SIZECHANGED received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
...etc...
The PostMessage() function never fails, but seems to only send GUI_MSG_SIZECHANGED (#defined as WM_APP + 0x000d) the first time WM_SIZE is handled, which is right after handling WM_CREATE.
I have no idea what could be causing this. I tried using SendMessage and PostThreadMessage but the result is the same. Also read through MSDN's message handling documentation but couldn't find what's wrong with my code.
Could anyone help?
Hacking a custom message loop is something you'll live to regret some day. You hit it early.
Don't post messages with a NULL window handle, they can only work if you can guarantee that your program only ever pumps your custom message loop. You cannot make such a guarantee. These messages fall into the bit bucket as soon as you start a dialog or Windows decides to pump a message loop itself. Which is the case when the user resizes a window, the resize logic is modal. Windows pumps its own message loop, WM_ENTERSIZEMOVE announces it. This is also the reason that PostThreadMessage is evil if the thread is capable of displaying any window. Even a MessageBox is fatal. DispatchMessage cannot deliver the message.
Create a hidden window that acts as the controller. Now you can detect GUI_MSG_SIZECHANGED in its window procedure and no hacks to the message loop are necessary. That controller is not infrequently the main window of your app btw.