Для решения задачи попробуем
несколько сместить точку зрения. До сих
пор, реализовывалась виртуальность фигур
в рамках действий над этими фигурами.
Теперь попробуем реализовать виртуальность
действий по отношению к фигурам, ведь,
в конце концов, нам надо реализовать матрицу
из множества действий для множества фигур.
Поэтому переключающие вектора теперь извлечём
из подпрограмм, реализующих действия,
и разместим вне этих подпрограмм. Содержимым
векторов по-прежнему останутся конкретные
обработчики для конкретных фигур.
Представим это решение:
enum Figures line,
rectangle, circle
MaxFigure = circle
enum Actions Draw, Hide, Select, Drag
MaxActions = Drag
;объявляем типы
Struc tLine
x |
dd |
? |
; x - координата
якорной точки |
y |
dd |
? |
; y - координата
якорной точки |
x1 |
dd |
? |
; x – координата
конца линии |
y1 |
dd |
? |
; y – координата
конца линии |
ends tLine
TYPEDEF LineRef PTR tLine
Struc tRectangle
x |
dd |
? |
; x – координата
якорной точки |
y |
dd |
? |
; y – координата
якорной точки |
width |
dd |
? |
; ширина прямоугольника |
height |
dd |
? |
; высота прямоугольника |
ends tRectangle
TYPEDEF RectangleRef PTR tRectangle
Struc tCircle
x |
dd |
? |
; x – координата
якорной точки |
y |
dd |
? |
; y - координата
якорной точки |
radius |
dd |
? |
; радиус окружности |
ends tCircle
TYPEDEF CircleRef PTR tCircle
DataSeg
; создаём вектора-переключатели
(virtual tables) |
Label |
vectorLine |
:dword |
|
dd |
offset |
LineDraw |
|
dd |
offset |
LineHide |
|
dd |
offset |
LineSelect |
|
dd |
offset |
CommonDrag |
Label |
vectorRectangle |
:dword |
|
dd |
offset |
RectangleDraw |
|
dd |
offset |
RectangleHide |
|
dd |
offset |
RectangleSelect |
|
dd |
offset |
CommonDrag |
Label |
vectorCircle |
:dword |
|
dd |
offset |
CircleDraw |
|
dd |
offset |
CircleHide |
|
dd |
offset |
CircleSelect |
|
dd |
offset |
CommonDrag |
;
создаём экземпляры типов, объявленных
ранее |
aLine |
tLine |
<20, 20, 10,
15> |
; линия |
aRectangle |
tRectangle |
<10, 10, 20,
20> |
; прямоугольник |
aCircle |
tCircle |
<20, 20, 10> |
; окружность |
CodeSeg
Start: |
; начинаем программу |
|
... |
|
; рисуем линию |
|
call [Draw *
4 + vectorLine], offset aLine |
|
... |
|
; прячем прямоугольник |
|
call [Hide *
4 + vectorRectangle], offset
aRectangle |
|
... |
|
; выбираем окружность |
|
call [Select
* 4 + vectorCircle], offset
aCircle |
|
... |
Proc LineDraw
Arg |
@@ref |
:LineRef |
|
;
рисуем линию |
|
ret |
endp LineDraw
Proc LineHide
Arg |
@@ref |
:LineRef |
|
;
прячем линию |
|
ret |
endp LineHide
Proc LineSelect
Arg |
@@ref |
:LineRef |
|
;
выбираем линию |
|
ret |
endp LineSelect
Proc CommonDrag
Arg |
@@ref |
:dword |
|
;
перетаскиваем фигуру |
|
ret |
endp CommonDrag
Proc RectangleDraw
Arg |
@@ref |
:RectangleRef |
|
;
рисуем прямоугольник |
|
ret |
endp RectangleDraw
Proc RectangleHide
Arg |
@@ref |
:RectangleRef |
|
;
прячем прямоугольник |
|
ret |
endp RectangleHide
Proc RectangleSelect
Arg |
@@ref |
:RectangleRef |
|
;
выбираем прямоугольник |
|
ret |
endp RectangleSelect
Proc CircleDraw
Arg |
@@ref |
:CircleRef |
|
;
рисуем окружность |
|
ret |
endp CircleDraw
Proc CircleHide
Arg |
@@ref |
:CircleRef |
|
;
прячем окружность |
|
ret |
endp CircleHide
Proc CircleSelect
Arg |
@@ref |
:CircleRef |
|
;
выбираем окружность |
|
ret |
endp CircleSelect
... |
; продолжение
программы |
end Start |
; завершение
программы |
|
|