The MASM Forum

General => The Campus => Topic started by: raleep on July 25, 2012, 01:29:17 PM

Title: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 25, 2012, 01:29:17 PM
I found some C code that allegedly does it:

public override bool PreProcessMessage(ref Message msg)
        {
            // Always check for your window as the recipient!
            if (msg.HWnd == this.Handle)
            {
                // msg.Msg 0x104 is for SysKey
                // WParam 0x20 is for space key
                // LParam 0x20390001 is for space key modified by alt key
                if (msg.Msg == 0x104 && msg.WParam.ToInt32() == 0x20 && msg.LParam.ToInt32() == 0x20390001)
                {
                   // Prevent the message from being process, thus preventing the pop-up
                   // Use this time to alert anything that you want to know that alt+space was received
                    MessageBox.Show(msg.ToString());
                    msg = new Message();
                }
            }
            return base.PreProcessMessage(ref msg);
        }


I tried the following in an attempt to implement this:


WProc proc wp_hWnd,uMsg,wParam,lParam

pushad
mov eax, [uMsg]
mov edx, [wParam]
mov ecx, [lParam]
                           ;test for and process messages
cmp eax, WM_SYSKEYDOWN
  jnz @F
cmp ecx,20390001       ;alt spacebar
  jnz key

popad
mov eax,OFFSET NewMessage      ;a 0-terminated string
ret

@@:                        ;continue testing messages


Not surprisingly this doesn't work.

How does the C code work (assuming it does)?

Can anyone help?

Thanks, Robert
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 25, 2012, 05:17:17 PM
Why so complicated? You could

- show the MsgBox until the user clicks cancel (which sets a "don't show again" flag, as in the deb macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1017))

- check for the state of CapsLock with GetKeyState (after all, you are only interested in your own app - otherwise use GetAsyncKeyState, but I doubt it will make a difference for CapsLock)

Or is there some other logic behind?
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 25, 2012, 11:20:49 PM
Quote from: jj2007 on July 25, 2012, 05:17:17 PM
Why so complicated? You could

- show the MsgBox until the user clicks cancel (which sets a "don't show again" flag, as in the deb macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1017))

The only options in the box are restore,minimize, and close (which exits the app),  Just pressing the alt key gets rid of the box, but I don't want it to show at all or require any action by the user.
Quote
- check for the state of CapsLock with GetKeyState (after all, you are only interested in your own app - otherwise use GetAsyncKeyState, but I doubt it will make a difference for CapsLock)

The CapsLock state has nothing to do with it.

Thanks,  Robert
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 25, 2012, 11:43:50 PM
You could set a flag in the WM_SYSKEYDOWN message, and then reset it in the WM_SYSKEYUP message.  Check the flag before you show the MessageBox.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 26, 2012, 12:11:01 AM
Quote from: Ryan on July 25, 2012, 11:43:50 PM
You could set a flag in the WM_SYSKEYDOWN message, and then reset it in the WM_SYSKEYUP message.  Check the flag before you show the MessageBox.

I don't "show the MessageBox".  It pops up automatically.  In almost any active window (not desktop, but explorer windows, browser windows, etc.).

I never noticed it before because I never had a reason to press alt+spacebar, but now I want to use alt+spacebar in ny app.

Thanks,  Robert
Title: Re: Block Popup Messagebox on alt+spacebar - Update
Post by: raleep on July 26, 2012, 12:14:37 AM
1.  The source of the C code is

Visual Studio Developer Center >Visual C# Forums > Visual C# Language > Disable Alt + Space
http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/3107c8df-8bb0-4152-ac1f-a86894972a6f
Post by IsshouFuuraibou Friday, November 03, 2006 6:47 AM

But I don't think there is any more information there.

2.  I also tried without success:

cmp eax, WM_SYSKEYDOWN
  jnz @F
cmp ecx,20390001       ;alt spacebar
  jnz key

popad
mov eax,OFFSET NewMessage      ;a 0-terminated string
mov uMsg,eax
xor     eax,eax
ret


The code is reached and executed, after which the popup appears (in the WinDbg debugger).

3.  The key routine executes popad
xor eax,eax
ret

whenever an alt key is detected (uMsg=12h).


Thanks,  Robert
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 26, 2012, 12:28:10 AM
So it's not a MessageBox you're trying to block; it's the system menu.

Depending on how you create your window, you can omit WS_SYSMENU.  This will also get rid of the minimize, maximize and close (X) buttons.  WS_SYSMENU is included in WS_OVERLAPPEDWINDOW.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: qWord on July 26, 2012, 12:36:07 AM
Removing TranslateMessage() from the message lopp maybe solve your problem.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 26, 2012, 12:41:21 AM
Would an Accelerator work?  If you let the Accelerator do the work, you could bypass TranslateMessage and DispatchMessage in your message loop entirely.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: qWord on July 26, 2012, 01:49:01 AM
Filtering WM_SYSCOMMAND seems also to work:
.elseif uMsg == WM_SYSCOMMAND
    .if !(wParam == SC_KEYMENU && lParam == 20h)
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 26, 2012, 04:51:51 AM
Quote from: Ryan on July 26, 2012, 12:28:10 AM
So it's not a MessageBox you're trying to block; it's the system menu.

Depending on how you create your window, you can omit WS_SYSMENU.  This will also get rid of the minimize, maximize and close (X) buttons.  WS_SYSMENU is included in WS_OVERLAPPEDWINDOW.

Yess!  That certainly appears to work.  I replaced WS_OVERLAPPEDWINDOW in my CreateWindowEx code by the other WS_'s included and, voila, no popup.  And I still have the minimize, maximize and close (X) buttons

I didn't know the popup was called the system menu.

Thank you!

Best wishes, Robert
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 27, 2012, 06:31:20 AM
Quote from: raleep on July 26, 2012, 04:51:51 AM

Yess!  That certainly appears to work.  I replaced WS_OVERLAPPEDWINDOW in my CreateWindowEx code by the other WS_'s included and, voila, no popup.  And I still have the minimize, maximize and close (X) buttons

Correction: I do not have the minimize, maximize and close (X) buttons.  And evidently WS_MINIMIZEBOX  & WS_MAXIMIZEBOX require WS_SYSMENU.

So I guess I'll go back to WS_OVERLAPPEDWINDOW, curse Microsoft, and use alt+w or some such instead of alt+spacebar.

Thanks,  Robert
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 27, 2012, 06:34:55 AM
Look at qWord's post about filtering WM_SYSCOMMAND.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 27, 2012, 07:07:49 AM
At the end of the WM_CREATE handler:
push rv(GetSystemMenu, hWnd, 0)
.Repeat
invoke DeleteMenu, [esp+8], 0, MF_BYPOSITION
.Until !eax
pop eax
No more menu with Alt Space... but there are side effects :icon_mrgreen:

Now, honestly, try this:
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif

:icon14:
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: npnw on July 27, 2012, 03:56:40 PM


http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx)

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633570(v=vs.85).aspx#designing_proc (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633570(v=vs.85).aspx#designing_proc)

Your application can call the DefWindowProc function as part of the processing of a message. In such a case, the application can modify the message parameters before passing the message to DefWindowProc, or it can continue with the default processing after performing its own operations.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms647591(v=vs.85).aspx

Accelerators
Accelerator keystrokes that select items from the window menu are translated into WM_SYSCOMMAND messages.
If an accelerator keystroke occurs that corresponds to a menu item when the window that owns the menu is minimized, no WM_COMMAND message is sent. However, if an accelerator keystroke occurs that does not match any of the items in the window's menu or in the window menu, a WM_COMMAND message is sent, even if the window is minimized.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646373(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646373(v=vs.85).aspx)

Applies to: desktop apps only
Processes accelerator keys for menu commands. The function translates a WM_KEYDOWN or WM_SYSKEYDOWN message to a WM_COMMAND or WM_SYSCOMMAND message (if there is an entry for the key in the specified accelerator table) and then sends the WM_COMMAND or WM_SYSCOMMAND message directly to the specified window procedure. TranslateAccelerator does not return until the window procedure has processed the message.

Return value
Type: int
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: npnw on July 27, 2012, 04:14:35 PM
keyboard accelerators
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646335(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646335(v=vs.85).aspx)

Enabled menuItem

http://msdn.microsoft.com/en-us/library/windows/desktop/ms647636(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms647636(v=vs.85).aspx)

MF_GRAYED
0x00000001L
Indicates that the menu item is disabled and grayed so that it cannot be selected.

All this to show that JJ disabled the popup menu item which was activated by the alt + space key sequence.

Hopefully all this jumping around explains what is going on in windows.

I thought it would explain JJ code.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 27, 2012, 06:05:50 PM
Thanks ;)
The second snippet
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif

works just fine and is a shorter variant of qWord's code. And it has no side effects :biggrin:
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 29, 2012, 09:25:41 AM
Quote from: jj2007 on July 27, 2012, 06:05:50 PM
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif

works just fine and is a shorter variant of qWord's code. And it has no side effects :biggrin:

Yes.  That works.  And this time I really do still have the minimize, maximize and close (X) buttons.

I'm curious as to where you got this.  The only thing I could find about return values from the windows procedure (specifically the WM_SYSCOMMAND notification) was:

Quote
Return Value

An application should return zero if it processes this message.

Anyway, thank you very much.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 29, 2012, 09:39:10 AM
Quote from: raleep on July 29, 2012, 09:25:41 AM
Yes.  That works.  And this time I really do still have the minimize, maximize and close (X) buttons.

I'm curious as to where you got this.
...
From good ol' Win32.hlp:
A window receives this message when the user chooses a command from the window menu (also known as the System menu or Control menu) or when the user chooses the Maximize button or Minimize button.
...
SC_KEYMENU   Retrieves the window menu as a result of a keystroke


So if you suppress that message, the menu will not be triggered by a keystroke...

QuoteAnyway, thank you very much.

My pleasure :icon14:
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: qWord on July 29, 2012, 09:57:35 AM
Quote from: jj2007 on July 27, 2012, 06:05:50 PM
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif

... And it has no side effects :biggrin:
AFAICS you can't control the menus with the keyboard anymore.
For common windows it also needed to call DefWindowProc - otherwise it is not possible to move, resize, maximize and minimize the window.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: raleep on July 29, 2012, 12:00:18 PM
Quote from: jj2007 on July 29, 2012, 09:39:10 AM

I'm curious as to where you got this.

Quote...
From good ol' Win32.hlp:
A window receives this message when the user chooses a command from the window menu (also known as the System menu or Control menu) or when the user chooses the Maximize button or Minimize button.
...
SC_KEYMENU   Retrieves the window menu as a result of a keystroke


So if you suppress that message, the menu will not be triggered by a keystroke...

But where do you get the "return 1"?  Why not return -1 or return 456789?

:idea: Ok, I get it (I think).  Returning anything but 0 prevents the os from processing the key, although that's not what I would expect from:

QuoteReturn Value

An application should return zero if it processes this message.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 29, 2012, 05:50:03 PM
Quote from: qWord on July 29, 2012, 09:57:35 AM
Quote from: jj2007 on July 27, 2012, 06:05:50 PM
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif

... And it has no side effects :biggrin:
AFAICS you can't control the menus with the keyboard anymore.
For common windows it also needed to call DefWindowProc - otherwise it is not possible to move, resize, maximize and minimize the window.

On my puter my code just works fine (XP SP3). Maybe something is wrong with your Windows installation.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: qWord on July 29, 2012, 09:28:03 PM
Quote from: jj2007 on July 29, 2012, 05:50:03 PM
Quote from: qWord on July 29, 2012, 09:57:35 AM
Quote from: jj2007 on July 27, 2012, 06:05:50 PM
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif

... And it has no side effects :biggrin:
AFAICS you can't control the menus with the keyboard anymore.
For common windows it also needed to call DefWindowProc - otherwise it is not possible to move, resize, maximize and minimize the window.

On my puter my code just works fine (XP SP3). Maybe something is wrong with your Windows installation.
The attached EXE won't work on Win7,x64. Maybe I've misunderstood your snippet.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 29, 2012, 10:11:30 PM
Is this a window proc versus dialog proc issue?

A dialog proc should return TRUE (1) if it handles the message, otherwise FALSE (0).

A window proc should return 0 if it handles the WM_SYSCOMMAND message, otherwise DefWindowProc needs to be called.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360%28v=vs.85%29.aspx)
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 30, 2012, 01:50:41 AM
qWord,
Most HLL including Masm use, in a WndProc, the SWITCH/CASE/ENDSW construct followed by a call to DefWindowProc:
SWITCH uMsg
...
CASE WM_SYSCOMMAND
.if wParam==SC_KEYMENU
return 1
.endif
...
ENDSW
invoke DefWindowProc, hWnd, uMsg, wParam, lParam


This construct can be left e.g. by mov eax, 1 + ret, thus avoiding the call to DefWindowProc. Your code never called DefWindowProc for the WM_SYSCOMMAND message, and therefore blocked everything related to the SYS_MENU.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: qWord on July 30, 2012, 03:56:46 AM
Quote from: jj2007 on July 30, 2012, 01:50:41 AMMost HLL including Masm use, in a WndProc, the SWITCH/CASE/ENDSW construct followed by a call to DefWindowProc
no, commonly DefWindowProc() is called from the default case.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 30, 2012, 06:30:15 AM
Quote from: qWord on July 30, 2012, 03:56:46 AM
Quote from: jj2007 on July 30, 2012, 01:50:41 AMMost HLL including Masm use, in a WndProc, the SWITCH/CASE/ENDSW construct followed by a call to DefWindowProc
no, commonly DefWindowProc() is called from the default case.

commonly? I like it empirically :biggrin:

356 files found
#file   default endsw   defpro  file
+#59    0       4776    4796    \masm32\examples\enumerate\enumdd\enumdd.asm
+#73    7055    7066    7683    \masm32\examples\exampl01\generic\generic_with_global_vars.asm
+#149   3933    4285    4305    \masm32\examples\exampl03\timer\timer.asm
+#202   0       7830    10871   \masm32\examples\exampl05\hlldemo\smalled\redit.asm
+#218   0       6239    6991    \masm32\examples\exampl05\scroll\scroll.asm
+#222   0       7198    8100    \masm32\examples\exampl05\switch\switch.asm
+#234   0       3827    3847    \masm32\examples\exampl06\barchart\barchart.asm
+#269   3860    5883    5903    \masm32\examples\exampl07\ani\ani.asm
+#281   4831    8052    8879    \masm32\examples\exampl07\mangled\mangled.asm
-#287   0       3633    0       \masm32\examples\exampl07\sdw\sdw.asm
+#313   4286    10931   15768   \masm32\examples\exampl07\skins3\skins3.asm
+#321   4797    8043    9476    \masm32\examples\exampl07\ttbar2\ttb2.asm
+#337   0       5467    6094    \masm32\examples\threads\multhread\multhrd.asm
+#346   4434    7319    7974    \masm32\examples\unicode_extended\uwin2\uwin2.asm
+#356   5275    9376    10331   \masm32\examples\unicode_generic\template\template.asm
15 files used SWITCH
14 =     93.0% had DefWindowProc after the ENDSW
1 =      6.7% had DefWindowProc between DEFAULT and ENDSW
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: qWord on July 30, 2012, 06:45:27 AM
Ich vertraue nur Statistiken die ich selbst gefälscht habe!
:bgrin:
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 30, 2012, 06:54:30 AM
Actually, sdw.asm is a "false negative", so it's 100% :P
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 30, 2012, 02:07:21 PM
What is the reason for returning 1?
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: jj2007 on July 30, 2012, 03:54:36 PM
Good question. Return 0 works equally good :biggrin:
Probably the OS doesn't check the return value.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: sinsi on July 30, 2012, 08:57:19 PM
Quote from: Ryan on July 29, 2012, 10:11:30 PM
A window proc should return 0 if it handles the message, otherwise DefWindowProc needs to be called.
A window proc should return whatever the WM_x return value says, e.g. WM_CTLCOLORSTATIC returns a brush, whereas WM_CREATE expects 0 to continue.
Title: Re: Block Popup Messagebox on alt+spacebar
Post by: Ryan on July 30, 2012, 09:25:40 PM
Thanks for the clarification sinsi.  I've updated my post :)