News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Examples for Win64 Iczelion tutorial

Started by Mikl__, April 30, 2015, 03:14:46 PM

Previous topic - Next topic

Mikl__

Win x64 Tutorial #38m: Enum and set console fonts
bat-filecls
set masm64_path=\masm64\
set filename=%1
del %filename%.exe
%masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm || exit
%masm64_path%bin\link /SUBSYSTEM:CONSOLE /LIBPATH:"%masm64_path%Lib" ^
/entry:WinMain %filename%.obj /LARGEADDRESSAWARE:NO ^
/ALIGN:16 /BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe || exit
del %filename%.obj
asm-fileinclude win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
MAX_STACK  = 1000h
TOP_MENU   = 5
RIGHT_MENU = 34
COLS_MENU  = 17
;----------------------------------------------
CONSOLE_FONT_INFO struct
index dd ?
dwFontSize COORD <>
CONSOLE_FONT_INFO ends
;----------------------------------------------
buffersize   = 40
.code
WinMain proc
local hIn:qword
local n:dword
local count:dword
local new_op:dword
local prev_op:dword
local result:qword
local buffer[buffersize]:byte
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local CSBI:CONSOLE_SCREEN_BUFFER_INFO
local MOUSE_KEY:INPUT_RECORD
local hMem:qword
local coord:COORD

        push rbp
mov ebp,esp
sub esp,(28h+3*8+4*4+sizeof SMALL_RECT+sizeof INPUT_RECORD+sizeof COORD+\
        sizeof CONSOLE_CURSOR_INFO+sizeof CONSOLE_SCREEN_BUFFER_INFO+buffersize+15)and(-16)

        xor ebx,ebx
mov prev_op,1
mov new_op,1
mov coord,TOP_MENU*10000h+RIGHT_MENU

        call GetProcessHeap
mov hHeap,rax
mov r8d,4*MAX_STACK ; dwBytes
mov edx,HEAP_ZERO_MEMORY ; dwFlags
mov rcx,rax ; hHeap
call HeapAlloc
mov lpStack,rax

call FreeConsole
        call AllocConsole
        mov rcx,STD_INPUT_HANDLE
        call GetStdHandle
        mov hIn,rax
        mov rcx,STD_OUTPUT_HANDLE
        call GetStdHandle
        mov hOut,rax
        mov ecx,eax;hOut ; hConsoleOutput
call GetLargestConsoleWindowSize
; eax return in 31-16 bits: dwCoord.y
;               15-00 bits: dwCoord.x

        lea r8d,ConsoleWindow ; lpConsoleWindow
        mov [r8],ebx                        ; ConsoleWindow.Left = 0
; ConsoleWindow.Top = 0

sub ax, MAXSCREENX
sbb edx, edx
and ax, dx
add ax, MAXSCREENX-1
mov [r8+SMALL_RECT.Right],ax

shr eax, 16
sub eax, MAXSCREENY
sbb edx, edx
and eax, edx
add eax, MAXSCREENY-1
mov [r8+SMALL_RECT.Bottom],ax

mov edx,TRUE ; bAbsolute
mov rcx,hOut ; hConsoleOutput
call SetConsoleWindowInfo

mov edx,MAXSCREENY*10000h+MAXSCREENX;dwCoord
mov rcx,hOut ;hConsoleOutput
call SetConsoleScreenBufferSize ;establish the new size of a window of the console

mov ecx,offset ConsoleName
call SetConsoleTitle
;hide cursor----------------------------------------
lea edx,cci         ; lpConsoleCursorInfo
mov rcx,hOut ; hConsoleOutput
call GetConsoleCursorInfo
        lea edx,cci         ; lpConsoleCursorInfo
mov [rdx+CONSOLE_CURSOR_INFO.bVisible],FALSE
mov rcx,hOut ; hConsoleOutput
call SetConsoleCursorInfo
;------------------------------------------------------
        mov [rsp+20h],rbx
lea r9d,result ;&result
        mov r8d,sizeof Str2
mov edx,offset Str2     
mov rcx,hOut
        call WriteConsole
;------------------------------------------------------
        call GetNumberOfConsoleFonts
mov count,eax
shl eax,3
mov edx,eax      ; eax = count * sizeof CONSOLE_FONT_INFO
mov ecx,GMEM_FIXED or GMEM_ZEROINIT
call GlobalAlloc
mov hMem,rax
mov r9,rax
mov r8d,count
mov edx,TRUE
mov rcx,hOut
call GetConsoleFontInfo
;Draw menu-----------------------------------------------------------
mov edx,BACKGROUND_INTENSITY; wAttributes
mov rcx,hOut ; hConsoleOutput
call SetConsoleTextAttribute
mov r9d,count
add r9d,4                   ;rows   
mov r8d,COLS_MENU+4 ;cols   
mov edx,TOP_MENU-2 ;y
mov ecx,RIGHT_MENU-2 ;x
call draw

mov edx,BACKGROUND_BLUE or BACKGROUND_GREEN or \
BACKGROUND_RED; wAttributes
mov rcx,hOut ; hConsoleOutput
call SetConsoleTextAttribute
        mov r9d,count
add r9d,2                   ;rows   
mov r8d,COLS_MENU+2 ;cols   
mov edx,TOP_MENU-1 ;y
mov ecx,RIGHT_MENU-1 ;x
call draw
;fill memu----------------------------------------------------------
mov edi,count
mov rsi,hMem
@@: mov ax,300
cwd
div [rsi+CONSOLE_FONT_INFO.dwFontSize.y]
        mov r9d,eax ;font width
mov ax,640
cwd
div [rsi+CONSOLE_FONT_INFO.dwFontSize.x]
mov r8d,eax              ;font height
mov edx,offset fmt
lea ecx,buffer
        call sprintf
mov n,eax
        mov edx,coord
mov rcx,hOut
call SetConsoleCursorPosition;устанавливаем позицию курсора
        mov [rsp+20h],rbx  ; lpOverlapped
lea r9d,result              ; lpNumberOfBytesWritten
mov r8d,n        ; nNumberOfBytesToWrite
lea edx,buffer
mov rcx,hOut
        call WriteConsole ;выводим строку символов   
inc coord.y
add esi,sizeof CONSOLE_FONT_INFO
dec edi
jnz @b
mov rcx,hMem
call GlobalFree
; Select first label
mov ecx,TOP_MENU    ;y
call invert
; Keyboard read loop------------------------------------------------
@@:     lea r9d,result
mov r8d,1
lea edx,MOUSE_KEY
mov rcx,hIn
call ReadConsoleInput
        lea eax,MOUSE_KEY
cmp [rax+INPUT_RECORD.EventType],MOUSE_EVENT
je @b
cmp [rax+INPUT_RECORD.EventType],KEY_EVENT
jne @b
        cmp [rax+INPUT_RECORD.KeyEvent.bKeyDown],0
jne @b
        cmp [rax+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_UP
        je vkUP
        cmp [rax+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_DOWN
        je vkDOWN
        cmp [rax+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_RETURN
        je vkRETURN
cmp [rax+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_ESCAPE
jne @b
exit0: mov r8,lpStack ; lpMem
xor edx,edx ; dwFlags=0
mov rcx,hHeap ; hHeap
call HeapFree
        mov rcx,hOut ; hObject
call CloseHandle
mov rcx,hIn ; hObject
call CloseHandle
        call FreeConsole
xor ecx,ecx
        call ExitProcess
;-----------------------------------------------------     
vkUP:   dec new_op
        jnz     proceed
mov eax,count
        mov new_op,eax
jmp     proceed
vkDOWN: mov eax,count
inc new_op
        cmp new_op,eax
        jbe     proceed
        mov new_op,1
proceed: ; Select new label
        mov ecx,new_op
        add ecx,TOP_MENU-1
        call invert
        add prev_op,TOP_MENU-1
mov ecx,prev_op
        call invert
mov eax,new_op
        mov prev_op,eax
        jmp @b
vkRETURN:mov edx,new_op
dec edx
mov rcx,hOut
call SetConsoleFont
        jmp @b
WinMain endp
;--------------------------------------------------------
draw proc x:qword, y:qword, cols:qword, rows:qword

local Csbi:CONSOLE_SCREEN_BUFFER_INFO
local lpBuffer:qword
local dwBufferSize:COORD
local lpRegion:SMALL_RECT

push rbp
mov ebp,esp
sub esp,(28h+8+sizeof CONSOLE_SCREEN_BUFFER_INFO+\
sizeof COORD+sizeof SMALL_RECT+15)and(-16)

mov x,rcx
mov y,rdx
mov cols,r8
mov rows,r9

lea edx, Csbi       ; lpConsoleScreenBufferInfo
mov rcx,hOut ; hConsoleOutput
call GetConsoleScreenBufferInfo
;---------------------------------------------------------
mov eax,dword ptr cols
mov dwBufferSize.x,ax
mov ecx,dword ptr rows
mov dwBufferSize.y,cx
dec eax
dec ecx
mov edx,dword ptr x
mov lpRegion.Left,dx
add eax,dword ptr x ;eax=cols-1+x
mov lpRegion.Right,ax
mov edx,dword ptr y
mov lpRegion.Top,dx
add ecx,edx ;ecx=rows-1+y
mov lpRegion.Bottom,cx

mov eax,dword ptr cols
mul dword ptr rows
lea r8d,[rax*4+260] ;eax=4*cols*rows+260  dwBytes
mov edx,HEAP_ZERO_MEMORY; dwFlags
mov rcx,hHeap ; hHeap
call HeapAlloc
mov lpBuffer,rax
mov edi,eax

lea edx,lpRegion
mov [rsp+20h],rdx ; lpReadRegion
xor r9d,r9d ; dwBufferCoord
mov r8d,dwBufferSize
mov edx,eax ; lpBuffer
mov rcx,hOut ; hConsoleOutput
call ReadConsoleOutput
;---------------------------------------------------------
mov eax,dword ptr cols
mul dword ptr rows
mov ecx, eax
mov ax,Csbi.wAttributes
shl eax,16
rep stosd
;-----------------------------------------------------------
lea edx, lpRegion
mov [rsp+20h],rdx ; lpWriteRegion
xor r9d,r9d ; dwBufferCoord
mov r8d,dwBufferSize; dwBufferSize
mov rdx,lpBuffer ; lpBuffer
mov rcx,hOut ; hConsoleOutput
call WriteConsoleOutput

mov r8,lpBuffer ; lpMem
xor edx,edx ; dwFlags=0
mov rcx,hHeap ; hHeap
call HeapFree
leave
retn
draw endp
;-------------------------------------------------------
invert proc y:qword

local lpRegion:SMALL_RECT

push rbp
mov ebp,esp
sub esp,(28h+sizeof SMALL_RECT+15)and(-16)
;mov y,rcx

mov lpRegion.Left,RIGHT_MENU
mov lpRegion.Right,COLS_MENU+RIGHT_MENU-1
;mov rdx,y
mov lpRegion.Top,cx
mov lpRegion.Bottom,cx

mov r8d,COLS_MENU*4+260 ; dwBytes
mov edx,HEAP_ZERO_MEMORY; dwFlags
mov rcx,hHeap ; hHeap
call HeapAlloc
        mov rdi,rax         ; edi=lpBuffer

lea edx,lpRegion
mov [rsp+20h],rdx ; lpReadRegion
xor r9d,r9d ; dwBufferCoord
mov r8d,10000h+COLS_MENU; dwBufferSize
mov rdx,rax ; lpBuffer
mov rcx,hOut ; hConsoleOutput
call ReadConsoleOutput
;---------------------------------------------------------------
mov rsi,rdi
mov ecx,COLS_MENU ; cols

@@: lodsd          ;eax=xxABxxxx
ror eax,16 ;eax=xxxxxxAB
ror al,4    ;eax=xxxxxxBA
rol eax,16 ;eax=xxBAxxxx
stosd
loop @b
sub edi,COLS_MENU*4

lea edx,lpRegion
mov [rsp+20h],rdx ; lpWriteRegion
xor r9d,r9d ; dwBufferCoord
mov r8d,10000h+COLS_MENU; dwBufferSize   
mov edx,edi ; lpBuffer
mov rcx,hOut ; hConsoleOutput
call WriteConsoleOutput

mov r8d,edi ; lpBuffer
xor edx,edx ; dwFlags
mov rcx,hHeap ; hHeap
call HeapFree
leave
retn
invert endp
;-----------------------------------------------------------
ConsoleName db 'Enum and set console fonts',0
Str2 db 'For move into menu press Up or Down Arrow key',13,10,\
'For set selected font press Enter',13,10,\
'For exit press ESC or CTRL+C or CTRL+Break',13,10
hOut dq ?
hHeap dq ?
lpStack dq ?
fmt db 'font size %d x %d',0
end

TWell

#136
That API don't work well in windows 10 anymore :(
only 6x9 8x12 8x12 font sizes shown from
4x6 6x8 8x8 16x8 5x12 7x12 8x12 16x12 12x16 10x18 10x20


Mikl__

#137
Hi, Tim!
I've 10 console fonts in Windows 7 pro x64. May be you really have in windows 10 only tree console fonts (6x9, 8x12, 8x12) ? Start any console application, make the right click on an application frame, select item with name "Properties". It is so possible to learn how many and what fonts are established in your system

Mikl__

Tim,
I have Windows 7 and there is no opportunity to check the program in windows 10, but I wouldn't begin to object if you helped to write the program so that it without mistakes worked both in Windows 7 and in Windows 10. The asm-text of the program is open

TWell

#139
GetNumberOfConsoleFonts() gives only 3 fonts in Windows 10 :(

EDIT:
After chance of raster font from properties, all raster font sizes listed.
With Lucida Console those 3 sizes.

Mikl__

QuoteGetNumberOfConsoleFonts() gives only 3 fonts
Tim,
perhaps function GetNumberOfConsoleFonts returns quantity of "Terminal" fonts? See  topic Changing the font and the font size of a console via API

nidud

#141
deleted

Mikl__

#142
Hi, nidud!
I can't open your programs (console.zip, console2.zip). It is possible to attach them once again?
P.S. Oh, I have understood, these are the png-files renamed into zip-files

Mikl__

#143
Win x64 Tutorial #38m: Graphics in the console
asm-fileinclude win64a.inc
;----------------------------------------------
.code
WinMain proc
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local hOut:qword
local hWnd:qword
local hDC:qword
local hbitmap:qword
local memDC:qword
local bi:BITMAP
local ScreenX:dword
local ScreenY:dword

        push rbp
mov ebp,esp
sub esp,(40h+5*8+2*4+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+sizeof BITMAP+15)and(-16)

        xor ebx,ebx
call FreeConsole ; release the existing console
        call AllocConsole ; form the console

mov ecx,offset NameConsole
call SetConsoleTitle; definition of a title bar

mov ecx,STD_OUTPUT_HANDLE
        call GetStdHandle ; receive handle for a output
        mov hOut,rax
; load drawing into Heap
mov qword ptr [rsp+28h],LR_LOADFROMFILE
mov [rsp+20h],rbx
xor r9d,r9d
xor r8d,r8d
mov edx,offset bmp_path
mov ecx,400000h ; hInstance
        call LoadImage
mov hbitmap,rax
        lea r8d,bi  ;&bi
        mov edx,sizeof BITMAP
        mov rcx,rax ; hbitmap
        call GetObject
        movzx eax,bi.mBitsPixel
shr eax,3 ; eax=bmBitsPixel/8
mul bi.bmWidth
mul bi.bmHeight
mov edi,eax ;eax=bmpBitsPixel*bmpWidth*bmBitsPixel/8
        call GetProcessHeap
mov r8d,edi
mov edx,HEAP_NO_SERIALIZE ;1
        mov rcx,rax ; hHeap
        call HeapAlloc

mov eax,bi.bmWidth
shr eax,3
mov ScreenX,eax ; eax=bmWidth/8
mov eax,357913941    ; eax=(2^32)/12
        mul   bi.bmHeight
        mov ScreenY,edx    ; edx=bmHeight/12

mov rcx,hOut ; hConsoleOutput
call GetLargestConsoleWindowSize
;; eax return in 31-16 bits: dwCoord.y
;;               15-00 bits: dwCoord.x

        lea r8d,ConsoleWindow
mov [r8],ebx ;ConsoleWindow.Left=0 ConsoleWindow.Top=0
sub eax, ScreenX
sbb edx, edx
and ax, dx
dec eax
add eax, ScreenX
mov [r8+SMALL_RECT.Right],ax

shr eax, 16
sub eax,ScreenY
sbb edx, edx
and eax, edx
dec eax
add eax, ScreenY
mov [r8+SMALL_RECT.Bottom],ax
mov edx,TRUE ; bAbsolute
mov rcx,hOut ; hConsoleOutput
call SetConsoleWindowInfo
mov edx,ScreenY
shl edx,16                  ; Coord.y=ScreenY
add edx,ScreenX ; Coord.x=ScreenX
mov rcx,hOut ; hConsoleOutput
call SetConsoleScreenBufferSize;establish the new size of a window
;of the console which depends on the drawing size
;hide the cursor----------------------------------------
lea edx,cci                 ; lpConsoleCursorInfo
mov rcx,hOut ; hConsoleOutput
call GetConsoleCursorInfo
        lea edx,cci                 ; lpConsoleCursorInfo
mov [rdx+CONSOLE_CURSOR_INFO.bVisible],ebx ; FALSE
mov rcx,hOut ; hConsoleOutput
call SetConsoleCursorInfo
;-----------------------------------------------------
        mov rcx,hOut ; hObject
call CloseHandle
;------------------------------------------------------
call GetConsoleWindow
mov hWnd,rax
mov rcx,rax
call GetDC ;receive DC
mov hDC,rax

mov rcx,rax ;hDC
call CreateCompatibleDC ;create compatible DC
mov memDC,rax
mov rdx,hbitmap
mov rcx,rax
call SelectObject
;--------------------------------------------------------
@@: mov ecx,150
call Sleep
mov qword ptr [rsp+40h],SRCCOPY
mov [rsp+38h],rbx
mov [rsp+30h],rbx
mov rax,memDC
mov [rsp+28h],rax
mov eax,bi.bmHeight ;Rect.bottom
mov [rsp+20h],rax
mov r9d,bi.bmWidth ;Rect.right
xor r8d,r8d ;Rect.top
xor edx,edx ;Rect.left
mov rcx,hDC
call BitBlt
        mov ecx,VK_ESCAPE ; vKey
call GetAsyncKeyState
; Determine whether a key is up or down
test eax, 8000h
jz @b
;---------------------------------------------------------
mov rcx,hbitmap
call DeleteObject
mov rdx,hWnd
mov rcx,hDC
call ReleaseDC ;release DC
mov rcx,memDC
call DeleteDC ;delete a virtual window       
        call FreeConsole
xor ecx,ecx
        call ExitProcess
WinMain endp
;---------------------------------------------------------
bmp_path db 'Images\tweety78.bmp',0;'dragon.bmp',0;
NameConsole db "For exit press 'Esc'",0
end

jj2007

Interesting ::)

I've never thought of using the console window's DC for painting, but it makes sense :t

Mikl__

#145
Win x64 Tutorial #38n: ASCII-art in the console
Original the idea and the file are taken in http://www.benryves.com/tutorials/winconsole/
asm-fileinclude win64a.inc
MAXSCREENX = 30
MAXSCREENY = 23
.code
WinMain proc
local dithers:dword
local hOut:qword
local hIn:qword
local ConsoleWindow:SMALL_RECT
local Result:dword
local MOUSE_KEY:INPUT_RECORD

push rbp
mov ebp,esp
sub esp,(28h+4+3*8+sizeof SMALL_RECT+sizeof INPUT_RECORD+15)and(-16)

xor ebx,ebx
        call FreeConsole
        call AllocConsole
mov ecx,STD_INPUT_HANDLE ; nStdHandle
call GetStdHandle
mov hIn,rax

mov ecx,STD_OUTPUT_HANDLE ; nStdHandle
call GetStdHandle
mov hOut, rax
        mov rcx,rax;hOut ; hConsoleOutput
call GetLargestConsoleWindowSize
; eax return in 31-16 bits: dwCoord.y
;               15-00 bits: dwCoord.x
lea r8d,ConsoleWindow
mov [r8],ebx
; ConsoleWindow.Left = 0 ConsoleWindow.Top = 0
sub ax, MAXSCREENX
sbb edx, edx
and ax, dx
add ax, MAXSCREENX-1
mov [r8+SMALL_RECT.Right],ax

shr eax, 16
sub eax, MAXSCREENY
sbb edx, edx
and eax, edx
add eax, MAXSCREENY-1
mov [r8+SMALL_RECT.Bottom],ax
mov edx,TRUE ; bAbsolute
mov rcx,hOut ; hConsoleOutput
call SetConsoleWindowInfo

mov edx,MAXSCREENY*10000h+MAXSCREENX; dwSize
mov rcx,hOut ; hConsoleOutput
call SetConsoleScreenBufferSize

mov ecx,offset windowTitle ; lpConsoleTitle
call SetConsoleTitle
;decompressData--------------------------------------
mov esi,offset compSmallIcon ;in
        mov edi,offset bmpSmallIcon         ;out
xor ecx,ecx
@6: lodsb ; int x = in[ f++ ]
cmp al,91h ; if ( x == 0x91 )
jnz @f
lodsw
mov cl,ah
jecxz @7
rep stosb
jmp @7
@@: stosb ; in[ t++ ] = x 
@7: cmp edi,offset bmpSmallIcon+MAXSCREENX*MAXSCREENY
jnz @6
;---------------------------------------------------
mov edi,8        ; int c = 0
mov dword ptr dithers, 176+(177+(178+219*100h)*100h)*100h

@1: mov edx,7 ; int b=0

@2: cmp edx, 3 ; if (b>3)
mov ecx, edi        ; colour = c
jbe @f ; if (b==5 || b==3) colour|=((colour&7)<<4);
or ecx,FOREGROUND_INTENSITY; colour |= FOREGROUND_INTENSITY

@@: cmp edx, 5 ; if (b==5 || b==3)
jz @f
cmp edx, 3
jnz @3

@@: mov eax, ecx
and eax, 7          ;colour & 7
shl eax, 4          ;(colour & 7) << 4
or ecx, eax        ;colour |= ((colour&7) << 4)

@3: test edx, edx ; if (b==0)
jnz @f
xor ecx, ecx        ; colour = 0

@@: lea eax, [rdx+rdi*8] ; eax = b + c * 8
shl eax, 2          ; eax =(b + c * 8)*4
mov palette.Attributes[rax],cx ; palette[c][b].Attributes = colour;
mov ecx, edx                        ; ecx = b
shr ecx,1 ; ecx = b >> 1
mov cl,byte ptr dithers[rcx]        ; cl = dithers[b >> 1]
mov palette.Char.AsciiChar[rax],cl  ; palette[c][b].Char.AsciiChar = dithers[b>>1];
dec edx
jns @2
dec edi
jnz @1
;---------------------------------------------------------------------------------
;for (int x=0; x<MAXSCREENX; x++)
mov edi,offset chars
mov esi,offset bmpSmallIcon
@0: push rsi
push rdi
mov ecx, MAXSCREENY;for (int y=0; y<MAXSCREENY; y++)
@@: lodsb       ;al=pixel xxbbbccc   bbb = brightness ccc = colour
;getPalette(int pixel)
        shl eax,5 ;000xxbbb|ccc00000
        shl ah,2        ;0xxbbb00|ccc00000
        and eax,1CE0h   ;000bbb00|ccc00000
add al,ah       ;000bbb00|cccbbb00
and eax,0FFh    ;00000000|cccbbb00
mov eax, dword ptr palette[rax]; palette[colour][brightness]
stosd
add esi, MAXSCREENX-1
add edi, 320-4;
loop @b
pop rdi
pop rsi
add edi,4
inc esi
cmp esi,offset bmpSmallIcon+MAXSCREENX
jb @0

; copyBufferToScreen()
mov eax,offset write ; lpWriteRegion
mov [rsp+20h],rax
xor r9d,r9d ; dwBufferCoord
mov r8d,320050h ; dwBufferSize
mov edx,offset chars ; lpBuffer
mov rcx,hOut ; hConsoleOutput
call WriteConsoleOutput


@@:     lea r9d,Result
mov r8d,TRUE
lea edx,MOUSE_KEY                   ; lpMOUSE_KEY
mov rcx,hIn
call ReadConsoleInput
lea eax,MOUSE_KEY
cmp [rax+INPUT_RECORD.EventType],KEY_EVENT
jne @b
cmp [rax+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_ESCAPE
jne @b
mov rcx,hIn
call CloseHandle
mov rcx,hOut
call CloseHandle
call FreeConsole
xor ecx,ecx
        call ExitProcess
WinMain endp
compSmallIcon db 145, 0, 44, 63, 145, 0, 28, 63, 47, 63, 145, 0, 27, 63, 23, 63, 23, 145, 0, 25, 63, 47, 16, 0, 63, 145, 0, 25, 63, 23, 0, 0, 15, 63, 145, 0, 23, 63, 15, 145, 0, 4, 63, 23, 145, 0, 21
db 63, 47, 16, 145, 0, 4, 23, 63, 145, 0, 21, 63, 23, 145, 0, 6, 15, 63, 145, 0, 19, 63, 55, 145, 0, 8, 63, 23, 60, 60, 52, 36, 28, 12, 145, 0, 12, 63, 31, 0, 0, 8, 145, 0, 5, 23, 63, 145, 60
db 6, 52, 44, 36, 145, 0, 7, 15, 145, 63, 5, 15, 145, 0, 6, 63, 54, 54, 145, 62, 3, 54, 145, 38, 3, 0, 0, 15, 145, 63, 6, 145, 0, 5, 8, 145, 0, 6, 63, 59, 59, 51, 51, 58, 38, 46, 54, 145, 63
db 3, 16, 145, 0, 3, 63, 31, 145, 0, 12, 23, 63, 45, 51, 59, 59, 51, 51, 58, 145, 0, 6, 63, 23, 145, 0, 14, 63, 48, 145, 37, 3, 53, 45, 59, 145, 0, 6, 63, 7, 145, 0, 14, 31, 63, 145, 0, 3, 37
db 37, 45, 145, 0, 5, 63, 31, 145, 0, 16, 23, 63, 145, 0, 4, 37, 145, 0, 4, 63, 55, 145, 0, 18, 63, 48, 145, 0, 8, 63, 39, 145, 0, 18, 31, 63, 145, 0, 7, 63, 31, 8, 145, 0, 19, 23, 63, 145, 0
db 5, 16, 63, 145, 0, 22, 63, 145, 0, 5, 145, 63
db 26, 145, 0, 4, 145, 7, 25, 16, 0, 0
windowTitle db "ASCII Madness",0
write SMALL_RECT <0,0,MAXSCREENX-1,MAXSCREENY-1>
bmpSmallIcon db MAXSCREENX*MAXSCREENY dup (?)
palette CHAR_INFO 64 dup (<>)   ;64*(2+2+1)=320=140h
chars CHAR_INFO 80*50 dup (<>);Character buffer
end

Mikl__

Win x64 Tutorial #38o: Few methods of Creations of a Console
  • The system creates a new console when it starts a console process
  • Create a console process with a new console can use the CreateProcess function with CREATE_NEW_CONSOLE
  • A process uses AllocConsole to create a console
bat-filecls
set masm64_path=\masm64\
set filename=%1
del %filename%.exe
%masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm || exit
%masm64_path%bin\link /SUBSYSTEM:CONSOLE /LIBPATH:"%masm64_path%Lib" ^
/entry:WinMain %filename%.obj /LARGEADDRESSAWARE:NO ^
/ALIGN:16 /BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe || exit
del %filename%.obj
file c28.asminclude win64a.inc
;----------------------------------------------
.code
WinMain proc
local MOUSE_KEY:INPUT_RECORD; sizeof=0x14, align=0x4
local Result:QWORD
local hOut:DWORD
local hIn:DWORD

push rbp
mov ebp,esp
sub esp,(28h+3*8+sizeof INPUT_RECORD+15)and(-16)
xor ebx,ebx
mov ecx,STD_INPUT_HANDLE
call GetStdHandle
mov hIn,eax
mov ecx,STD_OUTPUT_HANDLE
call GetStdHandle
mov hOut,eax
mov [rsp+20h],rbx
lea r9d,Result
mov r8d,sizeof Str1
mov edx,offset Str1
mov ecx,eax
call WriteConsole
@@: lea r9d,Result
mov r8d,TRUE
lea edx,MOUSE_KEY;rbp-18h
mov ecx,hIn
call ReadConsoleInput
cmp MOUSE_KEY.EventType,KEY_EVENT
jnz @b
cmp MOUSE_KEY.KeyEvent.bKeyDown,ebx;FALSE
jnz @b
cmp MOUSE_KEY.KeyEvent.wVirtualKeyCode,VK_ESCAPE
jnz @b
mov ecx,hIn
call CloseHandle
mov ecx,hOut
call CloseHandle
call FreeConsole
xor ecx,ecx
call ExitProcess
WinMain endp
Str1 db 'This console was created by the CreateProcess',10,\
'function with the CREATE_NEW_CONSOLE parameter.',10,\
'For continuation press the Esc key'
end
asm-fileinclude win64a.inc

MAXSCREENX = 43
MAXSCREENY = 8
.code
WinMain proc
local ConsoleWindow:SMALL_RECT;  sizeof=0x8, align=0x2
local cci:CONSOLE_CURSOR_INFO; sizeof=0x8, align=0x4
local ExitCode:DWORD;
local pi:PROCESS_INFORMATION; sizeof=0x18, align=0x8
local cif:STARTUPINFO;          sizeof=0x68, align=0x8
local MOUSE_KEY:INPUT_RECORD; sizeof=0x14, align=0x4
local Result:QWORD
local hOut:DWORD
local hIn:DWORD

push rbp
mov ebp,esp
sub esp,(50h+8+3*4+sizeof INPUT_RECORD+sizeof STARTUPINFO+\
sizeof PROCESS_INFORMATION+sizeof CONSOLE_CURSOR_INFO+sizeof SMALL_RECT+15)and(-16)

xor ebx,ebx
mov ecx,offset Str2
call SetConsoleTitle
mov ecx,offset Str5
call system
mov ecx,STD_INPUT_HANDLE
call GetStdHandle
mov hIn,eax
mov ecx,STD_OUTPUT_HANDLE
call GetStdHandle
mov hOut,eax
mov [rsp+20h],rbx;0
lea r9d,Result;rbp-0B0h
mov r8d,sizeof Str1
mov edx,offset Str1
mov ecx,eax
call WriteConsole
@@: lea r9d,Result
mov r8d,TRUE
lea edx,MOUSE_KEY;rbp-0A8h
mov ecx,hIn
call ReadConsoleInput
cmp MOUSE_KEY.EventType,KEY_EVENT
jnz @b
cmp MOUSE_KEY.KeyEvent.bKeyDown,ebx;FALSE
jnz @b
cmp MOUSE_KEY.KeyEvent.wVirtualKeyCode,VK_ESCAPE
jnz @b
call FreeConsole
;----------------------------------------------------------------
mov cif.cb,sizeof STARTUPINFO;rbp-94h
mov cif.lpReserved,rbx;0
mov cif.lpDesktop,rbx;0
mov eax,offset Str3
mov cif.lpTitle,rax ;Display name for the title bar of the new console's window
mov cif.dwFlags,STARTF_USEPOSITION or STARTF_USESIZE or \
STARTF_USECOUNTCHARS or STARTF_USEFILLATTRIBUTE or \
STARTF_USESHOWWINDOW
mov cif.dwFillAttribute,BACKGROUND_BLUE+FOREGROUND_BLUE+\
FOREGROUND_GREEN+FOREGROUND_RED;Text and background color attributes of the new console's screen buffer
mov cif.dwX,200 ; left edge Location of the new console window, in screen pixel coordinates
mov cif.dwY,200 ; upper edge
mov cif.dwXSize,400 ; width 400/8=50
mov cif.dwYSize,96 ; height 96/12=8
mov cif.dwXCountChars,50 ; width Size of the new console's screen buffer, in character cells
mov cif.dwYCountChars,8 ; height
mov cif.wShowWindow,SW_SHOW
mov cif.cbReserved2,0
mov cif.lpReserved2,rbx
lea eax,pi
mov qword ptr [rsp+48h],rax
lea eax,cif
mov qword ptr [rsp+40h],rax
mov [rsp+38h],rbx
mov [rsp+30h],rbx
mov qword ptr [rsp+28h],CREATE_NEW_CONSOLE
mov [rsp+20h],rbx
xor r9d,r9d
xor r8d,r8d
xor     edx,edx
mov ecx,offset Str4
call CreateProcess
@@: lea edx,ExitCode;rbp-14h
mov rcx,pi.hProcess
call GetExitCodeProcess
cmp ExitCode,STILL_ACTIVE
jz @b
xor edx,edx
mov rcx,pi.hProcess
call TerminateProcess
mov rcx,pi.hThread
call CloseHandle
mov rcx,pi.hProcess
call CloseHandle
call FreeConsole
;--------------------------------------------------
call AllocConsole
mov ecx,hOut
call GetLargestConsoleWindowSize
lea r8d,ConsoleWindow
mov [r8],ebx;ConsoleWindow.Left = 0 ConsoleWindow.Top = 0
sub ax,MAXSCREENX
sbb edx,edx
and ax,dx
add ax,MAXSCREENX-1
mov [r8+SMALL_RECT.Right],ax
shr eax,16
sub eax,MAXSCREENY
sbb edx,edx
and eax,edx
add eax,MAXSCREENY-1
mov [r8+SMALL_RECT.Bottom],ax
mov edx,TRUE
mov ecx,hOut
call SetConsoleWindowInfo
mov edx,MAXSCREENY*10000h+MAXSCREENX
mov ecx,hOut
call SetConsoleScreenBufferSize
mov ecx,offset Str6
call SetConsoleTitle
mov [rsp-20h],rbx
lea r9d,Result
mov r8d,sizeof Str7
mov edx,offset Str7
mov ecx,hOut
call WriteConsole
lea edx,cci;rbp-10h
mov ecx,hOut
call GetConsoleCursorInfo
mov cci.bVisible,ebx;FALSE
lea edx,cci
mov ecx,hOut
        call SetConsoleCursorInfo
@@:     lea r9d,Result
        mov r8d,TRUE
        lea edx,MOUSE_KEY
        mov ecx,hIn
        call ReadConsoleInput
cmp MOUSE_KEY.EventType,KEY_EVENT
jnz @b
        cmp MOUSE_KEY.KeyEvent.bKeyDown,ebx;FALSE
jnz @b
        cmp MOUSE_KEY.KeyEvent.wVirtualKeyCode,VK_ESCAPE
jnz @b
        mov ecx,hIn
call CloseHandle
mov ecx,hOut
call CloseHandle
call FreeConsole
xor ecx,ecx
call ExitProcess
WinMain endp
Str1 db 'This console was created by system at start of the console application.',10,\
'For continue press the Esc key'
Str2 db 'First console',0
Str3 db 'Second console',0
Str4 db 'c28.exe',0
Str5 db 'cls',0
Str6 db 'Third console',0
Str7 db 'This console was created by the AllocConsole function.',10,\
'For an exit from the program press the Esc key'
end

Mikl__

#147
Win x64 Tutorial #38q: Charge accumulator
bat-filecls
set masm64_path=\masm64\
set filename=%1
del %filename%.exe
%masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm || exit
%masm64_path%bin\link /SUBSYSTEM:CONSOLE /LIBPATH:"%masm64_path%Lib" ^
/entry:WinMain %filename%.obj /LARGEADDRESSAWARE:NO ^
/ALIGN:16 /BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe || exit
del %filename%.obj
asm-fileinclude win64a.inc

MAXSCREENX = 80
MAXSCREENY = 25

.code
WinMain proc
local hOut:dword
local Result:dword
local color:dword
local cci:CONSOLE_CURSOR_INFO
local ConsoleWindow:SMALL_RECT
        push rbp
mov ebp,esp
sub esp,(28h+4*3+sizeof CONSOLE_CURSOR_INFO+sizeof SMALL_RECT+15)and(-16)

xor ebx,ebx
call FreeConsole
        call AllocConsole ; Allocate the console

        mov ecx,STD_OUTPUT_HANDLE
        call GetStdHandle
        mov hOut,eax
;-------------------------------------------------------------------
        mov ecx,eax ;hOut
call GetLargestConsoleWindowSize
; eax return in 31-16 bits: dwCoord.y
;               15-00 bits: dwCoord.x

        lea r8d,ConsoleWindow
mov [r8],ebx               ; ConsoleWindow.Left = 0 ConsoleWindow.Top = 0
sub ax, MAXSCREENX
sbb edx, edx
and ax, dx
add ax, MAXSCREENX-1
mov [r8+SMALL_RECT.Right],ax

shr eax, 16
sub eax, MAXSCREENY
sbb edx, edx
and eax, edx
add eax, MAXSCREENY-1
mov [r8+SMALL_RECT.Bottom],ax

mov edx,TRUE ; bAbsolute
mov ecx,hOut ; hConsoleOutput
call SetConsoleWindowInfo

mov edx,MAXSCREENY*10000h+MAXSCREENX;dwCoord
mov ecx,hOut ; hConsoleOutput
call SetConsoleScreenBufferSize;establish the new size of a window of the console
mov ecx,offset Str2
call SetConsoleTitle ;definition of a title bar
;hide the cursor------------------------------------------------------
lea edx,cci                  ; lpConsoleCursorInfo
mov ecx,hOut ; hConsoleOutput
call GetConsoleCursorInfo
        lea edx,cci                  ; lpConsoleCursorInfo
mov [rdx+CONSOLE_CURSOR_INFO.bVisible],ebx ;cci.bVisible = FALSE
mov ecx,hOut ; hConsoleOutput
call SetConsoleCursorInfo
;--------------------------------------------------------------------
        mov [rsp+20h],rbx ; 0
lea r9d,Result              ; lpResult
        mov r8d,sizeof Str3
mov edx,offset Str3
mov ecx,hOut;HANDL
        call WriteConsole ;remove a line of symbols
main_loop:mov edx,20001h ;coord.x=1 coord.y=2
        mov ecx,hOut
        call SetConsoleCursorPosition
xor edi,edi
@@: mov edx,edi
shr edx,2
movzx edx,index_color[rdx] ;color
mov ecx,hOut
        call SetConsoleTextAttribute
        mov [rsp+20h],rbx ; 0
lea r9d,Result              ; lpResult
        mov r8d,1;sizeof Str4
mov edx,edi
and edx,3
add edx,offset Str4
mov ecx,hOut;HANDL
        call WriteConsole ;remove a line of symbols
inc edi
        mov ecx,VK_ESCAPE ; vKey
call GetAsyncKeyState
; Determine whether a key is up or down
test eax, 8000h
jnz exit0
mov ecx,1000
call Sleep
cmp edi,16
jb @b
        mov edx,20001h;coord
        mov ecx,hOut
        call SetConsoleCursorPosition
        xor edx,edx;color
mov ecx,hOut
        call SetConsoleTextAttribute
        mov [rsp+20h],rbx ; 0
lea r9d,Result              ; lpResult
        mov r8d,16
mov edx,offset Str1
mov ecx,hOut;HANDL
        call WriteConsole ;remove a line of symbols
mov ecx,1000
call Sleep
jmp     main_loop
;--------------------------------------------------------------
exit0: mov ecx,hOut
call CloseHandle
        call FreeConsole

xor ecx,ecx
        call ExitProcess
WinMain endp
Str1 db 16 dup (0)
Str2 db 'Charge accumulator',0
Str3 db 'For an exit from the program press the Esc or CTRL+C or CTRL+Break key',10,\
0C9h, 16 dup (0CDh),0BBh,10,\
0BAh, 16 dup (0),   0BAh,0DDh,10,\
0C8h, 16 dup (0CDh),0BCh
Str4  db 176,   177,  178, 0DBh
index_color db 4,4Ch,0CEh,0EFh
end

jj2007


Mikl__