Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

codingfarm

7-8. 스크롤 바 본문

Windows/윈도우즈 API

7-8. 스크롤 바

scarecrow1992 2021. 12. 29. 00:03

0. 개요

  • "scrollbar" 윈도우 클래스로 생성
  • 수평의 경우 SBS_HORZ 스타일을, 수직일 경우 SBS_VERT 스타일을 지정
  • 다음 함수를 통해 허용 가능한 설정값 범위와 스크롤의 위치값을 설정할 수 있다.
1
2
BOOL SetScrollRange( HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw );
int SetScrollPos( HWND hWnd, int nBar, int nPos, BOOL bRedraw );
cs

 

스크롤바는 자신의 변화에 대해 WM_HSCROLL(수평일 경우), WM_VSCROLL(수직일 경우) 이라는 별도의 메시지를 부모 윈도우로 보내며 추가 정보는 아래와 같다.

인수 설명
LOWORD(wParam) 스크롤 바 내의 어디를 눌렀는가?
HIWORD(wParam) 현재 위치
lParam 스크롤 바의 윈도우 핸들

 

LOWORD(wParam)으로 전달되는 값은 사용자가 스크롤에 가한 조작에 대해 상세히 서술해준다. 값의 종류는 아래와 같다.

설명
SB_LINELEFT 또는
SB_LINEUP
사용자가 왼쪽 화살표 버튼을 눌렀다는 뜻이며 이때는 왼쪽으로 한 단위 스크롤시킨다.
SB_LINERIGHT 또는
SB_LINEDOWN
사용자가 오른쪽 화살표 버튼을 눌렀다는 뜻이며 이때는 오른쪽으로 한 단위 스크롤시킨다.
SB_PAGELEFT 또는
SB_PAGEUP
사용자가 왼쪽 몸통 부분을 눌렀다는 뜻이며 이때는 한페이지 왼쪽으로 스크롤시킨다.
SB_PAGERIGHT 또는
SB_PAGEDOWN
사용자가 오른쪽 몸통 부분을 눌렀다는 뜻이며 이때는 한페이지 오른쪽으로 스크롤시킨다.
SB_THUMBPOSITION 스크롤 박스를 드래그한 후 마우스 버튼을 놓았다.
SB_THUMBTRACK 스크롤 박스를 드래그하고 있는 중이다. 이 메시지는 마우스 버튼을 놓을 때까지 계속 전달된다.

수평 스크롤바를 예로들면 아래 그림을 통해 각 지점을 클릭했을때 LOWORD(wParam)에 전달되는 메시지가 무엇인지 알 수 있다.

 

생성부터 사용방법에 대한 서술은 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <windows.h>
#include <tchar.h>
#include <vector>
 
#define ID_SCRRED 100
#define ID_SCRGREEN 101
#define ID_SCRBLUE 102
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("Menu");
 
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)(COLOR_BTNFACE + 1);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hInstance = hInstance;
    WndClass.lpfnWndProc = (WNDPROC)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, 000)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    return Message.wParam;
}
 
HWND hRed, hGreen, hBlue;
int Red, Green, Blue;
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    HBRUSH MyBrush, OldBrush;
    int TempPos;
    switch (iMessage) {
    case WM_CREATE:
        hRed = CreateWindow(L"scrollbar"NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ,
            101020020, hWnd, (HMENU)ID_SCRRED, g_hInst, NULL);
        hGreen = CreateWindow(L"scrollbar"NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ,
            104020020, hWnd, (HMENU)ID_SCRGREEN, g_hInst, NULL);
        hBlue = CreateWindow(L"scrollbar"NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ,
            107020020, 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;
    case WM_HSCROLL:
        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);
            break;
        case SB_LINERIGHT:
            TempPos = min(255, TempPos + 1);
            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;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        MyBrush = CreateSolidBrush(RGB(Red, Green, Blue));
        OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
        Rectangle(hdc, 10100210200);
        SelectObject(hdc, OldBrush);
        DeleteObject(MyBrush);
        EndPaint(hWnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
cs

SetScrollRange 함수를 통해 각 스크롤이 설정 가능한 값은 0~255 이며, 각 notification message에 맞추어 프로그램내의 변수값을 설정하고 SetScrollPos를 통해 스크롤 바의 위치를 설정해준다.

 

 

 

 

 

 

 

 

 

 

 

 

'Windows > 윈도우즈 API' 카테고리의 다른 글

8. 대화상자 (Dialogue Box)  (0) 2022.01.03
7-9. 스태틱  (0) 2021.12.29
7-7. 콤보 박스  (0) 2021.12.28
7-6. 컨트롤 - 리스트 박스  (0) 2021.12.27
7-4. 컨트롤 - 에디트  (0) 2021.12.27
Comments