블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
    - 대화상자를 통해 입력 받는 값이 BOOL 형과 열거인 예제
     → BOOL 형은 체크 박스로 표시하고 열거형은 라디오 박스로 표시하는데 값을 보여주고 다시 읽는 방법이 정수나 문자열과 다를 뿐 전체적인 논리는 비슷하다.
    //main.cpp
    #include<windows.h>

    #include "MsgProc.h" // add

    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    HINSTANCE g_hInst;
    LPCTSTR lpszClass = TEXT("First");

    // add
    typedef struct MESSAGEMAP
    {
      UINT iMessage;
      LRESULT (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
    }MESSAGEMAP;

    //CALLBACKAboutDlgProc
    typedef struct DLGMESSAGEMAP  
    {
      UINT iMessage;
      BOOL (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
    }DLGMESSAGEMAP;


    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
    {
      HWND hWnd;
      MSG Message;
      WNDCLASS WndClass;
      g_hInst = hInstance;

      WndClass.cbClsExtra = 0;
      WndClass.cbWndExtra = 0;
      WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
      WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
      WndClass.hInstance = hInstance;
      WndClass.lpfnWndProc = WndProc;
      WndClass.lpszClassName = lpszClass;
      WndClass.lpszMenuName = NULL;
      WndClass.style = CS_HREDRAW | CS_VREDRAW;
      RegisterClass(&WndClass);

      hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);;
      ShowWindow(hWnd, nCmdShow);

      while(GetMessage(&Message, NULL, 00))
      {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
      }
      return (int)Message.wParam;

    }
    BOOL CALLBACK MajorDlgProc(HWND hDlg,UINT iMessage, WPARAM wParam, LPARAM lParam)
    {
      int i;
      static DLGMESSAGEMAP DlgMessageMaps[] = {
      {WM_INITDIALOG, OnInitDialog},
      {WM_COMMAND, OnDlgCommand}    
      };


      for(i=0; i<sizeof(DlgMessageMaps)/sizeof(DlgMessageMaps[0]); ++i)
      {
      if(DlgMessageMaps[i].iMessage == iMessage)
        return (*DlgMessageMaps[i].lpfnMsgProc)(hDlg, wParam, lParam);
      }

      return FALSE;
    }

    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
    {
      //add
      int i;
      static MESSAGEMAP MessageMaps[] = {
        {WM_CREATE, OnCreate},
        {WM_COMMAND, OnCommand},
        {WM_LBUTTONDOWN, OnLButtonDown},
        {WM_PAINT, OnPaint},
        {WM_DESTROY, OnDestroy}
      };

      for(i=0; i<sizeof(MessageMaps)/sizeof(MessageMaps[0]);++i)
      {
        if(MessageMaps[i].iMessage == iMessage)
        {
          return (*MessageMaps[i].lpfnMsgProc)(hWnd, wParam, lParam);
        }    
      }
      ///////////////////////////

      return(DefWindowProc(hWnd, iMessage, wParam, lParam)); 
    }


    //MsgProc.cpp
    #include
     "MsgProc.h"

    BOOL bMale;
    TCHAR str[128];
    enum tag_Major{MANAGE, KOREAN, ENGLISH, LAW}Major;
    TCHAR *arMajor[] = {TEXT("경영학과"), TEXT("국문학과"), TEXT("영문학과"), TEXT("법학과")};

    LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      bMale = TRUE;
      Major = KOREAN;
      return 0;
    }
    LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      return 0;
    }
    LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      if(DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, MajorDlgProc) == IDOK)
      {
        InvalidateRect(hWnd, NULL, TRUE);
      }
      return 0;
    }
    LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      HDC hdc;
      PAINTSTRUCT ps;

      hdc = BeginPaint(hWnd, &ps);

      wsprintf(str, TEXT("성별 = %s"), bMale ? TEXT("남자"):TEXT("여자"));
      TextOut(hdc, 1010, str, lstrlen(str));
      wsprintf(str, TEXT("전공 = %s"), arMajor[Major]);
      TextOut(hdc, 1030, str, lstrlen(str));
      EndPaint(hWnd, &ps);
      return 0;
    }
    LRESULT OnDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
    {
      PostQuitMessage(0);
      return 0;
    }

    /////////////////////////////////////////////////////////////////////
    BOOL OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
    {
      CheckDlgButton(hDlg, IDC_MALE, bMale ? BST_CHECKED:BST_UNCHECKED);
      CheckRadioButton(hDlg, IDC_MAJOR1, IDC_MAJOR4, IDC_MAJOR1+Major);
      return TRUE;
    }
    BOOL OnDlgCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
    {
      switch(LOWORD(wParam))
      {
      case IDOK:
        bMale = (IsDlgButtonChecked(hDlg, IDC_MALE)==BST_CHECKED);
        if(IsDlgButtonChecked(hDlg, IDC_MAJOR1)==BST_CHECKED)
        {
          Major = MANAGE;
        }
        if(IsDlgButtonChecked(hDlg, IDC_MAJOR2)==BST_CHECKED)
        {
          Major = KOREAN;
        }
        if(IsDlgButtonChecked(hDlg, IDC_MAJOR3)==BST_CHECKED)
        {
          Major = ENGLISH;
        }
        if(IsDlgButtonChecked(hDlg, IDC_MAJOR4)==BST_CHECKED)
        {
          Major = LAW;
        }
        EndDialog(hDlg, IDOK);
        return TRUE;
      case IDCANCEL:
        EndDialog(hDlg, IDCANCEL);
        return TRUE;
      }

      return FALSE;
    }


     → 출력 결과


     → 출력 결과
     → 성별을 나타내는 bMale과 전공을 나타내는 열거형 Major 변수가 선언되어 있으며 WndProc에서는 이 값을 화면으로 출력하여 확인하기만 한다. 이 두 값을 대화상자로 보여주고 입력받기 위해 다음과 같은 대화 상자를 만들었다.

     → bMale 변수의 상태를 IDC_MALE 체크 박스에 표시하고 Major 변수의 값을 IDC_MAJOR1 ~ IDC_MAJOR4 사이의 라디오 버튼에 표시하면 될 것이다.
     → WM_INITDIALOG에서 CheckDlgButton으로 bMale 변수값에 따라 IDC_MALE 체크 박스의 상태를 체크 또는 비체크로 설정했다. 
     → 편집된 값을 다시 읽어올 때는 IsDlgButtonChecked 함수로 각 버튼의 체크 상태를 조사한다. 라디오 버튼 중 체크된 버튼을 구할 때는 모든 라디오 버튼에게 일일이 질문을 해서 체크된 버튼을 찾는 방법밖에 없다.
     → 이럴 때는 어떤 그룹에서 어떤 버튼이 선택되어 있는지 조사하는 다음과 같은 함수를 만들어 쓸 수도 있을 것이다.
    int GetCheckedRadioButton(HWND hDlg, int First, int Last)
    {
           int id;
           for(id = First; id<=Last ; ++id)
           {
                  if(IsDlgButtonChecked(hDlg, id)==BST_CHECKED)
                  {
                         return id;
                  }
           }
           return -1;
    }
    → 인수로 전달된 First ~ Last 까지 라디오 그룹의 범위만큼 루프를 돌며 각 버튼들에게 질문하여 체크된 버튼을 만나면 그 버튼의 id를 리턴하는 것이다. 이 함수를 쓴다면 다음 한 줄로 라디오 버튼에서 사용자가 선택한 옵션을 읽을 수 있다.

    Major = tag_Major(GetCheckedRadioButton(hDlg, IDC_MAJOR1, IDC_MAJOR4)-IDC_MAJOR1);
    → API의  래퍼 라이브러리인 MFC에는 실제로 이 함수가 존재한다.
    → 이 함수의 예에서 볼수 있듯이 려러개의 컨트롤에 대해 루프를 돌리기 위해 핸들 외에도 사용자가 값을 통제할 수 있는 ID가 필요하다.
    → 단, 이런식의 루프를 돌리려면 라디오 버튼들이 반드시 연속적인 ID를 가지고 있어야 한다.



    '내장형 하드웨어 > WINAPI' 카테고리의 다른 글

    WINAPI - sokoban  (0) 2011.10.10
    WINAPI - 모델리스형 대화상자  (0) 2011.10.06
    WINAPI - 컨트롤과의 통신  (0) 2011.09.28
    WINAPI - 대화상자  (0) 2011.09.27
    WINAPI - 스크롤 바  (0) 2011.09.26
    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함