I'm trying to open a console window at the same size as the console buffer. The buffer can be increased in size with the following code:-
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov hConsoleOutput,eax
invoke GetConsoleScreenBufferInfo,hConsoleOutput,ADDR csbi
mov ax,53
shl eax,16
mov ax,csbi.dwSize.x
invoke SetConsoleScreenBufferSize,hConsoleOutput,eax
This increases the number of rows to 53, but when I add the following code:-
invoke SetSmallRect,ADDR small_rect,0,0,79,53
invoke SetConsoleWindowInfo,hConsoleOutput,TRUE,ADDR small_rect
nothing appears to happen, the console window opens with 25 rows still showing & the extra rows can only be seen by using the scroll bar or dragging the window bigger. Anyone know if this is an inherent part of windows & can't be changed or am I doing it the wrong way.
My first instinct would be to say that the SMALL_RECT is getting set up incorrectly, and SetConsoleWindowInfo is failing; is the return value non-zero? Is SetSmallRect even an API function? I thought the only one they had was SetRect() for LONG sized ones....
-ac
Hi Redskull,
SetSmallRect works the same way as SetRect, when I use it after making the buffer smaller the window also returns to that size, it's when I make the buffer larger that the problem arises.
I've gone through the code again & found that I was calling SetConsoleWindowInfo twice by mistake, I've removed one offending item but it still doesn't work. Here's the SetSmallRect proc :-
SetSmallRect proc ps_r:DWORD,left:DWORD,top:DWORD,right:DWORD,bottom:DWORD
mov edx,ps_r
mov eax,left
mov [edx].SMALL_RECT.Left,ax
mov eax,top
mov [edx].SMALL_RECT.Top,ax
mov eax,right
mov [edx].SMALL_RECT.Right,ax
mov eax,bottom
mov [edx].SMALL_RECT.Bottom,ax
invoke SetConsoleWindowInfo,hConsoleOutput,TRUE,ADDR small_rect
ret
SetSmallRect endp
As I said this works perfectly when reducing window size but not the other way around.
The SetSmallRect procedure looks ok. Here is another one, just in case - only 20 bytes long and pretty fast.
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
SetRect16 proc ps_r:DWORD,left:DWORD,top:DWORD,right:DWORD,bottom:DWORD
pop edx ; trash the return address
pop edx ; move the first argument to edx
pop dword ptr [edx].SMALL_RECT.Left
pop dword ptr [edx].SMALL_RECT.Top
pop dword ptr [edx].SMALL_RECT.Right
pop word ptr [edx].SMALL_RECT.Bottom
sub esp, 5*4+2 ; correct for 5 dword + 1 word pop, restore return address
ret 5*4 ; correct stack for five arguments
SetRect16 endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
watch for the 'off by one' error; if your buffer is 53 rows, then your window goes from 0 to 52; setting 53 is one row bigger than the buffer, and will fail.
-ac
Redskull you hit it on the nail, of course it should be 52 rows not 53, all these years of programming & I still make dumb mistakes ::)
It now works perfectly.
JJ nice proc it's smaller & I think faster than mine, I'll use it if you don't mind?
Thanks guys :U
Quote from: Neil on November 26, 2008, 08:24:04 AM
JJ nice proc it's smaller & I think faster than mine, I'll use it if you don't mind?
Sure you can use it. It's the fastest algo on a Core2 (Celeron M: 11 cycles), but relatively slow on a P4 (50+). You can replace edx with eax if you prefer to trash the accu.
Thanks jj :thumbu