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
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?
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
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.
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
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
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.
Removing TranslateMessage() from the message lopp maybe solve your problem.
Would an Accelerator work? If you let the Accelerator do the work, you could bypass TranslateMessage and DispatchMessage in your message loop entirely.
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
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
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
Look at qWord's post about filtering WM_SYSCOMMAND.
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:
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.
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.
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:
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.
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 keystrokeSo if you suppress that message, the menu will not be triggered by a keystroke...
QuoteAnyway, thank you very much.
My pleasure :icon14:
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.
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.
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.
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.
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)
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.
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.
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
Ich vertraue nur Statistiken die ich selbst gefälscht habe!
:bgrin:
Actually, sdw.asm is a "false negative", so it's 100% :P
What is the reason for returning 1?
Good question. Return 0 works equally good :biggrin:
Probably the OS doesn't check the return value.
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.
Thanks for the clarification sinsi. I've updated my post :)