Author Topic: Weird behaviour when switching to classes...  (Read 3170 times)

0 Members and 1 Guest are viewing this topic.

efgee

  • Full Member
  • ***
  • Posts: 172
Weird behaviour when switching to classes...
« 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:
Code: [Select]
#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"):
Code: [Select]
#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

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4097
    • Oxygen Basic
Re: Weird behaviour when switching to classes...
« Reply #1 on: October 12, 2010, 01:35:43 AM »

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.


Code: [Select]
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

efgee

  • Full Member
  • ***
  • Posts: 172
Re: Weird behaviour when switching to classes...
« Reply #2 on: October 12, 2010, 08:26:12 AM »
 8)


Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4097
    • Oxygen Basic
Re: Weird behaviour when switching to classes...
« Reply #3 on: October 12, 2010, 02:13:03 PM »

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.

Code: [Select]
#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

efgee

  • Full Member
  • ***
  • Posts: 172
Re: Weird behaviour when switching to classes...
« Reply #4 on: October 12, 2010, 04:11:02 PM »
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

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4097
    • Oxygen Basic
Re: Weird behaviour when switching to classes...
« Reply #5 on: October 12, 2010, 11:18:21 PM »

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