News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Console Scrolling revisted

Started by redskull, October 03, 2005, 04:01:51 PM

Previous topic - Next topic

redskull

I had a post a couple weeks ago about Console mode scrolling (or the lack thereof); if anybody cares:

WriteConsole() and SetConsoleCursorPosition() will always scroll the window upward, whereas WriteConsoleOutputCharacter won't.  The only difference is that WriteConsoleOutputCharacter requires you pass a COORD to define the position in the buffer, and WriteConsole() just displays the string at the most recent cursor position.

thanks again for the replies
alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

bozo

i missed that post, but i'd be really interested in seeing source code of your project, i'll check previous posts now. :)

redskull

It really wasn't much to look at but here goes;

.486
.model flt, stdcall
option casemap:none

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

COORD STRUCT
x WORD ?
y WORD ?
COORD ENDS

.const
STD_OUTPUT_HANDLE     equ -11
STD_INPUT_HANDLE        equ -10
NULL                              equ 0

.data
BufferSize     COORD <80, 100>
Cursor          COORD <25, 50>
outputstring  db "This is a sample string"

.data?
Addrspace     DWORD ?
hConsoleOut     DWORD ?

.code
start:

invoke AllocConsole
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hConsoleOut, eax
invoke SetConsoleScreenBufferSize, hConsoleOut, dword ptr BufferSize

; This statement writes a to a location OFF the screen (you pass the CORD value you want to write at)

invoke WriteConsoleOutputCharacter, hConsoleOut, addr outputstring, SIZEOF outputstring, dword ptr Cursor, addr Addrspace

; This statment will write to a location off the screen, and automatically scroll vertically ( writes the last curosor location

invoke WriteConsole, hConsoleOut, addr outputstring, SIZEOF outputstring, addr Addrspace, NULL

pause:
jmp pause
end start



I just typed that out by hand, so please excuse any typos.  Also, i'm still wicked new at this, so if there are better ways to do it, please let me know.

Again, to go back to my pointer questions:  When passing a CORD to the functions, I have to use DWORD PTR, but ADDR and OFFSET don't work at all?  I know pointers are variables that contain addresses, but I didn't think each CORD was?  Help?

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

Jeff

all you need to do is pass the name of the variable to the function (since the function was expecting a COORD).  invoke usually does an ok job at taking care of this (when it comes to passing structures).  fortunately the structure is simple and is only 32 bits.

invoke SetConsoleScreenBufferSize, hConsoleOut, BufferSize

if for some reason the variable wasnt the COORD type or you wanted to cast it, use COORD PTR:

invoke SetConsoleScreenBufferSize, hConsoleOut, COORD ptr [BufferSize]

MichaelW

redskull,

For "dword ptr BufferSize" the PTR operator causes MASM to treat BufferSize as having the type DWORD, essentially the MASM equivalent of a cast in C/C++. If you leave the dword ptr off then MASM returns a "error A2114: INVOKE argument type mismatch" because the function prototype in kernel32.inc specifies that the arguments should be dwords:

SetConsoleScreenBufferSize PROTO :DWORD,:DWORD

But BufferSize (and Cursor) are defined as type COORD.

eschew obfuscation

redskull

What *exactly* is the function expecting?  Is it expecting to get an DWORD that has the address of the CORD structure i'm using, or is it expecting the ENTIRE structure (two WORDS crammed together into one DWORD) , the data itself, pushed onto the stack?  I'm guessing it's the later, since using OFFSET and ADDR cause the program to suck, but i just want to make sure I got this down.
using the DWORD PTR basically converts two individual word variables (structure.1 and structure.2, both 16 bits) by saying 'put 32-bits on the stack starting at the address of struture.1", which just happens to include the first 16 of .1 and includes the second 16 bits of .2?  Something like that?
If I were so inclined, could I do something like this:


wholething   DWORD <?>
Buffer          CORD <80,25>

mov eax, buffer.1
mov ax, buffer.2
mov wholething, eax
invoke SetConsoleScreenBufferSize, hConsoleOut, wholething


Not that it would be more efficient or anything, is that pretty much what it's doing?  Or am I down the wrong path?

Once again, thanks to all for putting up with my dumbass questions
alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

GregL

Redskull,

SetConsoleScreenBufferSize is expecting an actual COORD, not a pointer to a COORD. This is a perfect situation to use a union.

.586
.MODEL FLAT, stdcall
option casemap:none

include windows.inc

include kernel32.inc
;include user32.inc

includelib kernel32.lib
;includelib user32.lib

main PROTO

;COORD STRUCT
;    x WORD ?
;    y WORD ?
;COORD ENDS

COORDU UNION
    d  DWORD 0
    co COORD <>   
COORDU ENDS   

.DATA

.CODE

start:

    call main
    invoke ExitProcess, 0

main PROC

    LOCAL hConsoleOut:HANDLE
    LOCAL Buffer:COORDU

    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov hConsoleOut, eax

    mov Buffer.co.x, 80
    mov Buffer.co.y, 25
    invoke SetConsoleScreenBufferSize, hConsoleOut, Buffer.d
   
    ret

main ENDP

end start


MichaelW

redskull,

The function is expecting a COORD value, pushed directly onto the stack, but because of the prototype MASM is expecting a DWORD value. The DWORD PTR tells MASM to ignore the defined type and treat the argument as a DWORD. Also, your example would not work because MASM would reject your attempt to move a word into a dword register and buffer.2 would overwrite buffer.1. You would need to do something like this:

COORD STRUCT
  x  WORD      ?
  y  WORD      ?
COORD ENDS
buffer COORD <>

mov ax, buffer.y
shl eax, 16
mov ax, buffer.x
invoke SetConsoleScreenBufferSize, hConsoleOut, eax


eschew obfuscation

redskull

Strange women, lying in ponds, distributing swords, is no basis for a system of government