Replacing+the+message+pump

//by Richard Russell, January 2012//

In Windows, every User Interface (UI) thread must have a [|message pump] (or message loop), the function of which is to serialise and dispatch incoming messages to their destination windows.

In //BBC BASIC for Windows// the message pump is provided by the Run Time Engine, and generally the programmer doesn't need to be aware of it. For anybody who may be interested, this is its C code: code format="C" while (GetMessage (&msg, NULL, 0, 0) != FALSE ) {      if (((hwndMDIC == NULL) || !TranslateMDISysAccel (hwndMDIC, &msg))       && ((haccel == NULL) || !TranslateAccelerator (hwacc, haccel, &msg))) {          TranslateMessage (&msg) ; DispatchMessage (&msg) ; }    } code Very occasionally there may be a requirement to use a different message pump. For example, in order for **keyboard navigation** to work in a dialogue box, the message pump must include a call to the [|IsDialogMessage] API.

Until very recently I believed that it was impossible to //replace// the existing BB4W message pump, and that therefore the only way to provide a different one was to start a new thread (each thread has its own message pump). This is the principal reason why the **WINLIB2** library creates a new thread for every new dialogue box created.

However I have discovered that in fact there is a way of replacing the 'main' message pump, and the procedure listed below does exactly that: code format="bb4w" DEF PROCnewmessagepump LOCAL K%, L%, M%, N%, O%, P%, S%, U%, code%, pass% DIM code% 130, L% -1 FOR pass% = 8 TO 10 STEP 2 P% = code% [OPT pass% .K%       add esp,28 ret 16 .N%       sub esp,28 push 0 : call "ReplyMessage" .U%       push @hwnd% : call "IsWindow" : or eax,eax : jz K%        mov eax,esp : push 0 : push 0 : push 0 : push eax call "GetMessage" : or eax,eax : jz K%       push esp : push @haccel% : push @hwnd% : call "TranslateAccelerator" or eax,eax : jnz U%       call "GetForegroundWindow" cmp eax,@hwnd% : jz S%       push esp : push eax : call "IsDialogMessage" or eax,eax : jnz U%       .S%        push esp : call "TranslateMessage" push esp : call "DispatchMessage" jmps U%       .M% cmp dword [esp+8],&502 : jz N%        pop eax : push [^O%] : push eax : jmp "CallWindowProc" ]     NEXT pass% SYS "GetWindowLong", @hwnd%, -4 TO O%     SYS "SetWindowLong", @hwnd%, -4, M%      SYS "SendMessage", @hwnd%, &502, 0, 0 SYS "SetWindowLong", @hwnd%, -4, O%     SYS "SendMessage", @hwnd%, 0, 0, 0 ENDPROC code