FreePascal Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
FreePacal 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

FreePascal 강좌/문서
[15] 라자루스를 이용한 업무 프로그램 개발 - 14
어느좋은날 [freepascal] 1096 읽음    2020-06-13 22:52
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;

+ -

관련 글 리스트
15 라자루스를 이용한 업무 프로그램 개발 - 14 어느좋은날 1096 2020/06/13
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.