スクロールバーコントロール
スクロールバーコントロールはウィンドウのスクロールバーによく似ています。
ウィンドウのスクロールバーはクライアント領域のスクロールに使用しますが、コントロールとしてのスクロールバーはウィンドウ上の任意の場所に設置でき、その値も自由に使用することができます。
スクロールバーコントロールの作成
スクロールバーコントロールはSCROLLBAR
クラスで作成できます。
#define IDC_SCROLLBAR1 100
case WM_CREATE:
CreateWindow(
L"SCROLLBAR", NULL,
WS_CHILD | WS_VISIBLE | SBS_HORZ,
10, 10, 200, 18,
hWnd, (HMENU)IDC_SCROLLBAR1, hInst, NULL);
ウィンドウスタイルにSBS_HORZ
を指定すると水平、SBS_VERT
を指定すると垂直のスクロールバーコントロールを作成できます。
ただし作成しただけでは操作しても何も起こりませんし、バーを動かすことすらできません。
ウィンドウのスクロールバーの時と同じく、動作は自分で定義する必要があります。
使用するメッセージと関数は同じなので、スクロールバーも参考にしてください。
スクロールバーコントロールを操作すると、親ウィンドウにWM_HSCROLL
(水平)またはWM_VSCROLL
(垂直)が送られてきます。
このときLPARAMには操作したコントロールのハンドルが格納されています。
(ウィンドウのスクロールバーの場合はLPARAMはNULLです)
SetScrollInfo
関数(GetScrollInfo関数)の第二引数にはコントロールのスクロールバーであることを示す定数SB_CTL
を指定します。
後の処理はウィンドウのスクロールバーと同じです。
#include <windows.h>
#include <strsafe.h>
//ウィンドウの生成等は省略
#define IDC_SCROLLH 100
#define IDC_SCROLLV 101
#define BUFFERSIZE 8
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hScrollH, hScrollV;
static WCHAR txtH[BUFFERSIZE];
static WCHAR txtV[BUFFERSIZE];
HDC hdc;
PAINTSTRUCT ps;
RECT rt;
SCROLLINFO si;
switch (message)
{
case WM_CREATE: //ウィンドウ作成
//水平スクロールバーコントロール
hScrollH = CreateWindow(
L"SCROLLBAR", NULL,
WS_CHILD | WS_VISIBLE | SBS_HORZ,
30, 10, 100, 15,
hWnd, (HMENU)IDC_SCROLLH, hInst, NULL);
//垂直スクロールバーコントロール
hScrollV = CreateWindow(
L"SCROLLBAR", NULL,
WS_CHILD | WS_VISIBLE | SBS_VERT,
10, 30, 15, 100,
hWnd, (HMENU)IDC_SCROLLV, hInst, NULL);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nPage = 10;
si.nMin = 0;
//スクロール可能な範囲はnMaxで指定した値よりも
//「ページサイズ - 1」分だけ少なくなるので
//その分だけ加算しておく
si.nMax = 100 + (si.nPage - 1);
SetScrollInfo(hScrollH, SB_CTL, &si, TRUE);
SetScrollInfo(hScrollV, SB_CTL, &si, TRUE);
StringCchPrintf(txtH, BUFFERSIZE, L"0");
StringCchPrintf(txtV, BUFFERSIZE, L"0");
break;
case WM_HSCROLL: //水平スクロール
if (lParam != hScrollH)
break;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hScrollH, SB_CTL, &si);
switch (LOWORD(wParam)) {
case SB_LEFT:
si.nPos = si.nMin;
break;
case SB_RIGHT:
si.nPos = si.nMax - (si.nPage - 1);
break;
case SB_LINELEFT:
if(si.nPos > 0)
si.nPos -= 1;
break;
case SB_LINERIGHT:
if (si.nPos < si.nMax - (si.nPage - 1))
si.nPos += 1;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = HIWORD(wParam);
break;
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
}
SetScrollInfo(hScrollH, SB_CTL, &si, TRUE);
StringCchPrintf(txtH, BUFFERSIZE, L"%d", si.nPos);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_VSCROLL: //垂直スクロール
if (lParam != hScrollV)
break;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hScrollV, SB_CTL, &si);
switch (LOWORD(wParam)) {
case SB_TOP:
si.nPos = si.nMin;
break;
case SB_BOTTOM:
si.nPos = si.nMax - (si.nPage - 1);
break;
case SB_LINEUP:
if (si.nPos > 0)
si.nPos -= 1;
break;
case SB_LINEDOWN:
if (si.nPos < si.nMax - (si.nPage - 1))
si.nPos += 1;
break;
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = HIWORD(wParam);
break;
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
}
SetScrollInfo(hScrollV, SB_CTL, &si, TRUE);
StringCchPrintf(txtV, BUFFERSIZE, L"%d", si.nPos);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 135, 10, txtH, lstrlen(txtH));
TextOut(hdc, 10, 135, txtV, lstrlen(txtV));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
水平スクロールバーと垂直スクロールバーを作成し、それぞれの値を文字列で表示しています。
コード中にもコメントで書いていますが、スクロールバーのスクロール可能な範囲はnMin
からnMax
までではありません。
nPage - 1
、つまり「スクロールボックスのサイズ - 1」分だけ実際にスクロール可能な範囲は小さくなります。
スクロールバーコントロールのスタイル
スクロールバーコントロールには以下のスタイルが指定できます。
定数 | 説明 |
---|---|
SBS_HORZ | 水平スクロールバー スクロールバーのサイズはCreateWindow関数で指定した通りのサイズになる |
SBS_VERT | 垂直スクロールバー スクロールバーのサイズはCreateWindow関数で指定した通りのサイズになる |
SBS_TOPALIGN | スクロールバーの上端を、CreateWindow関数で指定した矩形領域の上端に合わせる 高さは既定の高さになる このスタイルは SBS_HORZ スタイルと共に使用する
|
SBS_LEFTALIGN | スクロールバーの左端を、CreateWindow関数で指定した矩形領域の左端に合わせる 幅は既定の幅になる このスタイルは SBS_VERT スタイルと共に使用する
|
SBS_BOTTOMALIGN | スクロールバーの下端を、CreateWindow関数で指定した矩形領域の下端に合わせる 高さは既定の高さになる このスタイルは SBS_HORZ スタイルと共に使用する
|
SBS_RIGHTALIGN | スクロールバーの右端を、CreateWindow関数で指定した矩形領域の右端に合わせる 幅は既定の幅になる このスタイルは SBS_VERT スタイルと共に使用する
|
SBS_SIZEBOX | サイズボックス (ウィンドウサイズを変更するコントロール) サイズはCreateWindow関数で指定した通りのサイズになる |
SBS_SIZEBOXTOPLEFTALIGN | サイズボックスの左上隅を、CreateWindow関数で指定した矩形領域の左上隅に合わせる サイズは既定のサイズになる このスタイルは SBS_SIZEBOX またはSBS_SIZEGRIP スタイルと共に使用する
|
SBS_SIZEBOXBOTTOMRIGHTALIGN | サイズボックスの右上隅を、CreateWindow関数で指定した矩形領域の右上隅に合わせる サイズは既定のサイズになる このスタイルは SBS_SIZEBOX またはSBS_SIZEGRIP スタイルと共に使用する
|
SBS_SIZEGRIP | サイズボックスSBS_SIZEBOX と同じだがグリップのあるデザインになっている
|