flat assembler
Message board for the users of flat assembler.

Index > Windows > ReadConsoleInput

Author
Thread Post new topic Reply to topic
Ralph



Joined: 04 Oct 2003
Posts: 86
Ralph
Hey,

I'm trying to use ReadConsoleInput but for some reason I can only filter key events when in full screen mode. When the window is not full screened, it doesn't detect any keys pressed.

Code:
key:
    push    .count
    push    1
    push    .event
    push    dword [.stdin]
    call    dword [ReadConsoleInput]
    cmp     word  [.event],1
    jnz     key
    cmp     word  [.down],0
    jnz     key
    ret
.event dw 0
.down  dw 0
.rep   dw 0
.kcode dw 0
.scode dw 0
.char  db 0
.state dd 0  
    

This only returns when in full screen mode. I couldn't find those constants so I got them by trail and error. Any ideas what I'm doing wrong?
Post 30 Jul 2004, 07:29
View user's profile Send private message Reply with quote
mike.dld



Joined: 03 Oct 2003
Posts: 235
Location: Belarus, Minsk
mike.dld
Code:
typedef struct _KEY_EVENT_RECORD {
    BOOL bKeyDown;
    WORD wRepeatCount;
    WORD wVirtualKeyCode;
    WORD wVirtualScanCode;
    union {
        WCHAR UnicodeChar;
        CHAR   AsciiChar;
    } uChar;
    DWORD dwControlKeyState;
} KEY_EVENT_RECORD, *PKEY_EVENT_RECORD;

#define KEY_EVENT         0x0001 // Event contains key event record
#define MOUSE_EVENT       0x0002 // Event contains mouse event record
#define WINDOW_BUFFER_SIZE_EVENT 0x0004 // Event contains window change event record
#define MENU_EVENT 0x0008 // Event contains menu event record
#define FOCUS_EVENT 0x0010 // event contains focus change

typedef struct _INPUT_RECORD {
    WORD EventType;
    union {
        KEY_EVENT_RECORD KeyEvent;
        MOUSE_EVENT_RECORD MouseEvent;
        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
        MENU_EVENT_RECORD MenuEvent;
        FOCUS_EVENT_RECORD FocusEvent;
    } Event;
} INPUT_RECORD, *PINPUT_RECORD;

WINBASEAPI
BOOL
WINAPI
ReadConsoleInputA(
    IN HANDLE hConsoleInput,
    OUT PINPUT_RECORD lpBuffer,
    IN DWORD nLength,
    OUT LPDWORD lpNumberOfEventsRead
    );    


The Extension 'h' was deactivated by an board admin, therefore this Attachment is not displayed.

Post 30 Jul 2004, 11:38
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
mike.dld



Joined: 03 Oct 2003
Posts: 235
Location: Belarus, Minsk
mike.dld
Code:
proc getch
        invoke  FlushConsoleInputBuffer,[hConsIn]
    @@:
        invoke  ReadConsoleInput,[hConsIn],lpBuffer,1,lpEventsRead
        cmp     [lpBuffer.EventType],KEY_EVENT
        jne     @b
        ret
endp

lpEventsRead dd ?

lpBuffer:
  .EventType dw ?
   rw 7    
Post 30 Jul 2004, 12:32
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Ralph



Joined: 04 Oct 2003
Posts: 86
Ralph
Thanks a lot. Exactly what I'm looking for.

I used that same code but it still only works on full screen mode. Is that supposed to happen?
Post 30 Jul 2004, 18:44
View user's profile Send private message Reply with quote
Posetf



Joined: 01 Mar 2004
Posts: 35
Location: London
Posetf
Hi. I'm only here because I'm trying to find out more about "ReadConsoleInput", somthing I know *nothing* about, so YMMV. (I've scanned, but not digested the windows API docs)
The following snippet of C code (which is brand new to me) lead me here. I really cannot say, but maybe SetConsoleMode may help you.

Apologies if this is a total red herring, but here goes, cut 'n paste:

int get_event(){
int ret_val=1;
bSucces = GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),&dwInputMode);
bSucces = SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwInputMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));
bSucces = ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE),&inputBuffer,1,&dwInputEvents);
switch (inputBuffer.EventType)
{
case KEY_EVENT:
if(inputBuffer.Event.KeyEvent.bKeyDown) {
// printf("virtueel ; %d\n",inputBuffer.Event.KeyEvent.wVirtualKeyCode);
// printf("scan ; %d\n",inputBuffer.Event.KeyEvent.wVirtualScanCode);
// printf("ascii ; %d\n",inputBuffer.Event.KeyEvent.uChar.AsciiChar);
last_key=inputBuffer.Event.KeyEvent.uChar.AsciiChar;
if (last_key==0)last_key=256+inputBuffer.Event.KeyEvent.wVirtualScanCode;
} else {
last_key = 0; /* key up */
}
break;
case MOUSE_EVENT:
// printf("position ; %d %d\n",inputBuffer.Event.MouseEvent.dwMousePosition.X,mouseBuffer.Event.MouseEvent.dwMousePosition.Y);
// printf("state ; %d\n",inputBuffer.Event.MouseEvent.dwButtonState);
// printf("event ; %d\n",inputBuffer.Event.MouseEvent.dwEventFlags);
last_mouse_bot = inputBuffer.Event.MouseEvent.dwEventFlags +
2 * inputBuffer.Event.MouseEvent.dwButtonState;
last_mouse_y = inputBuffer.Event.MouseEvent.dwMousePosition.Y+1;
last_mouse_x = inputBuffer.Event.MouseEvent.dwMousePosition.X+1;
break;
default:
// onbekend event
ret_val = 0;
break;
}
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
bSucces = SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwInputMode);
return ret_val;
}
Post 05 Oct 2004, 23:07
View user's profile Send private message Visit poster's website Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
Hi all,
I'm experimenting on mouse and keyboard console events.
I found examples about ReadConsoleInput but mostly on c/c++.
Anyway i need your lights, i'm trying to get mouse x,y and print it, but i'm not sure i'm doing things the right way.
Here's my code so far:


Code Removed, 'Capturing Mouse and Keyboard Console Events example' below.


Last edited by Picnic on 16 Jan 2010, 14:44; edited 1 time in total
Post 17 Feb 2008, 10:51
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17269
Location: In your JS exploiting you and your system
revolution
Your union in EVENTS_UNION is wrong. Use a virtual block to define the union.
Post 17 Feb 2008, 10:55
View user's profile Send private message Visit poster's website Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
I never used virtual block feature, i'm reading now the manual.
Can you give me an example?
Thanks revolution.
Post 17 Feb 2008, 11:12
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17269
Location: In your JS exploiting you and your system
revolution
Code:
struc     EVENTS_UNION {
    virtual
  .MouseEvent             MOUSE_EVENT_RECORD
    end virtual
    virtual
        .WindowBufferSizeEvent  WINDOW_BUFFER_SIZE_RECORD
    end virtual
    virtual
 .MenuEvent              MENU_EVENT_RECORD
    end virtual
    virtual
 .FocusEvent             FOCUS_EVENT_RECORD
    end virtual
       .KeyEvent               KEY_EVENT_RECORD
}    
The KEY_EVENT_RECORD is put last because it is the largest record.
Post 17 Feb 2008, 11:39
View user's profile Send private message Visit poster's website Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
Thanks revolution.

This sample for win32 console, shows how to capture mouse and keyboard input events.
It can be easily expanded and used as basis for something bigger.

Link


Last edited by Picnic on 11 Sep 2013, 19:34; edited 2 times in total
Post 16 Jan 2010, 14:53
View user's profile Send private message Reply with quote
Dean



Joined: 27 Feb 2010
Posts: 3
Dean
I have a variation on this question. I would like to write a routine that emulates (more or less) the old INKEY$ function found in QuickBasic, FreeBasic and others. In Windows Console mode, it polls the keyboad 'on the fly' and returns an ASCII string value rather than a keyscan value and does not echo the character to the screen. Function keys and other special keys return a two string value. It is normally used within a loop. I've been trying to get it to work modifying the above example by 'Picnic' via ReadConsoleInput and checking InRec.Event.KeyEvent.wChar.Asciichar but no go. I've been working on this for some time and have tried to scour the forums but can't quite see what I need. My plan is to make this a Proc as part of a simple set of procs. Maybe someone has already done similar?? Thanks.
Post 27 Feb 2010, 23:29
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
Hi Dean,

Here is a simple INKEY$ like routine to help you start.
It needs the INPUT_RECORD structure from the console example above.

http://board.flatassembler.net/topic.php?p=154986#154986

Link update 3 Mar 2013


Last edited by Picnic on 03 Mar 2013, 20:03; edited 1 time in total
Post 07 Mar 2010, 01:37
View user's profile Send private message Reply with quote
Dean



Joined: 27 Feb 2010
Posts: 3
Dean
Thanks Picnic. I'll let you know how I go with this one. My goal is to produce a suite of console functions that can assembled into a DLL using FASM. I have successfully implemented several functions so far. Next puzzling one is being able to read one character from any location on the display to find out what its ASCII value is. ReadConsoleOutputCharacterA is supposed to do this, I think, but I haven't been successful. Then there's resetting window sizes, the font size and copying the characters and attributes from one buffer to another. If you or anyone else has a good reference on this, I would certainly appreciate it.
Post 11 Mar 2010, 05:10
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
Scan the fasm board Dean, a lot of code lines just hanging around. Razz

Quote:
Then there's resetting window sizes

I also experience some win32 console resize issues.
This microsoft piece of code works satisfying enough under XP & Vista.


Last edited by Picnic on 20 Feb 2013, 18:49; edited 3 times in total
Post 11 Mar 2010, 19:54
View user's profile Send private message Reply with quote
Dean



Joined: 27 Feb 2010
Posts: 3
Dean
Thanks. Sorry for the delay replying. I got the Inkey function working but hit a brick wall when trying to read a single character from the screen buffer. It should be via ReadConsoleOutputCharacterA but every time I try I always get a result of 32. No matter what coordinate I give even if the screen is full of characters. I have C code from a few sources that claims to work. The next trick after that is to copy the entire contents from a visible screen to another console buffer and then later, back again.

Honestly, I wish I had time to do the "scanning" of the boards. I have tried numerous searches and that's always the trick, getting the correct terms.
Post 22 Mar 2010, 03:04
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
Quote:
This microsoft piece of code works satisfying enough under XP & Vista.


I bring back the console window resize issue with a new code sample slightly different from above link.
It seems to work now in most cases.

Code:

        ;------------------------------------
        ;   Win32 Console Application
        ;   -- Resize Console Window
        ;   v0.1 14 Oct 2010
        ;   v0.2 17 Mar 2012
        ;------------------------------------
        ;   Author: Picnic
        ;   Fasm v1.69.42
        ;------------------------------------

        format PE CONSOLE 4.0

        include "include\win32ax.inc"

;------------------------------------------------------------
;
section ".data" data readable writeable
;
;------------------------------------------------------------
        hStdOut dd 0

    struct COORD
        X dw ?
        Y dw ?
    ends

    struct SMALL_RECT
        Left dw ?
        Top dw ?
        Right dw ?
        Bottom dw ?
    ends

;------------------------------------------------------------
;
section ".text" code readable executable
;
;------------------------------------------------------------
main:
        invoke GetStdHandle, STD_OUTPUT_HANDLE
        mov [hStdOut], eax

        stdcall WINDOW, [hStdOut], 60,30

        invoke Sleep, 2000

        invoke ExitProcess, 0


;------------------------------------------------------------
;
proc WINDOW uses ecx edx, handle, x, y
;   Usage:
;       stdcall WINDOW, output_handle, cols, rows
;   Returns:
;       EAX = zero on success, else -1.
;
;------------------------------------------------------------
        local coord COORD
        local rect SMALL_RECT

        ;cmp [x], MIN_COLS
        ;jb .error
        ;cmp [y], MIN_ROWS
        ;jb .error
        ;cmp [x], MAX_COLS
        ;ja .error
        ;cmp [y], MAX_ROWS
        ;ja .error

        cmp [handle], 0
        je .error

        ; Get the largest size we can size the console window to.
        invoke GetLargestConsoleWindowSize, [handle]
        mov [coord], eax

        mov [rect.Left], 0
        mov [rect.Top], 0
        mov [rect.Right], 1
        mov [rect.Bottom], 1

        ; Set window size to 1,1 in order to set any buffer size.
        invoke SetConsoleWindowInfo, [handle], TRUE, addr rect
        test eax, eax
        jz .error

        ; rect.Right = min(x, coord.X) - 1)
        mov eax, [x]
        movzx ecx, word [coord.X]
        sub ecx, eax
        sbb edx, edx
        and ecx, edx
        add eax, ecx
        dec eax
        mov [rect.Right], ax

        ; rect.Bottom = min(y, coord.Y) - 1)
        mov eax, [y]
        movzx ecx, word [coord.Y]
        sub ecx, eax
        sbb edx, edx
        and ecx, edx
        add eax, ecx
        dec eax
        mov [rect.Bottom], ax

        ; Define the new console buffer size.
        mov ax, word [x]
        mov [coord.X], ax
        mov ax, word [y]
        mov [coord.Y], ax

        ; Set console screen buffer size.
        invoke SetConsoleScreenBufferSize, [handle], dword [coord]
        test eax, eax
        jz .error

        ; Set console screen buffer's window size and position.
        invoke SetConsoleWindowInfo, [handle], TRUE, addr rect
        test eax, eax
        jz .error

        xor eax, eax
        ret

            .error:
        mov eax, -1
        ret
endp

.end main 
    



Image


Last edited by Picnic on 21 Mar 2020, 11:01; edited 2 times in total
Post 14 Oct 2010, 20:30
View user's profile Send private message Reply with quote
TheRaven



Joined: 22 Apr 2008
Posts: 89
Location: U.S.A.
TheRaven
PicNic -- it looks legible to boot -- that's some gorgeous code brother.

Code works fine.

I guess it fires up a console at a predetermined width and height at specified coordinates then. Bringing the GUI a little closer to the counter top console.

Interesting, especially for shell programmers and stuff and wouldn't that be fun?

I'm guilty of thinking about the undertaking, but who the hell hasn't -- it's so freaking cliche -- Oh well, I'm gonna try it anyway. Firstly, I gotta get my skull around this FASM stuff. A shell is my next opus -- fun, fun yeah, fun...


Last edited by TheRaven on 20 Sep 2011, 17:28; edited 1 time in total
Post 14 Sep 2011, 09:10
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Dean wrote:
I have a variation on this question. I would like to write a routine that emulates (more or less) the old INKEY$ function found in QuickBasic, FreeBasic and others. Maybe someone has already done similar?? Thanks.


Other solution: http://board.flatassembler.net/topic.php?t=11172
Post 18 Sep 2011, 08:49
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1288
Location: behind the arc
Picnic
Some more console stuff, this sample shows how to obtain a console window handle (HWND).
It may be useful to someone.

Code:
            ;------------------------------------
            ;   Win32 Console Application
            ;   -- How To Obtain a Console Window Handle (HWND)
            ;   http://support.microsoft.com/kb/124103
            ;------------------------------------
            ;   Author: Picnic
            ;------------------------------------

            format PE CONSOLE 4.0

            include "win32ax.inc"

.data
            LINESZ = 1024
            hWnd dd ?

.code
main:
            stdcall GetConsoleHwnd
            mov [hWnd], eax
            ;
            ;
            invoke ExitProcess, 0



proc GetConsoleHwnd uses ecx edx

            local hwndFound dd ?
            local pszNewWindowTitle dd ?
            local pszOldWindowTitle dd ?

            mov eax, LINESZ
            shl eax, 1

            ; Allocate memory.
            invoke LocalAlloc, LPTR, eax
            test eax, eax
            jz .error

            mov [pszOldWindowTitle], eax
            add eax, LINESZ
            mov [pszNewWindowTitle], eax

            ; Fetch current window title.
            invoke GetConsoleTitle, [pszOldWindowTitle], LINESZ
            test eax, eax
            jz .error

            ; Format a "unique" NewWindowTitle.
            cinvoke wsprintf,\
                [pszNewWindowTitle], "%d/%d",\
                <invoke GetTickCount>,\
                <invoke GetCurrentProcessId>

            ; Change current window title.
            invoke SetConsoleTitle, [pszNewWindowTitle]
            test eax, eax
            jz .error

            ; Ensure window title has been updated.
            invoke Sleep, 40

            ; Look for NewWindowTitle.
            invoke FindWindow, 0, [pszNewWindowTitle]
            test eax, eax
            jz .error

            mov [hwndFound], eax

            ; Restore original window title.
            invoke SetConsoleTitle, [pszOldWindowTitle]
            test eax, eax
            jz .error

            ; Free memory.
            invoke LocalFree, [pszOldWindowTitle]
            test eax, eax
            jz .error

            mov eax,  [hwndFound]
            ret

                .error:
            mov eax, -1
            ret
endp

.end main
    
Post 26 Mar 2012, 18:32
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
Isn't this one easier:
http://msdn.microsoft.com/en-us/library/ms683175(v=vs.85).aspx
Post 26 Mar 2012, 18:36
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.