Tasm, задание случайного цвета шрифта - Assembler
Формулировка задачи:
Здравствуйте! создаю простейшее оконное приложение для виндовс
подскажите пожалуйста в каком месте задается цвет шрифта? как задать его рендомно при запуске программы?
в моем понимании это происходит вот здесь
но вот как задать случайный цвет?..
помогите пожалуйста!
заранее спасибо всем участвующим
.386
locals
jumps
.model flat,STDCALL
include win32.inc
L equ <LARGE>
Extrn BeginPaint:PROC ;начало блока перерисовки окна
Extrn CreateWindowExA:PROC ;создать окно
Extrn DefWindowProcA:PROC ;процедура обработки сообщений ;по-умолчанию
Extrn DispatchMessageA:PROC ;процедура передачи сообщения оконному обработчику сооб-щений
Extrn EndPaint:PROC ;завершение блока перерисовки ок-на
Extrn ExitProcess:PROC ;завершение программы
extrn FindWindowA:PROC ;поиск окна в ОС
extrn GetMessageA:PROC ;принять сообщение из системной ;очереди
extrn GetModuleHandleA:PROC ;получить описатель модуля
extrn GetStockObject:PROC ;получить описатель основного пера,
extrn InvalidateRect:PROC ;объявление недостоверности области
extrn LoadCursorA:PROC ;загузить иконку курсора
extrn LoadIconA:PROC ;загрузить пиктограмму
extrn MessageBeep:PROC ;издать звуковой сигнал
extrn MessageBoxA:PROC ;выдать системное окно с сообщением
extrn PostQuitMessage:PROC ;послать сообщение о выходе из
extrn RegisterClassA:PROC ;регистрация класса окна
extrn ShowWindow:PROC ;показать окно на экране
extrn SetWindowPos:PROC ;изменяет размер, положение и поря-док
extrn TextOutA:PROC ;вывод текста в окно
extrn TranslateMessage:PROC ;обработка сообщений от клавиатуры
extrn UpdateWindow:PROC ;обновить окно
CreateWindowEx equ <CreateWindowExA>
DefWindowProc equ <DefWindowProcA>
DispatchMessage equ <DispatchMessageA>
FindWindow equ <FindWindowA>
GetMessage equ <GetMessageA>
GetModuleHandle equ <GetModuleHandleA>
LoadCursor equ <LoadCursorA>
LoadIcon equ <LoadIconA>
MessageBox equ <MessageBoxA>
RegisterClass equ <RegisterClassA>
TextOut equ <TextOutA>
.data
newhwnd dd 0 ;ячейку для хранения описателя (хэндела) нового окна.
lppaint PAINTSTRUCT <?> ;структура для перерисовки изображе-ния.
msg MSGSTRUCT <?> ;структура системного сообщения.
wc WNDCLASS <?> ;структура для регистрации окна.
mbx_count dd 0 ;ячейка - счетчик нажатий левой клавиши мыши.
hInst dd 0 ;ячейка для хранения системного указателя (хэндела)
;нашей программы.
szTitleName db 'Win32 Assembly Program' ;текст заголовка окна ;программы.
zero db 0 ;и его замыкающий ноль.
szAlternate db '(Secondary)',0 ;текст для изменения заголовка окна, ес-ли ;приложение запущено повторно.
szClassName db 'ASMCLASS32',0 ;придуманное нами имя класса окна,
;под которым будем регистрировать-ся.
szPaint db 'Левая кнопка нажата:' ;текст сообщения
s_num db '00000000h --раз.',0 ;в окне программы.
MSG_L EQU ($-offset szPaint)-1
.code
start:
push L 0 ;подготовим стэк к запуску процедуры
call GetModuleHandle ;выполним процедуру (результат в EAX)
mov [hInst], eax ;поместим полученный хэндел на ;подготовленное для него место
push L 0
push offset szClassName
call FindWindow
or eax,eax
jz reg_class
mov [zero], ' '
reg_class:
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
mov [wc.clsLpfnWndProc], offset WndProc
mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra], 0
mov eax, [hInst]
mov [wc.clsHInstance], eax
push L IDI_APPLICATION
push L 0
call LoadIcon
mov [wc.clsHIcon], eax
push L IDC_ARROW
push L 0
call LoadCursor
mov [wc.clsHCursor], eax
mov [wc.clsHbrBackground], COLOR_WINDOW + 1
mov dword ptr [wc.clsLpszMenuName], 0
mov dword ptr [wc.clsLpszClassName], offset szClassName
push offset wc
call RegisterClass
push L 0 ; параметры создания окна
push [hInst] ; описатель (хэндел) нашего приложения
push L 0 ; описатель оконного меню
push L 0 ; описатель родительского окна
push L CW_USEDEFAULT ; высота окна
push L CW_USEDEFAULT ; ширина окна
push L CW_USEDEFAULT ; координата y окна
push L CW_USEDEFAULT ; координата x окна
push L WS_OVERLAPPEDWINDOW ; стиль окна
push offset szTitleName ; строка заголовка окна
push offset szClassName ; имя класса окна
push L 0 ; расширенный стиль окна
call CreateWindowEx
mov [newhwnd], eax
push L SW_SHOWNORMAL ;режим показа окна на экране -
push [newhwnd] ;описатель окна, подлежащего показу на экране
call ShowWindow
push [newhwnd]
call UpdateWindow
msg_loop:
push L 0
push L 0
push L 0
push offset msg
call GetMessage
cmp ax, 0
je end_loop
push offset msg
call TranslateMessage
push offset msg
call DispatchMessage
jmp msg_loop
end_loop:
push [msg.msWPARAM]
call ExitProcess
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
LOCAL theDC:DWORD
cmp [wmsg], WM_DESTROY ;если - уничтожить окно?
je wmdestroy ;то перейти на уничтожение
cmp [wmsg], WM_RBUTTONDOWN ;нажата правая клавиша мы-ши?
je wmrbuttondown ;то перейти на обработку этого нажатия
cmp [wmsg], WM_SIZE ;изменен размер окна?
je wmsize
cmp [wmsg], WM_CREATE ;команда создать окно?
je wmcreate
cmp [wmsg], WM_LBUTTONDOWN ;нажата левая клавиша мыши?
je wmlbuttondown
cmp [wmsg], WM_PAINT ;это команда на перерисовку окна?
je wmpaint
cmp [wmsg], WM_GETMINMAXINFO ;минимизировать/
je wmgetminmaxinfo
jmp defwndproc ;иначе перейти на обработчик сообщений
wmpaint:
push offset lppaint
push [hwnd]
call BeginPaint
mov [theDC], eax
mov eax, [mbx_count]
mov edi, offset s_num
call HexWrite32
push L MSG_L ;длина строки
push offset szPaint ;адрес строки для вывода
push L 5 ;координата Y где выводится строка
push L 5 ;координата X где выводится строка
push [theDC] ;контекст устройства, через которое идет вывод
call TextOut
push offset lppaint
push [hwnd]
call EndPaint
wmcreate:
mov eax, 0
jmp finish
defwndproc:
push [lparam]
push [wparam]
push [wmsg]
push [hwnd]
call DefWindowProc
jmp finish
wmdestroy:
push L 0
call PostQuitMessage
mov eax, 0
jmp finish
wmlbuttondown:
inc [mbx_count]
push L 0
push L 0
push [hwnd]
call InvalidateRect
mov eax, 0
jmp finish
wmrbuttondown:
push L 0
call MessageBeep
wmsize:
mov eax, 0
jmp finish
wmgetminmaxinfo:
mov ebx, [lparam] ; указатель на структуру minmaxinfo
mov [(MINMAXINFO ptr ebx).mintrackposition_x] , 350
mov [(MINMAXINFO ptr ebx).mintrackposition_y] , 60
mov eax, 0
finish:
ret
WndProc endp
HexWrite8 proc
mov ah, al ;это число дублируется в ah
and al, 0fh ;затем в al оставляют младшую тетраду числа
shr ah, 4 ;а в ah - старшую
or ax, 3030h ;кадый нибл дополняется единицами (преобразуется в
;символ)
xchg al, ah ;байты меняются местами (так отображается на экране)
cmp ah, 39h ;идет сравнение старшего байта с символом '9'
ja @@4 ;переход, если символ оказался выше 9
@@1:
cmp al, 39h ;идет сравнение младшего байта с символом '9'
ja @@3 ;переход, если символ оказался выше 9
@@2:
stosw ;слово из AX заносится по адресу ES:EDI
ret
@@3:
sub al, 30h ;у числа убираются биты, переводящие его в символ
add al, 'A' - 10 ;затем снова добавляются, переводя число в букву
jmp @@2
@@4:
sub ah, 30h ;у числа убираются биты, переводящие его в символ
add ah, 'A'-10 ;затем снова добавляются, переводя число в букву
jmp @@1
HexWrite8 endp
HexWrite16 proc
push ax
xchg al,ah
call HexWrite8
pop ax
call HexWrite8
ret
HexWrite16 endp
HexWrite32 proc
push eax
shr eax, 16
call HexWrite16
pop eax
call HexWrite16
ret
HexWrite32 endp
public WndProc
ends
end startpush L MSG_L ;длина строки
push offset szPaint ;адрес строки для вывода
push L 5 ;координата Y где выводится строка
push L 5 ;координата X где выводится строка
push [theDC] ;контекст устройства, через которое идет вывод
call TextOutРешение задачи: «Tasm, задание случайного цвета шрифта»
textual
Листинг программы
extrn UpdateWindow:PROC ;обновить окно extrn SetTextColor;
Объяснение кода листинга программы
Обновить окно- вызывает процедуру обновления окна, чтобы изменения, сделанные в коде, отображались на экране.SetTextColor- устанавливает цвет текста для выбранного окна.BM_GETCH- получает текущий цвет шрифта из выбранного окна.BM_SETCH- устанавливает новый цвет шрифта для выбранного окна.BM_GETBUF- получает текущий буфер обмена из выбранного окна.BM_SETBUF- устанавливает новый буфер обмена для выбранного окна.BM_GETMODE- получает текущий режим отображения выбранного окна.BM_SETMODE- устанавливает новый режим отображения для выбранного окна.BM_GETMAP- получает текущую карту выбранного окна.BM_SETMAP- устанавливает новую карту для выбранного окна.BM_GETPIX- получает текущий пиксель выбранного окна.BM_SETPIX- устанавливает новый пиксель для выбранного окна.BM_GETSIZE- получает текущий размер выбранного окна.BM_SETSIZE- устанавливает новый размер для выбранного окна.BM_GETZOOM- получает текущий уровень масштабирования выбранного окна.BM_SETZOOM- устанавливает новый уровень масштабирования для выбранного окна.BM_GETSEL- получает текущий выделенный текст в выбранном окне.BM_SETSEL- устанавливает новый выделенный текст для выбранного окна.BM_GETVIEW- получает текущий вид выбранного окна.BM_SETVIEW- устанавливает новый вид для выбранного окна.