На этом шаге мы рассмотрим пример, демонстрирующий основы работы с графикой на ассемблере.
Студент 4 курса факультета математики и информационных технологий Курганского государственного университета Брылев Данил Алексеевич представляет ассемблерную программу, иллюстрирующую использование графики. Здесь можно строить линии, закрашенные и незакрашенные прямоугольники и эллипсы. Кроме того реализованы выбор цветов и толщины линий.
Приведем текст программы.
.386
.model flat, stdcall ;Плоская модель.
option casemap :none ;Директива говоpит MASM сделать метки
;чувствительными к pегистpу.
;Необходимо для безошибочного подключения
;windows.inc-файла.
;Директивы компоновщику для подключения inc-файлов и библиотек.
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\windows.inc
include \masm32\include\comdlg32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comdlg32.lib
;===============================
; Объявление локальных макросов
;===============================
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
m2m MACRO M1, M2
push M2
pop M1
ENDM
return MACRO arg
mov eax, arg
ret
ENDM
;=========================================
; Объявление прототипов локальных функций
;=========================================
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
TopXY PROTO :DWORD,:DWORD
.data
;Название нашего окна
szDisplayName db "Графика в окне",0
;Дескриптор коммандной строки
CommandLine dd ?
;Дескриптор окна
hWnd dd ?
;Дескриптор приложения
hInstance dd ?
;Дескриптор главного меню
hMenu dd ?
;Дескриптор контекста для хранения постоеного изображения
hMemBkDC dd ?
;Дескриптор контекста для хранения строящегося изображения
hMemDC dd ?
;Дескрипторы используемых карандашей и кистей
hPen dd ?
hLBrush dd ?
hRBrush dd ?
hLSPen dd ?
hRSPen dd ?
;Информация о текущих основном и дополнительном цветах
RColor dd 000000h ;clBlack
LColor dd 000080h ;clMaroon
;Структура для хранения координат вершин прямоугольника клиентской области
cRect RECT <?>
;Координаты начальной и текущей точек рисуемых объектов
sPosX dd ?
sPosY dd ?
cPosX dd ?
cPosY dd ?
;Текущий рисуемый объект: 0-ничего,1-лин,2-элл,3-к.элл,4-прям,5-к.прям
sFF db ?
;Текущий выбранный объект: 1-лин,2-элл,3-к.элл,4-прям,5-к.прям
cFF db 1
;Текущая толщина линий
sPen dd 3
;Текущие размеры экрана
XM dd ?
YM dd ?
;Информация о текущих выбранных пунктах меню
Menu103 dd 10301h
Menu104 dd 10401h
Menu105 dd 10500h
Menu106 dd 10603h
;Получаем цвет фона
RGBW equ (80 or (80 shl 8)) or (255 shl 16)
;Массив используемых нами цветов
Color dd 000000h ;clBlack
dd 000080h ;clMaroon
dd 008000h ;clGreen
dd 008080h ;clOlive
dd 800000h ;clNavy
dd 800080h ;clPurple
dd 808000h ;clTeal
dd 808080h ;clGray
dd 0C0C0C0h ;clSilver
dd 0000FFh ;clRed
dd 00FF00h ;clLime
dd 00FFFFh ;clYellow
dd 0FF0000h ;clBlue
dd 0FF00FFh ;clFuchsia
dd 0FFFF00h ;clAqua
dd 0C0C0C0h ;clLtGray
dd 808080h ;clDkGray
dd 0FFFFFFh ;clWhite
;Структура для ChooseColor диалога
cc CHOOSECOLOR <?>
;Массив дополнительных цветов ChooseColor диалога
CCCustColors dd 000000h ;clBlack
dd 000080h ;clMaroon
dd 008000h ;clGreen
dd 008080h ;clOlive
dd 800000h ;clNavy
dd 800080h ;clPurple
dd 808000h ;clTeal
dd 808080h ;clGray
dd 0C0C0C0h ;clSilver
dd 0000FFh ;clRed
dd 00FF00h ;clLime
dd 00FFFFh ;clYellow
dd 0FF0000h ;clBlue
dd 0FF00FFh ;clFuchsia
dd 0FFFF00h ;clAqua
dd 0FFFFFFh ;clWhite
.code
start:
invoke GetModuleHandle, NULL ;Получить дескриптор приложения
mov hInstance, eax
invoke GetCommandLine ;Получить дескриптор коммандной строки
mov CommandLine, eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax ;Выход из программы (завершить процесс).
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
;===============================
; Вводим "локальные" переменные
;===============================
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
szText szClassName,"Class32" ;Имя класса
;================================================
; Заполняем WNDCLASSEX структуру нужными данными
;================================================
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW + CS_VREDRAW + CS_SAVEBITS + CS_OWNDC
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
;Декскриптор кисти фона (NULL-фон рисоваться не будет)
mov wc.hbrBackground, NULL
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
;Читаем стандартную иконку
invoke LoadIcon,7F00h,0
mov wc.hIcon, eax
;Читаем курсор с идентификатором 1000 из ресурсов приложения
invoke LoadCursor,hInst,3e8h
mov wc.hCursor, eax
mov wc.hIconSm, 0
invoke RegisterClassEx, ADDR wc ;Регистрируем класс "Class32"
;Получаем информацию о размерах экрана и по заданным длине
;и ширине окна находим центральное расположение окна
mov Wwd, 500
mov Wht, 300
invoke GetSystemMetrics,SM_CXSCREEN
mov XM,eax
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
mov YM,eax
invoke TopXY,Wht,eax
mov Wty, eax
;Создаем окно зарегестрированного класса
invoke CreateWindowEx,0,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPED + WS_CAPTION + WS_SYSMENU + \
WS_MINIMIZEBOX + WS_MAXIMIZEBOX + WS_THICKFRAME,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
invoke LoadMenu,hInst,2 ;Читаем меню с идентификатором 2
mov hMenu,eax
invoke SetMenu,hWnd,eax ;Привязываем его к нашему окну
;Показываем созданное окно
invoke ShowWindow,hWnd,SW_SHOWNORMAL
;Перерисовываем содержимое окна
invoke UpdateWindow,hWnd
;==========================
; Цикл обработки сообщений
;==========================
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
;Функция обработки сообщений главного окна
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
;===============================
; Вводим "локальные" переменные
;===============================
LOCAL hDC :DWORD
LOCAL Ps :PAINTSTRUCT
.if uMsg == WM_MOUSEMOVE
;Получаем информацию о текущем рисуемом объекте,
;Если ничего не рисуем, то смысла прорисовывать окно нет
.if sFF == 0
return 0
.endif
;Получаем координаты точки местонахождения курсора
;и задаем их как координаты текущей точки рисования
mov ecx, 0h
mov cx, WORD PTR [lParam]
mov cPosX, ecx
mov cx, WORD PTR [lParam+2h]
mov cPosY, ecx
;Копируем изображение с контекста MemBkDC на MemDC
;и дорисовываем русуемый объект в текущем положении
invoke BitBlt,hMemDC,0,0,XM,YM,hMemBkDC,0,0,SRCCOPY
.if sFF == 1
invoke MoveToEx,hMemDC,sPosX,sPosY,NULL
invoke LineTo,hMemDC,cPosX,cPosY
.elseif sFF == 2
invoke Ellipse,hMemDC,cPosX,cPosY,sPosX,sPosY
.elseif sFF == 4
invoke Rectangle,hMemDC,cPosX,cPosY,sPosX,sPosY
.elseif sFF == 3
invoke Arc,hMemDC,cPosX,cPosY,sPosX,sPosY,0,0,0,0
.elseif sFF == 5
invoke MoveToEx,hMemDC,sPosX,sPosY,NULL
invoke LineTo,hMemDC,cPosX,sPosY
invoke LineTo,hMemDC,cPosX,cPosY
invoke LineTo,hMemDC,sPosX,cPosY
invoke LineTo,hMemDC,sPosX,sPosY
.endif
;Перерисовываем содержимое окна
invoke RedrawWindow,hWin,NULL,NULL,RDW_INVALIDATE
return 0
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWnd,ADDR Ps
mov hDC,eax
;Копируем изображение с контекста MemDC на контекст окна
invoke BitBlt,hDC,0,0,cRect.right,cRect.bottom,hMemDC,0,0,SRCCOPY
invoke EndPaint,hWnd,ADDR Ps
return 0
.elseif uMsg == WM_LBUTTONDOWN
;Получаем координаты точки нажатия кнопки мыши
;и задаем их как координаты начальной точки рисования
;И эти же координаты задаем координатми текущей точки,
;чтобы не возникало рисования фигуры из прошлой текущей точки
;при нажатии и отпускании кнопки в одной и той же точке без движения
mov ecx, 0h
mov cx, WORD PTR [lParam]
mov sPosX, ecx
mov cPosX, ecx
mov cx, WORD PTR [lParam+2h]
mov sPosY, ecx
mov cPosY, ecx
;Задаем информацию о текущем рисуемом объекте(sFF) в соответствии с
;выбранным инструментом(cFF)
mov cl,cFF
mov sFF,cl
;Выбираем карандаши и кисти в зависимости от рисуемого объекта
.if (cFF == 1) || (cFF == 3) || (cFF == 5)
invoke SelectObject,hMemDC,hLSPen
.elseif (cFF == 2) || (cFF == 4)
invoke SelectObject,hMemDC,hPen
invoke SelectObject,hMemDC,hLBrush
.endif
return 0
.elseif uMsg == WM_RBUTTONDOWN
mov ecx, 0h
mov cx, WORD PTR [lParam]
mov sPosX, ecx
mov cPosX, ecx
mov cx, WORD PTR [lParam+2h]
mov sPosY, ecx
mov cPosY, ecx
mov cl,cFF
mov sFF,cl
.if (cFF == 1) || (cFF == 3) || (cFF == 5)
invoke SelectObject,hMemDC,hRSPen
.elseif (cFF == 2) || (cFF == 4)
invoke SelectObject,hMemDC,hPen
invoke SelectObject,hMemDC,hRBrush
.endif
return 0
.elseif uMsg == WM_LBUTTONUP
;Завершаем рисование копированием полученного изображения
mov sFF,0
invoke BitBlt,hMemBkDC,0,0,XM,YM,hMemDC,0,0,SRCCOPY
return 0
.elseif uMsg == WM_RBUTTONUP
mov sFF,0
invoke BitBlt,hMemBkDC,0,0,XM,YM,hMemDC,0,0,SRCCOPY
return 0
.elseif uMsg == WM_COMMAND
cmp wParam,10101h ;<<<< Пункт меню "Файл" -> "Выход"
jne @F
invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
return 0
@@:
cmp wParam,10201h ;<<<< Пункт меню "Правка" -> "Очистить"
jne @F
;Здесь мы не выбираем кисть для контекста MemBkDC, так как не меняли
;ее после заполнения его изображения в момент создания окна
invoke PatBlt,hMemBkDC,0,0,XM,YM,PATCOPY
invoke BitBlt,hMemDC,0,0,XM,YM,hMemBkDC,0,0,SRCCOPY
invoke RedrawWindow,hWin,NULL,NULL,RDW_INVALIDATE
return 0
@@:
;Обрабатываем выбор пунктов меню "Инструменты"
cmp wParam,10301h
jb @F
cmp wParam,10305h
ja @F
;Сбрасываем "галочку" у прошлого выбранного пункта
invoke CheckMenuItem,hMenu,Menu103,MF_UNCHECKED
m2m Menu103,wParam
;Ставим "галочку" у соответствующего пункта меню
invoke CheckMenuItem,hMenu,wParam,MF_CHECKED
;Получаем относительный номер выбранного подпункта
;(Последний байт идентификатора)
mov cl,Byte Ptr [wParam]
;Выбираем текущий инструмент
mov cFF,cl
return 0
@@:
;Обрабатываем выбор пунктов меню "Инструменты" -> "Основной цвет"
cmp wParam,10400h
jb @F
cmp wParam,10412h
ja @F
invoke CheckMenuItem,hMenu,Menu104,MF_UNCHECKED
m2m Menu104,wParam
invoke CheckMenuItem,hMenu,wParam,MF_CHECKED
;Если выбран пункт "Другой...", то вызываем ChooseColor диалог.
;И задаем информацию о текущем выбранном основном цвете LColor
.if wParam == 10412h
m2m cc.rgbResult,LColor
invoke ChooseColor,offset cc
m2m LColor,cc.rgbResult
.else
xor ecx,ecx
mov cl, Byte Ptr [wParam]
m2m LColor,DWord Ptr [Color+ecx*4]
.endif
;Создаем кисть и карандаш выбранного цвета
invoke DeleteObject,hLBrush
invoke DeleteObject,hLSPen
invoke CreateSolidBrush,LColor
mov hLBrush,eax
invoke CreatePen,PS_SOLID,sPen,LColor
mov hLSPen,eax
return 0
@@:
;Обрабатываем выбор пунктов меню "Инструменты" -> "Дополнительный цвет"
cmp wParam,10500h
jb @F
cmp wParam,10512h
ja @F
invoke CheckMenuItem,hMenu,Menu105,MF_UNCHECKED
m2m Menu105,wParam
invoke CheckMenuItem,hMenu,wParam,MF_CHECKED
.if wParam == 10512h
m2m cc.rgbResult,RColor
invoke ChooseColor,offset cc
m2m RColor,cc.rgbResult
.else
xor ecx,ecx
mov cl, Byte Ptr [wParam]
m2m RColor,DWord Ptr [Color+ecx*4]
.endif
invoke DeleteObject,hRBrush
invoke DeleteObject,hRSPen
invoke CreateSolidBrush,RColor
mov hRBrush,eax
invoke CreatePen,PS_SOLID,sPen,RColor
mov hRSPen,eax
return 0
@@:
;Обрабатываем выбор пунктов меню "Инструменты" -> "Толщина линий"
cmp wParam,10601h
jb @F
cmp wParam,10605h
ja @F
invoke CheckMenuItem,hMenu,Menu106,MF_UNCHECKED
m2m Menu106,wParam
invoke CheckMenuItem,hMenu,wParam,MF_CHECKED
xor ecx,ecx
mov cl, Byte Ptr [wParam]
mov sPen, ecx
;Создаем новые карандаши выбранной толщины
invoke DeleteObject,hRSPen
invoke DeleteObject,hLSPen
invoke CreatePen,PS_SOLID,sPen,RColor
mov hRSPen,eax
invoke CreatePen,PS_SOLID,sPen,LColor
mov hLSPen,eax
@@:
return 0
.elseif uMsg == WM_SIZE
;Получаем информацию о текущих размерах клиентской области окна
invoke GetClientRect,hWin,ADDR cRect
return 0
.elseif uMsg == WM_CREATE
;Получаем дескриптор контекста окна.
invoke GetDC,hWin
mov hDC,eax
;Создаем совместимые с данным контекстом контексты.
invoke CreateCompatibleDC,eax
mov hMemBkDC, eax
invoke CreateCompatibleDC,hDC
mov hMemDC, eax
;Создаем в памяти растровое изображение, совместимое с hDC.
invoke CreateCompatibleBitmap,hDC,XM,YM
;Выбраем растровое изображение в данном контексте.
invoke SelectObject,hMemBkDC,eax
invoke CreateCompatibleBitmap,hDC,XM,YM
invoke SelectObject,hMemDC,eax
;Создаем кисть цвета фона и заполняем ей растровые изображения контекстов
invoke CreateSolidBrush,RGBW
mov hLBrush,eax
invoke SelectObject,hMemBkDC,eax
invoke PatBlt,hMemBkDC,0,0,XM,YM,PATCOPY
invoke SelectObject,hMemDC,hLBrush
invoke PatBlt,hMemDC,0,0,XM,YM,PATCOPY
;Освобождаем контекст и удаляем кисть
invoke ReleaseDC,hWin,hDC
invoke DeleteObject,hLBrush
invoke GetClientRect,hWin,ADDR cRect
;Создаем невидимый карандаш, используемый
;интсрументами "Прямоугольник" и "Эллипс"
invoke CreatePen,PS_NULL,1,0
mov hPen,eax
;Создаем карандаши и кисти начальных цветов и заданных парамметров
invoke CreatePen,PS_SOLID,sPen,LColor
mov hLSPen,eax
invoke CreatePen,PS_SOLID,sPen,RColor
mov hRSPen,eax
invoke CreateSolidBrush,RColor
mov hRBrush,eax
invoke CreateSolidBrush,LColor
mov hLBrush,eax
;Заполняем CHOOSECOLOR структуру, для вызова ChooseColor диалога
mov cc.lStructSize, sizeof CHOOSECOLOR
m2m cc.hwndOwner, hWin
m2m cc.hInstance, hInstance
mov cc.lpCustColors, offset CCCustColors
mov cc.Flags, CC_RGBINIT
return 0
.elseif uMsg == WM_DESTROY
;Удаляем созданные объекты
invoke DeleteObject,hRSPen
invoke DeleteObject,hLSPen
invoke DeleteObject,hPen
invoke DeleteObject,hRBrush
invoke DeleteObject,hLBrush
invoke DeleteDC,hMemBkDC
invoke DeleteDC,hMemDC
invoke PostQuitMessage,NULL
return 0
.endif
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
;Функция для центрирования окна
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim,1 ;Делим характеристику экрана на 2
shr wDim,1 ;Делим характеристику окна на 2
mov eax,wDim ;Копируем характеристику окна в eax
sub sDim,eax ;Вычитаем половину характеристики окна из половины
;характеристики экрана
return sDim
TopXY endp
end start
Файл ресурсов.
#include "c:\masm32\include\resource.h" ///////////////////////////////////////////////////////////////////////////// // Cursor 1000 CURSOR "Cursor.cur" ///////////////////////////////////////////////////////////////////////////// // Menu 2 MENUEX BEGIN POPUP "&Файл", 0x10100,MFT_STRING,MFS_ENABLED BEGIN MENUITEM "В&ыход", 0x10101,MFT_STRING,MFS_ENABLED END POPUP "Правка", 0x10200,MFT_STRING,MFS_ENABLED BEGIN MENUITEM "Очистить", 0x10201,MFT_STRING,MFS_ENABLED END POPUP "Инструменты", 0x10300,MFT_STRING,MFS_ENABLED BEGIN POPUP "Основной цвет", 0x10300,MFT_STRING,MFS_ENABLED BEGIN MENUITEM "Black", 0x10400,MFT_STRING,MFS_ENABLED MENUITEM "Maroon", 0x10401,MFT_STRING,MFS_CHECKED MENUITEM "Green", 0x10402,MFT_STRING,MFS_ENABLED MENUITEM "Olive", 0x10403,MFT_STRING,MFS_ENABLED MENUITEM "Navy", 0x10404,MFT_STRING,MFS_ENABLED MENUITEM "Purple", 0x10405,MFT_STRING,MFS_ENABLED MENUITEM "Teal", 0x10406,MFT_STRING,MFS_ENABLED MENUITEM "Gray", 0x10407,MFT_STRING,MFS_ENABLED MENUITEM "Silver", 0x10408,MFT_STRING,MFS_ENABLED MENUITEM "Red", 0x10409,MFT_STRING,MFS_ENABLED MENUITEM "Lime", 0x1040A,MFT_STRING,MFS_ENABLED MENUITEM "Yellow", 0x1040B,MFT_STRING,MFS_ENABLED MENUITEM "Blue", 0x1040C,MFT_STRING,MFS_ENABLED MENUITEM "Fuchsia", 0x1040D,MFT_STRING,MFS_ENABLED MENUITEM "Aqua", 0x1040E,MFT_STRING,MFS_ENABLED MENUITEM "Light Gray", 0x1040F,MFT_STRING,MFS_ENABLED MENUITEM "Dark Gray", 0x10410,MFT_STRING,MFS_ENABLED MENUITEM "White", 0x10411,MFT_STRING,MFS_ENABLED MENUITEM "Другой...", 0x10412,MFT_STRING,MFS_ENABLED END POPUP "Дополнительный цвет", 0x10300,MFT_STRING,MFS_ENABLED BEGIN MENUITEM "Black", 0x10500,MFT_STRING,MFS_CHECKED MENUITEM "Maroon", 0x10501,MFT_STRING,MFS_ENABLED MENUITEM "Green", 0x10502,MFT_STRING,MFS_ENABLED MENUITEM "Olive", 0x10503,MFT_STRING,MFS_ENABLED MENUITEM "Navy", 0x10504,MFT_STRING,MFS_ENABLED MENUITEM "Purple", 0x10505,MFT_STRING,MFS_ENABLED MENUITEM "Teal", 0x10506,MFT_STRING,MFS_ENABLED MENUITEM "Gray", 0x10507,MFT_STRING,MFS_ENABLED MENUITEM "Silver", 0x10508,MFT_STRING,MFS_ENABLED MENUITEM "Red", 0x10509,MFT_STRING,MFS_ENABLED MENUITEM "Lime", 0x1050A,MFT_STRING,MFS_ENABLED MENUITEM "Yellow", 0x1050B,MFT_STRING,MFS_ENABLED MENUITEM "Blue", 0x1050C,MFT_STRING,MFS_ENABLED MENUITEM "Fuchsia", 0x1050D,MFT_STRING,MFS_ENABLED MENUITEM "Aqua", 0x1050E,MFT_STRING,MFS_ENABLED MENUITEM "Light Gray", 0x1050F,MFT_STRING,MFS_ENABLED MENUITEM "Dark Gray", 0x10510,MFT_STRING,MFS_ENABLED MENUITEM "White", 0x10511,MFT_STRING,MFS_ENABLED MENUITEM "Другой...", 0x10512,MFT_STRING,MFS_ENABLED END POPUP "Толщина линий", 0x10600,MFT_STRING,MFS_ENABLED BEGIN MENUITEM "1 пикс.", 0x10601,MFT_STRING,MFS_ENABLED MENUITEM "2 пикс.", 0x10602,MFT_STRING,MFS_ENABLED MENUITEM "3 пикс.", 0x10603,MFT_STRING,MFS_CHECKED MENUITEM "4 пикс.", 0x10604,MFT_STRING,MFS_ENABLED MENUITEM "5 пикс.", 0x10605,MFT_STRING,MFS_ENABLED END MENUITEM MFT_SEPARATOR MENUITEM "Линия", 0x10301,MFT_STRING,MFS_CHECKED MENUITEM "Эллипс", 0x10302,MFT_STRING,MFS_ENABLED MENUITEM "Контур эллипса", 0x10303,MFT_STRING,MFS_ENABLED MENUITEM "Прямоугольник", 0x10304,MFT_STRING,MFS_ENABLED MENUITEM "Контур прямоугольника", 0x10305,MFT_STRING,MFS_ENABLED END END ///////////////////////////////////////////////////////////////////////////// // Version 1 VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x17L FILEFLAGS 0x1L FILEOS 0x4L FILETYPE 0x0L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "041904b0" BEGIN VALUE "CompanyName", "it.kgsu.ru" VALUE "LegalCopyright", "Copyright (C) 2006" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x419, 1200 END END
Результат работы приложения изображен на рисунке 1:

Рис.1. Результат работы приложения
Данил Алексеевич так прокомментировал свою программу.
Вызываемые функции:
Локальные функции:
Со следующего шага мы начнем рассматривать основы анализа кода программ.