Форум программистов, компьютерный форум, киберфорум
Assembler: MASM64, х64/long mode
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.87/89: Рейтинг темы: голосов - 89, средняя оценка - 4.87
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
1

Создание консольных приложений в 64-разрядной Windows Seven

02.03.2016, 06:46. Показов 16120. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Создаю папку masm64
в каталоге masm64 создаю подкаталоги bin, include, lib, examples
в каталоги include, lib копирую содержимое masm64.zip взятого с сайта httр://dsmhеlр.nаrоd.ru/еnvirоnmеnt.htm (в названии сайта латинские буквы "p", "e", "a", "o" заменены на буквы кириллицы, чтобы парсер сайта cyberforum.ru не испортил ссылку). Содержимое для каталога bin (cvtres.exe, link.exe, ml64.exe, msobj80.dll, mspdb80.dll, msvcp80.dll, msvcp90.dll, msvcr80.dll, msvcr90.dll, rc.exe, rc.hlp, rcdll.dll) взято из комплекта C++ компиляторов от Microsoft Microsoft Windows SDK for Windows 7 and .NET Framework 4 (распространяется бесплатно)
Создаю в папке Include файл win64a.inc следующего содержания
Кликните здесь для просмотра всего текста
Код
OPTION DOTNAME
include temphls.inc
include win64.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include comdlg32.inc
includelib comdlg32.lib
include comctl32.inc
includelib comctl32.lib
include gdi32.inc
includelib gdi32.lib
includelib msvcrt.lib
include msvcrt.inc

OPTION PROLOGUE:none
OPTION EPILOGUE:none
Пишу bat-файл следующего содержания
Кликните здесь для просмотра всего текста
Код
cls
set masm64_path=\masm64\
set filename= <--- здесь будет имя asm-файла
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 /SECTION:.text,W /BASE:0x400000 || exit
del %filename%.obj
содержимое asm-файла
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
include win64a.inc
BLACK   equ 0
BLUE    equ 1
GREEN   equ 2
CYAN    equ 3
RED equ 4
PURPLE  equ 5
YELLOW  equ 6
SYSTEM  equ 7
GREY    equ 8
BRIGHTBLUE equ 9
BRIGHTGREEN equ 10
BRIGHTCYAN equ 11
BRIGHTRED equ 12 
BRIGHTPURPLE equ 13
BRIGHTYELLOW equ 14
WHITE   equ 15
MAXSCREENX = 80
MAXSCREENY = 25
buffersize = 200
X = 0
Y = 10
.code
WinMain proc
local LENS:qword
local hOut:qword
local BUFF[buffersize]:byte
local ConsoleWindow:SMALL_RECT
 
        push rbp
    mov ebp,esp
    sub esp,(28h+2*8+buffersize+sizeof SMALL_RECT+15)and(-16)
 
    call    FreeConsole;release the existing console
        call    AllocConsole;create the console
        mov ecx,STD_OUTPUT_HANDLE
        call    GetStdHandle;receive the handle for a conclusion
        mov     hOut,rax
        mov rcx,rax     ; hConsoleOutput
    call    GetLargestConsoleWindowSize     
;   rax return in 31-16 bits: dwCoord.y
;                 15-00 bits: dwCoord.x
 
        lea r8d,ConsoleWindow
    mov [r8+SMALL_RECT.Left],0
    mov [r8+SMALL_RECT.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 STR2
    call    SetConsoleTitle     ;definition of a title bar
        mov     edx,Y*10000h+X
        mov     rcx,hOut
        call    SetConsoleCursorPosition;establish a cursor position
        mov     edx,BRIGHTGREEN     ;color of the output text
        mov     rcx,hOut
        call    SetConsoleTextAttribute ;set color attributes of the output text
        mov     qword ptr [rsp+20h],0
    lea     r9d,BUFF
        mov     r8d,sizeof STR1
    mov     edx,offset STR1
    mov     rcx,hOut
        call    WriteConsole        ;display a line of symbols
        mov     ecx,STD_INPUT_HANDLE
        call    GetStdHandle        ;receive HANDLE for input
        mov     qword ptr [rsp+20h],0
    lea     r9d,LENS
        mov     r8d,buffersize
    lea     edx,BUFF
        mov     rcx,rax
        call    ReadConsole     ;wait for input of a line of symbols
        mov     edx,BRIGHTCYAN      ;color of the input text
        mov     rcx,hOut
        call    SetConsoleTextAttribute ;set color attributes of the output text
        mov     qword ptr [rsp+20h],0
    lea     r9d,LENS
        mov     r8d,[r9]        ;length of the removed line
    lea edx,BUFF
        mov rcx,hOut
        call    WriteConsole
        mov     ecx,3000        ;small delay
    call    Sleep
        call    FreeConsole     ;close the console
    mov ecx,ecx
        call    ExitProcess
WinMain endp
STR1 db 'Enter line of any symbols and press "Enter":',13,10
STR2 db 'Iczelion''s tutorial #38a',0
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip masm64.zip (3.84 Мб, 168 просмотров)
Тип файла: zip lesson01.zip (2.6 Кб, 76 просмотров)
3
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.03.2016, 06:46
Ответы с готовыми решениями:

Создание консольных приложений Windows
Когда-то у меня был Microsoft Visual C++ и я лишь клацал F5 для компиляции консольных приложений....

Найти книгу "Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows" в djvu
Здравствуйте. Весь инет обыскал, а найти книгу &quot;Создание эффективных WIN32-приложений с учетом...

Создание консольных приложений на С #. Нужно написать программу
Здравствуйте, уважаемые обитатели форума, мне нужна ваша помощь, помогите написать программу ... \...

Запуск консольных приложений с кириллицей на англоязычной Windows
Всем привет! Установил Windows 10 с английским языком интерфейса. Сразу столкнулся с проблемой:...

22
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
02.03.2016, 08:18  [ТС] 2
Установка цвета символов и цвета фона в консольном приложении
Добавляю в папку bin файл stubby.exe следующего содержания:
Кликните здесь для просмотра всего текста
Код
0000: 4D 5A 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | MZ
0010: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 |
0020: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 |
0030: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 |
Это на сотню байтов уменьшает исходный ехе-файл
немного меняю содержимое bat-файла
Кликните здесь для просмотра всего текста
Код
cls
set masm64_path=\masm64\
set filename= <--- здесь будет имя asm-файла
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 /SECTION:.text,W /BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe || exit
del %filename%.obj
содержимое asm-файла
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
LEFT       = 8
TOP    = 4
buffersize   = 100
.code
WinMain proc
local BUFF[buffersize]:byte   
local hIn:qword
local hOut:qword
local result:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
local color:dword
local coord:COORD
 
        push rbp
    mov ebp,esp
    sub esp,(30h+3*8+4+buffersize+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
    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+SMALL_RECT.Left],0
    mov [r8+SMALL_RECT.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 Str1
    call    SetConsoleTitle
;прячем курсор----------------------------------------
    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 qword ptr [rsp+20h],0
    lea r9d,result;&result
        mov r8d,sizeof Str2
    mov edx,offset Str2     
    mov rcx,hOut
        call WriteConsole
        mov coord.x,LEFT
    
        mov color,0
@0:     mov coord.y,TOP
@@:     mov edx,coord
        mov rcx,hOut
        call SetConsoleCursorPosition    
        ; To establish color and a background of the text of the console
        ; 4-7 бит - background color
        ; 0-3 бит - text color
        ; other bits aren't used
    mov edx,color
    mov rcx,hOut
        call SetConsoleTextAttribute
    mov r8d,color
    mov edx,offset fmt
    lea ecx,BUFF
    call wsprintf
    mov qword ptr [rsp+20h],0
        lea r9d,result
        mov r8d,eax
    lea edx,BUFF
        mov rcx,hOut
        call WriteConsole
        inc coord.y
    inc color
    cmp coord.y,TOP+16
    jb @b
    add coord.x,4
    cmp coord.x,16*4+LEFT
    jb @0
@@:     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.wVirtualKeyCode],VK_ESCAPE
    jne @b
        call FreeConsole
    xor ecx,ecx
        call ExitProcess
WinMain endp
Str1 db 'Installation of color of symbols and background of the text of the console',0
Str2 db 'For exit press ESC or CTRL+C'
fmt  db '%.3d',0
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson02.zip (2.8 Кб, 36 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
02.03.2016, 08:33  [ТС] 3
Консольное приложение. "Градиентная заливка"
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
LEFT       = 8
TOP    = 4
buffersize = 100
.code
WinMain proc
local BUFF[buffersize]:byte   
local hIn:qword
local hOut:qword
local result:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
local color:dword
local count:dword
local coord:COORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(30h+3*8+2*4+buffersize+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+COORD+15)and(-16)
        xor ebx,ebx
        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+SMALL_RECT],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 Str1
    call    SetConsoleTitle
;hide 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     [rsp+20h],rbx       ;0
    lea r9d,result          ;&result
        mov r8d,sizeof Str2
    mov edx,offset Str2     
    mov rcx,hOut
        call    WriteConsole
        mov     count,0Fh
    mov     coord,10000h    ; X=0 Y=1
@0:     mov     color,0Fh
@@:     mov     edx,coord
        mov rcx,hOut
        call    SetConsoleCursorPosition
    ; To establish color and a background of the text of the console
        ; 4-7 bits - background color
        ; 0-3 bits - text color
        ; other bits aren't used
    mov edx,color
    mov rcx,hOut
        call    SetConsoleTextAttribute
        mov     [rsp+20h],rbx
        lea     r9d,result
        mov     r8d,1
    mov     edx,offset Str3
        mov     rcx,hOut
        call    WriteConsole
        inc     color
    inc     coord.x
    cmp     coord.x,MAXSCREENX
    jb  @b
    dec     count
    mov eax,count
    mov     color,eax
    inc     coord.y
        mov coord.x,0
    cmp coord.y,MAXSCREENY-1
    jnz @b
;------------------------------------------------------------------
@@:     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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
        call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
Str1 db 'Installation of color of symbols and background of the text of the  console application',0
Str2 db 'For exit press ESC or CTRL+C or CTRL+Break'
Str3 db 'o'
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson03.zip (2.8 Кб, 28 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
02.03.2016, 09:11  [ТС] 4
Простое консольное приложение
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
include win64a.inc
 
MAXSCREENX = 80
MAXSCREENY = 25
buffersize = 200
 
.code
WinMain proc
local coord:COORD
local hOut:qword
local hIn:qword
local BUFF[buffersize]:byte
local ConsoleWindow:SMALL_RECT
local result:qword
local dwLength:dword
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(28h+3*8+4+buffersize+sizeof INPUT_RECORD+sizeof COORD+\
        sizeof SMALL_RECT+sizeof CONSOLE_CURSOR_INFO+15)and(-16)
 
        xor ebx,ebx
        call    FreeConsole         ; release the existing console
        call    AllocConsole            ; create the console
        mov ecx,STD_INPUT_HANDLE
    call    GetStdHandle            ; receive handle for a input
    mov hIn,rax
    mov ecx,STD_OUTPUT_HANDLE
        call    GetStdHandle            ; receive handle for a output
        mov hOut,rax
        mov ecx,eax             ; hConsoleOutput
    call    GetLargestConsoleWindowSize
;   eax return in 31-16 bits: dwCoord.y
;                 15-00 bits: dwCoord.x
 
        lea r8d,ConsoleWindow       ; lpConsoleWindow
    mov [r8+SMALL_RECT],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 console window
    mov ecx,offset NameConsole
    call    SetConsoleTitle         ; definition of a title bar
;------------------------------------------------------------------------
    mov     [rsp+20h],rbx
    lea     r9d,BUFF
    mov r8d,sizeof Str1
    mov edx,offset Str1
    mov rcx,hOut            ; hConsoleOutput
    call    WriteConsole            ; display a line of symbols
;hide 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
;------------------------------------------------------
;demonstration of positioning of the cursor
        mov coord,10000h    ;y=1 x=0 
@@: movzx   r9d,coord.y
    movzx   r8d,coord.x
    mov edx,offset fmt1
    lea     ecx,BUFF
    call    sprintf
    mov     dwLength,eax
    mov edx,coord
    mov rcx,hOut
        call    SetConsoleCursorPosition    ; establish a cursor position
        mov     [rsp+20h],rbx
    lea     r9d,result
        mov r8d,dwLength
    lea     edx,BUFF
    mov rcx,hOut
        call    WriteConsole            ; display a line of symbols
        add coord,10005h            ; x = x + 5  y = y + 1
    cmp     coord.y,10
    jb  @b
; change of color of symbols
    mov edx,0C0000h         ; coord
    mov rcx,hOut
    call    SetConsoleCursorPosition    ; establish a cursor position
    mov edx,FOREGROUND_BLUE or BACKGROUND_GREEN
    mov rcx,hOut
    call    SetConsoleTextAttribute     ; set color attributes of the output text
    mov     [rsp+20h],rbx
    lea     r9d,result
    mov r8d,sizeof Str3
    mov edx,offset Str3
    mov rcx,hOut
    call    WriteConsole            ; display a line of symbols
    mov edx,FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED
    mov rcx,hOut
    call    SetConsoleTextAttribute     ; set color attributes of the output text
    mov edx,0E0000h         ; coord
    mov rcx,hOut
    call    SetConsoleCursorPosition    ; establish a cursor position
 
    mov     [rsp+20h],rbx
    lea     r9d,result
    mov r8d,sizeof Str4
    mov edx,offset Str4
    mov rcx,hOut
    call    WriteConsole            ; display a line of symbols
; reading the entered line        
    mov     [rsp+20h],rbx
    lea     r9d,result
    mov     r8d,80
    lea     edx,BUFF
    mov rcx,hIn
        call    ReadConsole         ; wait for input of a line of symbols
    mov rax,result
    lea esi,BUFF
    mov byte ptr [rax+rsi-2],0      ; 2 symbols CR and LF
; remove ASCII code of the entered symbols
    xor eax,eax
    mov dwLength,eax
@@: lodsb
    or  eax,eax
    jz  @f
    mov edx,eax
    mov ecx,offset fmt2
    call    printf
    add dwLength,eax
    jmp @b
@@: mov ecx,dwLength
    neg ecx
    mov     [rsp+20h],rbx
    lea     r9d,result
    mov     r8d,ecx             ; length of the removed line
    lea     edx,BUFF
    mov     rcx,hOut
    call    WriteConsole
; it is possible to use the functions printf, gets, etc.
    mov ecx,offset Str5
    call    printf
    lea ecx,BUFF
    call    gets
    lea edx,BUFF
    mov ecx,offset fmt3
    call    printf
    mov ecx,offset Str2
    call    printf
@@:     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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
        call    FreeConsole;закрываем консоль
    xor ecx,ecx
        call    ExitProcess
WinMain endp
NameConsole     db 'Simple example of console',0
Str1    db 'This is sample output string',13,10
Str2    db 'For exit from program press ESC or CTRL+C or CTRL+Break',0
Str3    db 'This is Blue text on Green background'
Str4    db 'Enter a line of symbols and you can to see ASCII-code of symbols: ',0Dh,0Ah
Str5    db 0Dh,0Ah,'This is a test. Enter another string: ',0Dh,0Ah,0
fmt1    db "Text position X=%d, Y=%d",0
fmt2    db "%X ",0
fmt3    db "%s",0Dh,0Ah,0
end
Программа демонстрирует изменение позиции курсора с помощью функции SetConsoleCursorPosition, изменение цветов фона и символов (SetConsoleTextAttribute), чтение введенной строки через ReadConsole, использование printf и gets, вывод ASCII-кода введенных символов строки, завершение программы по нажатию на клавишу "Esc".
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson04.zip (3.8 Кб, 35 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
02.03.2016, 09:31  [ТС] 5
Лучший ответ Сообщение было отмечено R71MT как решение

Решение

Прогресс-бар в консольной программе
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
colors1 = 159
colors2 = 249
.code
WinMain proc
local hIn:qword
local hOut:qword
local result:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local CSBI:CONSOLE_SCREEN_BUFFER_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(28h+3*8+sizeof SMALL_RECT+sizeof INPUT_RECORD+\
        sizeof CONSOLE_CURSOR_INFO+sizeof CONSOLE_SCREEN_BUFFER_INFO+15)and(-16)
 
        xor     ebx,ebx
    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 = 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],ebx;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
;Get Console Info
;with Get CursorPosition Start
    lea edx,CSBI
    mov rcx,hOut
    call    GetConsoleScreenBufferInfo
    ;Loop of bar 0 - 100
    ;Write procent char (only one time)
    mov procentbar[27], '%'
    ;Write ascii procent
@0: mov     dl,10
    mov     eax,procent
    div     dl
    add     ax,'00'
    mov     word ptr procentbar[24], ax
    cmp al,3Ah
    jnz @f
        mov word ptr procentbar[23],'01'
@@: ;Set CursorPosition Start
    mov eax,CSBI.dwCursorPosition
    mov edx, eax
    mov rcx,hOut
    call    SetConsoleCursorPosition
    ;Set Color1
    mov edx, colors1
        mov rcx,hOut
    call    SetConsoleTextAttribute
    ;Write proportial part
    mov [rsp+20h],rbx
    mov r9d,offset n
    mov     r8d,procent
    shr     r8d,1
    mov edx,offset procentbar
    mov rcx,hOut
    call    WriteFile
    ;Set Color2
    mov edx, colors2
    mov rcx,hOut
    call    SetConsoleTextAttribute
    ;Write proportial part end
    mov edx,procent
    shr edx,1
    mov r8d,50
    sub r8d,edx
    add edx,offset procentbar
    mov [rsp+20h],rbx
    mov r9d,offset n
    mov rcx,hOut
    call    WriteFile
;Wait for slow speed
    mov ecx,procent
    shr ecx,2
    add ecx,80
    call    Sleep
;Add procent
    inc procent
    cmp procent,101
    jb  @0
;Set Text Color on default
    movzx   edx,CSBI.wAttributes
    mov rcx,hOut
    call    SetConsoleTextAttribute
 
@@:     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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
        call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
ConsoleName db 'Progress bar in console',0
Str2 db 'For exit press ESC or CTRL+C or CTRL+Break',13,10,10,32
procentbar db 50 dup (32),0,0 
procent dd 0
n dd 0
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson05.zip (3.0 Кб, 35 просмотров)
4
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 05:55  [ТС] 6
Лучший ответ Сообщение было отмечено R71MT как решение

Решение

Двоичные часы в консольной программе
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
include win64a.inc
MAXSCREENX = 50
MAXSCREENY = 15
MAX_STACK  = 1000h
BLACK      = 0
BLUE       = 1
GREEN      = 2
CYAN       = 3
RED    = 4
PURPLE     = 5
YELLOW     = 6
SYSTEM     = 7
GREY       = 8
BRIGHTBLUE = 9
BRIGHTGREEN  = 10
BRIGHTCYAN = 11
BRIGHTRED  = 12 
BRIGHTPURPLE = 13
BRIGHTYELLOW = 14
WHITE      = 15
LEFT       = 4
TOP    = 4
W      = 3
.code
WinMain proc
local hIn:qword
local szReadWrite:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
local stm:SYSTEMTIME
 
        push    rbp
    mov     ebp,esp
    sub     esp,(28h+2*8+sizeof INPUT_RECORD+\
        sizeof SMALL_RECT+sizeof CONSOLE_CURSOR_INFO+\
    sizeof SYSTEMTIME+15)and(-16)
 
    xor ebx,ebx
        call    FreeConsole
        call    AllocConsole
    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
 
        mov ecx,STD_INPUT_HANDLE
        call    GetStdHandle
        mov hIn,rax
        mov ecx,STD_OUTPUT_HANDLE
        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           ; 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;устанавливаем новый размер окна консоли
 
    mov     ecx,offset Str1
    call    SetConsoleTitle
;hide 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 [rsp+20h],rbx       ;0
    lea r9d,szReadWrite
    mov r8d,sizeof Str2
    mov edx,offset Str2
    mov rcx,hOut
    call    WriteConsole        ;вывести Str2 на консоль
;--------------------------------------------------------
; Run until Esc is pressed
main_loop:mov   ecx,10          ; dwMilliseconds
    call    Sleep
    lea ecx,stm
    call    GetLocalTime
    mov Y,TOP
    mov X,LEFT+W+1
k = 16
rept 5
        test    stm.wHour,k
    jz  @f
    or  color,10000000y     ;установить в color 7-ой бит в 1
@@: call    set
k = k/2
endm
;-----------------------------------------
    mov X,LEFT
    add Y,W
k = 32
rept 6
    test    stm.wMinute,k
    jz  @f
    or  color,10000000y     ;установить в color 7-ой бит в 1
@@: call    set
k = k/2
endm
;-----------------------------------
        add Y,W
    mov X,LEFT
k = 32
rept 6
    test    stm.wSecond,k
    jz  @f
    or  color,10000000y     ;установить в color 7-ой бит в 1
@@: call    set
k = k/2
endm
;--------------------------------------
        mov ecx,VK_ESCAPE       ; vKey
    call    GetAsyncKeyState 
; Determine whether a key is up or down
    test    eax, 8000h
    jz  main_loop
EXIT:   mov rcx,hOut        ; hObject
    call    CloseHandle
    mov rcx,hIn         ; hObject
    call    CloseHandle
    call    FreeConsole
    xor ecx,ecx
        call    ExitProcess
WinMain endp
 
set proc
local Csbi:CONSOLE_SCREEN_BUFFER_INFO
local lpRegion:SMALL_RECT
 
    push    rbp
    mov ebp,esp
    sub esp,(20h+sizeof CONSOLE_SCREEN_BUFFER_INFO+sizeof SMALL_RECT+15)and(-16)
 
    lea edx, Csbi           ; lpConsoleScreenBufferInfo
    mov rcx,hOut        ; hConsoleOutput
    call    GetConsoleScreenBufferInfo
        
    mov edx, color
    mov ecx, edx
    shl edx, 4
    or  edx, ecx            ; wAttributes
    mov rcx,hOut        ; hConsoleOutput
    call    SetConsoleTextAttribute
;draw-------------------------------------------------------
    lea edx,Csbi            ; lpConsoleScreenBufferInfo
    mov rcx,hOut        ; hConsoleOutput
    call    GetConsoleScreenBufferInfo
;save------------------------------------------------------     
    mov edx,X
    mov lpRegion.Left,dx
    add edx,(W-1)
    mov lpRegion.Right,dx
    mov edx,Y
    mov lpRegion.Top,dx
    add edx,(W-2)
    mov lpRegion.Bottom,dx
    mov r8d,4*W*(W-1)+260   ; dwBytes
    mov edx,HEAP_ZERO_MEMORY    ; dwFlags
    mov rcx,hHeap       ; hHeap
    call    HeapAlloc       
    mov edi,eax         ; edi=lpBuffer
 
    lea edx,lpRegion
    mov [rsp+20h],rdx       ; lpReadRegion
    xor r9d,r9d         ; dwBufferCoord = 0
    mov r8d,(W-1)*10000h+; dwBufferSize
    mov rdx,rax         ; lpBuffer
    mov rcx,hOut        ; hConsoleOutput
    call    ReadConsoleOutput       
;end save--------------------------------------------------
    mov ecx,W*(W-1)
 
@@: mov ax, Csbi.wAttributes
    shl eax,16
    stosd
    loop    @b
    sub edi,4*W*(W-1)
;load------------------------------------------------------
    lea edx, lpRegion
    mov [rsp+20h],rdx       ; lpWriteRegion
    xor r9d,r9d         ; dwBufferCoord = 0
    mov r8d,(W-1)*10000h+; dwBufferSize
    mov edx,edi         ; lpBuffer
    mov rcx,hOut        ; hConsoleOutput
    call    WriteConsoleOutput      
;освободить память
    mov r8d,edi;lpBuffer    ; lpMem
    xor edx,edx         ; dwFlags = 0
    mov rcx,hHeap       ; hHeap
    call    HeapFree
;end load--------------------------------------------------
;end draw---------------------------------------------------
    and color,01111111y     ;сбросить в color 7-ой бит в 0
    add X,W+1
    leave
    retn
set endp
;-------------------------------------------------------
Str1 db 'Binary clock',0
Str2 db 'For exit press ESC or CTRL+C or CTRL+Break',13,10,10,10,\
5 dup(20h),'32  16  8   4   2   1',13,10,\
30 dup(20h),'Hours',13,10,10,10,30 dup(20h),'Minutes',13,10,10,10,30 \
dup(20h),'Seconds'
hOut    dq ?
X   dd ?
Y   dd ?
color   dd RED
dwStackTop dd -1
lpStack dq ?
hHeap   dq ?
end


«Теоретико-множественные» часы в Берлине показывают время 9:32
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven   Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson06.zip (3.8 Кб, 26 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 06:02  [ТС] 7
Перечисление и установка консольных шрифтов
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
include 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
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson07.zip (4.9 Кб, 29 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 06:24  [ТС] 8
Обработка сообщений мыши в консольном приложении
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
buffersize = 100
.code
WinMain proc
local BUFF[buffersize]:byte   
local hIn:qword
local hOut:qword
local result:qword
local MOUSE_KEY:INPUT_RECORD
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
 
    push    rbp
    mov     ebp,esp
    sub     esp,(28h+3*8+buffersize+sizeof INPUT_RECORD+\
        sizeof SMALL_RECT+sizeof CONSOLE_CURSOR_INFO+15)and(-16)
 
    xor ebx,ebx
    call    FreeConsole
        call    AllocConsole
        mov ecx,STD_INPUT_HANDLE
        call    GetStdHandle
        mov hIn,rax
        mov ecx,STD_OUTPUT_HANDLE
        call GetStdHandle
        mov hOut,rax
        mov ecx,eax ;hOut
    call    GetLargestConsoleWindowSize     
;   rax 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 console window
    mov ecx,offset NameConsole
    call    SetConsoleTitle
;hide 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 [rsp+20h],rbx
    lea r9d,result          ;&result
        mov r8d,sizeof Str1
    mov edx,offset Str1     
    mov rcx,hOut
        call    WriteConsole
        mov edx,0B000Bh         ;Y=11 X=0
        mov rcx,hOut
        call    SetConsoleCursorPosition
        mov [rsp+20h],rbx
        lea r9d,result
        mov r8d,sizeof Str2 
        mov edx,offset Str2
        mov rcx,hOut
        call    WriteConsole
@@:     mov edx,0A0009h         ;Y=10 X=9
        mov rcx,hOut
        call    SetConsoleCursorPosition
    lea r9d,result
    mov r8d,1
    lea edx,MOUSE_KEY
    mov rcx,hIn
    call    ReadConsoleInput
    lea edx,MOUSE_KEY
    cmp [rdx+INPUT_RECORD.EventType],MOUSE_EVENT
    jne LOO1
    xor eax,eax
    mov ax,[rdx+INPUT_RECORD.MouseEvent.dwMousePosition.y]
    mov [rsp+28h],rax
        mov ax,[rdx+INPUT_RECORD.MouseEvent.dwMousePosition.x]
        mov [rsp+20h],rax
        mov r8d,[rdx+INPUT_RECORD.MouseEvent.dwButtonState]
    cmp r8d,4
    sbb ecx,ecx
    and r8d,ecx
    mov edx,offset fmt
    lea ecx,BUFF
    call    wsprintf
    mov [rsp+20h],rbx
        lea r9d,result
        mov r8d,eax
    lea edx,BUFF
        mov rcx,hOut
        call    WriteConsole
    jmp @b
LOO1:   lea     eax,MOUSE_KEY
    cmp     [rax+INPUT_RECORD.EventType],KEY_EVENT
    jne     @b
    cmp     [rax+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_ESCAPE
    jne     @b
        call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
NameConsole db 'Processing of mouse messages',0
fmt db 'Button state: %u, X: %u, Y: %u',0
Str1    db 'For exit press ESC or CTRL+C'
Str2    db 'No clicks = 0',0Dh,0Ah,\
'          Left click = 1',0Dh,0Ah,\
'         Right click = 2',0Dh,0Ah,\
'Left and Right click = 3',0
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson08.zip (2.8 Кб, 27 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 06:44  [ТС] 9
Лучший ответ Сообщение было отмечено R71MT как решение

Решение

Просмотр главной загрузочной записи
Функция CreateFile может открывать не только файлы, но и дисковые устройства. Для открытия первого диска компьютера используется имя "\\.\PhysicalDrive0", для открытия логического раздела C: имя "\\.\C:". После открытия устройства можно использовать функции ReadFile и WriteFile, то есть читать и писать непосредственно в кластеры и сектора диска. Функция DeviceIOControl позволяет получить статическую информацию о диске либо выполнить форматирование диска. Программа ниже позволяет прочитать главную загрузочную запись диска (Master Boot Record -- MBR). При открытии устройства "\\.\PhysicalDrive0" главная загрузочная запись диска находится в начале гипотетического файла.
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
include win64a.inc
MAXSCREENX = 49
MAXSCREENY = 36
.code
WinMain proc
local hIn:qword
local hOut:qword
local hFile:qword
local szReadWrite:qword
local FileSize:qword    
local hMapping:qword
local pMapping:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
local i:dword
local buffer1[512+3]:byte
local buffer2[3*512]:byte
local buffer3:qword
 
        push    rbp
    mov     ebp,esp
    sub     esp,(38h+8*8+4+515+3*512+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
    xor     ebx,ebx
        call    FreeConsole
        call    AllocConsole
        mov ecx,STD_INPUT_HANDLE
        call    GetStdHandle
        mov     hIn,rax
        mov ecx,STD_OUTPUT_HANDLE
        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       ; 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 Str0
    call    SetConsoleTitle
;hide 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
;------------------------------------------------------
;open physical drive
    mov [rsp+30h],rbx       ;it has to be equal 0
    mov [rsp+28h],rbx       ;attribute of the file (if create it)
    mov qword ptr [rsp+20h],OPEN_EXISTING       ;how to open
    xor r9d,r9d;0       ;the pointer on security attr
    mov r8d,FILE_SHARE_WRITE    ;mode of the general access
    mov edx,GENERIC_READ    ;access mode
    mov ecx,offset filename ;file name
    call    CreateFile      ;open file
    inc eax         ;eax == INVALID_HANDLE_VALUE ? 
    jz  EXIT
    dec eax
    mov hFile,rax
;alignment on limit of the double word
    lea     eax,buffer1
    add eax,3
    and eax,-4
    mov buffer3,rax
;read from Partition Table
    mov [rsp+20h],rbx       ;0
    lea r9d,szReadWrite
    mov r8d,512
        mov rdx,rax         ;pMem2
    mov rcx,hFile
    call    ReadFile
;-------------------------------------------
    lea edi,buffer2
    mov esi,offset Str2
    mov ecx,sizeof Str2
    rep movsb
 
    mov rsi,buffer3
    mov FileSize,sizeof Str2
    mov i,ebx
@@: lodsq
    bswap   rax
    mov     r9d,eax
    mov     [rsp+20h],r9
    shr rax,32
        mov     r9d,eax
    lodsq
    bswap   rax
    mov edx,eax
    mov     [rsp+30h],rdx
    shr rax,32
    mov     [rsp+28h],rax
    mov r8d,i
    mov edx,offset fmt
    mov rcx,rdi
    call    wsprintf
    add edi,eax
    add FileSize,rax
    inc i
    cmp i,512/16
    jb  @b
    mov esi,offset Str1
    mov ecx,sizeof Str1
    rep movsb
        add FileSize,sizeof Str1
;to bring buffer contents to the console
    mov [rsp+20h],rbx           ;0
    lea r9d,szReadWrite
    mov r8,FileSize
    lea edx,buffer2
    mov rcx,hOut
    call    WriteConsole
;close handle and file----------------------
        mov rcx,hFile
    call    CloseHandle ; close file
    mov rcx,hOut    ; hObject
    call    CloseHandle     ; close file
;--------------------------------------------------------
@@:     lea r9d,szReadWrite
    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.wVirtualKeyCode],VK_ESCAPE
    jne @b
;---------------------------------------------------------
EXIT:   mov rcx,hIn         ; hObject
    call    CloseHandle
    call    FreeConsole
    mov ecx,ecx
        call    ExitProcess
WinMain endp
fmt db ' %.04X0 ',0BAh,' %.08X %.08X ',0B3h,' %.08X %.08X ',0BAh,0Dh,0Ah,0
Str0 db 'Master Boot Record',0
Str1 db 7 dup(20h),0C8h,19 dup (0CDh),0CFh,19 dup (0CDh),0BCh,13,10,\
'For exit press ESC or CTRL+C or CTRL+Break'
;имя устройства (первый диск)
filename db "\\.\PhysicalDrive0",0 
Str2    db 10 dup(20h),'0 1 2 3  4 5 6 7    8 9 A B  C D E F',0Dh,0Ah,\
7 dup(20h),0C9h,19 dup (0CDh),0D1h,19 dup (0CDh),0BBh,0Dh,0Ah
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson09.zip (3.4 Кб, 28 просмотров)
4
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 09:53  [ТС] 10
Анимация в консольном приложении
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
include win64a.inc
includelib winmm.lib
include winmm.inc
const1     = 68
MAXSCREENX = 80
MAXSCREENY = 25
.code
WinMain proc
local result:qword
local hIn:qword
local IDtimer:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
 
        push    rbp
    mov     ebp,esp
    sub     esp,(28h+3*8+sizeof INPUT_RECORD+\
        sizeof SMALL_RECT+sizeof CONSOLE_CURSOR_INFO+15)and(-16)
 
    xor ebx,ebx
        call    FreeConsole ;release the existing console
        call    AllocConsole    ;create the console
    mov ecx,STD_INPUT_HANDLE
        call    GetStdHandle
        mov hIn,rax                        ; receive handle for a input
        mov ecx,STD_OUTPUT_HANDLE
        call    GetStdHandle
        mov hOut,rax                       ; receive handle for a output
        mov ecx,eax ;hOut
    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 console window
 
        xor edx,edx
    mov ecx,offset ClassConsole 
    call    FindWindow
    mov hWnd,rax
    mov rcx,rax
    call    GetDC
    mov hDC,rax
        xor ecx,ecx
    call    CreateSolidBrush
    mov BlackBrush,rax
    mov rdx,rax         ;keep a black brush in a context
    mov rcx,hDC
    call    SelectObject
        ;load the picture
    mov qword ptr [rsp+28h],LR_LOADFROMFILE
    mov [rsp+20h],rbx
    xor r9d,r9d
    xor r8d,r8d
    mov edx,offset bmp
        mov ecx,400000h
        call    LoadImage
    mov hBit,rax
 
        
    mov ecx,offset NameConsole
    call    SetConsoleTitle     ;definition of a title bar
 
        mov qword ptr [rsp+20h],TIME_PERIODIC
        xor r9d,r9d
    mov r8d,offset TIME
    xor edx,edx
    mov ecx,100
    call    timeSetEvent
    mov IDTimer,rax
@@:     lea r9d,result
    mov r8d,1
    lea edx,MOUSE_KEY
    mov rcx,hIn
    call    ReadConsoleInput
        lea edx,MOUSE_KEY
    cmp [rdx+INPUT_RECORD.EventType],MOUSE_EVENT
    je  @b
    cmp     [rdx+INPUT_RECORD.EventType],KEY_EVENT
    jne @b
    cmp [rdx+INPUT_RECORD.KeyEvent.wVirtualKeyCode],VK_ESCAPE
    jne @b
        
    mov rcx,BlackBrush
    call    DeleteObject    ;delete a black brush
    mov rcx,hBit
    call    DeleteObject    ;delete drawing
 
    mov rdx,hDC
    mov rcx,hWnd
    call    ReleaseDC       ;free hDC
    mov rcx,IDTimer
    call    timeKillEvent
    call    FreeConsole ;close console
    xor ecx,ecx
    call    ExitProcess
 
WinMain endp
TIME proc 
local   memDC:qword
local   result:qword
 
        push    rbp
    mov ebp,esp
    sub esp,(2*8+48h+15)and(-16)
 
        xor edx,edx             ;Y=0 X=0
        mov rcx,hOut
        call    SetConsoleCursorPosition
    mov [rsp+20h],rbx           ;0
    lea r9d,result                      ;quantity of the removed symbols
        mov r8d,sizeof STR1
    mov edx,offset STR1
    mov rcx,hOut
    call    WriteConsole            ;output of a line of symbols to the screen
@@: mov rcx,hDC
    call    CreateCompatibleDC      ;create compatible DC
    mov memDC,rax
    mov rdx,hBit
    mov rcx,rax
    call    SelectObject
    mov eax,Y
    add eax,const1+1
    mov [rsp+20h],rax
        mov r9d,X
    add r9d,const1+1
    mov r8d,Y
    dec r8d
    mov edx,X
    dec edx
    mov rcx,hDC         ;remove a black circle to erase the previous image
    call    Ellipse         
    cmp     X,640-const1        ;check that the planet is in console limits
    jna     @f          ;otherwise change the direction of the movement
        neg     deltaX
@@: cmp     Y,300-const1
    jna     @f
        neg     deltaY
@@: mov     eax,deltaX
    add     X,eax           ;change planet coordinates
    mov     eax,deltaY
    add     Y,eax
        mov qword ptr [rsp+40h],SRCCOPY ;dwRaster
    mov [rsp+38h],rbx           ;SourceY=0
        mov [rsp+30h],rbx           ;SourceX=0
    mov rax,memDC           ;hSource
        mov [rsp+28h],rax
    mov r9d,const1              ;Width
    mov [rsp+20h],r9            ;const1=height
    mov r8d,Y
    mov edx,X
    mov rcx,hDC             ;hDest
    call    BitBlt      ;display the image
    mov rcx,memDC
    call    DeleteDC        ;release the DC memories
    leave
    retn
TIME endp
.data
bmp     db 'Images/Earth.bmp',0
ClassConsole    db 'ConsoleWindowClass',0
STR1        db 'For exit from program press ESC or CTRL+C or CTRL+Break'
NameConsole db 'Console application animation',0
hOut        dq ?
hWnd        dq ?
hDC     dq ?
BlackBrush  dq ?
hBit        dq ?
deltaX      dd 10
deltaY      dd 2
X           dd ?
Y       dd ?
IDTimer     dq ?
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson10.zip (7.4 Кб, 40 просмотров)
4
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 10:01  [ТС] 11
Вывод на консоль содержимого текстового файла. Первый вариант
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
.code
WinMain proc
local hIn:qword
local hOut:qword
local hFile:qword
local result:qword
local FileSize:qword    
local hMem:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(38h+6*8+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
        xor ebx,ebx
        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             ; 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 ecx,offset Str1
    call    SetConsoleTitle
;hide 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 [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filename     ;file name
    call    CreateFile      ;to open the file
    inc     eax;cmp eax,-1
    jz      EXIT
    dec     eax
    mov hFile,rax
    xor edx,edx         ;0
    mov rcx,rax         ;hFile
    call    GetFileSize
    mov FileSize,rax
    mov rdx,rax
    mov ecx,GMEM_FIXED or GMEM_ZEROINIT
    call    GlobalAlloc
    mov hMem,rax
    mov     [rsp+20h],rbx
    lea r9d,result
    mov r8,FileSize
    mov rdx,rax         ;hMem
    mov rcx,hFile
    call    ReadFile        ;to read in the buffer
    mov     [rsp+20h],rbx
    lea r9d,result
    mov r8,FileSize
        mov rdx,hMem
    mov     rcx,hOut
    call    WriteConsole        ;to bring buffer contents to the console
    mov     rcx,hFile
    call    CloseHandle     ;to close the file
;--------------------------------------------------------
    mov     [rsp+20h],rbx
    lea r9d,result
    mov r8d,sizeof Str2
    mov edx,offset Str2
    mov     rcx,hOut
    call    WriteConsole        ;to bring Str2 to the console
;--------------------------------------------------------
@@:     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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
EXIT:   call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
Str1 db 'Output to the console of text file contents. First variant.',0
Str2 db 0Dh,0Ah,'For exit press ESC or CTRL+C or CTRL+Break'
filename db 'c08.asm'
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson11.zip (2.8 Кб, 27 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 10:10  [ТС] 12
Вывод на консоль содержимого текстового файла. Второй вариант
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
.code
WinMain proc
local hIn:qword
local hOut:qword
local hFile:qword
local result:qword
local FileSize:qword    
local hMem:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(38h+6*8+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
        xor ebx,ebx
        call    FreeConsole
        call    AllocConsole
        mov [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filenameIn   ;file name
    call    CreateFile
        mov     hIn,rax                 ; hConsoleInput
        mov [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filenameOut  ;file name
    call    CreateFile
        mov     hOut,rax
        mov rcx,rax         ; hConsoleOutput
    call    GetLargestConsoleWindowSize
;   eax return in 31-16 bits: dwCoord.y
;                 15-00 bits: dwCoord.x
 
        lea r8d,ConsoleWindow   ;lpConsoleWindow
    mov [r8],ebx
;   lpConsoleWindow.Left = 0 lpConsoleWindow.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 ecx,offset ConsoleTitle
    call    SetConsoleTitle
;hide 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 [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filename     ;file name
    call    CreateFile      ;to open the file
    inc     eax;cmp eax,-1
    jz      EXIT
    dec     eax
    mov hFile,rax
    xor edx,edx         ;0
    mov rcx,rax         ;hFile
    call    GetFileSize
    mov FileSize,rax
    mov rdx,rax
    mov ecx,GMEM_FIXED or GMEM_ZEROINIT
    call    GlobalAlloc
    mov hMem,rax
    mov     [rsp+20h],rbx
    lea r9d,result
    mov r8,FileSize
    mov rdx,rax         ;hMem
    mov rcx,hFile
    call    ReadFile        ;to read in the buffer
    mov     [rsp+20h],rbx
    lea r9d,result
    mov r8,FileSize
        mov rdx,hMem
    mov     rcx,hOut
    call    WriteConsole        ;to bring buffer contents to the console
    mov     rcx,hFile
    call    CloseHandle     ;to close the file
;--------------------------------------------------------
    mov     [rsp+20h],rbx
    lea r9d,result
    mov r8d,sizeof Str2
    mov edx,offset Str2
    mov     rcx,hOut
    call    WriteConsole        ;to bring Str2 to the console
;--------------------------------------------------------
@@:     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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
EXIT:   call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
ConsoleTitle db 'Output to the console of text file contents. Second variant.',0
Str2 db 0Dh,0Ah,'For exit press ESC or CTRL+C or CTRL+Break'
filename db 'c09.asm',0
filenameOut db 'CONOUT$',0
filenameIn db 'CONIN$',0
end
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson12.zip (2.8 Кб, 37 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
03.03.2016, 10:18  [ТС] 13
Управление памятью, файловый ввод/вывод
через GlobalAlloc/Lock/Unlock и GlobalFree
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
.code
WinMain proc
local hIn:qword
local hOut:qword
local hFile:qword
local szReadWrite:qword
local FileSize:qword    
local hMem:qword
local pMem:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(38h+7*8+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
        xor ebx,ebx
        call    FreeConsole
        call    AllocConsole
        mov ecx,STD_INPUT_HANDLE
    call    GetStdHandle
        mov     hIn,rax
        mov ecx,STD_OUTPUT_HANDLE
    call    GetStdHandle
        mov     hOut,rax
        mov ecx,eax             ; hConsoleOutput
    call    GetLargestConsoleWindowSize
;   eax return in 31-16 bits: dwCoord.y
;                 15-00 bits: dwCoord.x
 
        lea r8d,ConsoleWindow       ; lpConsoleWindow
    mov [r8],ebx
;   lpConsoleWindow.Left = 0 lpConsoleWindow.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 ecx,offset Str1
    call    SetConsoleTitle
;hide 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 [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filename     ;file name
    call    CreateFile      ;to open the file
    inc     eax;cmp eax,-1
    jz      EXIT
    dec     eax
    mov hFile,rax
    xor edx,edx         ;0
    mov rcx,rax         ;hFile
    call    GetFileSize
    mov FileSize,rax
    mov rdx,rax
    mov ecx,GMEM_MOVEABLE or GMEM_ZEROINIT
    call    GlobalAlloc
    mov hMem,rax
        mov rcx,rax
    call    GlobalLock
    mov     pMem,rax
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8,FileSize
    mov rdx,rax         ;pMem
    mov rcx,hFile
    call    ReadFile        ;to read in the buffer
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8,FileSize
        mov rdx,pMem
    mov     rcx,hOut
    call    WriteConsole        ;to bring buffer contents to the console
    mov     rcx,hFile
    call    CloseHandle     ;to close the file
        mov rcx,pMem
    call    GlobalUnlock
    mov rcx,hMem
    call    GlobalFree
;--------------------------------------------------------
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8d,sizeof Str2
    mov edx,offset Str2
    mov     rcx,hOut
    call    WriteConsole        ;to bring Str2 to the console
;--------------------------------------------------------
@@:     lea     r9d,szReadWrite
    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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
EXIT:   call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
Str1 db 'Memory Management, File I/O, GlobalAlloc/Lock/Unlock and GlobalFree',0
Str2 db 0Dh,0Ah,'For exit press ESC or CTRL+C or CTRL+Break'
filename db 'c16.asm',0
end

Управление памятью, файловый ввод/вывод
через GetProcessHeap, HeapAlloc and HeapFree
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
MEM_SIZE   = 65535
.code
WinMain proc
local hIn:qword
local hOut:qword
local hFile:qword
local szReadWrite:qword
local FileSize:qword    
local hHeap:qword
local pMem:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(38h+7*8+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
        xor ebx,ebx
        call    FreeConsole
        call    AllocConsole
        mov ecx,STD_INPUT_HANDLE
    call    GetStdHandle
        mov     hIn,rax
        mov ecx,STD_OUTPUT_HANDLE
    call    GetStdHandle
        mov     hOut,rax
        mov ecx,eax             ; hConsoleOutput
    call    GetLargestConsoleWindowSize
;   eax return in 31-16 bits: dwCoord.y
;                 15-00 bits: dwCoord.x
 
        lea r8d,ConsoleWindow       ; lpConsoleWindow
    mov [r8],ebx
;   lpConsoleWindow.Left = 0 lpConsoleWindow.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 ecx,offset Str1
    call    SetConsoleTitle
;hide 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 [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filename     ;file name
    call    CreateFile      ;to open the file
    inc     eax;cmp eax,-1
    jz      EXIT
    dec     eax
    mov hFile,rax
    xor edx,edx         ;0
    mov rcx,rax         ;hFile
    call    GetFileSize
    mov FileSize,rax
    call    GetProcessHeap
    mov hHeap,rax
        mov r8d,MEM_SIZE
    mov edx,HEAP_ZERO_MEMORY
    mov rcx,rax
    call    HeapAlloc
    mov     pMem,rax
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8,FileSize
    mov rdx,rax         ;pMem
    mov rcx,hFile
    call    ReadFile        ;to read in the buffer
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8,FileSize
        mov rdx,pMem
    mov     rcx,hOut
    call    WriteConsole        ;to bring buffer contents to the console
    mov     rcx,hFile
    call    CloseHandle     ;to close the file
        mov r8,pMem
        xor edx,edx
    mov rcx,hHeap
    call    HeapFree
;--------------------------------------------------------
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8d,sizeof Str2
    mov edx,offset Str2
    mov     rcx,hOut
    call    WriteConsole        ;to bring Str2 to the console
;--------------------------------------------------------
@@:     lea     r9d,szReadWrite
    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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
EXIT:   call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
Str1 db 'Memory Management, File I/O, GetProcessHeap, HeapAlloc and HeapFree',0
Str2 db 0Dh,0Ah,'For exit press ESC or CTRL+C or CTRL+Break'
filename db 'c17.asm',0
end

Memory Mapped File
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
include win64a.inc
MAXSCREENX = 80
MAXSCREENY = 25
MEM_SIZE   = 65535
.code
WinMain proc
local hIn:qword
local hOut:qword
local hFile:qword
local szReadWrite:qword
local FileSize:qword    
local hMapping:qword
local pMapping:qword
local ConsoleWindow:SMALL_RECT
local cci:CONSOLE_CURSOR_INFO
local MOUSE_KEY:INPUT_RECORD
 
        push    rbp
    mov     ebp,esp
    sub     esp,(38h+7*8+sizeof SMALL_RECT+\
        sizeof CONSOLE_CURSOR_INFO+INPUT_RECORD+15)and(-16)
 
        xor ebx,ebx
        call    FreeConsole
        call    AllocConsole
        mov ecx,STD_INPUT_HANDLE
    call    GetStdHandle
        mov     hIn,rax
        mov ecx,STD_OUTPUT_HANDLE
    call    GetStdHandle
        mov     hOut,rax
        mov ecx,eax             ; hConsoleOutput
    call    GetLargestConsoleWindowSize
;   eax return in 31-16 bits: dwCoord.y
;                 15-00 bits: dwCoord.x
 
        lea r8d,ConsoleWindow       ; lpConsoleWindow
    mov [r8],ebx
;   lpConsoleWindow.Left = 0 lpConsoleWindow.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 ecx,offset Str1
    call    SetConsoleTitle
;hide 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 [rsp+30h],rbx       ;it has to be equal to zero
    mov [rsp+28h],rbx       ;attribute of the file (if we create it)
    mov     qword ptr [rsp+20h],OPEN_EXISTING;how to open the file
    xor r8d,r8d         ;mode of the general access
    xor r9d,r9d         ;the index on security attr
    mov edx,GENERIC_READ or GENERIC_WRITE;access mode
    mov ecx,offset filename     ;file name
    call    CreateFile      ;to open the file
    inc     eax;cmp eax,-1
    jz      EXIT
    dec     eax
    mov hFile,rax
    xor edx,edx         ;0
    mov rcx,rax         ;hFile
    call    GetFileSize
    mov FileSize,rax
;creation in memory of object "a file projection"
        mov [rsp+28h],rbx
        mov [rsp+20h],rbx
    xor r9d,r9d
    mov r8d,PAGE_READWRITE
    xor edx,edx         ;0
    mov rcx,hFile
    call    CreateFileMapping
    mov hMapping,rax
;display of a projection of the file to address space of process
        mov [rsp+20h],rbx
    xor r9d,r9d
        xor r8d,r8d
    mov edx,FILE_MAP_WRITE
    mov rcx,rax
    call    MapViewOfFile
    mov     pMapping,rax
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8,FileSize
        mov rdx,rax         ;pMapping
    mov     rcx,hOut
    call    WriteConsole        ;to bring buffer contents to the console
    mov     rcx,pMapping
    call    UnmapViewOfFile
    mov     rcx,pMapping
    call    CloseHandle     ;to close the file
        mov     rcx,hMapping
    call    CloseHandle
;--------------------------------------------------------
    mov     [rsp+20h],rbx
    lea r9d,szReadWrite
    mov r8d,sizeof Str2
    mov edx,offset Str2
    mov     rcx,hOut
    call    WriteConsole        ;to bring Str2 to the console
;--------------------------------------------------------
@@:     lea     r9d,szReadWrite
    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.wVirtualKeyCode],VK_ESCAPE
    jne     @b
EXIT:   call    FreeConsole
    xor     ecx,ecx
        call    ExitProcess
WinMain endp
Str1 db 'Memory Mapped File',0
Str2 db 0Dh,0Ah,'For exit press ESC or CTRL+C or CTRL+Break'
filename db 'c18.asm',0
end
Вложения
Тип файла: zip lesson13.zip (7.6 Кб, 25 просмотров)
3
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
14.03.2016, 12:08  [ТС] 14
Вывод графики в консольное приложение
asm-файл
Кликните здесь для просмотра всего текста
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
include 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 ; освободим существующую консоль
        call    AllocConsole    ; образуем свою консоль
 
    mov ecx,offset NameConsole
    call    SetConsoleTitle; определение заголовка окна
 
    mov ecx,STD_OUTPUT_HANDLE
        call    GetStdHandle    ; получаем handle для вывода
        mov hOut,rax
; загружаем рисунок в 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 edx,357913941       ; edx=(2^32)/12
        mov eax,bi.bmHeight
    mul edx
        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
    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;устанавливаем новый 
;размер окна консоли, который зависит от размера рисунка
;прячем курсор----------------------------------------
    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       ;получить DC
    mov hDC,rax
 
    mov rcx,rax         ;hDC
    call    CreateCompatibleDC  ;создать совместимый 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   ;освободить DC
    mov rcx,memDC
    call    DeleteDC    ;удаляем виртуальное окно         
        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


Теоретические основы программирования консольных приложений
Консоли. Текстовый пользовательский интерфейс (Character User Interface)
Консоли управляют вводом и выводом (I/O) консольных приложений (character-mode applications) (прикладных программ, которые не предусматривают свой собственный графический интерфейс пользователя (Graphics User Interface ― GUI)) — разновидность интерфейса пользователя, использующая при вводе-выводе и представлении информации исключительно набор буквенно-цифровых символов и символов псевдографики. Характеризуется малой требовательностью к ресурсам аппаратуры ввода-вывода (в частности, памяти) и высокой скоростью отображения информации.
Недостатком подобного типа интерфейса является ограниченность изобразительных средств по причине ограниченности количества символов, включённых в состав шрифта, предоставляемого аппаратурой.
Программы с текстовым интерфейсом могут имитировать оконный интерфейс.
В простейшем случае текстовый интерфейс использует интерфейс командной строки, однако многие программы с помощью интерактивных элементов создают более дружественный интерфейс, приближающийся по удобству к графическому.
В текстовом интерфейсе реализованы все базовые элементы интерфейса, используемые и в графическом интерфейсе — меню, кнопки, переключатели, флажки, выпадающие списки, полосы прокрутки и так далее.
На программном уровне для ввода и вывода информации консольные программы используют стандартные устройства ввода-вывода (stdin, stdout, stderr), хотя могут открывать и другие файлы, сетевые соединения и совершать иные действия, доступные в выполняющей их среде. Вывод печатных символов в stdout и stderr приводит к появлению этих символов на устройстве вывода и к получению их пользователем.
Консольная программа не обязана заботиться о реализации самого взаимодействия с пользователем, ограничиваясь вводом-выводом на стандартные устройства. Собственно взаимодействие с пользователем обычно осуществляет операционная система.
Любая программа, получающая данные путём чтения stdin и отправку данных путём записи в stdout, по определению является консольной программой. Однако, такие программы могут обходиться и без пользователя, поскольку stdin и stdout могут быть связаны не с интерактивными устройствами (клавиатурой и монитором), а с файлами или потоками ввода/вывода других программ.
Консольные функции дают возможность разного уровня доступа к консоли. Высокоуровневые консольные функции ввода-вывода данных (I/O) дают возможность приложению читать из их стандартного ввода данных, чтобы извлечь введённую информации с клавиатуры, сохраненную во входном буфере консоли. Функции также дают возможность программе записать в стандартный вывод или показать на экране текст стандартной ошибки в экранном буфере консоли. Высокоуровневые функции поддерживают также переадресацию стандартных дескрипторов и управление режимами работы консоли для различных функциональных возможностей ввода-вывода. Низкоуровневые консольные функции I/O дают возможность прикладным программам получит подробный отчет о событиях ввод данных от клавиатуры и мыши, а также о событиях, включающих взаимодействие пользователя с консольным окном. Низкоуровневые функции также дают больше возможностей в управлении выводом данных на экран.
Консольные приложения ― некогда единственная форма программного обеспечения для работы с пользователем. После широкого распространения программ с графическим интерфейсом, консольные приложения продолжают сохранять своё значение. Постепенно программное обеспечение с GUI практически полностью вытеснило приложения с текстовым интерфейсом из повседневного использования. Однако и сейчас есть консольные приложения, которые могут в большей или меньшей степени конкурировать с программами с графическим интерфейсом, быть полезными при решении разнообразных задач.
Виды консольных программ:
  • Файловые менеджеры (Far menager)
  • Мультимедиа
  • Веб браузеры
  • Текстовые редакторы

Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven  
Вложения
Тип файла: zip lesson14.zip (97.0 Кб, 26 просмотров)
1
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
16.03.2016, 06:55  [ТС] 15
Консоли обеспечивают высокоуровневую поддержку для простых консольных приложений, взаимодействующих с пользователем, используя функции, которые читают из стандартного ввода данных и записывают в стандартный вывод или стандартную ошибку. Консоли также предусматривают сложную низкоуровневую поддержку, которая дает прямой доступ к экранному буферу консоли, а это дает возможность прикладным программам получать расширенную входную информацию (такую, как ввод данных от мыши).
Консоль (console) ― интерфейс, который обеспечивает ввод-вывод данных консольным приложениям. Этот независимый от процессора механизм делает её легкой для поддержания в готовности существующих консольных приложений или создание новых консольных инструментальных средств и прикладных программ.
Консоль состоит из буфера вводимых данных и одного или нескольких экранных буферов. Буфер вводимых данных (input buffer) содержит очередь записей введенных данных, каждая из которых содержит информацию о событии ввода. Входная очередь всегда включает в себя события отпуска и нажатия клавиши. Она может также включать в себя события с мышью (перемещение указателя и нажатие и отпускание кнопки) и события, в течение которых действия пользователя воздействуют на размер активного экранного буфера. Экранный буфер (screen buffer) ― двухмерный массив символьных данных и данных о цвете для вывода информации в консольном окне.
Любое число процессов может совместно использовать консоль.
Функции Windows API дают возможность разного уровня доступа к консоли. Высокоуровневые консольные функции I/O дают возможность приложению читать из стандартного ввода данных, чтобы получать ввод информации от клавиатуры, сохраненный в буфере ввода консоли. Функции дают также возможность прикладной программе записывать в стандартный вывод или показать на экране текст стандартной ошибки в экранном буфере консоли. Высокоуровневые функции также поддерживают переназначение стандартных дескрипторов и управление режимами работы консоли для разных функциональных возможностей ввода-вывода (I/O). Низкоуровневые консольные функции I/O дают возможность прикладным программам получить подробный ввод данных
о событиях с клавиатурой и мышью, также как и о событиях, включающих взаимодействие пользователя с консольным окном. Низкоуровневые функции к тому же включают большую часть управления выводом на экран.
Система создает новую консоль тогда, когда она запускает консольный процесс (console process), процесс символьного режима, точка входа которого ― функция main. Например, система создает новую консоль, когда она запускает командный процессор. Когда командный процессор запускает новый консольный процесс, пользователь может установить, создает ли система новую консоль для нового процесса или она наследует консоль командного процессора.
Процесс может создать консоль, используя один из следующих способов:
  • GUI или консольный процесс может использовать функцию CreateProcess с флажком CREATE_NEW_CONSOLE, чтобы создать консольный процесс с новой консолью. (По умолчанию, консольный процесс наследует консоль своего родителя, однако нет гарантии, что вводимые данные получит процесс, для которого они были предназначены).
  • Графический интерфейс пользователя (GUI) или консольный процесс, который в настоящее время не связан с консолью могут использовать функцию AllocConsole для создания новой консоли. (Процесс, который вызывает функцию AllocConsole, не должен подключаться к существующей консоли. Процессы GUI, когда они создаются, не подключаются к консоли. Консольные процессы не связываются с консолью, если они созданы с использованием функции CreateProcess с флажком DETACHED_PROCESS).
  • Как правило, процесс использует функцию AllocConsole, чтобы создать консоль, когда происходит ошибка, требующая взаимодействия с пользователем. Например, процесс GUI может создать консоль, когда происходит ошибка, которая препятствует ему использовать его нормальный графический интерфейс, или консольный процесс, который обычно не взаимодействует с пользователем, может создать консоль, чтобы показать на экране ошибку.
Процесс может также создать консоль, устанавливая флажок CREATE_NEW_CONSOLE при вызове функции CreateProcess. Этот метод создает новую консоль, которая является доступной для дочернего процесса, но не для родительского процесса. Отдельные консоли дают возможность, и родительским и дочерним процессам взаимодействовать с пользователем без конфликта. Если этот флажок не установлен, когда создается консольный процесс, оба процесса присоединяются на одну ту же консоль, и нет никакой гарантии, что корректный процесс получит ввод данных, предназначенный для него. Прикладные программы могут предотвратить, беспорядок, создавая дочерние процессы, которые не наследуют дескрипторы буфера вводимых данных, или включать одновременно только один дочерний процесс, который наследует дескриптор буфера вводимых данных, в тоже время предотвращая чтение родительским процессом введенных данных консоли, до тех пор, пока не дочерний процесс не закончил.
Создание новой консоли заканчивается созданием консольного окна, а также отдельных экранных буферов ввода-вывода. Процесс связывается с новой консолью, используя функцию GetStdHandle, чтобы получить дескрипторы экранных буферов и буфера ввода данных новой консоли. Эти дескрипторы дают возможность процессу обращаться к консоли.
Когда процесс использует функцию CreateProcess, он может определить структуру STARTUPINFO, члены которой управляют характеристиками первой новой консоли (если таковая имеется) созданной для дочернего процесса. Структура STARTUPINFO, определяемая при вызове функции CreateProcess воздействует на созданную консоль, если установлен флажок CREATE_NEW_CONSOLE. Она также воздействует на созданную консоль, если дочерний процесс впоследствии использует функцию AllocConsole. Ниже перечислены параметры консоли, которые могут быть заданы:
  • Размер окна новой консоли, в знакоместах
  • Размещение окна новой консоли в пиксельных экранных координатах
  • Размер экранного буфера консоли, в знакоместах
  • Атрибуты цвет текста и фона экранного буфера новой консоли
  • Экранное имя в строке заголовка нового консольного окна
  • Система использует значения по умолчанию, если значения STARTUPINFO не определены. Дочерний процесс может использовать функцию GetStartupInfo, чтобы установить значения в своей структуре STARTUPINFO.
Процесс не может изменить местоположение своего консольного окна на экране, но нижеследующим консольным функциям доступно устанавливать или извлекать другие параметры, определяемые в структуре STARTUPINFO.
Кликните здесь для просмотра всего текста
ФункцияОписание
GetConsoleScreenBufferInfoИзвлекает размер окна, размер экранного буфера и атрибуты цвета.
SetConsoleWindowInfoИзменяет размер окна консоли.
SetConsoleScreenBufferSizeИзменяет размер экранного буфера консоли.
SetConsoleTextAttributeУстанавливает атрибуты цвета.
SetConsoleTitleУстанавливает заголовок окна.
GetConsoleTitleИзвлекает заголовок окна консоли.

Процесс может использовать функцию FreeConsole, чтобы отключить себя от унаследованной консоли или от консоли, созданной функцией AllocConsole.
Процесс может использовать функцию AttachConsole, чтобы подключиться к консоли. Процесс может быть подключен к одной консоли.
Консоль может иметь много процессов связанных с ней. Чтобы получить список процессов, связанных с консолью, вызовите функцию GetConsoleProcessList.
Процесс может использовать функцию FreeConsole, чтобы отключить себя от ее консоли. Если другие процессы совместно используют консоль, консоль не разрушается, но процесс, который обратился к функции FreeConsole не сможет обратиться к ней. После вызова FreeConsole, процесс может использовать функцию AllocConsole, чтобы создать новую консоль или функцию AttachConsole, чтобы подключиться к другой консоли.
Консоль закрывается, когда последний процесс, связанный с ней завершает работу или вызывает функцию FreeConsole.
Консольный процесс использует дескрипторы для того, чтобы обратиться к буферу ввода данных и экранным буферам своей консоли. Процесс может использовать функцию GetStdHandle, CreateFile или функцию CreateConsoleScreenBuffer, чтобы открыть один из этих дескрипторов
Функция GetStdHandle обеспечивает механизм для получения дескрипторов стандартного ввода данных (STDIN), стандартного вывода данных (STDOUT) и стандартной ошибки (STDERR), связанных с процессом. В ходе создания консоли, система генерирует эти дескрипторы. Вначале, дескриптор STDIN для буфера вводимых данных консоли, а затем дескрипторы STDOUT и STDERR активного экранного буфера консоли. Однако функция SetStdHandle может переназначать стандартные дескрипторы, изменяя дескриптор, связанный с STDIN, STDOUT или STDERR. Поскольку стандартные дескрипторы родительского элемента наследуются любым дочерним процессом, последующие вызовы к GetStdHandle возвращают переназначенный дескриптор. Дескриптор, возвращенный функцией GetStdHandle, по этой причине может сослаться на что-либо другое, а не на консольный ввод-вывод (I/O). Например, перед созданием дочернего процесса, родительский процесс может использовать SetStdHandle, чтобы установить дескриптор канала, который должен быть дескриптором STDIN и который будет унаследован дочерним процессом. Когда дочерний процесс вызывает функцию GetStdHandle, он получает дескриптор канала. Это означает, что родительский процесс может управлять стандартными дескрипторами дочернего процесса. Дескрипторы, возвращенные функцией GetStdHandle, имеют доступ GENERIC_READ | GENERIC_WRITE, если функция SetStdHandle не была использована для установки стандартного дескриптора, имеющего меньший доступ.
Значение дескрипторов, возвращенных функцией GetStdHandle ― не 0, 1 и 2, как стандартные предопределенные константы потока в файле Stdio.h (STDIN, STDOUT и STDERR), не могут быть использованы в функциях, которые требуют дескриптора консоли.
Функция CreateFile дает возможность процессу получить дескриптор для буфера вводимых данных его консоли и активного экранного буфера, даже если STDIN и STDOUT были переназначены. Чтобы открыть дескриптор буфера вводимых данных консоли, при вызове функции CreateFile установите значение CONIN$. Чтобы открыть дескриптор активного экранного буфера консоли, при вызове CreateFile установите значение CONOUT$. Функция CreateFile дает возможность Вам, чтобы определять доступ для чтения ― записи дескриптора, который она возвращает.
Функция CreateConsoleScreenBuffer создает новый экранный буфер и возвращает дескриптор. Этот дескриптор может быть использован в любой функции, которая принимает дескриптор для консольного вывода данных. Новый экранный буфер не активен до тех пор, пока его дескриптор не определится при вызове к функции SetConsoleActiveScreenBuffer.
Обратите внимание на то, что этот изменяющийся активный экранный буфер не воздействует на дескриптор, возвращенный GetStdHandle. Точно так же использование функции SetStdHandle, чтобы изменить дескриптор STDOUT не воздействует на активный экранный буфер.
Консольные дескрипторы, возвращенные функциями CreateFile и CreateConsoleScreenBuffer, могут быть использованы в любой из консольных функций, которые требуют дескриптора буфера вводимых данных или экранного буфера консоли. Дескрипторы, возвращенные функцией GetStdHandle могут быть использованы консольными функциями, если они не были переназначены, чтобы не сослаться на что-либо иное, чем консольный ввод-вывод. Однако, если стандартный дескриптор был переназначен, чтобы сослаться на файл или канал, он может быть использован только функциями ReadFile и WriteFile.
Процесс может использовать функцию DuplicateHandle, чтобы создать дубликат консольного дескриптора, который имеет другой доступ или наследственность от исходного дескриптора.
Обратите внимание на то, что, не смотря на это, процесс может создать дубликат дескриптора консоли только для своего собственного использования. Это его отличает от других типов дескрипторов, (таких как файла, канала или мьютекс-объекта), для которых функция DuplicateHandle может создавать дубликат, являющийся допустимым для другого процесса.
Чтобы закрыть консольный дескриптор, процесс может использовать функцию CloseHandle.
2
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
16.03.2016, 08:27  [ТС] 16
Каждая консоль имеет буфер вводимых данных, который содержит очередь записей о событиях ввода. Когда окно консоли имеет фокус клавиатуры, консоль оформляет каждое событие ввода (типа отдельного нажатия клавиши, перемещение мыши или щелчка кнопки мыши) как введенное данное, которое оно помещает в буфер вводимых данных консоли.
Прикладные программы могут обращаться к буферу вводимых данных консоли косвенно при помощи использования высокоуровневых консольных функций I/O или непосредственно при помощи использования низкоуровневых консольных функций ввода. Высокоуровневые функции ввода фильтруют и обрабатывают данные в буфере вводимых данных, возвращая только поток введенных символов. Низкоуровневые функции ввода дают возможность прикладным программам читать введенные данные непосредственно из буфера вводимых данных консоли, или помещать введенные данных в буфер вводимых данных. Чтобы открыть дескриптор буфера вводимых данных консоли, при вызове к функции CreateFile установите значение CONIN$.
Запись ввода данных ― это структура, содержащая информацию о типе события, которое произошло (клавиатура, мышь, изменение размеров окна, фокус или событие меню), а также конкретные детали о событии. Поле EventType в структуре INPUT_RECORD содержит тип события в записи.
Фокус и события меню помещаются в буфере вводимых данных консоли для внутреннего использования системой и должны быть игнорироваться прикладными программами.События клавиатуры генерируются тогда, когда любая клавиша нажимается или отпускается; это включает в себя управляющие клавиши. Однако клавиша ALT имеет специальное предназначение в системе, когда нажимается и отпускается без объединения с другим символом, и это не передается прямо в приложение. Комбинация клавиш CTRL+C также не передается непосредственно в программу, если введенный дескриптор находится в режиме обработки.
Если событие ввода ― нажатие клавиши, поле Event в структуре INPUT_RECORD является структурой KEY_EVENT_RECORD, содержащей нижеследующую информацию:
  • Булево значение, указывающее, была ли клавиша нажата или отпущена.
  • Счет повторений, который может быть больше, чем один, когда клавиша удерживается.
  • Код виртуальной клавиши, идентифицирующий данную клавишу не зависящим от устройства способом.
  • Виртуальный ― скэн-код, обозначающий аппаратно-зависимое значение, созданное аппаратными средствами клавиатуры.
  • Преобразованный символ UNICODE или ANSI.
  • Флажковая переменная, которая указывает на состояние управляющих клавиш (клавиши ALT, CTRL, SHIFT, NUM LOCK, SCROLL LOCK и CAPS LOCK) и обозначает, была ли нажата дополнительная клавиша. Дополнительные клавиши для 101-клавишные и 102-клавишные клавиатуры имеют INS, DEL, HOME, END, PAGE UP, PAGE DOWN клавиши и клавиши со стрелкой в блоках слева от цифровой клавиатуры и клавиши делителя (/) и ENTER в цифровой клавиатуре.
События с мышью генерируются всякий раз, когда пользователь перемещает мышь или нажимает или отпускает одну из кнопок мыши. События с мышью помещаются в буфере вводимых данных, только в том случае, если выполнены нижеследующие условия:
  • Режим ввода консоли установлен в значение ENABLE_MOUSE_INPUT (режим заданный по умолчанию).
  • Консольное окно имеет фокус клавиатуры.
  • Курсор мыши находится в пределах рамок окна консоли.
Если событие ввода ― событие с мышью, поле Event в структуре INPUT_RECORD является структурой MOUSE_EVENT_RECORD, содержащей нижеследующую информацию:
  • Координаты курсора мыши в переводе на строки и столбцы символьных знакоместа в системе координат экранного буфера консоли
  • Флажковая переменная, обозначающая состояния кнопок мыши.
  • Флажковая переменная, обозначающая состояния управляющих клавиш (клавиши ALT, CTRL, SHIFT, NUM LOCK, SCROLL LOCK и CAPS LOCK) и обозначает, была ли нажата дополнительная клавиша. Дополнительные клавиши для 101-клавишной и 102-клавишной клавиатуры имеют INS, DEL, HOME, END, PAGE UP, PAGE DOWN клавиши и клавиши со стрелкой в блоках слева от цифровой клавиатуры и клавиши делителя (/) и ENTER в цифровой клавиатуре.
  • Флажковая переменная, обозначающая, было ли событие нормальным нажатием кнопки или событием отпуска кнопки, событием перемещения мыши, или вторым щелчком события двойного щелчка.
Обратите внимание координаты позиции мыши ― в понятиях экранного буфера консоли, не консольное окно. Экранный буфер, может прокручиваться относительно окна, так что верхний левый угол окна ― это не обязательно координата (0,0) экранного буфера консоли. Чтобы отрегулировать координаты мыши относительно системы координат окна, вычтите начальные координаты окна из координат позиции мыши. Чтобы установить начало координат окна, используйте функцию GetConsoleScreenBufferInfo.
Поле dwButtonState структуры MOUSE_EVENT_RECORD имеет битовое соответствие для каждой кнопки мыши. Бит равен 1, если кнопка нажата, и 0, если кнопка отпущена. Событие отпуска кнопки регистрируется как значение 0 в поле dwEventFlags структуры MOUSE_EVENT_RECORD и изменяется в бите кнопки с 1 на 0. Функция GetNumberOfConsoleMouseButtons получает число кнопок на мышиМеню консольного окна дает возможность пользователю изменить размер активного экранного буфера; это изменение создает событие изменения размеров буфера. События изменения размеров буфера помещаются в буфере вводимых данных, если режим ввода данных консоли установлен в ENABLE_WINDOW_INPUT (то есть заданный по умолчанию режим заблокирован).
Если событие ввода данных является событием, изменяющим размеры буфера, поле Event структуры INPUT_RECORD является структурой WINDOW_BUFFER_SIZE_RECORD, содержащей новый размер экранного буфера консоли, выраженного в столбцах и строках символьных знакомест.
Если пользователь уменьшает размер экранного буфера консоли, любые данные в отброшенной части буфера теряются.
Изменения размера экранного буфера консоли, как результат вызовов из прикладной программы функции SetConsoleScreenBufferSize, не создают событий изменения размера буфера.
Экранный буфер (screen buffer) ― двухмерный массив символов и данных о цвете для вывода данных в консольном окне. Консоль может иметь множество экранных буферов. Активный экранный буфер (active screen buffer) ― тот, который отображается на экране.
Система создает экранный буфер всякий раз, когда она создает новую консоль. Чтобы открыть дескриптор активного экранного буфера консоли, при вызове к функции CreateFile установите значение CONOUT$. Процесс может использовать функцию CreateConsoleScreenBuffer, чтобы создать дополнительные экранные буферы для своей консоли. Новый экранный буфер не активен до тех пор, пока его дескриптор не будет определен при вызове к функции SetConsoleActiveScreenBuffer. Однако к экранным буферам можно обращаться для чтения и записи, независимо, являются ли они активными или неактивными.
Каждый экранный буфер имеет свой собственный двухмерный массив записей текстовой информации. Данные для каждого символа сохраняются в структуре CHAR_INFO, которая определяет символы Unicode или ANSI, и цвет текста и цвета фона, на котором этот символ отображен.
Ряд свойств, связанных с экранным буфером может быть установлен независимо для каждого буфера дисплея. Это означает, что изменяющийся активный экранный буфер может иметь негативное влияние на внешний вид консольного окна. Свойства, связанные с экранным буфером включают в себя:
  • Размер экранного буфера, в строках и столбцах символов.
  • Атрибуты текста (цвет текста и цвет фона для отображения на экране текста, который будет написан функцией WriteFile или WriteConsole).
  • Размер окна и расположение (прямоугольная область экранного буфера консоли, которая отображается в консольном окне).
  • Позиция, внешний вид и видимость курсора.
  • Режимы вывода (ENABLE_PROCESSED_OUTPUT и ENABLE_WRAP_AT_EOL_OUTPUT). Для получения дополнительной информации о консольных режимах вывода, см. Высокоуровневые консольные режимы работы.
Когда экранный буфер создается, он содержит пробелы. Его курсор видим и установлен в начало координат буфера (0,0), а окно устанавливается в его верхний левый угол в начало координат буфера. Размер экранного буфера консоли, размеры окна, текстовые атрибуты и внешний вид курсора определяется пользователем или системными значениями по умолчанию. Чтобы получить текущие значения различных свойств, связанных с экранным буфером консоли, используйте функции GetConsoleScreenBufferInfo, GetConsoleCursorInfo и GetConsoleMode.
Прикладные программы, которые изменяют любое из свойств экранного буфера консоли, должны или создать свой собственный экранный буфер или сохранить состояние унаследованного буфера дисплея в ходе запуска и восстанавливать его при выходе.
Курсор экранного буфера может быть видим или скрыт. Когда он видим, его внешний вид может изменяться в пределах от полностью заполненного знакоместа символа до вида как горизонтальная линия внизу ячейки. Чтобы получить информацию о внешнем виде и видимости курсора, используйте функцию GetConsoleCursorInfo. Эта функция сообщает, является ли курсор видимым и описывает внешний вид курсора как процентное отношение от знакоместа символа, которое он заполняет. Чтобы установить внешний вид и видимость курсора, используйте функцию SetConsoleCursorInfo.
1
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
16.03.2016, 09:35  [ТС] 17
Символы, написанные высокоуровневыми консольными функциями I/O пишутся в текущем местоположении курсора, продвигая курсор к следующему местоположению. Чтобы определить текущую позицию курсора в системе координат экранного буфера, используйте функцию GetConsoleScreenBufferInfo. Вы можете использовать функцию SetConsoleCursorPosition, чтобы установить позицию курсора и, таким образом, управлять размещением текста, который написан или отображен на экране высокоуровневыми консольными функциями I/O функциями. Если Вы перемещаете курсор, текст в новом местоположении курсора переписывается.
Позиция, внешний вид и видимость курсора устанавливаются независимо для каждого экранного буфера.
Атрибуты символов могут быть поделены на два класса: класс цвета и класс DBCS (double-byte character set) ― набор двухбайтовых комбинаций символов. Нижеследующие атрибуты определяются в заголовочном файле Wincon.h.
Кликните здесь для просмотра всего текста
АтрибутПредназначение
FOREGROUND_BLUEСодержит синий цвет текста.
FOREGROUND_GREENСодержит зеленый цвет текста.
FOREGROUND_REDСодержит красный цвет текста.
FOREGROUND_INTENSITYУстанавливает цвет текста более интенсивный.
BACKGROUND_BLUEСодержит синий цвет фона.
BACKGROUND_GREENсодержит зеленый цвет фона.
BACKGROUND_REDСодержит красный цвет фона.
BACKGROUND_INTENSITYУстанавливает цвет фона более интенсивный.
COMMON_LVB_LEADING_BYTEНачальный байт.
COMMON_LVB_TRAILING_BYTEКонцевой файл.
COMMON_LVB_GRID_HORIZONTALВерх горизонтали.
COMMON_LVB_GRID_LVERTICALЛевая вертикаль.
COMMON_LVB_GRID_RVERTICALПравая вертикаль.
COMMON_LVB_REVERSE_VIDEOИзменяет на противоположные атрибуты цвета текста и цвета фона.
COMMON_LVB_UNDERSCOREПодчеркивает.

Атрибуты цвета текста определяют его цвет. Атрибуты фона определяют цвет, который используется для закрашивания фона ячейки. Другие атрибуты используются DBCS.
Приложение может комбинировать константы цвета текста и фона, чтобы получать разные цвета. Например, нижеследующая комбинация приводит к яркому синему тексту на синем фоне.
Кликните здесь для просмотра всего текста
C
1
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE
Если константа фона не определена, то фон черный, а если константа цвета текста не определена, текст черный. Например, нижеследующая комбинация производит черный текст на белом фоне.
Кликните здесь для просмотра всего текста
C
1
BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED
Каждое знакоместо символа экранного буфера сохраняет атрибуты цвета для цветов, используемых в прорисовке цвета текста (текст) и фона этой ячейки. Приложение может устанавливать данные о цвете для каждого знакоместа символа индивидуально, сохраняя информацию в поле Attributes структуры CHAR_INFO для каждой ячейки. Текущие атрибуты текста каждого экранного буфера используются для символов, впоследствии записываемых или отображаемых на экране высокоуровневыми функциями.
Приложение может использовать функцию GetConsoleScreenBufferInfo, чтобы регулировать текущие текстовые атрибуты экранного буфера и функцию SetConsoleTextAttribute, чтобы установить атрибуты символов. Изменение атрибутов экранного буфера не воздействует на отображение символов, записанных перед этим. Эти текстовые атрибуты не затрагивают символы, написанные низкоуровневыми консольными функциями I/O (типа функции WriteConsoleOutput или WriteConsoleOutputCharacter), которые или явно устанавливают атрибуты для каждой ячейки, в которой есть запись, или оставляют атрибуты неизменными.
Функция GetCurrentConsoleFont извлекает информацию о текущем консольном шрифте. Информация, сохраненная в структуре CONSOLE_FONT_INFO включает в себя ширину и высоту каждого символа в шрифте.
Функция GetConsoleFontSize получает данные о размере шрифта, используемого заданным экранным буфером консоли.
Размер экранного буфера выражается в понятиях координатной сетки, основанной на знакоместах символов. Ширина равна числу символьных знакомест в каждой строке, а высота ― числу строк. С каждым экранным буфером связано окно, которое обуславливает размер и расположение прямоугольной части экранного буфера консоли, отображенного в консольном окне. Окно экранного буфера определяется при помощи установки координат в символьных знакоместах верхней левой и нижней правой ячеек прямоугольника окна.
Экранный буфер может быть любого размера, ограниченный только доступной памятью. Размеры окна экранного буфера, основанные на текущем размере шрифта (управляемым исключительно пользователем), не могут превышать соответствующие размеры или экранного буфера консоли, или максимального окна, которое может вместиться на экране.
Функция GetConsoleScreenBufferInfo возвращает нижеследующую информацию об экранном буфере и его окне:
  • Текущий размер экранного буфера консоли
  • Текущее местоположение окна
  • Максимальный размер данного окна при текущем размере экранного буфера, текущий размер шрифта и размер экрана.
Функция GetLargestConsoleWindowSize возвращает значение максимального размера окна консоли, базирующейся на текущем шрифте и размеры экрана. Эти размеры отличаются от максимального размера окна, возвращаемого функцией GetConsoleScreenBufferInfo, в которой размер экранного буфера консоли игнорируется.

Чтобы изменить размер экранного буфера, используйте функцию SetConsoleScreenBufferSize. Эта функция терпит неудачу, если любой габарит определяемого размера является меньше, чем соответствующий размер окна консоли.
Чтобы изменить размер или расположение окна экранного буфера, используйте функцию SetConsoleWindowInfo. Эта функция не выполняет свою задачу, если координаты угла определяемого окна превышают пределы экранного буфера консоли или экрана. Изменение размера окна активного экранного буфера изменяет размер консольного окна, отображенного на экране.
Процесс может изменить режим ввода данных своей консоли, чтобы дать возможность вводить данные окна так, чтобы процесс был в состоянии получить вводимую информацию, когда пользователь изменяет размер экранного буфера консоли. Если приложение дает возможность ввод данных окна, оно может использовать функцию GetConsoleScreenBufferInfo, чтобы получить окно и размер экранного буфера при автозагрузке. Эта информация может затем использоваться, чтобы определить способ, которым информация будет показана на экране в окне. Если пользователь изменяет размер экранного буфера консоли, приложение может в ответ изменить способ, которым информация показывается на экране. Например, приложение может откорректировать способ автоматического переноса текста на новую строку в конце строки, если число символов в строке изменяется. Если приложение не дает возможности ввод данных в окно, ого должно или использовать унаследованное окно, а экранный буфер изменяет размер, или привести их к желательному размеру в течение запуска и восстанавливать унаследованный буфер, изменяя размер при выходе. Для дополнительной информации о режиме ввода данных окна, смотри раздел Низкоуровневые консольные режимы работы.

Консольное окно показывает на экране часть активного экранного буфера. Каждый экранный буфер поддерживает свой собственный текущий прямоугольник окна, который задает координаты верхних левых и нижних правых символьных знакомест, которые будут показаны на экране в консольном окне. Чтобы установить текущий прямоугольник окна экранного буфера, используйте функцию GetConsoleScreenBufferInfo. Когда экранный буфер создается, верхний левый угол его окна находится в верхнем левом угле экранного буфера консоли в (0,0).

Прямоугольник окна может изменяться, чтобы отображать различные части экранного буфера консоли. Прямоугольник окна экранного буфера может изменяться в нижеследующих ситуациях:
  • Когда вызывается функция SetConsoleWindowInfo, чтобы установить новый прямоугольник окна, она прокручивает вид экранного буфера консоли, изменяя позицию прямоугольника окна без изменения размеров окна. Примеры прокрутки содержания окна, смотри раздел Прокрутка окна экранного буфера.
  • Когда используется функция WriteFile, чтобы сделать запись в экранный буфер, тогда в режиме вывода включается переход в конце строки (EOL) на новую строку, который автоматически перемещает прямоугольник окна, так, что курсор всегда отображается на экране.
  • Когда функция SetConsoleCursorPosition устанавливает новую позицию курсора, которая находится вне границ текущего прямоугольника окна, тогда прямоугольник окна перемещается автоматически, чтобы показать на экране курсор.
  • Когда пользователь изменяет размер консольного окна или использует линейки прокрутки окна, тогда прямоугольник окна активного экранного буфера может измениться. Об этом изменении не сообщается, как о событии, изменяющем размеры окна в буфере вводимых данных.
В каждой из этих ситуаций, прямоугольник окна перемещается, чтобы показать на экране разные части экранного буфера консоли, но содержание экранного буфера консоли остается в той же самой позиции. Нижеследующие ситуации могут заставить переместить содержание экранного буфера консоли:
  • Когда вызывается функция ScrollConsoleScreenBuffer, прямоугольный блок копируется из одной части экранного буфера в другой
  • Когда используется функция WriteFile, чтобы сделать запись в экранный буфер, тогда в режиме вывода включается переход в конце строки (EOL) на новую строку, содержание экранного буфера консоли автоматически прокручивается
  • Когда используется функция WriteFile, чтобы записать в экранный буфер с автоматическим переходом на новую строку, в случае если встречается конец экранного буфера консоли. Эта прокрутка сбрасывает верхнюю строку экранного буфера консоли.
Функция ScrollConsoleScreenBuffer устанавливает прямоугольник экранного буфера консоли, который перемещается и новые верхние левые координаты, в которые прямоугольник копируется. Эта функция может прокручивать часть или взятое в целом содержание экранного буфера консоли.

Иллюстрация показывает действие функции ScrollConsoleScreenBuffer, которая прокручивает несколько верхних строк взятого в целом содержания экранного буфера консоли. Содержание верхних строк отвергается, а строки внизу заполняются заданными символами и цветом.
Действия функции ScrollConsoleScreenBuffer могут быть ограничены, при помощи установки необязательного прямоугольника отсечения по границам так, чтобы содержание экранного буфера консоли вне прямоугольника отсечения было неизменно. Действие отсечения по границам должно создать подокно (прямоугольник отсечения), содержание которого прокручивается без воздействия на остальную часть экранного буфера консоли. Пример, в котором используется, ScrollConsoleScreenBuffer, рассматривается в статье Прокрутка содержания экранного буфера.

Win32 API предоставляет два разных подхода к консольному вводу ― выводу (I/O), выбор которого зависит от того, сколько гибкости и управляемости необходимо приложению. Высокоуровневый метод включает простой символьный поток ввода-вывода, но он ограничивает доступ к буферу ввода данных консоли и экранным буферам. Низкоуровневый метод требует, чтобы разработчики писали большее количество кода и выбирали среди большего количества функций, однако это придает приложению большую гибкость.

Приложение может использовать функции файлового ввода-вывода, ReadFile и WriteFile, и консольные функции, ReadConsole и WriteConsole, для высокоуровневого ввода-вывода, которые обеспечивают косвенный доступ к вводу данных консоли и экранным буферам. Высокоуровневые функции ввода данных фильтруют и обрабатывают информацию в буфере вводимых данных консоли, чтобы возвратить их как поток символов, не учитывая вводимой информации от мыши и при изменении размеров буфера. Точно так же, высокоуровневые функции вывода данных записывают поток символов, который отображается на экране в текущем местоположении курсора в экранном буфере. Приложение управляет способом работы этой функций, устанавливая режимы ввода-вывода консоли.

Низкоуровневые функции I/O обеспечивают прямой доступ к вводу данных консоли и экранным буферам, давая возможность приложению обращаться к событиям мыши и событиям изменения размера буфера ввода и к расширенной информации для событий клавиатуры. Низкоуровневые функции вывода данных дают возможность приложению читать или записывать в экранном буфере заданное число последовательных символьных знакомест, или читать, или записывать в прямоугольные блоки символьные знакоместа в заданном месте в экранном буфере. Режимы ввода данных консоли воздействуют на низкоуровневый ввод данных, разрешая приложению устанавливать, чьи это события в буфере вводимых данных, мыши или изменения размера буфера. Режимы вывода информации консоли не воздействуют на низкоуровневый вывод данных.

Высокоуровневая и низкоуровневая методики ввода-вывода не являются взаимоисключающими и приложение может использовать любую комбинацию этих функций. Тем не менее, как правило, прикладная программа использует исключительно один или другой способ.

Нижеследующие разделы описывают консольные режимы работы и высокоуровневые и низкоуровневые функции I/O.
1
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
16.03.2016, 09:42  [ТС] 18
Связанная с каждым консольным буфером вводимых данных установка режимов ввода, воздействует на операции ввода информации. Точно так же, каждый экранный буфер консоли имеет установку режимов вывода, который воздействует на операции вывода данных. Режимы ввода данных могут быть разделены на две группы: которые воздействуют на высокоуровневые функции ввода данных и которые воздействуют на низкоуровневые функции ввода. Режимы вывода воздействуют только на прикладные программы, которые используют высокоуровневые функции вывода данных.
Функция GetConsoleMode сообщает о текущем режиме ввода данных буфера ввода консоли или текущего режима вывода экранного буфера. Функция SetConsoleMode устанавливает текущий режим или консольного буфера вводимых данных или экранного буфера. Если консоль имеет множество экранных буферов, режимы вывода каждого могут быть разными. Приложение может изменять режимы ввода-вывода (I/O) в любое время. Для получения дополнительной информации о консольных режимах работы, которые находятся под влиянием высокоуровневых и низкоуровневых операций ввода-вывода, смотрите статью Высокоуровневые консольные режимы работы и Низкоуровневые консольные режимы работы.

Функция GetConsoleDisplayMode сообщает, находится ли текущая консоль в полноэкранном режиме и связывается ли она непосредственно с аппаратными средствами.
Функции высокоуровневого ввода-вывода (I/O) обеспечивают простой способ чтения потока символов из консольного ввода данных или записи потока символов в консольном выводе информации. Высокоуровневая операция чтения получает введенные символы из буфера вводимых данных консоли и сохраняет их в заданном буфере. Высокоуровневая операция записи берет символы из заданного буфера и записывает их в экранный буфер в текущем местоположении курсора, продвигая курсор, по мере того, как записывается символ.

Высокоуровневый ввод-вывод дает Вам выбор между функциями ReadFile и WriteFile и функциями ReadConsole и WriteConsole. Они были бы идентичны, если бы не два важных различия. Консольные функции поддерживают использование или символов Unicode или набора символов ANSI; функции файлового ввода-вывода не поддерживают Unicode. К тому же, функции файлового ввода-вывода могут быть использованы для обращения к файлам, каналам и последовательным устройствам связи; консольные функции могут быть использованы только с консольными дескрипторами. Это различие важно, если приложение опирается на стандартные дескрипторы, которые, могут быть переназначены.

При использовании любого набора высокоуровневых функций, приложение может управлять цветом текста и фона используемыми символами дисплея, впоследствии записанными в экранном буфере. Прикладная программа может также использовать и консольные режимы работы, которые воздействуют на высокоуровневый консольный ввод-вывод (I/O), чтобы включать или отключать нижеследующие свойства:
  • Эхо-контроль ввода информации с клавиатуры в активном экранном буфере
  • Построчный ввод данных, в котором операция чтения не возвращается до тех пор, пока не нажата клавиша ENTER.
  • Автоматические процессы ввода информации с клавиатуры, которые манипулируют возвратом каретки, CTRL+C и другими частностями ввода данных
  • Автоматические действия вывода данных, которые управляют переносом строки, возвратом каретки, возвратом на один символ и другими частностями вывода информации
Характер работы высокоуровневых консольных функций находится под влиянием консольного режима ввода и вывода. Когда консоль создана, для ее буфера вводимых данных разрешены все из ниже перечисленных консольных режимов ввода:
  • Режим построчного ввода данных
  • Режим обработки ввода данных
  • Режим отражения ввода данных
Для обоих из ниже перечисленных консольных режимов вывода, когда они создаются, разрешены действия экранного буфера консоли:
  • Режим обработки вывода данных
  • Режим переноса выводимых данных в конце строки (EOL)
Все три режима ввода данных, наряду с режимом обработки вывода, предназначены, чтобы работать вместе. Самое лучшее или включать, или отключить все эти режимы, как группу. Когда все они включены, приложение, как говорится, находится в "приготовленном" режиме, который означает то, что большинство действий являются управляемыми для приложения. Когда все отключены, прикладная программа находится в "неприготовленном" режиме, который означает, что ввод данных не фильтруется и любая его обработка оставлена приложению.

Прикладная программа может использовать функцию GetConsoleMode, чтобы установить текущий режим буфера вводимых данных консоли или экранного буфера. Вы можете включать или отключать любой из этих режимов при помощи использования нижеследующих значений в функции SetConsoleMode.

Обратите внимание на то, что установка режима вывода в одном из экранных буферов не воздействует на режим вывода других экранных буферов
Кликните здесь для просмотра всего текста
.
РежимОписание
ENABLE_PROCESSED_INPUTДескриптор используется консольным вводом, чтобы заставить систему обрабатывать любое системное редактирование или ввод данных от управляющей клавиши, а не возвращать его как введенное данное при операции чтения буфера. Если к тому же включается построчный ввод данных, возвраты на один символ и возвраты каретки обрабатываются правильно. Возврат на один символ заставляет курсор, двигаться назад на один пробел без воздействия на символ в позиции курсора. Возврат каретки преобразуется в комбинацию кодов возврата каретки ASCII 13 и конца строки ASCII 10, представляемые как пустая строка. Если включен отраженный режим ввода данных, а вывод данных должен отразить системное редактирование, должна быть включена обработка вывода информации для активного экранного буфера. Если включается обработка ввода данных, комбинация клавиш CTRL+C пересылается на соответствующий обработчик независимо от того, включен или нет построчный ввод данных. Для получения дополнительной информации об управляющих обработчиках, см. статью Консольное управление обработчиками.
ENABLE_LINE_INPUTИспользуется с дескриптором консольного ввода данных, чтобы заставить функции ReadFile и ReadConsole возвращать значение, когда нажата клавиша ENTER. Если режим построчного ввода данных заблокирован, функции возвращают значение тогда, когда один или несколько символов доступны в буфере вводимых данных.
ENABLE_ECHO_INPUTИспользуется с дескриптором консольного ввода данных, чтобы заставить ввод информации с клавиатуры читать при помощи функций ReadFile или ReadConsole, которая будет отображаться на экране активным экранным буфером. Символы отображаются на экране только в том случае, если процесс, который вызывает ReadFile или ReadConsole имеет открытый дескриптор активного экранного буфера. Эхо-режим не может быть разрешен, если также не включен построчный ввод данных. Режим вывода активного экранного буфера воздействует на способ, которым отображаемый на экране ввод данных показывается на экране.
ENABLE_PROCESSED_OUTPUTИспользуется с дескриптором экранного буфера консоли, чтобы заставить систему выполнить соответствующее действие для управляющих символов ANSI, которые пишутся в экранном буфере. Обрабатываются возврат на один символ, перемещение при помощи клавиши TAB, звонковая сигнализация, возврат каретки и символы перевода строки. Символ табуляции перемещает курсор в следующую позицию табуляции, которая установлена через каждые восемь символов. Звонковая сигнализация издает звук краткой длительности.
ENABLE_WRAP_AT_EOL_OUTPUTИспользуется с дескриптором экранного буфера консоли, чтобы заставить текущую позицию вывода данных (позицию курсора) переместиться в первый столбец следующей строки, когда текущая строка достигла конца. Если достигается низ области окна, начало координат окна перемещается вниз на одну строку. Это перемещение имеет действие прокрутки содержания окна на одну строку. Если достигается низ экранного буфера консоли, содержание экранного буфера консоли прокручивается на одну строку, а верхняя строка экранного буфера консоли сбрасывается.

Если этот режим заблокирован, последний символ в строке переписывается поверх любого последующего символа.
Функции ReadFile и WriteFile или функции ReadConsole и WriteConsole, дают возможность приложению читать ввод данных консоли и записывать консольный вывод информации как поток символов. ReadConsole и WriteConsole ведут себя точно подобно ReadFile и WriteFile за исключением того, что они могут быть использованы или как функции расширенного 16-битного алфавита (в которой текстовые параметры должны использовать Unicode) или как функции ANSI (в которой текстовые параметры должны использовать символы из набора символов Windows). Прикладные программы, которым нужно поддерживать один набор источников, чтобы поддержать или Unicode или набор символов ANSI, должны использовать ReadConsole и WriteConsole.

Функции ReadConsole и WriteConsole могут быть использованы только с дескрипторами консоли; функции ReadFile и WriteFile могут быть использованы с другими дескрипторами (такими как дескрипторы файлов или каналов). Функции ReadConsole и WriteConsole завершаются с ошибкой, если используются со стандартным дескриптором, который был переназначен и больше не является консольным дескриптором.

Чтобы получать ввод информации с клавиатуры, процесс может использовать функции ReadFile или ReadConsole с дескриптором буфера вводимых данных консоли, или он может использовать ReadFile, чтобы читать ввод данных из файла или канала, если был переназначен STDIN. Эти функции возвращают только события клавиатуры, которые могут быть преобразованы в символы ANSI (или в символы Unicode в случае ReadConsole). Ввод данных, который может быть возвращен, включает в себя комбинации управляющих клавиш. Функции не возвращают события клавиатуры, включающие функциональные клавиши или клавиши со стрелкой. События ввода, созданные мышью, окном, фокусом или вводом меню не учитываются.

Если включен режим построчного ввода данных (режим по умолчанию), функции ReadFile и ReadConsole не возвращают значения вызывающей программе до тех пор, пока не будет нажата клавиша ENTER. Если режим построчного ввода данных заблокирован, функции не возвращают значения до тех пор, пока, по меньшей мере, не будет доступен один символ. В любом режиме, все доступные символы читаются до тех пор, пока, или к набору на клавиатуре, больше нет доступа, или было прочитано заданное число символов. Непрочитанные символы буферизируются до следующей операции чтения. Функции сообщают об общем количестве фактически прочитанных символов. Если включается эхо-режим ввода данных, символы, читаемые этими функциями, записываются в текущую позицию курсора активного экранного буфера.

Процесс может использовать функцию WriteFile или WriteConsole, чтобы записать в или активный или неактивный экранный буфер, или, если STDOUT был переназначен, он может использовать функцию WriteFile, чтобы записать в файл или канал. Обработка режима вывода и автоматического перехода в режиме вывода на новую строку в конце строчки EOL управляется путем записи символов или отображения в экранном буфере.

Символы, написанные функцией WriteFile или WriteConsole, или повторенные на экране функцией ReadFile или ReadConsole, вставляются в экранный буфер в текущей позиции курсора. По мере того, как пишется символ, позиция курсора продвигается на следующее символьное знакоместо; однако поведение ее в конце строки зависит от режима автоматического перехода на новую строку в режиме вывода экранного буфера консоли (EOL). Приложение может использовать функцию GetConsoleScreenBufferInfo, чтобы получить текущую позицию курсора и функцию SetConsoleCursorPosition, чтобы установить позицию курсора.

За примером, в котором используются высокоуровневые консольные функции I/O, обратитесь к статье Использование высокоуровневых функций ввода и вывода.
Низкоуровневые консольные функции I/O расширяют контроль приложения над консольным вводом ― выводом (I/O), разрешая прямой доступ к вводу данных консоли и экранным буферам. Эти функции дают возможность прикладной программе выполнять нижеследующие задачи:
  • Принимать ввод информации о событиях мыши и изменениях размеров буфера.
  • Принимать расширенную информацию о событиях ввода с клавиатуры.
  • Фиксировать запись ввода данных в буфере ввода.
  • Читать запись вводимых данных без их удаления из буфера ввода.
  • Выяснять число ждущих обработки событий в буфере ввода.
  • Сбрасывать на диск данные буфера ввода.
  • Читать и писать строки символами Unicode или ANSI в заданном месте экранного буфера.
  • Читать и писать строчки текста и атрибуты цвета фона в заданном месте экранного буфера.
  • Читать и писать прямоугольные блоки символов и данные цвета в заданном месте экранного буфера.
  • Читать одиночные символы Unicode или ANSI, или комбинацию текста и атрибутов фона, которые определяют последовательность ячеек, начинающихся в заданном месте экранного буфера.
События ввода с клавиатуры записываются в буфере вводимых данных консоли в зависимости от режима ввода данных мышью и окном консоли. Режим обработки ввода данных консоли устанавливает, как система обрабатывает комбинацию клавиш CTRL+C. Чтобы установить или получить состояние режимов ввода данных консоли, приложение может определить дескриптор буфера вводимых данных консоли при вызове функции SetConsoleMode или GetConsoleMode. Ниже перечисленные режимы используются с дескрипторами консольного ввода данных.
1
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
16.03.2016, 09:42  [ТС] 19
Кликните здесь для просмотра всего текста
РежимОписание
ENABLE_MOUSE_INPUTОпределяет, фиксировать ли события с мышью в буфере вводимых данных. По умолчанию, ввод информации от мыши включен, а ввод данных окна заблокирован. Изменение любого из этих режимов воздействует только на ввод данных, который происходит после того, как режим установлен; ждущие обработки события мыши или окна в буфере вводимых данных не сбрасываются. Курсор мыши показывается на экране независимо от режима работы мыши.
ENABLE_WINDOW_INPUTОпределяет, фиксировать ли события изменения размера буфера в буфере вводимых данных. По умолчанию, ввод информации от мыши включен, а ввод данных окна заблокирован. Изменение любого из этих режимов воздействует только на ввод данных, который происходит после того, как режим установлен; ждущие обработки события мыши или окна в буфере вводимых данных не сбрасываются. Курсор мыши отображается на экране независимо от режима работы мыши.
ENABLE_PROCESSED_INPUTУправляет обработкой ввода данных для прикладных программ, используя высокоуровневые консольные функции I/O. Однако, если режим обработки ввода данных включен, комбинация клавиш CTRL+C не фиксируется в буфере вводимых данных консоли. Вместо этого, комбинация пересылается соответствующей функции, управляющей обработчиком. Для получения дополнительной информации об управлении обработчиками см. статью Консольное управление обработчиками.

Буфер вводимых данных консоли содержит записи вводимых данных, которые могут включать в себя информацию о событиях клавиатуры, мыши, изменения размера буфера, фокуса и меню. Низкоуровневые функции обеспечивают прямой доступ к буферу вводимых данных, в отличие от высокоуровневых функций, которые фильтруют и обрабатывают информацию буфера вводимых данных, сбрасывая все, кроме ввода информации с клавиатуры.

Имеется пять низкоуровневых функций для доступа к буферу вводимых данных консоли:
  1. ReadConsoleInput
  2. PeekConsoleInput
  3. GetNumberOfConsoleInputEvents
  4. WriteConsoleInput
  5. FlushConsoleInputBuffer
Функции ReadConsoleInput, PeekConsoleInput и WriteConsoleInput используют структуру INPUT_RECORD, чтобы читать из или записывать в буфер вводимых данных.

Ниже описания низкоуровневых консольных функций ввода.
Кликните здесь для просмотра всего текста
ФункцияОписание
ReadConsoleInputЧитает и удаляет записи вводимых данных из буфера ввода. Функция не возвращает значение до тех пор, пока, по меньшей мере, не будет доступна хотя бы одна запись для чтения. Далее все доступные записи передаются в буфер вызывающего процесса до тех пор, пока или не окажется больше записей, которые доступны, или заданное число записей было прочитано. Непрочитанные записи остаются в буфере ввода для следующей операции чтения. Функция сообщает об общем количестве записей, которые были прочитаны. Пример, который использует функцию ReadConsoleInput, смотри в статье События чтения буфера вводимых данных.
PeekConsoleInputЧитает без удаления ждущих обработки записей вводимых данных в буфере ввода. Все доступные записи до заданного числа копируются в буфер вызывающего процесса. Если доступных записей нет, функция немедленно возвращает значение. Функция сообщает об общем количестве записей, которые были прочитаны.
GetNumberOfConsoleInputEventsВыясняет число непрочитанных записей вводимых данных в буфере ввода.
WriteConsoleInputПомещает записи вводимых данных в буфер ввода позади любых ждущих обработки записей в буфере. В случае необходимости, буфер ввода растет динамически, чтобы вместить столько записей, сколько записывается. Чтобы использовать эту функцию, определяемый дескриптор буфера ввода должен иметь право доступа GENERIC_READ.
FlushConsoleInputBufferСбрасывает все непрочитанные события в буфере ввода. Чтобы использовать эту функцию, определяемый дескриптор буфера ввода должен иметь право доступа GENERIC_READ.

Поток процесса прикладной программы может выполнить операцию "занять", чтобы ждать ввод данных, который будет доступным в буфере ввода. Чтобы инициализировать операцию "занять", определите дескриптор буфера ввода при вызове любой из функций ожидания. Эти функции могут возвратить значение тогда, когда сообщается о состоянии одного или нескольких объектов. Состояние дескриптора консольного ввода становится сигнальным тогда, когда имеются непрочитанные записи в его буфере ввода. Состояние дескриптора сбрасывается в несигнальное тогда, когда буфер ввода становится пустым. Если не имеется доступного ввода данных, вызывающий поток входит в рациональное состояние ожидания, расходуя очень небольшое процессорное время при ожидании условия удовлетворяющего операцию "занять".
Низкоуровневые консольные функции вывода данных обеспечивают прямой доступ к символьным знакоместам экранного буфера. Один набор функций читает из или записывает в последовательные ячейки, начинающиеся в любом месте в экранном буфере консоли. Другой набор функций читает из или записывает в прямоугольные блоки ячеек.

Нижеследующие функции чтения из или записи в заданное число последовательных символьных знакомест в экранном буфере, начинающихся с определенной ячейки.
Кликните здесь для просмотра всего текста
ФункцияОписание
ReadConsoleOutputCharacterКопирует строку символов Unicode или ANSI из экранного буфера.
WriteConsoleOutputCharacterЗаписывает строку символов Unicode или ANSI в экранный буфер.
ReadConsoleOutputAttributeКопирует строку текста и атрибуты цвета фона из экранного буфера дисплея.
WriteConsoleOutputAttributeЗаписывает строку текста и атрибуты цвет фона в экранном буфере дисплея.
FillConsoleOutputCharacterЗаписывает одиночный символ Unicode или ANSI в заданном числе последовательных ячеек в экранном буфере.
FillConsoleOutputAttributeЗаписывает текст и комбинацию атрибутов цвета фона в заданном числе последовательных ячеек в экранном буфере.

Для всех этих функций, когда подходит последняя ячейка строки, операции чтения или записи автоматически переходят на новую строку обратно в первую ячейку следующей строки. Когда подходит конец последней строки экранного буфера консоли, функции записи сбрасывают все не записанные символы или атрибуты, а функции чтения сообщают о числе символов или атрибутах, действительно записанных.
Нижеследующие функции читают из или записывают в прямоугольные блоки символьных знакомест, в заданном месте экранного буфера.
Кликните здесь для просмотра всего текста
ФункцияОписание
ReadConsoleOutputКопирует символ и данные о цвете от заданного блока ячеек экранного буфера в данный блок в буфере назначения.
WriteConsoleOutputЗаписывает символ и данные о цвете в заданном блоке ячеек экранного буфера из данного блока в исходном буфере.

Эти функции рассматривают экранные буферы и буфер источника или буферы назначения, как двухмерные массивы структур CHAR_INFO (содержащих символы и данные атрибутов цвета для каждой ячейки). Функции устанавливают ширину и высоту, в символьных знакоместах, буфера источника или буфера назначения, а указатель на буфер рассматривается как указатель на начальную ячейку с координатами (0,0) двухмерного массива. Функции используют структуру SMALL_RECT, которая определяет, какой прямоугольник доступен в экранном буфере консоли, и обуславливает координаты левой верхней ячейки в буфере источнике или буфере назначения в месте соответствующего прямоугольника в этом буфере.
Эти функции автоматически ограничивают определяемый прямоугольник экранного буфера, чтобы вместить его в пределах границ экранного буфера консоли. Например, если прямоугольник устанавливает нижние правые координаты, которые являются (столбец 100, строка 50), а экранный буфер консоли устанавливается шириной только 80 столбцов, координаты отсекаются так, чтобы они были (столбец 79, строка 50). Точно так же этот откорректированный прямоугольник снова отсекается, чтобы вместиться в пределах границ буфера назначения или источника. Координаты экранного буфера фактического прямоугольника, в котором происходит чтение из или запись в является установленным. Пример, который использует эти функции, посмотрите в статье Чтение и запись блоков символов и атрибутов.
Иллюстрация показывает операцию ReadConsoleOutput, где происходит отсечение по границам, когда блок читается из экранного буфера консоли, и снова, когда блок копируется в буфер назначения. Функция сообщает о фактическом прямоугольнике экранного буфера, который она скопировала.
Экранный буфер окна с буфером назначения

Кодовые страницы консоли
Кодовая страница (code page) является отображением 256 символьных кодов для каждого отдельного символа. Разные кодовые страницы включают в себя разные специальные символы, обычно настраиваемые для языка или группы языков.
Каждая консоль связана с двумя кодовыми страницами: одна для ввода данных и один для вывода информации. Консоль использует свою кодовую страницу ввода, чтобы преобразовать ввод информации с клавиатуры в соответствующее символьное значение. Свою кодовую страницу вывода данных она использует, чтобы преобразовать символьные значения, записанные различными функциями вывода в изображение, отображаемое в консольном окне. Приложение может использовать функции SetConsoleCP и GetConsoleCP, чтобы устанавливать и получать кодовые страницы ввода консоли, а функции SetConsoleOutputCP и GetConsoleOutputCP, чтобы устанавливать и получать свои кодовые страницы вывода данных.
Идентификаторы кодовых страниц, доступных на локальном компьютере сохраняются в системном реестре под нижеследующим ключом.
Кликните здесь для просмотра всего текста
Assembler
1
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
За информацией об использования функций системного реестра, чтобы выяснить доступные кодовые страницы, обратитесь к статье Системный реестр.
Каждый консольный процесс имеет свой собственный перечень функций управления обработчиками, которые вызываются системой, когда процесс получает сигнал CTRL+C, CTRL+BREAK или CTRL+CLOSE. Вначале, перечень управления обработчиками для каждого процесса содержит только заданную по умолчанию функцию обработчика, которая вызывает функцию ExitProcess. Консольный процесс может добавлять или удалять дополнительные функции HandlerRoutine путем вызова функции SetConsoleCtrlHandler. Эта функция не находится под влиянием перечней управления обработчиками для других процессов. Когда консольный процесс получает какой-либо из управляющих сигналов он вызывает функции обработчика. Основа для вызова ― последняя из зарегистрированных и первая из вызываемых функций, до тех пор, пока один из обработчиков не возвратит значение 1 (TRUE). Если ни один из обработчиков не возвращает значение 1 (TRUE), вызывается заданный по умолчанию обработчик.
Нижеследующее объявление typedef иллюстрирует формат управляющей функции обработчика.
Кликните здесь для просмотра всего текста
C
1
typedef BOOL (*PHANDLER_ROUTINE)(DWORD dwCtrlType);
Параметр dwCtrlType функции идентифицирует, какой управляющий сигнал был принят, а величина возвращаемого значения указывает, был ли сигнал обработан.
Пример функции управления обработчиком, см. в статье Регистрация функции управления обработчиком.
  • Сигналы CTRL+C и CTRL+BREAK
  • Сигнал CTRL+CLOSE
  • Группы консольных процессов
Миниатюры
Создание консольных приложений в 64-разрядной Windows Seven   Создание консольных приложений в 64-разрядной Windows Seven   Создание консольных приложений в 64-разрядной Windows Seven  

1
Ушел с форума
Автор FAQ
16338 / 7659 / 1075
Регистрация: 11.11.2010
Сообщений: 13,696
16.03.2016, 10:02  [ТС] 20
Модель системы безопасности Windows NT дает Вам возможность управлять доступом к консольным буферам ввода и экранным буферам консоли. Для получения дополнительной информации о системе безопасности, смотри раздел Модель контроля доступа.
Вы можете определить дескриптор защиты для консольного ввода данных и экранных буферов консоли, когда Вы вызываете функцию CreateFile или CreateConsoleScreenBuffer. Если Вы определяете значение NULL, объект получает заданный по умолчанию дескриптор защиты. ACL, в заданном по умолчанию дескрипторе защиты для консольного буфера, исходят из первичного права или маркера заимствования прав создателя.
Обработанные возвращенные значения функций CreateFile, CreateConsoleScreenBuffer и GetStdHandle имеют права доступа GENERIC_READ и GENERIC_WRITE.
Правильные права доступа включают в себя GENERIC_READ и GENERIC_WRITE универсальные права доступа.
Кликните здесь для просмотра всего текста
ЗначениеПредназначение
GENERIC_READЗапрашивает доступ для чтения в экранном буфере консоли, включая процесс, который читает данные из буфера.
GENERIC_WRITEЗапрашивает доступ для записи в экранный буфер консоли, включая процесс, который записывает данные в буфер.

Нижеследующий пример использует высокоуровневые консольные функции I/O для консольного ввода-вывода. Для получения дополнительной информации о высокоуровневых консольных функциях I/O, см. статью Высокоуровневый консольный ввод-вывод I/O).
В примере предполагается, что заданные по умолчанию режимы ввода-вывода (I/O) являются по существу вначале для первого вызова функций ReadFile и WriteFile. Затем для второго вызова ReadFile и WriteFile режим ввода данных изменяется, выключается режим построчного ввода данных и отраженный режим ввода данных. Функция SetConsoleTextAttribute используется для, установки цвета, которым впоследствии письменный текст будет показан на экране. Перед выходом, программа восстанавливает исходный консольный режим ввода данных и атрибуты цвета.
Функция NewLine примера используется тогда, когда отключается режим построчного ввода данных. Она обрабатывает возвраты каретки, перемещая позицию курсора в первую ячейку следующей строки. Если курсор находится уже в последней строке экранного буфера консоли, содержание экранного буфера консоли прокручивается вверх на одну строку.
Обратите внимание на то, что MyErrorExit ― групповой символ ― заместитель для определяемой программой функции, которая показывает на экране и обрабатывает аварийные ситуации.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <windows.h>
void NewLine(void);
void ScrollScreenBuffer(HANDLE, INT);
HANDLE hStdout, hStdin;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
void main(void)
{
    LPSTR lpszPrompt1 = "Type a line and press Enter, or q to quit: ";
    LPSTR lpszPrompt2 = "Type any key, or q to quit: ";
    CHAR chBuffer[256];
    DWORD cRead, cWritten, fdwMode, fdwOldMode;
    WORD wOldColorAttrs;
    // Получим дескрипторы для STDIN и STDOUT
    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL, "GetStdHandle", "Console Error", MB_OK);
        return;
    }
// Сохраним текущий цвет текста
    if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
    {
        MessageBox(NULL, "GetConsoleScreenBufferInfo", "Console Error", MB_OK);
        return;
    }
    wOldColorAttrs = csbiInfo.wAttributes;
// Установим атрибуты текста которые пишут красный текст по черному фону.
    if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED|FOREGROUND_INTENSITY))
    {
        MessageBox(NULL, "SetConsoleTextAttribute", "Console Error", MB_OK);
        return;
    }
// Запишем в STDOUT и прочитаем из STDIN, используя режим по умолчанию.
// При вводе данных эхо-режим осуществляется автоматически, а функция ReadFile
// не возвращает значения до тех пор, пока не напечатается каретка возврата.
//
// Режим ввода по умолчанию ― построчный, обрабатываемый и эхо-режим.
// Режим вывода по умолчанию ― обрабатываемый и с автопереносом в конце строки EOL.
    while (1)
    {
        if (! WriteFile(
            hStdout,                    // дескриптор вывода
            lpszPrompt1,                // строка приглашения к вводу
            lstrlen(lpszPrompt1),       // длина строки
            &cWritten,                  // записано байтов
            NULL) )                     // не перекрывающееся
        {
            MessageBox(NULL, "WriteFile", "Console Error", MB_OK);
            return;
        }
        if (! ReadFile(
            hStdin,         // дескриптор ввода
            chBuffer,       // буфер для передачи
            255,            // размер буфера
            &cRead,         // действительно прочитанные байты
            NULL) )         // не перекрывающееся
        break;
        if (chBuffer[0] == 'q')
        break;
    }
    // Выключим построчный режим ввода и эхо-режим
    if (! GetConsoleMode(hStdin, &fdwOldMode))
    {
        MessageBox(NULL, "GetConsoleMode", "Console Error", MB_OK);
        return;
    }
    fdwMode = fdwOldMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
    if (! SetConsoleMode(hStdin, fdwMode))
    {
        MessageBox(NULL, "SetConsoleMode", "Console Error", MB_OK);
        return;
    }
    // Без эхо-режима и построчного ввода, ReadFile возвращает значение,
    // когда доступен какой либо ввод данных. Возврат каретки должен
    // обрабатываться, а WriteFile используется в эхо-режиме для ввода данных
    NewLine();
    while (1)
    {
        if (! WriteFile(
            hStdout,                      // дескриптор вывода
            lpszPrompt2,                  // строка приглашения к вводу
            lstrlen(lpszPrompt2),         // длина строки
            &cWritten,                    // записано байтов
            NULL) )                       // не перекрывающееся
        {
            MessageBox(NULL, "WriteFile", "Console Error", MB_OK);
            return;
        }
        if (! ReadFile(hStdin, chBuffer, 1, &cRead, NULL))
            break;
        if (chBuffer[0] == '\r')
            NewLine();
        else if (! WriteFile(hStdout, chBuffer, cRead,
            &cWritten, NULL))
            break;
        else
            NewLine();
        if (chBuffer[0] == 'q')
            break;
    }
// Восстанавливаем исходный режим консоли
    SetConsoleMode(hStdin, fdwOldMode);
// Восстанавливаем исходный режим текста
    SetConsoleTextAttribute(hStdout, wOldColorAttrs);
}
// Функция NewLine обрабатывает возврат каретки тогда, когда режим обработки
// вводимых данных отключается. Она получает текущую позицию курсора
// и сбрасывает ее до позиции первой ячейки следующей строки
void NewLine(void)
{
    if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
    {
        MessageBox(NULL, "GetConsoleScreenBufferInfo", "Console Error", MB_OK);
        return;
    }
    csbiInfo.dwCursorPosition.X = 0;
// Если это последняя строка в буфере экрана, прокручивает буфер вверх
    if ((csbiInfo.dwSize.Y-1) == csbiInfo.dwCursorPosition.Y)
    {
        ScrollScreenBuffer(hStdout, 1);
    }
// Иначе, продвигает вперед курсор к следующей строке
    else csbiInfo.dwCursorPosition.Y += 1;
    if (! SetConsoleCursorPosition(hStdout,
        csbiInfo.dwCursorPosition))
    {
        MessageBox(NULL, "SetConsoleCursorPosition", "Console Error", MB_OK);
        return;
    }
}
void ScrollScreenBuffer(HANDLE h, INT x)
{
    SMALL_RECT srctScrollRect, srctClipRect;
    CHAR_INFO chiFill;
    COORD coordDest;
    srctScrollRect.Left = 0;
    srctScrollRect.Top = 1;
    srctScrollRect.Right = csbiInfo.dwSize.X - x;
    srctScrollRect.Bottom = csbiInfo.dwSize.Y - x;
// Назначение для прямоугольника прокрутки - одна строка вверх
    coordDest.X = 0;
    coordDest.Y = 0;
// Прямоугольник отсечения по границам тот же самый, что и прокручивающийся прямоугольник.
// Строка назначения оставлена неизменной
    srctClipRect = srctScrollRect;
// Установим символ - заполнитель и атрибуты
    chiFill.Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY;
    chiFill.Char.AsciiChar = ' ';
    // Прокрутим вверх на одну строку
    ScrollConsoleScreenBuffer(
        h,               // дескриптор экранного буфера
        &srctScrollRect, // прямоугольник прокрутки
        &srctClipRect,   // прямоугольник отсечения
        coordDest,       // верхняя левая ячейка назначения
        &chiFill);       // символ-заполнитель и цвет
}
Символы или атрибуты цвета могут быть записаны в заданные символьные знакоместа в экранном буфере. Нижеследующий пример использует функцию WriteConsoleOutputCharacter, чтобы записать строку символов, начинающихся в верхнем левом угле экранного буфера. Далее пример использует функцию WriteConsoleOutputAttribute, чтобы записать строку атрибутов цвета для первых 51 ячейки той же самой строки. Параметр coord для обеих функций устанавливает символьное знакоместо в экранном буфере консоли, в котором начинается запись. Местоположение в консольном окне, где эти символы или цвета появляются, зависит от прямоугольника текущего окна экранного буфера консоли. За дополнительной информацией о соотношениях между экранным буфером и его окнами, обратитесь к статьям Окно и размер экранного буфера и Прокрутка экранного буфера.
Обратите внимание на то,что MyErrorExit ― групповой символ ― заместитель для определяемой программой функции, которая показывает на экране и обрабатывает аварийные ситуации.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
HANDLE hOutput;
    LPTSTR lpszString = "Character String";
    DWORD cWritten;
    BOOL fSuccess;
    COORD coord;
    WORD wColors[3], wColor;
    CHAR chFillChar;
// Запишем строку символов в буфер экрана
    coord.X = 0;            // начало на первую ячейку
    coord.Y = 0;            // первой строки
    fSuccess = WriteConsoleOutputCharacter(
        hOutput,              // дескриптор экранного буфера
        lpszString,           // указатель на строку ― источник
        lstrlen(lpszString),  // длина строки
        coord,                // первая ячейка для записи
        &cWritten);           // действительное число записей
    if (! fSuccess)
        MyErrorExit("WriteConsoleOutputCharacter");
// Запишем строку цветов в экранный буфер
    wColors[0] = BACKGROUND_RED;
    wColors[1] = BACKGROUND_RED |     // белый фон
                 BACKGROUND_GREEN |
                 BACKGROUND_BLUE;
    wColors[2] = BACKGROUND_BLUE;
    for (;fSuccess && coord.X < 50; coord.X += 3)
    {
        fSuccess = WriteConsoleOutputAttribute(
            hOutput,          // дескриптор экранного буфера
            wColors,          // указатель на строку ― источник
            3,                // длина строки
            coord,            // первая ячейка для записи
            &cWritten);       // действительное число записей
    }
    if (! fSuccess)
        MyErrorExit("WriteConsoleOutputAttribute");
Те же самые символы или атрибуты цвета можно записать в заданное число последовательных ячеек экранного буфера, начинающихся в заданном местоположении. Нижеследующий пример использует функцию FillConsoleOutputCharacter, чтобы очистить область экранного буфера 80 на 50 символов, а затем он использует функцию FillConsoleOutputAttribute, чтобы установить атрибуты цвета в тех же самых ячейках.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Заполним область экранного буфера 80-на-50 символов пробелами
    coord.X = 0;            // начнем с первой ячейки
    coord.Y = 0;            //   первой строки
    chFillChar = ' ';
    fSuccess = FillConsoleOutputCharacter(
        hStdout,          // дескриптор экранного буфера
        chFillChar,       // заполнение пробелами
        80*50,            // число ячеек для заполнения
        coord,            // первая ячейка для записи
        &cWritten);       // фактическое число записей
    if (! fSuccess)
        MyErrorExit("FillConsoleOutputCharacter");
// Установим в области экранного буфера 80-на-50 символов цвета для белого текста на красном
    wColor = BACKGROUND_RED |
             FOREGROUND_RED |
             FOREGROUND_GREEN |
             FOREGROUND_BLUE;
    fSuccess = FillConsoleOutputAttribute(
        hStdout,          // дескриптор экранного буфера
        wColor,           // цвет для заполнения
        80*50,            // число заполняемых ячеек
        coord,            // первая ячейка для записи
        &cWritten);       // фактическое число записей
    if (! fSuccess)
        MyErrorExit("FillConsoleOutputAttribute");
Функция ReadConsoleOutput копирует прямоугольный блок символьных и цветных атрибутов данных из экранного буфера консоли в буфер назначения. Функция рассматривает буфер назначения как двухмерный массив структур CHAR_INFO. Точно так же функция WriteConsoleOutput копирует прямоугольный блок символьных и цветных атрибутов данных из исходного буфера в экранный буфер консоли. Для получения дополнительной информации о чтении или записи в прямоугольных блоках ячеек экранного буфера, смотри раздел Методы ввода и вывода данных.
Нижеследующий пример использует функцию CreateConsoleScreenBuffer, чтобы создать новый экранный буфер. После того, как функция SetConsoleActiveScreenBuffer сделает этот экранный буфер активным, во временный буфер скопируется блок символов и атрибутов цвета верхних двух строк SDTOUT экранного буфера. Данные далее копируются из временного буфера в новый активный экранный буфер. Когда приложение завершает работу, используя новый экранный буфер, оно вызывает SetConsoleActiveScreenBuffer, чтобы восстановить исходный STDOUT экранный буфер.
1
16.03.2016, 10:02
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.03.2016, 10:02
Помогаю со студенческими работами здесь

Как создать свой шрифт для консольных приложений Windows XP?
я знаю, что у windows используется два шрифта для консоли: 1) Lucida Console - это библиотека...

Установка 64-разрядной поверх 32-разрядной Windows 7
Здравствуйте! купил бук, на нем стоит 7базовая 32бита, можно както поставить 64 не сшибая винду?...

Разработка консольных приложений
Как в консольном приложении обеспечить вывод текста в кодировке 866 (MS-DOS) при наборе его в...

Компиляция консольных приложений VC 6.0
Может быть я совсем дурак, но программировать ни разу не пробовал и даже не знаю с чего начать. Вот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru