C++ Event signal and background thread - c++

Here is the issue that I have in c++ code implementation.
In the main thread , created a dialogbox showing static text with cancel button which also spins a child thread.
In the back ground thread ( or the child thread) check the database to see if the certain status field is updated. If updated, then return true, otherwise continue to poll the database at regular intervals.
Expected behavior - Show dialog box with cancel button , continue showing it until the event is signaled by child thread or the user hits cancel button.
I created an event in the main thread with unsignalled state , this event state will be modified by the child tread ( when the status field is updated ).
The problem is if i block the main thread until it gets response from the background thread, the user cannot hit the cancel button in the dialog , it is always accompanied with hour glass symbol.
Not sure what is wrong with the below code.
HANDLE mainThread = NULL;
HANDLE ghWriteEvent;
MainMethod()
{
mainThread = GetCurrentThread() ;
dlgCancelDialog dog // dialog with cancel button .
ghWriteEvent = CreateEvent( NULL, TRUE, FALSE, TEXT("WriteEvent") );
HANDLE hThread = CreateThread(0,0, childThread, &threadData,0,NULL);
dlg.showDialog(); // Show dialog with cancel button .
DWORD dwWaitResult = WaitForSingleObject( ghWriteEvent, INFINITE);
//AT THIS POINT i WANT TO SAY WAIT FOR SIGNAL EVENT OR WAIT UNTIL CANCEL OPERATION IS HIT , BUT THE DIALOG IS SHOWN WITH HOURGLASS SYMBOL.
switch (dwWaitResult)
{
// Event object was signaled
case WAIT_OBJECT_0:
break;
}
dlg.hideDialog();
}
//Child thread code.
childThread(LPVOID lpParam)
{
while(!databaseIsUpdated) // Check database.
{
Sleep(1000);
}
if (! SetEvent(ghWriteEvent) )
{
return 0;
}
return 0;
}

You should not wait with INFINITE because you block your dialog thread.
So my proposal is, create timer using SetTimer(hDlg, 500, 1, NULL) and handle WM_TIMER inside DlgProc like this:
case WM_TIMER:
{
DWORD dwWaitResult = WaitForSingleObject( ghWriteEvent, 0); //We will not wait
if(dwWaitResult == WAIT_OBJECT_0) //We are signaled, exit now
dlg.hideDialog();
}
break;
This will check every 500ms state of event.If signaled, dialog ends, if not, continue.

You could also use MsgWaitForMultipleObjectsEx() : http://msdn.microsoft.com/en-us/library/windows/desktop/ms684245%28v=vs.85%29.aspx

Related

Cannot exit message loop from thread using Windows API and C++

I'm trying to implement the following scenario:
Requirement
Write a C++ program to capture all the keyboard inputs on Windows OS. The program should start capturing keystrokes and after about 3 seconds (the specific amount time is not very relevant, it could be 4/5/etc.), the program should stop capturing keystrokes and continue its execution.
Before I proceed with the actual implementation details, I want to clarify that I preferred tο write the requirements in a form of exercise, rather than providing a long description. I'm not trying to gather solutions for homework. (I'm actually very supportive to such questions when its done properly, but this is not the case here).
My solution
After working on different implementations the past few days, the following is the most complete one yet:
#include <iostream>
#include <chrono>
#include <windows.h>
#include <thread>
// Event, used to signal our thread to stop executing.
HANDLE ghStopEvent;
HHOOK keyboardHook;
DWORD StaticThreadStart(void *)
{
// Install low-level keyboard hook
keyboardHook = SetWindowsHookEx(
// monitor for keyboard input events about to be posted in a thread input queue.
WH_KEYBOARD_LL,
// Callback function.
[](int nCode, WPARAM wparam, LPARAM lparam) -> LRESULT {
KBDLLHOOKSTRUCT *kbs = (KBDLLHOOKSTRUCT *)lparam;
if (wparam == WM_KEYDOWN || wparam == WM_SYSKEYDOWN)
{
// -- PRINT 2 --
// print a message every time a key is pressed.
std::cout << "key was pressed " << std::endl;
}
else if (wparam == WM_DESTROY)
{
// return from message queue???
PostQuitMessage(0);
}
// Passes the keystrokes
// hook information to the next hook procedure in the current hook chain.
// That way we do not consume the input and prevent other threads from accessing it.
return CallNextHookEx(keyboardHook, nCode, wparam, lparam);
},
// install as global hook
GetModuleHandle(NULL), 0);
MSG msg;
// While thread was not signaled to temirnate...
while (WaitForSingleObject(ghStopEvent, 1) == WAIT_TIMEOUT)
{
// Retrieve the current messaged from message queue.
GetMessage(&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Before exit the thread, remove the installed hook.
UnhookWindowsHookEx(keyboardHook);
// -- PRINT 3 --
std::cout << "thread is about to exit" << std::endl;
return 0;
}
int main(void)
{
// Create a signal event, used to terminate the thread responsible
// for captuting keyboard inputs.
ghStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD ThreadID;
HANDLE hThreadArray[1];
// -- PRINT 1 --
std::cout << "start capturing keystrokes" << std::endl;
// Create a thread to capture keystrokes.
hThreadArray[0] = CreateThread(
NULL, // default security attributes
0, // use default stack size
StaticThreadStart, // thread function name
NULL, // argument to thread function
0, // use default creation flags
&ThreadID); // returns the thread identifier
// Stop main thread for 3 seconds.
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
// -- PRINT 4 --
std::cout << "signal thread to terminate gracefully" << std::endl;
// Stop gathering keystrokes after 3 seconds.
SetEvent(ghStopEvent);
// -- PRINT 5 --
std::cout << "from this point onwards, we should not capture any keystrokes" << std::endl;
// Waits until one or all of the specified objects are
// in the signaled state or the time-out interval elapses.
WaitForMultipleObjects(1, hThreadArray, TRUE, INFINITE);
// Closes the open objects handle.
CloseHandle(hThreadArray[0]);
CloseHandle(ghStopEvent);
// ---
// DO OTHER CALCULATIONS
// ---
// -- PRINT 6 --
std::cout << "exit main thread" << std::endl;
return 0;
}
Implementation details
The main requirement is the capturing of keystrokes for a certain amount of time. After that time, we should NOT exit the main program. What I thought would be suitable in this case, is to create a separate thread that will be responsible for the capturing procedure and using a event to signal the thread. I've used windows threads, rather than c++0x threads, to be more close to the target platform.
The main function starts by creating the event, followed by the creation of the thread responsible for capturing keystrokes. To fulfill the requirement of time, the laziest implementation I could think of was to stop the main thread for a certain amount of time and then signaling the secondary one to exit. After that we clean up the handlers and continue with any desired calculations.
In the secondary thread, we start by creating a low-level global keyboard hook. The callback is a lambda function, which is responsible for capturing the actual keystrokes. We also want to call CallNextHookEx so that we can promote the message to the next hook on the chain and do not disrupt any other program from running correctly. After the initialization of the hook, we consume any global message using the GetMessage function provided by the Windows API. This repeats until our signal is emitted to stop the thread. Before exiting the thread, we unhook the callback.
We also output certain debug messages throughout the execution of the program.
Expected behavior
Running the above code, should output similar messages like the ones bellow:
start capturing keystrokes
key was pressed
key was pressed
key was pressed
key was pressed
signal thread to terminate gracefully
thread is about to exit
from this point onwards, we should not capture any keystrokes
exit main thread
Your output might differ depending on the number of keystrokes that were captured.
Actual behavior
This is the output I'm getting:
start capturing keystrokes
key was pressed
key was pressed
key was pressed
key was pressed
signal thread to terminate gracefully
from this point onwards, we should not capture any keystrokes
key was pressed
key was pressed
key was pressed
A first glance into the output reveals that:
The unhook function was not called
The program keeps capturing keystrokes, which might indicate that something is wrong with the way I process the message queue
There is something wrong regarding the way I'm reading the messages from the message queue, but after hours of different approaches, I could not find any solution for the specific implementation. It might also be something wrong with the way I'm handling the terminate signal.
Notes
The closer I could get on finding an answer, here in SO, was this question. However the solution did not helped me as much as I wanted.
The provided implementation is a minimum reproducible example and can be compiled without the need to import any external libraries.
A proposed solution will be to implement the capturing-keystrokes functionality as a separate child process, where will be able to start and stop whenever we like. However, I'm more interested in finding a solution using threads. I'm not sure if this is even possible (it might be).
The above code does not contain any error handling. This was on purpose to prevent possible over bloated of the code.
For any questions you might have, feel free to comment! Thank you in advance for your time to read this question and possibly post an answer (it will be amazing!).
I think this is your problem:
while (WaitForSingleObject(ghStopEvent, 1) == WAIT_TIMEOUT)
{
// Retrieve the current messaged from message queue.
GetMessage(&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
The reason is that currently your loop can get stuck on the GetMessage() step forever and never again look at the manual-reset event.
The fix is simply to replace the combination of WaitForSingleObject + GetMessage with MsgWaitForMultipleObjects + PeekMessage.
The reason you've made this mistake is that you didn't know GetMessage only returns posted messages to the message loop. If it finds a sent message, it calls the handler from inside GetMessage, and continues looking for posted message. Since you haven't created any windows that can receive messages, and you aren't calling PostThreadMessage1, GetMessage never returns.
while (MsgWaitForMultipleObjects(1, &ghStopEvent, FALSE, INFINITE, QS_ALLINPUT) > WAIT_OBJECT_0) {
// check if there's a posted message
// sent messages will be processed internally by PeekMessage and return false
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
1 You've got logic to post WM_QUIT but it is conditioned on receiving WM_DESTROY in a low-level keyboard hook, and WM_DESTROY is not a keyboard message. Some hook types could see a WM_DESTROY but WH_KEYBOARD_LL can't.
What I thought would be suitable in this case, is to create a separate
thread that will be responsible for the capturing procedure
it's not necessary to do this if another thread will just wait for this thread and nothing to do all this time
you can use code like this.
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if (HC_ACTION == code)
{
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
DbgPrint("%x %x %x %x\n", wParam, p->scanCode, p->vkCode, p->flags);
}
return CallNextHookEx(0, code, wParam, lParam);
}
void DoCapture(DWORD dwMilliseconds)
{
if (HHOOK hhk = SetWindowsHookExW(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0))
{
ULONG time, endTime = GetTickCount() + dwMilliseconds;
while ((time = GetTickCount()) < endTime)
{
MSG msg;
switch (MsgWaitForMultipleObjectsEx(0, 0, endTime - time, QS_ALLINPUT, MWMO_INPUTAVAILABLE))
{
case WAIT_OBJECT_0:
while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
break;
case WAIT_FAILED:
__debugbreak();
goto __0;
break;
case WAIT_TIMEOUT:
DbgPrint("WAIT_TIMEOUT\n");
goto __0;
break;
}
}
__0:
UnhookWindowsHookEx(hhk);
}
}
also in real code - usual not need write separate DoCapture with separate message loop. if your program before and after this anyway run message loop - posiible all this do in common message loop,

What is the proper use of WTL CIdleHandler?

I'm trying to learn WTL / Win32 programming, and I don't quite understand the design of the CIdleHandler mixin class.
For WTL 9.1, The CMessageLoop code is as follows (from atlapp.h):
for(;;)
{
while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!OnIdle(nIdleCount++))
bDoIdle = FALSE;
}
bRet = ::GetMessage(&m_msg, NULL, 0, 0);
if(bRet == -1)
{
ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
continue; // error, don't process
}
else if(!bRet)
{
ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
break; // WM_QUIT, exit message loop
}
if(!PreTranslateMessage(&m_msg))
{
::TranslateMessage(&m_msg);
::DispatchMessage(&m_msg);
}
if(IsIdleMessage(&m_msg))
{
bDoIdle = TRUE;
nIdleCount = 0;
}
}
The actual call to idle handlers is very straightforward.
// override to change idle processing
virtual BOOL OnIdle(int /*nIdleCount*/)
{
for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
{
CIdleHandler* pIdleHandler = m_aIdleHandler[i];
if(pIdleHandler != NULL)
pIdleHandler->OnIdle();
}
return FALSE; // don't continue
}
As is the call to IsIdleMessage
static BOOL IsIdleMessage(MSG* pMsg)
{
// These messages should NOT cause idle processing
switch(pMsg->message)
{
case WM_MOUSEMOVE:
#ifndef _WIN32_WCE
case WM_NCMOUSEMOVE:
#endif // !_WIN32_WCE
case WM_PAINT:
case 0x0118: // WM_SYSTIMER (caret blink)
return FALSE;
}
return TRUE;
}
My analysis is as follows: it seems like once per "PeekMessage Drought" (a period of time where no messages are sent to the Win32 Application), the OnIdle handlers are called.
But why just once? Wouldn't you want background idle tasks to continuously be called over and over again in the case when PeekMessage ? Furthermore, it seems strange to me that WM_LBUTTONDOWN (User has left-clicked something on the Window) would activate idle processing (bDoIdle = True), but WM_MOUSEMOVE is explicitly called out to prevent reactivation of idle processing.
Can anyone give me the "proper" use scenario of WTL Idle Loops (or more specifically: CIdleHandler)? I guess my expectation was that Idle-processing functions would be small, incremental tasks that take no more than say... 100ms to complete. And then they'd be called repeatedly in the background.
But it seems like this is not the case in WTL. Or maybe I'm not fully understanding Idle loops? Because if I had an incremental background task registered as a CIdleHandler... then if the user stepped away from the window, the task would get run only once! Without any messages pumped into the system (such as WM_LBUTTONDOWN), the bDoIdle variable would remain false for all time!
Does anyone have a good explanation for all this?
As said in the comments, OnIdle handler is supposed to be called when idling starts after certain activity, esp. in order to update UI. This explains "once" calling of the handlers: something happened and then you have a chance to once update the UI elements. If you need ongoing background processing, you are supposed to use timers or worker threads.
WTL samples suggest the use of idle handlers, e.g. in \Samples\Alpha\mainfrm.h.
Window class picks up message loop of the thread and requests idleness updates:
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// ...
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
Later on after message processing and user interaction, the idleness handler updates toolbar to reflect possible state changes:
virtual BOOL OnIdle()
{
UIUpdateToolBar();
return FALSE;
}

Win32, MFC: Ending threads

I have a DLL which has a CWinThread based class called CWork.
I create it using AfxBeginThread.
In this class I defined a procedure that will loop infinetly and perform a certain task. This procedure will be used as a thread by itself. I create it also using AfxBeginThread.
Now, when my DLL exits, I'd like to end the thread. This is because I have a crash on exit, and I am affraid that is the reason.
In addition, there is
Pseudo Code example:
class Cmain
Cmain::Cmain(){
pMyThread = AfxBeginThread(CWork - a CWinThread based Class);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam);
class CWork
CWork:CWork(){
AfxBeginThread(HandleNextVTSConnectionCommandProc, this);
}
UINT HandleNextVTSConnectionCommandProc(LPVOID pParam){
while(true){
dosomething();
sleep(2000);
}
}
My question is, what is the correct way of ending those 2 threads?
Thank you!
In general the correct way to end a thread is to ask it to finish and then wait for it to do so. So on Windows you might signal an event to ask the thread to finish up then wait on the thread HANDLE. Forcefully terminating a thread is almost always a misguided idea which will come back to haunt you.
Create an event calling CreateEvent that is initially non-signaled. When your application terminates, signal this event (SetEvent) and wait for the thread to terminate (WaitForSingleObject on the thread handle).
Inside your thread function HandleNextVTSConnectionCommandProc replace your while(true) loop with
while(WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
Doing the above allows you to signal the thread to terminate from your application. The thread terminates, when it returns from its thread proc.
Set a flag instead of using while(true) to tell your thread when it should end. You could also use an event.
You should also wait for your thread to be complete before you exit, so you should use (in the main code, once you signal the thread to end):
WaitForSingleObject(thread_handle)
Something like this should get you started:
HANDLE g_hThreadExitRequest = NULL;
UINT __cdecl ThreadFunction(LPVOID pParam)
{
AllocConsole();
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
for (int i=1; true; ++i)
{
CStringA count;
count.Format("%d\n", i);
WriteFile(hCon, (LPCSTR)count, count.GetLength(), NULL, NULL);
if (WaitForSingleObject(g_hThreadExitRequest, 1000) == WAIT_OBJECT_0)
break;
}
// We can do any thread specific cleanup here.
FreeConsole();
return 0;
}
void Go()
{
// Create the event we use the request the thread exit.
g_hThreadExitRequest = CreateEvent(
NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
TRUE, // BOOL bManualReset
FALSE, // BOOL bInitialState
NULL // LPCTSTR lpName
);
// We create the thread suspended so we can mess with the returned CWinThread without
// MFC auto deleting it when the thread finishes.
CWinThread *pThread = AfxBeginThread(
&ThreadFunction, // AFX_THREADPROC pfnThreadProc
NULL, // LPVOID pParam
THREAD_PRIORITY_NORMAL, // int nPriority
0, // UINT nStackSize
CREATE_SUSPENDED , // DWORD dwCreateFlags
NULL // LPSECURITY_ATTRIBUTES lpSecurityAttrs
);
// Turn off MFC's auto delete "feature".
pThread->m_bAutoDelete = FALSE;
// Start the thread running.
pThread->ResumeThread();
// Wait 30 seconds.
Sleep(30*1000);
// Signal the thread to exit and wait for it to do so.
SetEvent(g_hThreadExitRequest);
WaitForSingleObject(pThread->m_hThread, INFINITE);
// Delete the CWinTread object since we turned off auto delete.
delete pThread;
// We're finished with the event.
CloseHandle(g_hThreadExitRequest);
g_hThreadExitRequest = NULL;
}

How to define CWinThread in MFC?

I have set an int variable for the "EditBox" control in c++/mfc. now I want to change its value in a thread.
I define a thread like the bellow :
CWinThread *pThread();
UINT FunctionThread(CthDlg& d)
{
DWORD result = 0;
int i = 0;
while (1)
{
if (i == 5000) i = 0;
d.m_text1 = i;
i++;
d.UpdateData(FALSE);
}
return result;
}
void CthDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
pThread = AfxBeginThread(FunctionThread, THREAD_PRIORITY_NORMAL);
}
Where's the Problem?
You should run your code in debug mode and under the debugger, then you would see that you get an assertion.
The problem is that MFC only allows access to a window from the thread that created the window. In your case that means that the main thread can access the windows, but the worker thread can not. UpdateData is accessing the windows, so this does not work in a worker thread.
So what you need to do is signal from the worker thread to the main thread that a new value is available and shall be displayed. For that signaling you can post a window message to the dialog window (PostMessage). Be sure not to use SendMessage because this will block until the message is received. You might run into a dead lock if the main thread is waiting for the worker thread and the worker thread is waiting for the main thread in SendMessage. When the main thread receives the message it can update the window control.
BTW, your code is not valid. AfxBeginThread requires a AFX_THREADPROC which is declared as UINT __cdecl MyControllingFunction(LPVOID pParam);. You need to change your thread function to
UINT __cdecl FunctionThread(LPVOID pParam)
{
CthDlg& d = *reinterpret_cast<CthDlg*>(pParam);

My 'show progress thread' doesn't run when it counts

I have a thread that does lengthy processing. While I am waiting for the thread to finish, I kick start another 'show progress' thread which simply toggles a bitmap back and forth to show program is crunching on data. To my surprise this approached didn't work at all.
My 'show progerss' thread simply stop updating (=running) when the main activity starts and it starts updating when that activity ends. This is nearly the oppose of what I want! Should I expect this behavior because of the WaitForSingleOBjectwhich is in wait state for most of the time and wakes up briefly?
// This is the main thread that does the actual work
CWinThread* thread = AfxBeginThread(threadDoWork, this, THREAD_PRIORITY_LOWEST, 0, CREATE_SUSPENDED );
thread->m_bAutoDelete = FALSE;
thread->ResumeThread();
// before I start to wait on the above thread, I start this thread which will toggle image to show application is processing
AfxBeginThread(ProgressUpdateThread, &thread_struct_param, THREAD_PRIORITY_NORMAL, 0 );
// wait for the main thread now.
DWORD dwWaitResult = WaitForSingleObject( thread->m_hThread, INFINITE );
DWORD exitCode;
::GetExitCodeThread( thread->m_hThread, &exitCode );
delete thread;
// This thread toggles image to show activity
UINT ProgressUpdateThread(LPVOID param)
{
CEvent * exitEvent = ((mystruct *)param)->exitEvent;
MyView *view ((mystruct *)param)->view;
int picture = 0;
do
{
waitResult = WaitForSingleObject( exitEvent->m_hObject, 100);
if (waitResult == WAIT_TIMEOUT)
{
picture = toggle ? 1: 0;
// invert
toggle = !toggle;
View->Notify( UPDATE_IMAGE, picture );
}
else if (waitResult == WAIT_OBJECT_0)
{
return TRUE;
}
}
while( 1);
}
Another consideration in my solution is that I would like to not touch the actual 'DoWork' thread code and that's also why I am using separate thread to update GUI. Can I make this approach work? Is the only way to update GUI reliable is to update it from the actual 'DoWork thread itself?
I do want to clarify that my 'Show progress' thread does the job perfectly if the application is idle, but if I launch the worker thread operation (in lower thread priority), the update gui thread simply stops running and resume only when the worker finishes.
I am using Windows 7.
Your design is all wrong and over-complicated for what you are attempting. Try something more like this simpler solution:
bool toggle = false;
VOID CALLBACK updateProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
int picture = toggle ? 1: 0;
toggle = !toggle;
View->Notify( UPDATE_IMAGE, picture );
}
CWinThread* thread = AfxBeginThread(threadDoWork, this, THREAD_PRIORITY_LOWEST, 0, CREATE_SUSPENDED );
thread->m_bAutoDelete = FALSE;
thread->ResumeThread();
UINT_PTR updateTimer = SetTimer(NULL, 0, 100, updateProc);
do
{
DWORD dwWaitResult = MsgWaitForMultipleObjects(1, &(thread->m_hThread), FALSE, INFINITE, QS_ALLINPUT );
if (dwWaitResult == WAIT_OBJECT_0)
break;
if (dwWaitResult == (WAIT_OBJECT_0+1))
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
while (true);
KillTimer(NULL, updateTimer);
DWORD exitCode;
::GetExitCodeThread( thread->m_hThread, &exitCode );
delete thread;
If you do not want to use a standalone procedure for the timer, you can adjust the parameters of SetTimer() to have it post WM_TIMER messages to an HWND of your choosing instead, and then do the UI updates in that window's message procedure as needed. You would still need the message loop to pump the timer messages, though.
The alternative is to simply not do any waiting at all. Once you start the worker thread, move on to other things, and let the worker thread notify the main UI thread when it is done with its work.
Remy Lebeau pointed out correctly that my main GUI thread was actually waiting on the worker thread. Now since my worker gui-update thread was (obviously) calling gui function, it was in turn blocked on main GUI thread. I realized even SetWindowText() from a third thread will put that thread in wait if the main GUI thread is in wait or blocked state.
I don't like to use PeekandPump() mechanism, I thought it was a bad design smell. It was originally used in early windows (before win95 I think) which were not truly multitasking. To the best of my knowledge this should not be used now.
My solution was to put the whole code that I posted in OP in a new thread. So my button click in gui creates this threat and returns immediately. This master worker thread can now wait on other threads and my GUI will never block. When it gets completed, it post a message to the parent window to notify it. The bitmap is now changed perfectly using a separate gui-update thread when the application is processing in another thread.