Console mouse coordinates?

Everything else that doesn't fall into one of the other PB categories.
deadmoap
User
User
Posts: 79
Joined: Sun Feb 22, 2004 11:45 pm
Location: Riverdale, Utah
Contact:

Console mouse coordinates?

Post by deadmoap »

Since I love DOS programs so much (too bad PB can't compile real DOS programs), and I'm completely bored and have absolultely nothing else to do whatsoever, I've decided to write my own... hmmm what do you call it... "set of console functions". You know, to make windows, text boxes, and menus in a console program. Everything's going fine so far, then I thought "Well what about the mouse?"

I once attempted to use the mouse while in the console in the past, but I haven't used PB in a long time and I can't remember anything I did/learned. I do remember that I spent hours looking at the functions and structures of the console at msdn, but don't remember if I found anything good.

Anyway, I thought I'd ask here, to save myself from wasting my time on the possibly impossible :? . Does anyone know if you can even use the mouse in the console? When you go full screen, you can see the big block that's used for the console's mouse, but can you get the coordinates/button presses from it?

Btw, it's annoying how the position of where the text is is called the "cursor". I remember going to msdn and seeing a bunch of functions and structures with "cursor" in the name and got all excited. :(


Edit: After a couple hours of work, I seem to getting somewhere. Due to PB's lack of certain structures and whatnot, I had to improvise a little. I'm still trying to figure it all out but I'll keep this thread open so I can share my findings with the rest of the community :P . This is what I got so far:

Code: Select all

OpenConsole()

Structure INPUT_RECORD
  EventType.w
  StructureUnion
    MouseEvent.MOUSE_EVENT_RECORD
  EndStructureUnion
EndStructure

Dim inpt.INPUT_RECORD(1)

hCon.w=GetStdHandle_(#STD_INPUT_HANDLE)

SetConsoleMode_(hCon,#ENABLE_MOUSE_INPUT)

Repeat
  If ReadConsoleInput_(hCon,@inpt(1),1,@hey.l)
    ConsoleLocate(3,3)
    ClearConsole()
    Print(Str(inpt(1)\MouseEvent\dwButtonState))
  EndIf
  Delay(1)
ForEver
How it's SUPPOSED to work is that the dwMousePosition in MouseEvent should be a COORD structure, but instead it's a long. But apparently, the Y position of the mouse is stores in dwButtonState. It also the seems that the X position is stored in dwMousePosition, but it's just a bunch of numbers. Although everything doesn't have to be perfect, as long as the numbers in dwMousePosition stay the same, I can still figure out what the X coordinate is. For example, if the X position is at 0, it says 30134. If it's at 1, it's 95670. These numbers stay the same, so I could collect all the numbers it gives for the X position and set it up with a Select:Case. Also, in dwButtonState, if the left mouse button is pressed, it says 65544.

If anyone cares, I'll write a procedure that returns the mouse events through a pointer to a structure.[/code]
deadmoap
User
User
Posts: 79
Joined: Sun Feb 22, 2004 11:45 pm
Location: Riverdale, Utah
Contact:

Post by deadmoap »

Yesssss I did it! Here's the complete source:

Code: Select all

OpenConsole()

Structure INPUT_RECORD
  EventType.w
  StructureUnion
    MouseEvent.MOUSE_EVENT_RECORD
  EndStructureUnion
EndStructure

Structure MOUSE
  x.b
  y.b
  b.b
EndStructure

Declare GetMouseInput(*mouse.MOUSE)

Dim inpt.INPUT_RECORD(1)

hCon.w=GetStdHandle_(#STD_INPUT_HANDLE)

SetConsoleMode_(hCon,#ENABLE_MOUSE_INPUT)

mouse.MOUSE

Repeat
  If ReadConsoleInput_(hCon,@inpt(1),1,@hey.l)
    GetMouseInput(@mouse.MOUSE)
    
    ClearConsole()
    ConsoleLocate(3,3)
    Print("X: "+Str(mouse\x))
    ConsoleLocate(3,4)
    Print("Y: "+Str(mouse\y))
    ConsoleLocate(3,5)
    Print("B: "+Str(mouse\b))
  EndIf
  Delay(1)
ForEver

Procedure GetMouseInput(*mouse.MOUSE)
  *mouse\x=0
  Select inpt(1)\MouseEvent\dwMousePosition
    Case 65536
      *mouse\x=0
    Case 30134
      *mouse\x=1
    Case 95670
      *mouse\x=2
    Case 161206
      *mouse\x=3
    Case 226742
      *mouse\x=4
    Case 292278
      *mouse\x=5
    Case 357814
      *mouse\x=6
    Case 423350
      *mouse\x=7
    Case 488886
      *mouse\x=8
    Case 554422
      *mouse\x=9
    Case 619958
      *mouse\x=10
    Case 685494
      *mouse\x=11
    Case 751030
      *mouse\x=12
    Case 816566
      *mouse\x=13
    Case 882102
      *mouse\x=14
    Case 947638
      *mouse\x=15
    Case 1013174
      *mouse\x=16
    Case 1078710
      *mouse\x=17
    Case 1144246
      *mouse\x=18
    Case 1209782
      *mouse\x=19
    Case 1275318
      *mouse\x=20
    Case 1340854
      *mouse\x=21
    Case 1406390
      *mouse\x=22
    Case 1471926
      *mouse\x=23
    Case 1537462
      *mouse\x=24
    Case 1602998
      *mouse\x=25
    Case 1668534
      *mouse\x=26
    Case 1734070
      *mouse\x=27
    Case 1799606
      *mouse\x=28
    Case 1865142
      *mouse\x=29
    Case 1930678
      *mouse\x=30
    Case 1996214
      *mouse\x=31
    Case 2061750
      *mouse\x=32
    Case 2127286
      *mouse\x=33
    Case 2192822
      *mouse\x=34
    Case 2258358
      *mouse\x=35
    Case 2323894
      *mouse\x=36
    Case 2389430
      *mouse\x=37
    Case 2454966
      *mouse\x=38
    Case 2520502
      *mouse\x=39
    Case 2586038
      *mouse\x=40
    Case 2651574
      *mouse\x=41
    Case 2717110
      *mouse\x=42
    Case 2782646
      *mouse\x=43
    Case 2848182
      *mouse\x=44
    Case 2913718
      *mouse\x=45
    Case 2979254
      *mouse\x=46
    Case 3044790
      *mouse\x=47
    Case 3110326
      *mouse\x=48
    Case 3175862
      *mouse\x=49
    Case 3241398
      *mouse\x=50
    Case 3306934
      *mouse\x=51
    Case 3372470
      *mouse\x=52
    Case 3438006
      *mouse\x=53
    Case 3503542
      *mouse\x=54
    Case 3569078
      *mouse\x=55
    Case 3634614
      *mouse\x=56
    Case 3700150
      *mouse\x=57
    Case 3765686
      *mouse\x=58
    Case 3831222
      *mouse\x=59
    Case 3896758
      *mouse\x=60
    Case 3962294
      *mouse\x=61
    Case 4027830
      *mouse\x=62
    Case 4093366
      *mouse\x=63
    Case 4158902
      *mouse\x=64
    Case 4224438
      *mouse\x=65
    Case 4289974
      *mouse\x=66
    Case 4355510
      *mouse\x=67
    Case 4421046
      *mouse\x=68
    Case 4486582
      *mouse\x=69
    Case 4552118
      *mouse\x=70
    Case 4617654
      *mouse\x=71
    Case 4683190
      *mouse\x=72
    Case 4748726
      *mouse\x=73
    Case 4814262
      *mouse\x=74
    Case 4879798
      *mouse\x=75
    Case 4945334
      *mouse\x=76  
    Case 5010870
      *mouse\x=77
    Case 5076406
      *mouse\x=78
    Case 5141942
      *mouse\x=79
    Case 5207478
      *mouse\x=80
    Default
      *mouse\x=0
  EndSelect
  *mouse\y=inpt(1)\MouseEvent\dwButtonState+1
  If inpt(1)\MouseEvent\dwButtonState > 65500 And inpt(1)\MouseEvent\dwButtonState+1 < 65600
    *mouse\b=1
  ElseIf inpt(1)\MouseEvent\dwButtonState+1 > 65600
    *mouse\b=2
  EndIf
EndProcedure
The procedure is long, I know, but there's no way around it, believe me. I whipped out my calculator and tried all kinds of different things to try to find some kind of pattern for the numbers, but I think they're all just random. Oh well. But anyway this program shows the X and Y coordinates in the upper left corner, as well as the last mouse button that was pressed.

I kind of feel like a jackass for posting this thread now (and wasting precious server space :wink: ), but hopefully someone else can learn from this.
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

What do you know, seems like the win sdk isn't correct or something!! Try this code and see if it works better for you:

Code: Select all

OpenConsole()

Structure INPUT_RECORD
  EventType.l
  StructureUnion
  	KeyEvent.KEY_EVENT_RECORD
    MouseEvent.MOUSE_EVENT_RECORD
    WindowBufferSizeEvent.WINDOW_BUFFER_SIZE_RECORD
    MenuEvent.MENU_EVENT_RECORD
    FocusEvent.FOCUS_EVENT_RECORD
  EndStructureUnion
EndStructure

Structure MOUSE
  x.b
  y.b
  b.b
EndStructure

Declare GetMouseInput(*mouse.MOUSE)

Global in_rec.INPUT_RECORD


hCon.w=GetStdHandle_(#STD_INPUT_HANDLE)

SetConsoleMode_(hCon,#ENABLE_MOUSE_INPUT)

mouse.MOUSE

Repeat
  If ReadConsoleInput_(hCon,@in_rec,1,@hey.l)
    GetMouseInput(@mouse.MOUSE)
   
    ClearConsole()
    ConsoleLocate(3,3)
    Print("X: "+Str(mouse\x))
    ConsoleLocate(3,4)
    Print("Y: "+Str(mouse\y))
    ConsoleLocate(3,5)
    Print("B: "+Str(mouse\b))
    ConsoleLocate(3,6)
    Print("MPos: $"+Hex(in_rec\MouseEvent\dwMousePosition))
  EndIf
  Delay(1)
ForEver

Procedure GetMouseInput(*mouse.MOUSE)
  *mouse\x = in_rec\MouseEvent\dwMousePosition & $ffff
  *mouse\y = in_rec\MouseEvent\dwMousePosition >> 16 & $ffff
  If in_rec\MouseEvent\dwButtonState & #FROM_LEFT_1ST_BUTTON_PRESSED
  	*mouse\b = 1 ; Leftmost button
  ElseIf in_rec\MouseEvent\dwButtonState & #RIGHTMOST_BUTTON_PRESSED
  	*mouse\b = 2 ; Rightmost button
  ElseIf in_rec\MouseEvent\dwButtonState & #FROM_LEFT_2ND_BUTTON_PRESSED
  	*mouse\b = 3 ; Middle button?
  Else
  	*mouse\b = 0
  EndIf
EndProcedure
Kevin
User
User
Posts: 12
Joined: Fri Aug 01, 2003 7:35 pm
Location: England

Post by Kevin »

That's neat being able to use the mouse in the console, but is it posible to stop the text 'flikering' when you move the mouse about?

Thanks.
Post Reply