본문 바로가기
Windows/MFC 강좌 & Tips

(1) 로그인 기능 + 위젯 띄우기

by 미티치 2017. 1. 3.

(1) wTest4 라는 프로젝트에서, wTest.cpp의 InitInstance()에서 wTestDlg객체를 생성하지 않고 개발자가 새로 만든 로그인 다이얼로그 CLoginDlg 객체를 생성해서 DoModal() 함수를 실행시키는 방법

 

 

1. wTest4.cpp 의 InitInstance()

 

BOOL CwTest4App::InitInstance()
{
     // 응용 프로그램 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
     // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요합니다.
     // InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
     INITCOMMONCONTROLSEX InitCtrls;
     InitCtrls.dwSize = sizeof(InitCtrls);
     // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록
     // 이 항목을 설정하십시오.
     InitCtrls.dwICC = ICC_WIN95_CLASSES;
     InitCommonControlsEx(&InitCtrls);

 CWinApp::InitInstance();

 AfxEnableControlContainer();

 // 표준 초기화
 // 이들 기능을 사용하지 않고 최종 실행 파일의 크기를 줄이려면
 // 아래에서 필요 없는 특정 초기화
 // 루틴을 제거해야 합니다.
 // 해당 설정이 저장된 레지스트리 키를 변경하십시오.
 // TODO: 이 문자열을 회사 또는 조직의 이름과 같은
 // 적절한 내용으로 수정해야 합니다.
 SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램"));

 

 /* 로그인 창 먼저 띄우기 */
 CLoginDlg loginDlg;
 if( IDOK != loginDlg.DoModal() ){
  return FALSE;
 }else{
  
 }

 

//  CwTest4Dlg dlg;
//  m_pMainWnd = &dlg;
//  INT_PTR nResponse = dlg.DoModal();
//  if (nResponse == IDOK)
//  {
//   // TODO: 여기에 [확인]을 클릭하여 대화 상자가 없어질 때 처리할
//   //  코드를 배치합니다.
//  }
//  else if (nResponse == IDCANCEL)
//  {
//   // TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
//   //  코드를 배치합니다.
//  }
//
//  // 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고  응용 프로그램을 끝낼 수 있도록 FALSE를
//  // 반환합니다.

return FALSE;

}

-> 주석처리 되어있는 부분이 기존에 있던 소스코드, 즉 wTestDlg 객체를 생성하는 부분이었다. 로그인 창을 먼저 보여주기 위해서 이 부분을 주석처리하고 로그인 객체 CLoginDlg 객체를 생성한다.

 

 

 

2. CwTestDlg 보다 먼저 띄울 로그인을 하는 창(다이얼로그) CLoginDlg 클래스 생성 및 연결, LoginDlg.cpp 에서 OK 버튼을 누르면 로그인 기능을 수행하도록 다음과 같은 함수 구현 

 

void CLoginDlg::OnBnClickedOk()
{
      CString strID;
      CString strPW;
      BOOL isLogin = FALSE;     // 로그인 여부
      GetDlgItemText(IDC_EDIT_ID, strID);  // EditText 컨트롤의 값을 변수로 가지고옴
      GetDlgItemText(IDC_EDIT_PW, strPW);

 m_login.setIdPw(&strID, &strPW);  // 로그인 객체의 ID, PW 설정

 
 /* 예외처리로 잡아 준 이유는, '잘못된 인수가 발견되었습니다'라는 에러 메세지와 함께
  IsLogin() 함수로 디버깅이 넘어가지 않아서이 부분에서 에러가 났다고 판단하였기 때문이었다.
  
  근데 인수가 잘못된 것이 아니라 IsLogin 함수 안에서 CStdioFile 객체를 NULL로 초기화해서 난 것이었음
 */
 try{
  isLogin = m_login.IsLogin(); // 1. 로그인 처리
 }catch(CInvalidArgException * e){ 
  e->ReportError();
 }catch (CException* e){
  e->ReportError();
 }
 
 
 // 2. 로그인 성공 시에 위젯 띄우기
 if(TRUE == isLogin){
  CwTest4Dlg dlg;
  //m_pMainWnd = &dlg;
  INT_PTR nResponse = dlg.DoModal();


  if (nResponse == IDOK)
  {
   // TODO: 여기에 [확인]을 클릭하여 대화 상자가 없어질 때 처리할
   //  코드를 배치합니다.
  }
  else if (nResponse == IDCANCEL)
  {
   // TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
   //  코드를 배치합니다.
  }

  // 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고  응용 프로그램을 끝낼 수 있도록 FALSE를
  // 반환합니다. 
 }
 OnOK();

}

-> 실제 로그인을 수행하는 클래스 CLogin m_login 객체를 이용해서 로그인을 수행하는 프로세스이다. 여기서 예외처리가 되어있는 부분에서 한참 에러가 났었다. 이유는 IsLogin 함수안에서 ID와 PW가 저장되어있는 파일을 읽어오기 위해서 CStdioFile 객체를 선언하는데,

 

CStdioFile file = NULL;

 

로 선언했더니 '잘못된 인수가 발견되었습니다' 라는 에러가 났다. CStdioFile 객체는 NULL로 초기화할 필요가 없다. 내부에서 객체를 초기화해주기 때문이다.