Шаг 115.
Небольшое отступление: демонстрация основ работы с графикой

    На этом шаге мы рассмотрим пример, демонстрирующий основы работы с графикой на ассемблере.

    Студент 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. Результат работы приложения

    Данил Алексеевич так прокомментировал свою программу.

    Вызываемые функции:

    Локальные функции:

    Со следующего шага мы начнем рассматривать основы анализа кода программ.




Предыдущий шаг Содержание Следующий шаг