MFC - UpdateData() 함수

원형: BOOL UpdateData(BOOL bSaveAndValidate=TRUE);

UpdateData() 함수는 DDX_Text 계열, 즉 Value 형태로 연결되었을 때 사용한다.
파라미터가 TRUE일 때는 컨트롤의 데이터를 컨트롤과 연결된 멤버 변수로 가져오는 기능을 하며,
반대로 FALSE일 때는 컨트롤과 연결된 변수의 내용을 컨트롤에 세팅하는 기능을 한다.

예) 간단한 사칙연산 계산기

void CTttDlg::Calcul(char type)
{
  //Edit Box로 부터 값을 받아옴.
  m_NUM1;   
  m_NUM2;
  UpdateData(TRUE);
  // 받아온 값을 type에 따라 계산해서 Edit Box 에 출력함
  switch(type)
  { 
  case '*':
     m_OutPut=m_NUM1*m_NUM2;
     UpdateData(FALSE);
   break;
  case '+':
    m_OutPu  t=m_NUM1+m_NUM2;
    UpdateData(FALSE);
   break;
  case '-':
    m_OutPut=m_NUM1-m_NUM2;
    UpdateData(FALSE);
   break;
  case '/':
    m_OutPut=m_NUM1/m_NUM2;
    UpdateData(FALSE);
  break;
}

혹 DDX를 사용하지 않고 컨트롤의 핸들을 가져 오려면, 컨트롤의 포인터를 받을 포인터 변수가 필요하다.
즉, Edit Box의 포인터를 얻기 위해 CEdit 클래스의 포인터 변수를 선언한다.

예)
CEdit *pEdit;
pEdit = (CEdit *)GetDlgItem(IDC_EDIT1);
pEdit->SetWindowText("안녕하세요!");

RegisterHotKey 사용법...

1. 시작 시기에 걸맞는 곳에다 코딩합니다다.
   예를 들어 CMainFrame의 OnCreate에 코딩한다고 하고, Ctrl + I(영어 대문자 아이임) 를 핫키로 하겠다면 멤버 변수로 int m_nHotKeyID; 를 추가하고, OnCreate함수 안에서 핫키를 레지스트리에 등록을 합니다.

[위치] CMainFrame.h
class CMainFrame : public CFrameWnd
{
  // 중략
public:
  int 
m_nHotKeyID;  // 핫키로 사용할 멤버 변수 추가

  // 중략
}
[위치] CMainFrame.cpp
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  // 중략
  // ...

  // m_nHotKeyID의 등록
  m_nHotKeyID = ::GlobalAddAtom("test");   // 추가

  // HotKey를 윈도우 레지스트리에 등록을 한다. 
  if(!::RegisterHotKey(GetSafeHwnd(), m_nHotKeyID,MOD_CONTROL,'I'))   // 추가
    AfxMessageBox("핫키 등록 실패");                                  // 추가
  // 중략
}

2. CMainFrame에 afx_msg LONG OnHotKey(WPARAM wParam, LPARAM lParam)함수 추가하고 메시지맵에
 ON_MESSAGE(WM_HOTKEY, OnHotKey) 를 추가합니다.
 이 때 //}}AFX_MSG_MAP 바깥에 이를 추가하면 됩니다..

  LONG CMainFrame::OnHotKey(WPARAM wParam, LPARAM lParam)
  {
       if((int)wParam == m_nHotKeyID)
       {
           // 하고 싶은 일 구현
       }
   }

이렇게 소스를 구현 시키면 됩니다. 아래는 그 예가 되겠습니다. 여기서는 인터넷 익스프롤러를 띄우는 것이 목적이었습니다.

[위치] MainFrm.h
protected:
  //{{AFX_MSG(CMainFrame)
  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  afx_msg void OnDestroy();
  //}}AFX_MSG
  afx_msg LONG OnHotKey(WPARAM wParam,LPARAM lParam);   // 추가
  afx_msg void OnClose();
  DECLARE_MESSAGE_MAP()



[위치] MainFrm.cpp
///////////////////////////////////////////////
// CMainFrame

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  //{{AFX_MSG_MAP(CMainFrame)
  ON_WM_CREATE()
  ON_WM_DESTROY()
  //}}AFX_MSG_MAP
  ON_MESSAGE(WM_HOTKEY, OnHotKey)      // 추가
END_MESSAGE_MAP()
[위치] MainFrm.cpp
LONG CMainFrame::OnHotKey(WPARAM wParam, LPARAM lParam)
{
  if((int)wParam == m_nHotKeyID)
  {
    // 하고 싶은 일 구현
    AfxMessageBox("HotKey : Internet Explorer Excuted~");
    WinExec("C:/Program Files/Internet Explorer/IEXPLORE.EXE",SW_SHOW);
    /*
    ShellExecute(NULL,
      "open",
      //"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",
      "C:/Program Files/Internet Explorer/IEXPLORE.EXE",
      NULL,NULL,SW_SHOW);
    */

  }
  return 0;
}


3. 종료할 때 핫키를 해제해야 합니다..
 - 클래스 위자드를 이용하신다면 WM_Destroy를 추가시킨다음 제일 아래에 있는 OnDestory함수만 추가 시키시면 됩니다. 만약 직접 입력하시고 싶으시다면 아래 파일 위치와 추가해야 할 소스를 표시해 놓았습니다.

[위치] MainFrm.h
protected:
  //{{AFX_MSG(CMainFrame)
  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  afx_msg void OnDestroy();   // 추가
  //}}AFX_MSG
  afx_msg LONG OnHotKey(WPARAM wParam,LPARAM lParam);
  afx_msg 
void OnClose();
  DECLARE_MESSAGE_MAP()
};
[위치] MainFrm.cpp
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  //{{AFX_MSG_MAP(CMainFrame)
  ON_WM_CREATE()
  ON_WM_DESTROY()       // 추가
  //}}AFX_MSG_MAP
  ON_MESSAGE(WM_HOTKEY, OnHotKey)
END_MESSAGE_MAP()
// 아래 전체 추가
void
 CMainFrame::OnDestroy() 
{
  CFrameWnd::OnDestroy();
  
  // TODO: Add your message handler code here
#ifdef _DEBUG    
  int nRet = UnregisterHotKey(GetSafeHwnd(), m_nHotKeyID); 
  if(!nRet)
    AfxMessageBox(_T("UnregisterHotKey 0 false"));
#else
  UnregisterHotKey(GetSafeHwnd(), m_nHotKeyID); 
#endif
}

[ 풀 소스를 올려 드립니다. :
MFC 안에서 외부 프로그램을 동작 시킬수 있다는 (획기적인) 방법이 있다는 것을 듣고 직접 실행 시켜 보았습니다. 프로그램안에서 외부 프로그램을 동작 시켜 볼 수 있다는 점에서 참 재미가 있었네요.

1) WinExec 함수

외부 프로그램을 동작 시킬 수 있는 함수들 중에서 제일 먼저 사용된 그래서 오래된 함수(win3.x 버전부터 사용된 함수입니다.)는 WinExec함수입니다. 

이 함수의 프로토 타입은 

UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);

으로 사용방법은 아래와 같습니다.

WinExec("C:/Program Files/Internet Explorer/IEXPLORE.EXE",SW_SHOW);
혹은 WinExec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",SW_SHOW);

로 프로그램안에서 위 함수를 위와 같이 인자를 넣으면 인터넷 익스프롤러가 실행이되는 구문입니다. 

이 함수의 장점은 인자가 2개뿐이어서 사용하기는 간편다는 것이지만,
단점으로는 실행을 시켜 놓으면 실행이 되는지 에러가 났는지, 종료 되었는지 전혀 알수가 없다는 것입니다.

2) CreateProcess 함수

다음은 CreateProcess()의 Prototype입니다.

BOOL CreateProcess(
  LPCTSTR lpApplicationName, // 실행파일 모듈의 이름에 대한 포인터
  LPTSTR lpCommandLine, // 커맨드 문자열에 대한 포인터
  LPSECURITY_ATTRIBUTES lpPA, // 프로세스 보안 속성 포인터
  LPSECURITY_ATTRIBUTES lpTA, // 스레드 보안속성 포인터
  BOOL bInheritHandles, // 핸들 상속 여부 플래그
  DWORD dwCreationFlags, // 생성 플래그
  LPVOID lpEnvironment, // 환경 블록에 대한 포인터
  LPCTSTR lpCurrentDirectory, // 현재 디렉토리
  LPSTARTUPINFO lpStartupInfo, // STARTUPINFO 포인터
  LPPROCESS_INFORMATION lpPI // PROCESS_INFORMATION 포인터
);

이 함수의 실행 방법은 아래와 같습니다.

STARTUPINFO StartupInfo = {0};
PROCESS_INFORMATION ProcessInfo;
StartupInfo.cb = sizeof( STARTUPINFO );
::CreateProcess("C:/Program Files/Internet Explorer/IEXPLORE.EXE",
    NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo);

만약 위의 프로그램을 실행시키고 종료하기를 기다린다고 하면,

BOOL ret = CreateProcess(............);
if(!ret)
return FALSE;

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
return TRUE;

이렇게 하면 됩니다.

3) ShellExecute 함수

이 함수의 원형은 아래와 같습니다.

HINSTANCE ShellExecute(
  HWND hwnd, // 부모 윈도우 핸들
  LPCTSTR lpVerb, // 동사 혹은 작업
  LPCTSTR lpFile, // 실행 대상 문서
  LPCTSTR lpParameters, // 컴맨드 인자
  LPCTSTR lpDirectory, // 현재 디렉토리
  INT nShowCmd // 보여주기 옵션
);

일단 위의 함수를 살펴보면 CreateProcess() 함수보다 기능이 많이 떨어지는 것 처럼 보이지만 이 함수의 진정한 의미는 동사 연결이라는 점입니다.
보통 우리가 말하는 [연결 프로그램]을 지칭합니다.

이 함수는 아래와 같이 사용할 수 있습니다.

ShellExecute(NULL,
    "open",
    //"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",   // 경로가 이렇게도 사용가능
    "C:/Program Files/Internet Explorer/IEXPLORE.EXE",
    NULL,NULL,SW_SHOW);

이 함수는 3번째 인자에 다양한 타입을 열수 있도록 되어 있으므로 다양한 응용이 가능한 함수가 되겠습니다.
  1. YYM 2013.07.02 16:10

    배우고 갑니다

  2. 조제우 2013.07.02 19:37

    외부 프로그램을 실행 시키고 그 외부프로그램을 제어 할 수도 있나요?
    예를 들면 메모장을 실행시키고 a.txt 파일을 불러오고 해당 내용을 수정하고 저장 후 종료
    이런식으로요...
    메시지를 보내면 됀다는데 감이 잘 안와서요...

  3. swJman 2015.03.23 16:56 신고

    어이쿠, 정제된 내용 감사드립니다~

+ Recent posts