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

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
    - 스크롤바는 이전의 컨트롤들에 비해서는 비교적 복잡한 컨트롤이다.
     → 윈도우의 스크롤 상태를 관리하기 위해 사용하기도 하며 일정 범위에 있는 값을 대충 선택할 때도 사용한다.
     → 예로 사운드 볼륨이나 당구 게임의 힘 세기를 선택할 때 등에는 수치로 된 정확한 값보다는 대충의 값을 신속하게 선택해야 하는데 이럴 때 스크롤 바가 적합하다.
     → 스크롤 바는 "scrollbar" 윈도우 클래스로 생성하며 수평 스크롤 바인 경우 SBS_HORZ 스타일을, 수직 스크롤 바인 경우는 SBS_VERT 스타일을 지정한다.

    BOOL SetScrollRange(HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw);
    int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw);
     → SetScrollRange 함수로 최대값(nMaxPos), 최소값(nMinPos)을 지정하되 첫 번째 인수가 스크롤 바의 윈도우 핸들이다.
     → 두 번재 인수 nBar는 메인 윈도우에 부착된 표준 스크롤 바 또는 별도의 스크롤 바 컨트롤을 지정하는데 이 값이 SB_CTL이면 별도의 컨트롤을 지정한다.
     → SetScrollPos는 스크롤 바의 현재 위치를 세 번재 인수 nPos로 지정한다.

     → 다른 컨트롤들은 자신에게 변화가 있을 때 부모 윈도우로 WM_COMMAND 통지 메시지를 보내는데 비해 스크롤 바는 WM_HSCROLL)수평인 경우), WM_VSCROLL(수직인 경우)이라는 별도의 메시지를 부모 윈도우로 보낸다.
     → 이 메시지들은 단순한 사건의 발생뿐만 아니라 스크롤 상태에 대한 다음과 같은 추가 정보를 보내야 하는데 WM_COMMAND의 파라미터는 이미 용도가 예약되어 있으므로 이 정보를 보낼 수 없다.
     인수 설명 
     LOWORD(wParam) 스크롤 바 내의 어디를 눌렀는가. 
     HIWORD(wParam)  현재 위치
     lParam  스크롤 바의 윈도우 핸들

     → LOWORD(wParam)으로 전달되는 값은 사용자의 스크롤 요구사항을 나타낸다.
     → 수평 스크롤 바를 예로 들어 사용자가 클릭한 부분과 이때 전달되는 메시지를 보면 다음과 같다. 양끝의 버튼을 누르는 것은 비교적 작은 단위(예를 들어 한 줄씩)로 섬세하가 이동하라는 명령이며 몸통 부분을 클릭하는 것은 비교적 큰 단위(예를 들어 한 페이지씩)로 이동하라는 명령이다.
     → 또한 수평 스크롤바는 왼쪽, 오른쪽으로 스크롤되지만 수직 스크롤바는 위, 아래로 스크롤되는데 이때 수평의 왼쪽 이동과 수직의 위쪽 이동은 둘다 값을 감소시키는 점에서 동일하다. 그래서 SB_LINELEFT와 SB_LINEUP은 같은 의미라고 할 수 있다.

     → 예제
      스크롤 바 새 개를 사용하여 R, G, B 값을 입력받아 브러시를 만든 후 사각형을 그린다.
    #include "MsgProc.h"
    #define ID_SCRRED 100
    #define ID_SCRGREEN 101
    #define ID_SCRBLUE 102

    HWND hRed, hGreen, hBlue;
    int Red, Green, Blue; // 전역변수이므로 0으로 초기화

    LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      hRed = CreateWindow(TEXT("scrollbar"), NULL, WS_CHILD|WS_VISIBLE|SBS_HORZ,
        101040020, hWnd, (HMENU)ID_SCRRED, g_hInst, NULL);
      hGreen = CreateWindow(TEXT("scrollbar"), NULL, WS_CHILD|WS_VISIBLE|SBS_HORZ,
        104040020, hWnd, (HMENU)ID_SCRGREEN, g_hInst, NULL);
      hBlue = CreateWindow(TEXT("scrollbar"), NULL, WS_CHILD|WS_VISIBLE|SBS_HORZ,
        107040020, hWnd, (HMENU)ID_SCRBLUE, g_hInst, NULL);
      SetScrollRange(hRed, SB_CTL, 0255, TRUE);
      SetScrollPos(hRed, SB_CTL, 0, TRUE);
      SetScrollRange(hGreen, SB_CTL, 0255, TRUE);
      SetScrollPos(hGreen, SB_CTL, 0, TRUE);
      SetScrollRange(hBlue, SB_CTL, 0255, TRUE);
      SetScrollPos(hBlue, SB_CTL, 0, TRUE);

      return 0;
    }
    LRESULT OnHscroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      int TempPos;
      // TempPos의 초기화
      if((HWND)lParam == hRed)
      {

         TempPos = Red;
      }
      if((HWND)lParam == hGreen)
      {
         TempPos = Green;
      }
      if((HWND)lParam == hBlue)
      {
         TempPos = Blue;
      }
      switch(LOWORD(wParam))
      {
      case SB_LINELEFT:
        TempPos = max(0, TempPos-1); // 둘 중에 큰 값을 TempPos에 대입한다.
        break;
      case SB_LINERIGHT:
        TempPos = min(255, TempPos+1);// 둘 중에 작은 값을 TempPos에 대입한다.
        break;
      case SB_PAGELEFT:
        TempPos = max(0, TempPos -10);
        break;
      case SB_PAGERIGHT:
        TempPos = min(255, TempPos+10);
        break;
      case SB_THUMBTRACK:                               
        TempPos = HIWORD(wParam);
        break;
      }
      if((HWND)lParam == hRed)
      {
         Red = TempPos;
      }
      if((HWND)lParam == hGreen)
      {
         Green = TempPos;
      }
      if((HWND)lParam == hBlue)
      {
         Blue = TempPos;
      }
      SetScrollPos((HWND)lParam, SB_CTL, TempPos, TRUE);
      InvalidateRect(hWnd, NULL, FALSE);

      return 0;
    }
    LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
    {
      HDC hdc;
      PAINTSTRUCT ps;
      HBRUSH MyBrush, OldBrush;

      hdc = BeginPaint(hWnd, &ps);
      MyBrush = CreateSolidBrush(RGB(Red, Green, Blue));
      OldBrush = (HBRUSH)SelectObject(hdc, MyBrush); 
      Rectangle(hdc, 10100410300);
      SelectObject(hdc, OldBrush);
      DeleteObject(MyBrush);
      EndPaint(hWnd, &ps);
      return 0;
    }
    LRESULT OnDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
    {
      PostQuitMessage(0);
      return 0;
    }
     → 스크롤 바를 드래그하여 이동하면 아래쪽 사각형의 색상이 변경된다. 

     → WM_CREAT에서 세 개의 수평 스크롤 바를 만들고 범위를 각각 0~255까지 지정하였다. 색상 요소값은 1바이트이기 때문에 최대값은 155이면 된다. 이 수평 스크롤 바는 사용자가 자신을 드래그하거나 클릭할 때 부모 인도우로 WM_HSCROLL 메시지를 보낼 것이다.
     → 메인 윈도우는 스크롤 바가 WM_HSCROLL 메시지를 보내올 때 사용자가 스크롤 바의 어디를 눌렀는지 LOWORD(wParam) 값에 따라 색상값을 적당히 증감시키는데 SB_LINE* 메시지일 경우 1씩 증감시키고 SB_PAGE*일 경우는 19씩 증감시켰다.

     → 증감된 값의 결과는 Red, Green, Blue 전역변수에 대입되며 이 값이 변경될 때마다 작업영역을 무효화하여 다시 그린다. WM_PAINT 메시지에서는 전역변수 Red, Green, Blue 값을 혼합하여 단색의 브러시를 만들고 사각형을 그림으로써 스크롤 바로 선택한 색상값을 출력한다.
     → 색상이란 세 요소의 적당한 종합으로 만들어지므로 이 값들을 빠르게 선택할 때는 스크롤 바가 가장 편리하다.
     → 빨간색 강도 얼마, 파란색은 얼마 하는 식으로 드래그 해서 원하는 색을 빨리 선택할 수 있고 결과를 금방 볼 수 있다. 
     → 만약 각 요소에 대해 정확한 수치를 입력하여 색상을 만들고 싶다면 이때는 스크롤 바보다는 에디트 컨트롤을 사용해야 한다.

     → 
     int TempPos; // 를 전역변수로 둔다면
    // 아래의 코드는 필요 없다.
     if((HWND)lParam == hRed)
     {

        TempPos = Red;
     }
     if((HWND)lParam == hGreen)
     {
        TempPos = Green;
     }
     if((HWND)lParam == hBlue)
     {
        TempPos = Blue;
     }



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

    WINAPI - 컨트롤과의 통신  (0) 2011.09.28
    WINAPI - 대화상자  (0) 2011.09.27
    WINAPI - EDIT  (1) 2011.09.23
    WINAPI - Static  (1) 2011.09.22
    WINAPI - 라디오 버튼  (0) 2011.09.21
    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함