Oxygen Basic
Programming => Problems & Solutions => Topic started by: efgee on October 11, 2010, 04:24:50 PM
-
Hello Charles
here is an example how to use the GetConsoleScreenBufferInfo function.
Seems to work well using "normal" code but the values are weird as soon the code is switched to a class.
Here the working version:
#file "GetConsoleScreenBufferInfo.exe"
#console
; =======
; imports
; =======
dim as long kernel32 = LoadLibrary ("kernel32.dll")
bind kernel32 (
AllocConsole_ AllocConsole : @0
FreeConsole_ FreeConsole : @0
WriteConsole_ WriteConsoleA : @5
ReadConsole_ ReadConsoleA : @5
SetConsoleTitle_ SetConsoleTitleA : @1
SetConsoleCursorPosition_ SetConsoleCursorPosition : @2
GetConsoleScreenBufferInfo_ GetConsoleScreenBufferInfo : @2
GetStdHandle_ GetStdHandle : @1
GetCommandLine_ GetCommandLineA : @0
GetModuleHandle_ GetModuleHandleA : @4
ExitProcess_ ExitProcess : @4
)
; ========
; CONSTANTS
; ========
def STD_INPUT_HANDLE -10
def STD_OUTPUT_HANDLE -11
def STD_ERROR_HANDLE -12
; =========
; STRUCTURES
; =========
type COORD
x as SHORT
y as SHORT
end type
type SMALL_RECT
Left as SHORT
Top as SHORT
Right as SHORT
Bottom as SHORT
end type
type CONSOLE_SCREEN_BUFFER_INFO
Size as COORD
CursorPosition as COORD
Attributes as WORD
Window as SMALL_RECT
MaximumWindowSize as COORD
end type
; ====
; MAIN
; ====
dim _ConsoleOut as long
dim _ConsoleInfo as CONSOLE_SCREEN_BUFFER_INFO
dim _BufferLength as long
dim _text as string
dim _Coordinate as COORD
&_ConsoleOut = GetStdHandle_(STD_OUTPUT_HANDLE)
_text = "Hello"
_BufferLength = len(_text)
WriteConsole_(_ConsoleOut, *_text, _BufferLength, 0, 0)
_Coordinate.x = 8
_Coordinate.y = 9
SetConsoleCursorPosition_(_ConsoleOut, _Coordinate)
_text = "World"
_BufferLength = len(_text)
WriteConsole_(_ConsoleOut, *_text, _BufferLength, 0, 0)
GetConsoleScreenBufferInfo_(_ConsoleOut, &_ConsoleInfo)
print "X: " _ConsoleInfo.CursorPosition.x
print "Y: " _ConsoleInfo.CursorPosition.y
print "Max X: " _ConsoleInfo.MaximumWindowSize.x
print "Max Y: " _ConsoleInfo.MaximumWindowSize.y
print "Size X: " _ConsoleInfo.Size.x
print "Size Y: " _ConsoleInfo.Size.y
print "Window: " _ConsoleInfo.Window.left ":" _ConsoleInfo.Window.top "," _ConsoleInfo.Window.right ":" _ConsoleInfo.Window.bottom
This is the one acting weird (the actual test code is inside "WriteLine"):
#file "GetConsoleScreenBufferInfoClass.exe"
#console
; =======
; imports
; =======
dim as long kernel32 = LoadLibrary ("kernel32.dll")
bind kernel32 (
AllocConsole_ AllocConsole : @0
FreeConsole_ FreeConsole : @0
WriteConsole_ WriteConsoleA : @5
ReadConsole_ ReadConsoleA : @5
SetConsoleTitle_ SetConsoleTitleA : @1
SetConsoleCursorPosition_ SetConsoleCursorPosition : @2
GetConsoleScreenBufferInfo_ GetConsoleScreenBufferInfo : @2
GetStdHandle_ GetStdHandle : @1
GetCommandLine_ GetCommandLineA : @0
GetModuleHandle_ GetModuleHandleA : @4
ExitProcess_ ExitProcess : @4
)
; ========
; CONSTANTS
; ========
def STD_INPUT_HANDLE -10
def STD_OUTPUT_HANDLE -11
def STD_ERROR_HANDLE -12
; =========
; STRUCTURES
; =========
type COORD
x as SHORT
y as SHORT
end type
type SMALL_RECT
Left as SHORT
Top as SHORT
Right as SHORT
Bottom as SHORT
end type
type CONSOLE_SCREEN_BUFFER_INFO
Size as COORD
CursorPosition as COORD
Attributes as WORD
Window as SMALL_RECT
MaximumWindowSize as COORD
end type
; =====
; CLASS
; =====
class oCONSOLE alias "oCONSOLE"
method CmdLine() as string
method Position(x as short, y as short)
method Title(text as string)
method Write(text as string)
method WriteLine(text as string)
method ctor()
method dtor()
private
_Buffer as string
_BufferLength as long
_CommandLine as string
_ConsoleIn as long
_ConsoleOut as long
_ConsoleError as long
_Coordinate as COORD
_ConsoleInfo as CONSOLE_SCREEN_BUFFER_INFO
/
end class
; ================
; METHODS OF CLASS
; ================
methods of oCONSOLE
method CmdLine() as string
'print _classcmdline
method = this._CommandLine
end method
method ctor ()
print "CONSOLE ctor"
' store command line for later use
zstring ptr z
&z=GetCommandLine_()
this._CommandLine=z
AllocConsole_()
;SetConsoleTitle_(this._cmdline)
'set std handles
this._ConsoleIn = GetStdHandle_(STD_INPUT_HANDLE)
this._ConsoleOut = GetStdHandle_(STD_OUTPUT_HANDLE)
this._ConsoleError = GetStdHandle_(STD_ERROR_HANDLE)
'set console buffer
this._Buffer = nuls 1000
end method
method Position(x as short, y as short)
this._Coordinate.x = x
this._Coordinate.y = y
SetConsoleCursorPosition_(this._ConsoleOut, this._Coordinate)
end method
method Title(text as string)
SetConsoleTitle_(*text)
end method
method Write(text as string)
this._BufferLength = len(text)
WriteConsole_(this._ConsoleOut, *text, this._BufferLength, 0, 0)
end method
method WriteLine(text as string)
'this._BufferLength = len(text)
'print this._ConsoleOut
'GetConsoleScreenBufferInfo_(this._ConsoleOut, &this._ConsoleInfo)
'this._Coordinate.x = 0
'this._Coordinate.y = this._ConsoleInfo.CursorPosition.y + 1
'print "X: " this._ConsoleInfo.CursorPosition.x
'print "Y: " this._ConsoleInfo.CursorPosition.y
&_ConsoleOut = GetStdHandle_(STD_OUTPUT_HANDLE)
text = "Hello"
this._BufferLength = len(text)
WriteConsole_(_ConsoleOut, *text, this._BufferLength, 0, 0)
this._Coordinate.x = 8
this._Coordinate.y = 9
SetConsoleCursorPosition_(this._ConsoleOut, this._Coordinate)
text = "World"
this._BufferLength = len(text)
WriteConsole_(this._ConsoleOut, *text, this._BufferLength, 0, 0)
GetConsoleScreenBufferInfo_(_ConsoleOut, &this._ConsoleInfo)
print "X: " this._ConsoleInfo.CursorPosition.x
print "Y: " this._ConsoleInfo.CursorPosition.y
print "Max X: " this._ConsoleInfo.MaximumWindowSize.x
print "Max Y: " this._ConsoleInfo.MaximumWindowSize.y
print "Size X: " this._ConsoleInfo.Size.x
print "Size Y: " this._ConsoleInfo.Size.y
print "Window: " this._ConsoleInfo.Window.left ":" this._ConsoleInfo.Window.top "," this._ConsoleInfo.Window.right ":" this._ConsoleInfo.Window.bottom
'print this._Coordinate.x
'print this._Coordinate.y
'WriteConsole_(this._ConsoleOut, *text, this._BufferLength, 0, 0)
'SetConsoleCursorPosition_(this._ConsoleOut, this._Coordinate)
end method
method dtor ()
print "CONSOLE dtor"
FreeConsole_()
end method
end methods
; ======
; macros
; ======
def new
dim as %1 byref %2
&%2 = news sizeof %1
%2.ctor()
end def
def delete
%1.dtor()
frees &%1
end def
; ====
; MAIN
; ====
new oCONSOLE con
con.title = "hello"
con.writeline = "hello"
'con.writeline = "world"
'con.writeline = con.cmdline
'con.writeline = con.cmdline
'con.position(0, 10)
'con.write = con.cmdline
'con.writeline = "bye"
delete con
Maybe I'm doing something wrong or something is messing up the structure sizes or structure members.
Thanks
efgee
-
Hi efgee,
Taking the properties out of the static part of the class and placing them into the object body section cures te problem.
To do this simply reposition the "/" after the last method declaration.
class oCONSOLE alias "oCONSOLE"
method CmdLine() as string
method Position(x as short, y as short)
method Title(text as string)
method Write(text as string)
method WriteLine(text as string)
method ctor()
method dtor()
/
private
_Buffer as string
_BufferLength as long
_CommandLine as string
_ConsoleIn as long
_ConsoleOut as long
_ConsoleError as long
_Coordinate as COORD
_ConsoleInfo as CONSOLE_SCREEN_BUFFER_INFO
end class
Oxygen should be able to cope with class static UDTs but there is an offset problem which causes the wrong static elements to be accessed and gave you those strange results. I will try to fix this today.
Thanks,
Charles
-
8)
-
Hot off the press: Alpha014.
efgee, I've reworked your example here, removing leading and trailing underscores, which I use for a few o2 system labels. I also took out all the "this." as the compiler checks for implicit this. But you can still use these things if you need to.
structureof this is a very useful diagnostic, displaying the resolved class structure. All class structures are flattened out except where there are pointers to other classes. #recordof also displays similar information at compile-time.
#file "GetConsoleScreenBufferInfo.exe"
#console
; =======
; imports
; =======
dim as long kernel32 = LoadLibrary ("kernel32.dll")
bind kernel32 (
AllocConsole AllocConsole : @0
FreeConsole FreeConsole : @0
WriteConsole WriteConsoleA : @5
ReadConsole ReadConsoleA : @5
SetConsoleTitle SetConsoleTitleA : @1
SetConsoleCursorPosition SetConsoleCursorPosition : @2
GetConsoleScreenBufferInfo GetConsoleScreenBufferInfo : @2
GetStdHandle GetStdHandle : @1
GetCommandLine GetCommandLineA : @0
GetModuleHandle GetModuleHandleA : @4
ExitProcess ExitProcess : @4
)
; ========
; CONSTANTS
; ========
def STD_INPUT_HANDLE -10
def STD_OUTPUT_HANDLE -11
def STD_ERROR_HANDLE -12
; =========
; STRUCTURES
; =========
type COORD
x as SHORT
y as SHORT
end type
type SMALL_RECT
Left as SHORT
Top as SHORT
Right as SHORT
Bottom as SHORT
end type
type CONSOLE_SCREEN_BUFFER_INFO
Size as COORD
CursorPosition as COORD
Attributes as WORD
Window as SMALL_RECT
MaximumWindowSize as COORD
end type
; =====
; CLASS
; =====
class oCONSOLE alias "oCONSOLE"
method CmdLine() as string
method Position(x as short, y as short)
method Title(text as string)
method Write(text as string)
method WriteLine(text as string)
method ctor()
method dtor()
private
Buffer as string
BufferLength as long
CommandLine as string
ConsoleIn as long
ConsoleOut as long
ConsoleError as long
Coordinate as COORD
ConsoleInfo as CONSOLE_SCREEN_BUFFER_INFO
/
end class
; ================
; METHODS OF CLASS
; ================
methods of oCONSOLE
method CmdLine() as string
'print classcmdline
method = CommandLine
end method
method ctor ()
'print "CONSOLE ctor"
' store command line for later use
zstring ptr z
&z=GetCommandLine()
CommandLine=z
AllocConsole()
;SetConsoleTitle(cmdline)
'set std handles
ConsoleIn = GetStdHandle(STD_INPUT_HANDLE)
ConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE)
ConsoleError = GetStdHandle(STD_ERROR_HANDLE)
'set console buffer
Buffer = nuls 1000
end method
method Position(x as short, y as short)
Coordinate.x = x
Coordinate.y = y
SetConsoleCursorPosition(ConsoleOut, Coordinate)
end method
method Title(text as string)
SetConsoleTitle(*text)
end method
method Write(text as string)
BufferLength = len(text)
WriteConsole(ConsoleOut, *text, BufferLength, 0, 0)
end method
method WriteLine(text as string)
'BufferLength = len(text)
'print ConsoleOut
'GetConsoleScreenBufferInfo(ConsoleOut, &ConsoleInfo)
'Coordinate.x = 0
'Coordinate.y = ConsoleInfo.CursorPosition.y + 1
'print "X: " ConsoleInfo.CursorPosition.x
'print "Y: " ConsoleInfo.CursorPosition.y
&ConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE)
text = "Hello"
BufferLength = len(text)
WriteConsole(ConsoleOut, *text, BufferLength, 0, 0)
Coordinate.x = 8
Coordinate.y = 9
SetConsoleCursorPosition(ConsoleOut, Coordinate)
text = "World"
BufferLength = len(text)
WriteConsole(ConsoleOut, *text, BufferLength, 0, 0)
GetConsoleScreenBufferInfo(ConsoleOut, & ConsoleInfo)
'--------------
'STATUS MESSAGE
'==============
tab=chr(9)
cr=chr(13)+chr(10)
c=" : "
'
pr="CHECK: GetConsoleScreenBufferInfo" cr cr +
'
"Curs X:" tab ConsoleInfo.CursorPosition.x cr +
"Curs Y:" tab ConsoleInfo.CursorPosition.y cr +
"Max X:" tab ConsoleInfo.MaximumWindowSize.x cr +
"Max Y:" tab ConsoleInfo.MaximumWindowSize.y cr +
"Size X:" tab ConsoleInfo.Size.x cr +
"Size Y:" tab ConsoleInfo.Size.y cr +
"Coord X:" tab Coordinate.x cr +
"Coord Y:" tab Coordinate.y cr +
"WinLTRB:" tab ConsoleInfo.window.left c ConsoleInfo.Window.top c ConsoleInfo.Window.right c ConsoleInfo.Window.bottom cr
'
print pr
'
print "STRUCTURE RECORD OF THIS:" cr structureof this
'===========================
'WriteConsole(ConsoleOut, *text, BufferLength, 0, 0)
'SetConsoleCursorPosition(ConsoleOut, Coordinate)
end method
method dtor ()
'print "CONSOLE dtor"
FreeConsole()
end method
end methods
; ======
; macros
; ======
def new
dim as %1 byref %2
&%2 = news sizeof %1
%2.ctor()
end def
def delete
%1.dtor()
frees &%1
end def
; ====
; MAIN
; ====
new oCONSOLE con
con.title = "hello"
con.writeline = "hello"
'con.writeline = "world"
'con.writeline = con.cmdline
'con.writeline = con.cmdline
'con.position(0, 10)
'con.write = con.cmdline
'con.writeline = "bye"
delete con
Charles
-
Thank you Charles, will test it as soon as I can.
BTW: sorry to find all these bugs on my own; I know you "placed" them for "all" to find - not only for me ;D
Thanks again
efgee
-
Yes the bugs are placed for the benefit of all!
In the biological sciences, including entomology new species are often named after those who discover them ;D
Charles