Смекни!
smekni.com

Багатокритеріальна задача лінійного програмування (стр. 16 из 17)

Else if InSolving then

Begin

If Self. CurGridSolveCol=ACol then {якщо це розв'язувальний стовпець:}

Begin

If Self. CurGridSolveRow=ARow then {якщо це розв'язувальна комірка:}

CurColor:=lwc_SolveCellColor

Else CurColor:=lwc_SolveColColor;

End{Якщо це розв'язувальний рядок (але не розв'язувальна комірка):}

Else if Self. CurGridSolveRow=ARow then CurColor:=lwc_SolveRowColor;

End;

End;

{Зафарбовуємо комірки-заголовки стовпців коефіцієнтів при змінних

відповідно до масиву поміток про залежність:}

If (ARow=Self.CHeadRowNum) and

(Not (ACol<(Self.CHeadColNum+bc_LTaskColsBeforeVars))) then

Begin

CurVarColState:=Self. CurHeadRow [ACol – Self.CHeadColNum-

bc_LTaskColsBeforeVars].ElmType;

CurColor:=GetColorByElmType(CurVarColState)

End;

If CurColor<>bc_NotColored then {якщо комірку треба пофарбувати:}

Begin {Малюємо текст на фоні з кольором CurColor:}

CurGrid. Canvas. Brush. Color:=CurColor;

CurGrid. Canvas. TextRect (Rect, Rect. Left, Rect. Top,

CurGrid. Cells [ACol, ARow]);

End;

CurGrid. Canvas. Brush. Color:=SafeBrushColor;

End;

End;

procedure TGridFormattingProcs. EdLineTaskOnDblClick (Sender: TObject);

{Процедура реагує на подвійне натискання лівою кнопкою миші на

комірки рядка-заголовка таблиці (другий рядок StringGrid).

Редагує масив позначок про обрані стовпці (SipmlexVarsDependencyRec)

залежних змінних. Залежні змінні – це змінні, для яких є умова

невід'ємності. Тобто вони не повинні бути менше нуля.}

Var CurGrid:TStringGrid; CurCol, CurRow: Integer;

MouseCoordsInGrid:TPoint;

Begin

If Sender=Nil then Exit;

{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}

If @Self. OldOnDblClick<>Nil then Self. OldOnDblClick(Sender);

If Sender is TStringGrid then

Begin

CurGrid:=TStringGrid(Sender);

{Пробуємо узнати, на яку комірку двічі натиснула миша:}

MouseCoordsInGrid:=CurGrid. ScreenToClient (Mouse. CursorPos);

CurCol:=-1; CurRow:=-1;

CurGrid. MouseToCell (MouseCoordsInGrid.X, MouseCoordsInGrid.Y, CurCol, CurRow);

{Якщо натиснуто на комірку-заголовок стовпця коефіцієнтів при змінній, то:}

If ((CurCol>=(Self.CHeadColNum+bc_LTaskColsBeforeVars)) and

(CurCol<(CurGrid. ColCount-bc_LTaskColsAfterVars))) and

(CurRow=Self.CHeadRowNum) then

Begin

{Змінюємо ознаку залежності відповідної змінної:}

If CurHeadRow [CurCol – Self.CHeadColNum-

bc_LTaskColsBeforeVars].ElmType=bc_IndependentVar then

CurHeadRow [CurCol – Self.CHeadColNum-

bc_LTaskColsBeforeVars].ElmType:=bc_DependentVar

Else

CurHeadRow [CurCol – Self.CHeadColNum-

bc_LTaskColsBeforeVars].ElmType:=bc_IndependentVar;

{Задаємо перемалювання комірок, щоб відобразилася зміна позначки

для змінної:}

CurGrid. Invalidate;

End;

End;

End;

Procedure TGridFormattingProcs. InitGridPopupMenu (SGrid:TStringGrid);

{Процедура перевіряє наявність об'єкта TPopupMenu. Якщо його немає

(SGrid. PopupMenu=Nil), то створює новий.

Видаляє усі пунтки (елементи, теми) з меню.}

Begin

If SGrid. PopupMenu=Nil then

Begin

SGrid. PopupMenu:=TPopupMenu. Create(Application);

End;

SGrid. PopupMenu. AutoPopup:=False;

SGrid. PopupMenu. Items. Clear;

End;

Procedure TGridFormattingProcs. ProcOnCellTypeSelInMenu (Sender: TObject);

{Обробник вибору пункту в меню типів для комірки

рядка – чи стовпця-заголовка.}

Constsc_CurProcName='ProcOnCellTypeSelInMenu';

ProcedureReportUnsupportedCell;

Begin

{Відображає координати комірки з повідомленням про те, що вона

не підтримується:}

If Self. CurOutConsole<>Nil then

Begin

Self. CurOutConsole. Lines. Add (sc_CurProcName + sc_NoCellOrNotSupported+

' ['+IntToStr (Self. CurGridSolveCol)+';'+IntToStr (Self. CurGridSolveRow)+

']… ');

End;

End;

Var CurMenuItem:TMenuItem; TypeForCell:THeadLineElmType;

Begin

If (Sender=Nil) or (Not (Sender is TMenuItem)) then

Begin

If Self. MemoForOutput<>Nil then

Self. MemoForOutput. Lines. Add (sc_CurProcName + sc_CantDetMenuItem);

Exit;

End;

{Читаємо тип, що обраний для комірки:}

CurMenuItem:=TMenuItem(Sender);

TypeForCell:=THeadLineElmType (CurMenuItem. Tag);

If (Self. CurGridSolveCol<0) and (Self. CurGridSolveRow<0) then

Begin {якщо комірка вище чи лівіше заголовків таблиці:}

ReportUnsupportedCell; Exit;

End;

{Перевіряємо координати комірки і змінюємо її тип:}

{координати комірки мають бути записані у CurGridSolveRow і CurGridSolveCol:}

If Self. CurGridSolveRow=-bc_LTaskRowsBeforeVars then

Begin{якщо це комірка рядка-заголовка:}

If Length (Self. CurHeadRow)>Self. CurGridSolveCol then {якщо комірка існує:}

Begin {задаємо тип комірки:}

Self. CurHeadRow [Self. CurGridSolveCol].ElmType:=TypeForCell;

End

Else{якщо в рядку-заголовку немає такої комірки:}

Begin

ReportUnsupportedCell; Exit;

End;

End

Else if Self. CurGridSolveCol=-bc_LTaskColsBeforeVars then

Begin {якщо це комірка стовпця-заголовка:}

If Length (Self. CurHeadCol)>Self. CurGridSolveRow then {якщо комірка існує:}

Begin {задаємо тип комірки:}

Self. CurHeadCol [Self. CurGridSolveRow].ElmType:=TypeForCell;

End

Else {якщо в стовпці-заголовку немає такої комірки:}

Begin

ReportUnsupportedCell; Exit;

End;

End

Else {якщо комірка у таблиці коефіцієнтів або правіше чи нижче неї:}

Begin

ReportUnsupportedCell; Exit;

End;

{Якщо тип комірки змінено, то перемальовуємо екранну таблицю для

відображення нового типу комірки:}

IfSelf. CurGrid<>Nil then Self. CurGrid. Invalidate;

End;

Procedure TGridFormattingProcs. AddCellTypeItemToMenu (SMenu:TPopupMenu;

SCaption: String; IsCurrentItem: Boolean; SAssocType:THeadLineElmType;

ToSetReactOnClick: Boolean=True);

{Додає пункт меню для вибору типу комірки в таблиці з заданим

написом SCaption і кругом того кольору, що асоційований з даним

типом SAssocType. Для нового пункту меню настроює виклик процедури обробки

комірки для задавання їй обраного типу SAssocType. Значення SAssocType

записує у поле Tag об'єкта пункту меню.

Вхідні дані:

SMenu– контекстне меню для комірки, що формується;

SCaption– підпис для пункту меню (назва типу комірки);

IsCurrentItem– ознака того, що даний пункт меню має бути поточним

(ввімкненим, відміченим) – що це поточний тип комірки;

SAssocType– тип комірки, що прив'язаний до цього пункта меню, і буде

присвоєний комірці при виборі цього пункту;

ToSetReactOnClick– вмикач настройки виклику процедури задавання нового

типу комірки (при виборі елемента меню). При ToSetReactOnClick=False

це не виконується, і натискання елемента меню не викликає ніяких дій.}

Var CurMenuItem:TMenuItem;

SAssocColor:TColor;

Begin

If SMenu=Nil then Exit; {якщо меню не задано – елемент не додаємо в нього}

{Створюємо новий тункт меню:}

CurMenuItem:=TMenuItem. Create(Application);

{Отримуємо колір для даного типу комірки:}

SAssocColor:=Self. GetColorByElmType(SAssocType);

{Біля тексту малюємо круг такого кольору, який асоційований

з типом комірки, і буде присвоєний їй у разі вибору цього пунтку

меню:}

CurMenuItem. Bitmap. Height:=bc_MenuItemColorCircleDiameter;

CurMenuItem. Bitmap. Width:=bc_MenuItemColorCircleDiameter;

CurMenuItem. Bitmap. Canvas. Pen. Color:=SAssocColor;

CurMenuItem. Bitmap. Canvas. Brush. Color:=SAssocColor;

CurMenuItem. Bitmap. Canvas. Ellipse (CurMenuItem. Bitmap. Canvas. ClipRect);

{0 – картинка задана у самому об'єкті, а не в SMenu. Images:}

CurMenuItem. ImageIndex:=0;

CurMenuItem. RadioItem:=True; {промальовувати перемикач, якщо не буде картинки}

{Текст пункту меню:}

CurMenuItem. Caption:=SCaption;

CurMenuItem. Checked:=IsCurrentItem;

If ToSetReactOnClick then {якщо обробка вибору елемента меню ввімкнена}

Begin

{Тип для комірки у випадку вибору цього пунтку меню:}

CurMenuItem. Tag:=Integer(SAssocType);

{Процедура-обробник вибору пункта меню:}

CurMenuItem. OnClick:=Self. ProcOnCellTypeSelInMenu;

CurMenuItem. AutoCheck:=True;

End;

SMenu. Items. Add(CurMenuItem);

End;

(* {Ідентифікатор для типу елемента масиву чисел та імен змінних.

Типи змінних: залежні, незалежні, функції (умови-нерівності).

Залежні змінні – це змінні, для яких діє умова невід'ємності:}

THeadLineElmType=(bc_IndependentVar, bc_DependentVar, bc_FuncVal, bc_Number,

bc_DestFuncToMax);} *)

procedure TGridFormattingProcs. EdLineTaskOnMouseUp (Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

{Процедура реагує на відпускання правої кнопки миші на

комірках рядка-заголовка та стовпця-заголовка таблиці.

Формує та відкриває контекстне меню для вибору типу комірки із можливих

типів для цієї комірки.}

Constsc_CurProcName='EdLineTaskOnMouseUp';

Var CurCol, CurRow, ArrayRow, ArrayCol: Integer; CurElmType:THeadLineElmType;

MouseScrCoords:TPoint;

Begin

{Якщо до вмикання форматування був якийсь обробник події, запускаємо його:}

If @Self. OldOnMouseUp<>Nil then Self. OldOnMouseUp (Sender, Button, Shift, X, Y);

If Sender=Nil then Exit;

{Якщо задано екранну таблицю даного об'єкта TGridFormattingProcs:}

If Sender = Self. CurGrid then

Begin

If Button=mbRight then {якщо була відпущена права кнопка миші}

Begin

{Пробуємо узнати, на яку комірку натиснула миша:}

CurCol:=-1; CurRow:=-1;

Self. CurGrid. MouseToCell (X, Y, CurCol, CurRow);

MouseScrCoords:=Self. CurGrid. ClientToScreen (Point(X, Y));

{Координати комірки у масивах таблиці і її заголовків:}

ArrayRow:=CurRow-Self.CHeadRowNum-bc_LTaskRowsBeforeVars;

ArrayCol:=CurCol-Self.CHeadColNum-bc_LTaskColsBeforeVars;

{Якщо натиснуто на комірку рядка-заголовка:}

If (CurRow=Self.CHeadRowNum) and (ArrayCol>=0) and

(ArrayCol<Length (Self. CurHeadRow)) then

Begin {очищаємо меню перед заповненням:}

Self. InitGridPopupMenu (Self. CurGrid);

{Якщо в екранній таблиці були зміни з часу останнього її читання,

то читаємо комірку, для якої треба сформувати меню:}

If Self. CurGridModified then Self. ReadHeadRowCell(ArrayCol);

{Читаємо поточний тип комірки:}

CurElmType:=Self. CurHeadRow[ArrayCol].ElmType;

{Додаємо пункти меню:}

{Якщо в комірці число-то тип комірки може бути тільки числовий:}

If CurElmType=bc_Number then

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_ValInHeadColOrRow, True, CurElmType)

Else{якщо в комірці не число:}

Begin

{незалежна змінна:}

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_IndependentVar,

CurElmType = bc_IndependentVar, bc_IndependentVar);

{залежна змінна:}

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_DependentVar,

CurElmType = bc_DependentVar, bc_DependentVar);

End;

End

Else If (CurCol=Self.CHeadColNum) and (ArrayRow>=0) and

(ArrayRow<Length (Self. CurHeadCol)) then

Begin {якщо натиснуто на комірку стовпця-заголовка:}

Self. InitGridPopupMenu (Self. CurGrid);

{Якщо в екранній таблиці були зміни з часу останнього її читання,

то читаємо комірку, для якої треба сформувати меню:}

If Self. CurGridModified then Self. ReadHeadColCell(ArrayRow);

{Читаємо поточний тип комірки:}

CurElmType:=Self. CurHeadCol[ArrayRow].ElmType;

{Додаємо пункти меню:}

{Якщо в комірці число-то тип комірки може бути тільки числовий:}

If CurElmType=bc_Number then

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_ValInHeadColOrRow, True, CurElmType)

Else{якщо в комірці не число:}

Begin

{назва фінкції – рядка нерівності:}

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_InequalFuncName, CurElmType = bc_FuncVal, bc_FuncVal);

{назва функції мети, що максимізується:}

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_DestFuncToMaxName, CurElmType = bc_DestFuncToMax,

bc_DestFuncToMax);

{назва функції мети, що мінімізується:}

Self. AddCellTypeItemToMenu (Self. CurGrid. PopupMenu,

sc_DestFuncToMinName, CurElmType = bc_DestFuncToMin,

bc_DestFuncToMin);

End;