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

FreePascal 강좌/문서
[18] 라자루스를 이용한 업무 프로그램 개발 - 17
어느좋은날 [freepascal] 1143 읽음    2020-06-13 22:55
4-6. 암호 변경 및 사용자 관리 화면



암호 변경은 이전 암호를 먼저 비교한 후 변경할 암호를 서버에 UPDATE 한다. 암호를 비교하거나 등록 시 입력값을 SHA256으로 변환해서 처리한다.
procedure TdlgChgPWD.btnOKClick(Sender: TObject);
var
  s, l_SQL: string;
begin
  if edNew.Text <> edConf.Text then
  begin
    MessageDlg(Self.Caption, '"변경 암호"와 "암호 확인" 내용이 다릅니다!', mtError, [mbOK], 0);
    edNew.SetFocus;
    edNew.SelectAll;
    Exit;
  end;

  try
    l_SQL := 'SELECT passwd FROM slusrm WHERE usr_id = ' + QuotedStr(dmSIMLaz.u_uid);
    dmSIMLaz.UP_SIMLazOpen(dmSIMLaz.qrTmp, l_SQL, True);
    if dmSIMLaz.qrTmp.EOF then s := ''
    else s := dmSIMLaz.qrTmp.FieldByName('passwd').AsString;
    dmSIMLaz.qrTmp.Close;

    if dmSIMLaz.UF_SIMLazSHA(edOld.Text) <> s then
    begin
      MessageDlg(Self.Caption, '"이전 암호"가 설정된 값과 다릅니다!', mtError, [mbOK], 0);
      edOld.SetFocus;
      edOld.SelectAll;
      Exit;
    end;

    l_SQL := 'UPDATE slusrm SET passwd = ' + QuotedStr(dmSIMLaz.UF_SIMLazSHA(edNew.Text)) + ' WHERE usr_id = ' + QuotedStr(dmSIMLaz.u_uid);
    if dmSIMLaz.UF_SIMLazExec(l_SQL) = 1 then
    begin
      ShowMessage('암호가 변경되었습니다!');
      Close;
    end
    else MessageDlg(Self.Caption, '처리도중 오류가 발생하였습니다!', mtError, [mbOK], 0);
  finally
    if dmSIMLaz.qrTmp.Active then dmSIMLaz.qrTmp.Close;
  end;
end;


사용자 관리용 폼을 앞에서 만든 부모폼을 상속해서 만들어 보자. New메뉴에서 Inherited Item에 있는 Inherited project component에서 등록용 팝업 부모폼을 선택한 후 OK 버튼을 클릭한다.




생성된 상속폼에 아래와 같이 TDataSet과 DBGrid를 올려놓고 연결한 다음 DataSet 컴퍼넌트에 TField를 추가하고 DBGrid에 Column들을 추가해준다. 조회조건으로 사용여부를 지정하기위한 체크박스를 추가해준다.




조회용 SQL을 등록하기 위한 procedure와 조회 후 DBGrid로 Focus를 주기위해 조회용 procedure를 override 한다.
unit user_dlg;
:
:
  TdlgUser = class(TdlgSIMLazQ)
  :
  :
  public
    procedure UP_SetSQL; override;
    procedure UP_OpenSQL; override;
:
:
procedure TdlgUser.UP_SetSQL;
var
  s: string;
begin
  if ckxUseYN.Checked then s := '''1'''
  else  s := '''0''';
  u_SQL := 'SELECT usr_id, usr_name, passwd, reg_date, admin_yn, use_yn, remark FROM slusrm WHERE use_yn = ' + s + ' ORDER BY usr_name';
end;

procedure TdlgUser.UP_OpenSQL;
begin
  inherited UP_OpenSQL;
  dbgMaster.SetFocus;
end;


폼 생성 Event에 등록/삭제/저장 시 SQL 구문 생성에 사용되는 테이블명을 설정하고 자료를 조회한다. 사용여부 체크박스의 Click Event에도 조회 처리를 추가한다.
procedure TdlgUser.FormShow(Sender: TObject);
begin
  inherited;
  u_TableName := 'slusrm';
  UP_OpenSQL;
end;

procedure TdlgUser.ckxUseYNClick(Sender: TObject);
begin
  UP_OpenSQL;
end;


DBGrid의 경우 Enter Key 입력시 다른 컨트롤로 이동되면 안 되고 DBGrid 내의 Column간 이동이 되어야한다. 따라서 DBGrid에 Focus가 왔을 때 팝업의 경우 Self.Tag, Docking 폼의 경우 Application.MainForm.Tag를 1로 설정해서 컨트롤간 이동 처리가 안 되게 해야한다.
procedure TdlgUser.dbgMasterEnter(Sender: TObject);
begin
  Self.Tag := 1;
end;

procedure TdlgUser.dbgMasterExit(Sender: TObject);
begin
  Self.Tag := 0;
end;


Enter Key로 DBGrid의 Column간 이동처리는 Delphi의 DBGrid와 비슷하다. 다만 라자루스의 DBGrid의 Column에는 CheckBox나 Button을 사용할 수 있기때문에 Check Box일 경우 EditorMode로 들어가지않고 바로 이동해야한다. (※ Column의 ButtonStyle에 대한 정의는 Grids 유닛에 있다.)
procedure TdlgUser.dbgMasterKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_RETURN then // uses LCLType
  begin
    with TDBGrid(Sender) do
    begin
      if (not (SelectedColumn.ButtonStyle in [cbsCheckboxColumn, cbsButtonColumn])) and (not SelectedColumn.ReadOnly) and (not EditorMode) then Exit; // uses Grids
      if Shift = [] then
      begin
        if SelectedIndex < (Columns.Count - 1) then SelectedIndex := SelectedIndex + 1
        else
        begin
          SelectedIndex := 0;
          DataSource.DataSet.Next;
          if DataSource.DataSet.Eof then DataSource.DataSet.Append;
        end;
      end
      else if ssShift in Shift then
      begin
        if SelectedIndex > 0 then SelectedIndex := SelectedIndex - 1
        else
        begin
          SelectedIndex := Columns.Count - 1;
          DataSource.DataSet.Prior;
        end;
      end;
    end;
  end;
end;


사용자ID는 다른 Table에 연계되어 등록되는 경우가 많다. 그렇기때문에 사용자ID가 바뀔 경우 연계된 데이터도 같이 변경되게하거나 아예 변경 못되게 막아야한다. 외래키를 써서 처리하면 되지만 불편한 점이 많아서 실제 개발할 때 쓰지 않는 경우가 많다. 본 예제에서는 한번 등록된 사용자ID는 수정 안 되게 처리 한다.
사용자ID TField의 ProviderFlags 중 pfInUpdate 속성을 False로 설정해서 UPDATE SQL 구문 생성시 제외시키고 TDataSource의 Change Event에서 Insert 상태가 아니면 ReadOnly가 되게 설정한다.
procedure TdlgUser.dsMasterStateChange(Sender: TObject);
begin
  qrMasterUSR_ID.ReadOnly := not (qrMaster.State in [dsInsert]);
end;


신규 레코드가 추가되면 초기값을 설정한다. 암호는 기본 암호를 SHA256으로 인코딩 후 지정한다. 암호 Field 역시 사용자ID와 같이 등록은 되지만 수정하면 안 되기때문에 TField의 ProviderFlags 중 pfInUpdate 속성을 False로 설정한다. 암호는 화면상에 보여줄 필요가 없는 항목이기때문에 ReadOnly 처리는 하지않아도 된다.
procedure TdlgUser.qrMasterAfterInsert(DataSet: TDataSet);
begin
  with DataSet do
  begin
    FieldByName('passwd').AsString := dmSIMLaz.UF_SIMLazSHA('1234');
    FieldByName('reg_date').AsDateTime := Date;
    FieldByName('admin_yn').AsString := '0';
    FieldByName('use_yn').AsString := '1';
  end;
  dbgMaster.SelectedIndex := 0;
end;


사용자ID에 대문자만 입력 받게 할 경우 DBGrid의 Column에는 대문자 처리용 속성이 없으므로 TField의 SetText Event에서 대문자로 변경해야한다.
procedure TdlgUser.qrMasterUSR_IDSetText(Sender: TField; const aText: string);
begin
  TField(Sender).AsString := UpperCase(aText);
end;

+ -

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