Why's ALT pausing my app in windowed mode?

BlitzPlus Forums/BlitzPlus Programming/Why's ALT pausing my app in windowed mode?

sswift(Posted 2005) [#1]
Why is ALT pausing my app when it is running in a window?

I've triple checked my code... I never added a pause function. I never read the alt key.

When I press alt in my browser I notice the file menu is highlighted but doesn't open. Same for media player. I'm guessing this is why my app is pausing.

How can I stop this behavior?


CS_TBL(Posted 2005) [#2]
If you have a window with a menu (even if nothing is in it), then ALT triggers the menu, and all the rest stops. Create the window without menu.


sswift(Posted 2005) [#3]
I did create my window without a menu.

Window = CreateWindow(APPLICATION_NAME$, Window_X, Window_Y, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1+2+32)


sswift(Posted 2005) [#4]
It's the 1 flag that's causing it. The 4 flag also causes it, but I don't have that.

The 1 flag makes the title bar. The 4 flag makes the menu.

If I remove the 1 flag, then I will no longer have buttons to minimize, maximize, and close the window. Also, there will be no title bar to grab to move the window around. That's unacceptable!

There's gotta be some way to fix this. This is a language for making games. CTRL, ALT, and SHIFT are very important keys for games. We must be able to access them without triggering the menu and pausing the game, even if we have a title bar AND a menu!

There's gotta be a windows function I can call to disable this behavior... Unfortunately I don't have a clue what terms I could use to search for it on MSN because the word ALT and PAUSE bring up hundreds of irrelevant pages.


CS_TBL(Posted 2005) [#5]
yeah, I just tested with flag=0 ... no issues anymore then..


CS_TBL(Posted 2005) [#6]
Well, you can try to make your own titlebar and close/minimize/maximize buttons using canvasses orso .. I did that once.. works like a charm. You're basically overruling standard windows shortcuts by having your own buttons..


sswift(Posted 2005) [#7]
Making my own title bar and buttons with canvasses? That's crazy talk. :-) I'm not doing that!

It would look different from the standard windows interface, and be a pain in the ass to add menu options to if I chose to do that.

No, there must be some way to disable this behavior. I simply don't want pressing alt to activate the menu. That doesn't seem like it would be impossible to accomplish.


WolRon(Posted 2005) [#8]
You might try this command:?
GetAsyncKeyState(somekeyvaluehere)

It requires this userlib declarations:
.lib "user32.dll"
GetAsyncKeyState%(virtualkeycode%):"GetAsyncKeyState"


CS_TBL(Posted 2005) [#9]
Dunno for sure, but I don't think that works.. it only grabs the keystate, but meanwhile windows continues to link that ALT keypress to the menu..


Arem(Posted 2005) [#10]
Graphics 800,600,32,2

Or whatever resolution you choose.


sswift(Posted 2005) [#11]
Arem:
That gives me a window with a title bar, but no X to close it, and no way to modify it. I can't maximize it, I can't minimize it, I can't add a file menu or a config screen.

I know it is possible to do what I want to do, because the game Demonstar does it. I'll just have to ask that guy I guess. :-)


Grey Alien(Posted 2005) [#12]
Only prob with GetAsyncKeyState is that altough you may be able to capture and process the key, you won't have stopped windows from processing it too. There are other windows api commands that let you get the key, process it and remove it from the buffer to stop windows using it.


sswift(Posted 2005) [#13]
Someone on flipcode suggested the following, and for windows without menus, it appears to be the case that there is still a "system menu", but I still need a way to bypass it, and it doesn't solve the problem with the menus.


Hi there !

Your problem is the system menu, I guess, which is always there for normal windows ;) It not only reacts to ALT key presses, but also on the F10 key, and on right-clicking window buttons in the taskbar. Try pressing Alt and "Arrow down" after that to see the system menu.

If you were able to change the window callback function somehow, you could try catching the key events before passing to DefWindowProc, and see if that helps.

Alternatively, you might try if there is a combination of window flags which disable the system menu (i.e. SetWindowLong or a similiar call). If I remember right though, disabling the system menu will also hide the maximize and minimize buttons of your window




VIP3R(Posted 2005) [#14]
I've been trying to find you a solution here sswift but I haven't been able to change the SYSMENU to accept min, max and close buttons while the menu is disabled.

It's almost like the min, max and close buttons are classed as menu items themselves :/

The easiest workaround would be to create a window using the Graphics command, then create buttons for min, max and close inside the window. (which is crappy, I know)

Anyway, I'll keep trying and let you know if I have any luck with it.


CS_TBL(Posted 2005) [#15]
If it isn't for a pulldown menu, manually making a dragable titlebar, and some minimize/restore/close buttons sounds (to me) like a solution for the moment..


Blitz Amateur(Posted 2005) [#16]
I know how to fix your problem, use a bitwise OR rather than a '+'.

Try this out

Window = CreateWindow(APPLICATION_NAME$, Window_X, Window_Y, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1 Or 2 Or 32)

|EDIT|
I just tested this and it works perfectly to eliminate the menu
|EDIT|


sswift(Posted 2005) [#17]
Amateur:
1+2+32 gives you the same result as doing a bitwise OR if each value sets only one bit, which they do.

1 Or 2 Or 32 = 35


The problem isn't the window menu, it is the window system menu. The one hidden under the icon to the left of the window title. The one that lets you close the window, minimize, or maximize it with a menu. It apepars you can't get rid of that without getting rid of the close, min and max buttons on the right side of the window.


Blaine(Posted 2005) [#18]
Use this command on the window, with the parameter being the handle for the window:
Function RemoveSysMenu(win)
hWnd=QueryObject(win,1)
s=GetWindowLong(hWnd, -16)
s=s Xor $80000				;Turn WS_SYSMENU off, thus removing the system menu
SetWindowLong hWnd, -16, s
End Function

Requires the following userlibs:
.lib "user32.dll"
GetWindowLong%(hWnd%, nIndex%) : "GetWindowLongA"
SetWindowLong%(hWnd%, nIndex%, Value%) : "SetWindowLongA"

I tested it and didn't have any problems.


CS_TBL(Posted 2005) [#19]
Are there clear beginner-tutorials on those alien commands (Queryobject etc.) in combination with working with those userlibs somewhere?


Blaine(Posted 2005) [#20]
I don't know about the API commands, but QueryObject() is a B+ command, included in the manual here: http://www.blitzbasic.com/bpdocs/command.php?name=QueryObject&ref=2d_cat


CS_TBL(Posted 2005) [#21]
I hardly call *that* help bit a beginner-tutorial :)


VIP3R(Posted 2005) [#22]
All it does is grab the Windows compatible handle of a Blitz gadget, what more do you need to know?

Blitz's internal handles won't work with Win32 API (userlib) calls, so to pass the handle of a Blitz gadget to the Windows API functions you need to use QueryObject to retrieve the Windows compatible handle first.

I've got the feeling I'm going to have to explain this again in more detail :)


sswift(Posted 2005) [#23]
Blaine:
That appears to work. Thanks. :-)

But there's still one problem. When you maximize the window, the window icon on the left, and all the buttons on the right disspear, and do not reappear when you make the window normal sized again.


Grey Alien(Posted 2005) [#24]
sswift: I am having similar problems (but luckily my game doesn't use Alt). It seems you can't have a minimise and close on the left without having the system menu on the right. Kill the system menu and you loose the minimise and close icons. Did you find a solution yet?

In my platform game I was using shift and ctrl but if you press them rapidly (or hold them for a long time), windows sticky keys pops up and you have to disable it. This stinks. I have documented it in the readme but really I want to stop windows processing Alt, Ctrl and Shift, and the Windows Key whilst I'm at it but Blitz Plus lets Windows have them first which is a bummer for a games language. Anyone got any tips about this? I could start a new thread I guess.


Grey Alien(Posted 2005) [#25]
OK I have a possible workround. Note that your app can still trap the Left Alt key (right alt doesn't activate the menu), but that FlushKeys doesn't stop windows from getting it. Well to unpause you have to press escape, so what about poking an escape #27 keypress into the keyboard buffer so that windows immediately unpauses. This would work for general apps but maybe not for games as the delay could be too long. Anyone know how to poke a key into the buffer as I would really find this useful?

What blitz really needs (instead of extra dlls) is a global variable (or function) you can set called GiveWindowsKeys that you can set to false so your game has complete control just like other professional games out there.


sswift(Posted 2005) [#26]
Grey:
Well I haven't had time to test my theory, but I figure that I can save the window flags and then when I detect that the user has maximized or minimized the winddow, I can reset those flags to the state I want them to be in. That should restore the buttons that dissapeared.


Grey Alien(Posted 2005) [#27]
sound plausible. Please let me know if you find out how to detect when the user has clicked the minimise button as it's the answer to an earlier topic of min.


sswift(Posted 2005) [#28]
Grey:
This probably isn't the best method and I'm sure I will find stuff on MSDN to do it properly, but each time you maximize, restore, or minimize a window, a $801 window position event is generated. If this position is -4 -4 then the window has been maximized, and if it is -32000 -32000 it has been minimized.

But it is possible to get -4 -4 just by positioning the window so you probably do not want to go off that alone.

An event 802 is also generated immediately after the 801 event, so you might use that info in conjunction.

I would look on MSDN though and find the right windows function to call to get the window state. I'm sure there must be one. Maybe someone realdy added a function to do it to the code archives.


Grey Alien(Posted 2005) [#29]
OK I have a "workaround/hack" for the alt pausing problem.
define these constants:
Const LEFT_ALT = 56
Const KEYEVENTF_KEYUP = 2			

Then add this of code to your main loop:
If KeyHit (LEFT_ALT) Then			
User32_keybd_event(255,0,0,0)
User32_keybd_event(255,0,KEYEVENTF_KEYUP,0)
EndIf

It requires that you have made a user.decls file with this in it:
.lib "user32.dll"
User32_keybd_event%(bVk%, bScan%, dwFlags%, dwExtraInfo%) : "keybd_event" 

Basically, when alt is pressed, the blitz program intercepts it and pushes a 255 Key Down (and Key Up (for safety)). This modifies the alt key press so that it thinks alt+255 is pressed (which doesn't exist) and thus the window menu is not focused. Tada.


sswift(Posted 2005) [#30]
That might only be useful if you don't expect the player to be using the arrow keys at the same time or also pressing control?


Grey Alien(Posted 2005) [#31]
As I said, in my game Alt isn't used, so it is a useful prevention of the app pausing if they accidentally press it during windowed mode.

*** Actually, I just tested it and you can press the arrow keys and control at the same time with no obvious problems!


sswift(Posted 2005) [#32]
I just found out that the suggestion of changing the window flags to remove the system menu actually deactivates the minimize and maximize buttons. I didn't realise clicking the title bar would maximize the window, so I thought that indicated it was working.

Also, restoring the flags to the state you set them to to remove the system menu doesn't return the buttons to normal.

It appears that the buttons stay there simply because the border of the window is not redrawn until the window is resized.

I guess I'll try your solution next Grey, and see if it works for me.


Grey Alien(Posted 2005) [#33]
Yeah, I found that flag thing out when I just tried to add minimise. It didn't work until I added the system menu. Also the buttons don't appear until you call ShowWindow or WindowPos (or drag it). So you must have been experiencing the reverse.

I admit my solution is a bit of an unsatisfactory hack, which could have side effects, but if it works, then great. Really we just need a nice Windows Keyboard Hook to be programmed for us.


Nicstt(Posted 2005) [#34]
using this to stop it affecting the program

		Case EVENT_KeyUp
			If EventData() = 1 ; quit
				Gosub freeallgadgets : EndGraphics : End
			EndIf
			If EventData() = 56 Or EventData() = 184 ; if Alt key pressed activate main window as will pause program
				ActivateGadget encoderwindow
			EndIf



sswift(Posted 2005) [#35]
Nic:
That does not work.

I don't know WHY it doesn't work, but it doesn't work.

Even if you call ActivateGadget every loop regardless of what keys are pressed, it still doesn't unpause it.


T-C(Posted 2014) [#36]
i recently ran into this problem again, albeit in blitz3d, and solved it using GrayAlien's solution, which works both in blitz3d and blitzplus.

here's the blitzplus code that makes it work:
AutoSuspend False

..

window = CreateWindow("",0,0,400,300,0,1)

..

    WaitEvent()
    
    Select EventID()
        Case $101  ; key down
            ; left/right alt
            If EventData()=56 Or EventData()=184
                ; release keys instantly
                api_keybd_event $FF,0,2,0
            End If


for blitz3d it's simply:
    If KeyHit(56) or KeyHit(184)
        api_keybd_event $FF,0,2,0
    End if


also, in blitz3d, to quickly release all keys (like shift, ctrl and alt hanging or stuck), for example when opening an external windows dialog (like a file requester), here's a nifty trick to perform just before for example opening such a dialog:
EnableDirectInput DirectInputEnabled()