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
i missed that post, but i'd be really interested in seeing source code of your project, i'll check previous posts now. :)
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
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]
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.
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
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
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
you guys rules :U
thanks again