2011년9월19일_winAPI_컨트롤, 버튼 컨트롤예제



● 컨트롤(Control)이란 사용자와의 인터페이스를 이루는 도구이다.
                            인터페이스를 이룬다는 말은 사용자로부터 명령과 입력을 받아들이고 출력 결과를 보여준다는 뜻이므로,
                            컨트롤은 곧 입출력 도구를 뜻한다.


image

VS6.0에서 메뉴 – Tools - Options를 선택하면 아래와 같은 대화상자가 뜨고,

image   

대화상자 내부에는 다양한 컨트롤이 사용되었다.
File Type 선택은 콤보박스를 사용하여 파일형식리스트가 보이도록 하였으며,
Tab size와 Indent size 옆에 하얀 박스는 에디트로 값을 입력할 수 있게 되어 있다.
오른쪽은 라디오버튼으로 여러 가지 중에 하나만 선택할 수 있다.
음각으로 파인 네모는 그룹박스로 컨트롤들을 그룹지을 수 있다.
Indent open brace옆에 작은 사각형은 체크박스로 라디오버튼과 다르게 모든 경우의 수를 선택할 수 있다.
Previous lines used for context라는 문자열은 텍스트이다. 텍스트는 왼쪽 위에 더 있다. 
맨 아래에는 이번에 실습할 OK버튼과 Cancel버튼이 있다.

이와 같이 컨트롤은 VS6.0 옵션을 설정하여 프로그램을 제어할 수 있다.

windows 3.1부터 지원하는 컨트롤에는,
① 버튼
② 에디트
③ 리스트 박스
④ 콤보 박스
⑤ 스크롤 바
⑥ 스태틱
6가지에 불과했는데 이 6가지를 표준컨트롤이라고 한다.
windows 95부터는 사용할 수 있는 컨트롤의 수가 대폭 증가되었으며 IE와 함께 지속적으로 업그레이드되어 왔다.
현재는 ActiveX컨트롤까지 사용할 수 있어 컨트롤의 수는 거의 무한대에 이른다고 한다. (ActiveX 공화국인 우리나라 ㅠㅠ)


● 컨트롤도 하나의 윈도우이다. 화면상의 일정한 영역을 차지하며 자신의 고유 메시지를 처리할 수 있는 능력을 가지고 있다.
   독립적으로 사용되는게 아니며 보통 대화상자의 차일드 윈도우로 존재.
● 컨트롤은 윈도우즈가 운영체제 차원에서 제공하기 때문에 윈도우 클래스를 등록할 필요없이,
   미리 등록되어 있는 윈도우 클래스를 사용하기만 하면 된다.

윈도우 클래스 컨트롤
button 버튼, 체크, 라디오
static 텍스트
scrollbar 스크롤 바
edit 에디트
listbox 리스트 박스
combobox 콤보 박스

 

● 예제 : Button
▷ main.cpp

   1: // winAPI p.194 Button
   2: // 2011년 9월 19일 작성 
   3: #include <windows.h>    // 모든 API함수들의 원형과 사용하는 상수들이 정의되어 있음.
   4: #include "MsgProc.h"    //add
   5:  
   6: LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);    //메시지처리함수
   7: HINSTANCE g_hInst;    //핸들 인스턴스
   8: HWND hWndMain;
   9: LPCTSTR lpszClass = TEXT("MyButton");        //Button이라는 클래스명은 윈도우즈가 미리 사용 중.
  10:  
  11: //add
  12: typedef struct MESSAGEMAP {
  13:     UINT iMessage;
  14:     LRESULT (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
  15: } MESSAGEMAP;
  16:  
  17: //시작함수.
  18: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
  19: {
  20:     HWND hWnd;
  21:     MSG Message;
  22:     WNDCLASS WndClass;
  23:     g_hInst = hInstance;
  24:  
  25:     WndClass.cbClsExtra = 0;
  26:     WndClass.cbWndExtra = 0;
  27:     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  28:     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  29:     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  30:     WndClass.hInstance = hInstance;
  31:     WndClass.lpfnWndProc = WndProc;
  32:     WndClass.lpszClassName = lpszClass;
  33:     WndClass.lpszMenuName = NULL;
  34:     WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  35:     RegisterClass(&WndClass);
  36:  
  37:     
  38:     hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
  39:         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,        
  40:         NULL, (HMENU)NULL, hInstance, NULL);
  41:     
  42:     ShowWindow(hWnd, nCmdShow);
  43:  
  44:     while(GetMessage(&Message, NULL, 0, 0)) {
  45:         TranslateMessage(&Message);
  46:         DispatchMessage(&Message);
  47:     }
  48:  
  49:     return (int)Message.wParam;
  50: }
  51:  
  52: //운영체제가 호출하는 CALLBACK함수 (메시지 처리)
  53: LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
  54: {
  55:     //add
  56:     int i;
  57:  
  58:     static MESSAGEMAP MessageMaps[] = {
  59:         {WM_CREATE, OnCreate},
  60:         {WM_COMMAND, OnCommand},
  61:         {WM_LBUTTONDOWN, OnLButtonDown},
  62:         {WM_RBUTTONDOWN, OnRButtonDown},
  63:         {WM_MOUSEMOVE, OnMouseMove},
  64:         {WM_LBUTTONUP, OnLButtonUp},
  65:         {WM_LBUTTONDBLCLK, OnLButtonDBLCLK},
  66:         {WM_PAINT, OnPaint},
  67:         {WM_DESTROY, OnDestroy}
  68:     };
  69:  
  70:     for(i = 0 ; i < sizeof(MessageMaps) / sizeof(MessageMaps[0]) ; ++i)
  71:     {
  72:         if(MessageMaps[i].iMessage == iMessage)
  73:         {
  74:             return (*MessageMaps[i].lpfnMsgProc)(hWnd, wParam, lParam);
  75:         }
  76:     }
  77:     /////////////////////////////////
  78:  
  79:     return(DefWindowProc(hWnd, iMessage, wParam, lParam));
  80: }


▷ MsgProc.cpp

   1: //MsgProc.cpp
   2:  
   3: #include "MsgProc.h"
   4:  
   5:  
   6: LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
   7: {
   8:     CreateWindow(TEXT("button"), TEXT("Click Me"), WS_CHILD | WS_VISIBLE |
   9:         BS_PUSHBUTTON, 20, 20, 100, 25, hWnd, (HMENU)0, g_hInst, NULL);
  10:     CreateWindow(TEXT("button"),    //윈도우 클래스명
  11:                 TEXT("Me Two"),        //캡션 (버튼 위에 표시될 문자열)
  12:                 WS_CHILD |            //차일드윈도우
  13:                 WS_VISIBLE |        //화면에 표시
  14:                 BS_PUSHBUTTON,        //푸쉬버튼 (스타일)
  15:                 20, 50,                //시작좌표
  16:                 100, 25,            //끝좌표
  17:                 hWnd,                //부모 윈도우의 핸들
  18:                 (HMENU)1,            //ID = 1
  19:                 g_hInst,            //이 윈도우를 만드는 인스턴스의 핸들
  20:                 NULL);                //사용자 정의 데이터 (차일드 윈도우는 사용하지 않음)
  21:                                     // CreateWindow()의 리턴값은 윈도우의 핸들
  22:  
  23:  
  24:     CreateWindow(TEXT("button"), TEXT("끝내기"), WS_CHILD | WS_VISIBLE |
  25:         BS_PUSHBUTTON, 20, 80, 100, 25, hWnd, (HMENU)2, g_hInst, NULL);
  26:  
  27:     return 0;
  28: }
  29:  
  30: LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
  31: {
  32:     switch(LOWORD(wParam))
  33:     {
  34:     case 0:        // 컨트롤의 ID = 0
  35:         MessageBox(hWnd, TEXT("First Button Clicked"), TEXT("Button"), MB_OK);
  36:         break;
  37:  
  38:     case 1:        // 컨트롤의 ID = 1
  39:         MessageBox(hWnd, TEXT("Second Button Clicked"), TEXT("Button"), MB_OK);
  40:         break;
  41:     case 2:        // 컨트롤의 ID = 2
  42:         DestroyWindow(hWnd);
  43:         break;
  44:     }
  45:  
  46:     return 0;
  47: }
  48:  
  49: LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
  50: {
  51:  
  52:     return 0;
  53: }
  54:  
  55: LRESULT OnRButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
  56: {
  57:  
  58:     return 0;
  59: }
  60:  
  61:  
  62: LRESULT OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
  63: {
  64:  
  65:     return 0;
  66: }
  67:  
  68: LRESULT OnLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam)
  69: {
  70:  
  71:     return 0;
  72: }
  73:  
  74: LRESULT OnLButtonDBLCLK(HWND hWnd, WPARAM wParam, LPARAM lParam)
  75: {
  76:  
  77:     return 0;
  78: }
  79:  
  80:  
  81: LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
  82: {
  83:     HDC hdc;
  84:     PAINTSTRUCT ps;
  85:  
  86:     hdc = BeginPaint(hWnd, &ps);
  87:     EndPaint(hWnd, &ps);
  88:  
  89:  
  90:     return 0;
  91: }
  92:  
  93: LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
  94: {
  95:  
  96:     PostQuitMessage(0);
  97:     return 0;
  98: }


//여기에 소스분석추가


HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight, hwndParent, hmenu, hinst, lpvParam)




<실행결과>

image image image

끝내기 버튼을 클릭하면 종료된다.