Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Главное меню программы


Автор: Serggggg 22.1.2004, 12:14
Доброго времени суток!
Прошу совета! Дело вот в чём - в главном меню программы есть куча разных элементов (Item'ов). С прогой будут работать несколько отделов предприятия! Желательно, чтобы тупой юзер из 1-го отдела не влез в таблицу (таблицы), с которой работает 2-й отдел!
Всё это можно, конечно, блокировать на уровне самой БД. Однако в самой программе лучший способ, как мне кажется, - это просто скрыть пункты меню, которые вызывают процедуры, не нужные юзеру из 1-го отдела.
У пунктов меню есть замечательное свойство - Visible! Стоит сказать, что у разных пунктов разная вложенность. И, в принципе, скрывать придется вложенные и вложенные-вложенные пункты.
Собственно, вопрос: можно ли как-то универсально описать эту процедуру (как, например, обработку матрицы)? Потому что с оператором Case (User_ID of) долбаться не хочется.
Надеюсь, все (или основное) понятно!
Спасибо.

С уважением, Serggggg.

Автор: Paradox 22.1.2004, 12:32
У нас в системе это функционирует созданием в БД таблицы юзеров и к ним привязаны пункты меню им позвлленные по=моему

Автор: P@dla 22.1.2004, 12:48
Сделай несколько вариантов главного меню, один экшэн лист (ActionList) и в каждом главном меню назначь экшены (Action) на соответствующие Items. А после выбора юзверем своего отдела назначай форме соответствующее главное меню...


вот пример:
Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ActnList, Menus;

type
 TForm1 = class(TForm)
   MainMenu1: TMainMenu;
   MainMenu2: TMainMenu;
   MainMenu3: TMainMenu;
   N1: TMenuItem;
   N2: TMenuItem;
   N3: TMenuItem;
   N11: TMenuItem;
   N21: TMenuItem;
   N4: TMenuItem;
   N5: TMenuItem;
   N6: TMenuItem;
   N22: TMenuItem;
   N7: TMenuItem;
   N8: TMenuItem;
   N9: TMenuItem;
   N10: TMenuItem;
   N12: TMenuItem;
   N13: TMenuItem;
   N14: TMenuItem;
   N15: TMenuItem;
   N23: TMenuItem;
   ActionList1: TActionList;
   AQuit: TAction;
   AUser1: TAction;
   AUser2: TAction;
   AMain: TAction;
   N16: TMenuItem;
   N17: TMenuItem;
   N24: TMenuItem;
   procedure AQuitExecute(Sender: TObject);
   procedure AUser1Execute(Sender: TObject);
   procedure AUser2Execute(Sender: TObject);
   procedure AMainExecute(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AQuitExecute(Sender: TObject);
begin
 Close;
end;

procedure TForm1.AUser1Execute(Sender: TObject);
begin
 form1.Menu:=Self.MainMenu2;
end;

procedure TForm1.AUser2Execute(Sender: TObject);
begin
 form1.Menu:=Self.MainMenu3;
end;

procedure TForm1.AMainExecute(Sender: TObject);
begin
 form1.Menu:=Self.MainMenu1;
end;

end.


вот форма:
Код

object Form1: TForm1
 Left = 227
 Top = 198
 Width = 696
 Height = 480
 Caption = 'Form1'
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 Menu = MainMenu1
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 13
 object MainMenu1: TMainMenu
   Left = 160
   Top = 152
   object N1: TMenuItem
     Caption = #1060#1072#1081#1083
     object N2: TMenuItem
       Action = AQuit
     end
   end
   object N3: TMenuItem
     Caption = #1070#1079#1077#1088
     object N11: TMenuItem
       Action = AUser1
     end
     object N21: TMenuItem
       Caption = '-'
     end
     object N23: TMenuItem
       Action = AUser2
     end
   end
   object N16: TMenuItem
     Caption = #1080#1090#1077#1084' '#1076#1086#1089#1090#1091#1087#1085#1099#1081' '#1074' '#1075#1083' '#1084#1077#1085#1102
   end
 end
 object MainMenu2: TMainMenu
   Left = 208
   Top = 152
   object N4: TMenuItem
     Caption = #1060#1072#1081#1083
     object N5: TMenuItem
       Action = AQuit
     end
   end
   object N6: TMenuItem
     Caption = #1070#1079#1077#1088
     object N22: TMenuItem
       Action = AUser2
     end
     object N7: TMenuItem
       Caption = '-'
     end
     object N8: TMenuItem
       Action = AMain
     end
   end
   object N17: TMenuItem
     Caption = #1080#1090#1077#1084' '#1076#1086#1089#1090#1091#1087#1085#1099#1081' 1 '#1102#1079#1077#1088#1091
   end
 end
 object MainMenu3: TMainMenu
   Left = 248
   Top = 152
   object N9: TMenuItem
     Caption = #1060#1072#1081#1083
     object N10: TMenuItem
       Action = AQuit
     end
   end
   object N12: TMenuItem
     Caption = #1070#1079#1077#1088
     object N13: TMenuItem
       Action = AUser1
     end
     object N14: TMenuItem
       Caption = '-'
     end
     object N15: TMenuItem
       Action = AMain
     end
   end
   object N24: TMenuItem
     Caption = #1080#1090#1077#1084' '#1076#1086#1089#1090#1091#1087#1085#1099#1081' 2 '#1102#1079#1077#1088#1091
   end
 end
 object ActionList1: TActionList
   Left = 288
   Top = 152
   object AQuit: TAction
     Caption = #1042#1099#1093#1086#1076
     OnExecute = AQuitExecute
   end
   object AUser1: TAction
     Caption = '1'
     OnExecute = AUser1Execute
   end
   object AUser2: TAction
     Caption = '2'
     OnExecute = AUser2Execute
   end
   object AMain: TAction
     Caption = #1075#1083#1072#1074#1085#1086#1077' '#1084#1077#1085#1102
     OnExecute = AMainExecute
   end
 end
end

Автор: Serggggg 22.1.2004, 13:30
Paradox, а клиентская прога хватала индексы пунктов меню или названия из таблицы пунктов?

Автор: Serggggg 22.1.2004, 13:32
И ещё, можно ли пройтись по всему меню со вложенностью N и за один раз выставить на ВСЕХ пунктах нужный Visible?

Автор: Pakshin A. S. 22.1.2004, 20:23
Если меню большая, то долго будет... но это сейчас не актуально.

Автор: x77 22.1.2004, 21:37
Serggggg, можно, рекурсией.

ещё один вариант: у всех юзверей, видящих определённую таблицу должен быть некий общий признак, X. например, номер отдела. или ещё что-то. если его нет, значит, его надо ввести. после этого делаешь полное меню (на всех), привязываешь его к Action'ам при желании, а потом выставляешь в тегах меню (или экшенов) нужный параметр. если нужен не один, например, один юзверь может видеть некоторые меню другого, то их можно комбинировать (например, как в FileAttr: 1 + 2 + 4 + 8 + 26 + 32 + 64 + ... ) на уровне бита всегда можно определить, входит туда нужный номер или нет. 32 бита тебе, я думаю, хватит. хотя можно и просто вести какую-то линковочную таблицу вида [Х, № меню]). при запуске программы получаешь Х, проходишь в цикле все меню/экшены, и проверяешь, есть ли такой "бит" в теге. если нет - выключаешь. с линковочной таблицей сложнее и медленнее, там всё-таки таблицу сосать из базы придётся.

Автор: Medved 23.1.2004, 02:13
TActionList+RTTI;

Автор: x77 23.1.2004, 04:50
Pegas, а чем поможет RTTI? 8)

Автор: Serggggg 23.1.2004, 14:25
Интересная идея с битами. Благодарю за совет. Надо опробовать.

Автор: Medved 26.1.2004, 23:22
Цитата(x77 @ 23.1.2004, 07:50)
Pegas, а чем поможет RTTI? 8)

Посмотрите наш FAQ. Там кое-что есть о RTTI. Там Вы найдете ответ на свой вопрос. Если же не найдете, то пишите, отвечу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)