Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
_CONSOLEINPUT is blocking
#1
I can't find it in the documentation, but _CONSOLEINPUT seems blocking (waiting for a key) after the first call.

Code: (Select All)
$Console:Only
Do
  x%% = _ConsoleInput
  Print x%%;
Loop
Will only show one 0 and then waits for a keypress...
Is there any other way to check non-blocking for a key in a $CONSOLE window?
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#2
For a single keypress?  Not usually.  Why not create a normal program, hide the normal screen, use it to read the keystrokes via INKEY$ or _KEYHIT, and then process it on the visible CONSOLE if you need to do something like that?
Reply
#3
_CONSOLEINPUT is like _MOUSEINPUT, it just shows if new input is available and returns 1 for new keyboard input and 2 for new mouse input, however to retrieve the keyboard input use _CINP and for mouse the respective _MOUSExxx functions. _CONSOLEINPUT blocks until the actual input is retrieved, see example on the _CONSOLEINPUT and _CINP wiki pages.
Reply
#4
I'm with @mdijkens that this seems like a bug. We're currently calling `ReadConsoleInput` which blocks when there are no new events, we can call `GetNumberOfConsoleInputEvents` beforehand to check if it will block or not.
Reply
#5
(4 hours ago)RhoSigma Wrote: _CONSOLEINPUT is like _MOUSEINPUT, it just shows if new input is available and returns 1 for new keyboard input and 2 for new mouse input, however to retrieve the keyboard input use _CINP and for mouse the respective _MOUSExxx functions. _CONSOLEINPUT blocks until the actual input is retrieved, see example on the _CONSOLEINPUT and _CINP wiki pages.
Yes, I know, but the point is that it is blocking
Code: (Select All)
Do
  _Limit 10
  x%% = _ConsoleInput
  If x%% = 1 Then
    k& = _CInp
    Print k&;
  Else
    k& = 0
    Print "-";
  End If
Loop

Here I would expect to see --------------------------- all the time except when pressing keys
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#6
Just as @DSMan195276 mentioned above, it's the used WINAPI function which blocks until at least one input event could be read. I've made the fix suggested by him and will push it for the next release.

However, if you cant wait, here's the fixed version of the C-Function, just look for it in internal\c\libqb.cpp and replace it.

Code: (Select All)
int32 func__getconsoleinput() {
#ifdef QB64_WINDOWS
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD irInputRecord;
    DWORD dwEventsRead, fdwMode, dwMode;
    CONSOLE_SCREEN_BUFFER_INFO cl_bufinfo;

    GetConsoleMode(hStdin, (LPDWORD)&dwMode);
    fdwMode = ENABLE_EXTENDED_FLAGS;
    SetConsoleMode(hStdin, fdwMode);
    fdwMode = dwMode | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
    SetConsoleMode(hStdin, fdwMode);

    DWORD numEvents = 0;
    GetNumberOfConsoleInputEvents(hStdin, &numEvents);
    if (numEvents) {
        ReadConsoleInputA(hStdin, &irInputRecord, 1, &dwEventsRead);
        switch (irInputRecord.EventType) {
        case KEY_EVENT: // keyboard input
            consolekey = irInputRecord.Event.KeyEvent.wVirtualScanCode;
            if (!irInputRecord.Event.KeyEvent.bKeyDown)
                consolekey = -consolekey; // positive/negative return of scan codes.
            return 1;
        case MOUSE_EVENT: // mouse input
            consolemousex = irInputRecord.Event.MouseEvent.dwMousePosition.X + 1;
            consolemousey = irInputRecord.Event.MouseEvent.dwMousePosition.Y - cl_bufinfo.srWindow.Top + 1;
            consolebutton = irInputRecord.Event.MouseEvent.dwButtonState; // button state for all buttons
            // SetConsoleMode(hStdin, dwMode);
            return 2;
        }
    }
#endif
    return 0; // no or unhandled input
}

After that compile the following program and it should print "-" for no input, "M' for mouse input (Quick Edit mode must be off for mouse events (info added to the _CONSOLEINPUT Wiki page)) and the respective scan codes for keyboard input.

Code: (Select All)
$CONSOLE:ONLY

DO
_LIMIT 10
x%% = _CONSOLEINPUT
IF x%% = 1 THEN
k& = _CINP
PRINT k&;
ELSEIF x%% = 2 THEN
k& = 0
PRINT "M";
ELSE
k& = 0
PRINT "-";
END IF
LOOP
Reply
#7
That is great.
I am going to make that change.
Would be nice to have that in next version; waiting for input is easy enough if you still need that
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply




Users browsing this thread: mdijkens, 3 Guest(s)