4-3. 메인 화면 TreeView 메뉴 및 권한체크
메뉴 버튼은 트리 메뉴를 숨기거나 나타내기위한 버튼이다. Docking 폼이 생성되면 트리 메뉴를 감춰 메인 폼 전체를 Docking 폼이 쓸 수 있게한다.
procedure TfrmMain.btnMenuClick(Sender: TObject);
begin
trvMenu.Visible := not trvMenu.Visible;
if trvMenu.Visible then trvMenu.SetFocus;
end;
트리 메뉴 노드에 아이콘을 보여주기 위해서 TImageList를 추가하고 트리 메뉴에 연결한다.
메인 폼 Show Event에서 트리 메뉴를 생성한다. 그 외 상태바에 날짜와 사용자명도 표시한다. TTreeView는 ReadOnly를 True로 설정해서 수정을 막고, RightClickSelect를 True 설정해서 마우스 오른쪽 버튼으로도 선택되게 한다. 관리자일 경우 메뉴 전체를, 일반 사용자일 경우 각 사용자에게 할당된 메뉴만을 선별해서 생성한다. 메뉴와 프로그램을 구분해서 아이콘을 지정해준다. 아이콘 Index 값은 TreeView 클릭시 메뉴 항목인지 프로그램 항목인지 구분하기위한 값으로도 활용된다.
procedure TfrmMain.FormShow(Sender: TObject);
// ID로 노드찾기
function LF_FindNode(AID: string): TTreeNode;
var
i: Int32;
s: string;
l_Tmp: PSIMLazNodeInfo;
begin
Result := nil;
if trvMenu.Items.Count < 1 then Exit;
i := -1;
repeat
Inc(i);
l_Tmp := trvMenu.Items[i].Data;
s := l_Tmp^.menu_id;
until (i = (trvMenu.Items.Count - 1)) or (s = AID);
if s = AID then Result := trvMenu.Items[i];
end;
var
l_SQL: string;
l_Node: TTreeNode;
l_NodeInfo: PSIMLazNodeInfo;
begin
stbMain.Panels[0].Text := FormatDateTime('yyyy"년 "m"월 "d"일"', Date);
stbMain.Panels[1].Text := dmSIMLaz.u_uname;
// Tree Menu 생성
trvMenu.Items.BeginUpdate;
try
trvMenu.Items.Clear;
if dmSIMLaz.u_admin_flag then
l_SQL := 'SELECT menu_id, up_id, menu_name, menu_yn, prg_id, ord FROM slmenum ORDER BY up_id, ord'
else
l_SQL := 'SELECT a.menu_id, a.up_id, a.menu_name, a.menu_yn, a.prg_id, a.ord' +
' FROM slmenum a' +
' WHERE EXISTS ( SELECT 1 FROM slmenut z WHERE z.usr_id = ' + QuotedStr(dmSIMLaz.u_uid) + ' AND z.menu_id = a.menu_id )' +
' ORDER BY a.up_id, a.ord';
dmSIMLaz.UP_SIMLazOpen(dmSIMLaz.qrTmp, l_SQL, True);
with dmSIMLaz.qrTmp do
begin
while not Eof do
begin
New(l_NodeInfo);
l_NodeInfo^.menu_id := FieldByName('menu_id').AsString;
l_NodeInfo^.prg_id := FieldByName('prg_id').AsString;
// Root Node
if FieldByName('up_id').IsNull or (FieldByName('up_id').AsString = '') then
trvMenu.Selected := trvMenu.Items.AddObject(nil, FieldByName('menu_name').AsString, l_NodeInfo)
// Sub Node
else
begin
l_Node := LF_FindNode(FieldByName('up_id').AsString);
trvMenu.Selected := trvMenu.Items.AddChildObject(l_Node, FieldByName('menu_name').AsString, l_NodeInfo);
end;
if FieldByName('menu_yn').AsString = '1' then
begin
trvMenu.Selected.ImageIndex := 0;
trvMenu.Selected.SelectedIndex := 0;
end
else
begin
trvMenu.Selected.ImageIndex := 1;
trvMenu.Selected.SelectedIndex := 1;
end;
Next;
end;
Close;
end;
finally
if dmSIMLaz.qrTmp.Active then dmSIMLaz.qrTmp.Close;
trvMenu.FullExpand;
SetScrollPos(trvMenu.Handle, SB_VERT, 0, True);
if trvMenu.Items.Count > 0 then trvMenu.Selected := trvMenu.Items[0];
trvMenu.Items.EndUpdate;
trvMenu.SetFocus;
end;
end;
TreeView 클릭시 선택한 Node가 메뉴인지 프로그램 항목인지는 메뉴 생성시 설정한 ImageIndex로 구분한다. 메뉴면 접거나 펼치는 동작을, 프로그램 항목이면 해당 폼을 생성한다.
procedure TfrmMain.trvMenuClick(Sender: TObject);
var
l_NodeuInfo: PSIMLazNodeInfo;
begin
if TTreeView(Sender).Selected = nil then Exit;
if TTreeView(Sender).Selected.ImageIndex = 0 then
begin
if TTreeView(Sender).Selected.Expanded then TTreeView(Sender).Selected.Collapse(False)
else TTreeView(Sender).Selected.Expand(False);
end
else
begin
l_NodeuInfo := TTreeView(Sender).Selected.Data;
UP_CreatePRG(l_NodeuInfo^.menu_id, l_NodeuInfo^.prg_id, TTreeView(Sender).Selected.Text);
end;
end;
procedure TfrmMain.trvMenuKeyPress(Sender: TObject; var Key: char);
begin
if Key = #13 then trvMenuClick(Sender);
end;
메뉴ID를 이용해서 폼을 생성하기 전에 먼저 사용권한을 확인한다. 사용권한이 있을 경우, 프로그램 ID가 "http"로 시작하면 웹브라우저를 띄우고 "dlg"로 시작하면 Popup 창을, 아니면 Docking 폼을 생성한다. Docking된 TabSheet의 Name은 차후 Docking한 폼을 찾기위한 정보로 활용하기 위해 Docking 폼의 이름 앞에 "ts_"를 붙여서 할당한다.
procedure TfrmMain.UP_CreatePRG(AMID, APID, ACaption: string);
function LF_Auth(AID: string): Boolean;
var
l_SQL: string;
begin
Result := False;
with dmSIMLaz do
begin
try
l_SQL := 'SELECT auth_v, auth_n, auth_m, auth_d, auth_p, auth_a' +
' FROM slmenut' +
' WHERE usr_id = ' + QuotedStr(u_uid) +
' AND menu_id = ' + QuotedStr(AID);
UP_SIMLazOpen(qrTmp, l_SQL, True);
if not qrTmp.Eof then
begin
u_auth_n := qrTmp.FieldByName('auth_n').AsString = '1';
u_auth_m := qrTmp.FieldByName('auth_m').AsString = '1';
u_auth_d := qrTmp.FieldByName('auth_d').AsString = '1';
u_auth_p := qrTmp.FieldByName('auth_p').AsString = '1';
u_auth_a := qrTmp.FieldByName('auth_a').AsString = '1';
Result := qrTmp.FieldByName('auth_v').AsString = '1';
end;
qrTmp.Close;
finally
if qrTmp.Active then qrTmp.Close;
end;
end;
end;
var
i: Int32;
l_Form: TCustomForm;
begin
if not (dmSIMLaz.u_admin_flag or LF_Auth(AMID)) then
begin
MessageDlg(Self.Caption, '사용 권한이 없거나 프로그램이 존재하지않습니다! [' + ACaption + ']', mtError, [mbOK], 0);
Exit;
end;
// URL
if LeftStr(APID, 4) = 'http' then
begin
ShellExecute(0, 'open', PChar(APID), nil, nil, SW_SHOWNORMAL);
Exit;
end;
// Create Form
if LeftStr(APID, 3) = 'dlg' then GF_SIMLazForm(APID)
else
begin
for i := 0 to pgcMain.PageCount - 1 do
begin
if pgcMain.Pages[i].Name = 'ts_' + APID then
begin
pgcMain.ActivePageIndex := i;
l_Form := Screen.FindForm(APID);
if l_Form <> nil then l_Form.SetFocus;
Exit;
end;
end;
if pgcMain.PageCount >= 10 then
begin
MessageDlg(Self.Caption, '너무 많은 프로그램이 실행중입니다!', mtError, [mbOK], 0);
Exit;
end;
if GF_SIMLazForm(APID) then
begin
l_Form := Screen.FindForm(APID);
if l_Form <> nil then;
begin
l_Form.ManualDock(pgcMain);
pgcMain.ActivePageIndex := pgcMain.PageCount - 1;
l_Form.Show;
l_Form.SetFocus;
end;
pgcMain.ActivePage.Name := 'ts_' + APID;
end;
if pgcMain.PageCount > 0 then trvMenu.Hide;
end;
end;