#include <tchar.h>
#include <Windows.h>
#define WIDTH 800
#define HEIGHT 600
// グローバル変数
static const TCHAR g_atcClassName[] = _T("ScrollTest");
static const TCHAR g_atcWindowName[] = _T("Scroll Test");
static SCROLLINFO g_siHorz;
// 関数プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnCreate(HWND hWnd);
void OnSize(HWND hWnd);
void OnHScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
void OnPaint(HWND hWnd);
int APIENTRY _tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hWnd;
MSG msg;
// ウィンドウクラスの登録
wcex.cbSize = sizeof wcex;
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_atcClassName;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (RegisterClassEx(&wcex) == 0) {
return 0;
}
// ウィンドウの作成
hWnd = CreateWindow(
g_atcClassName, // ClassName
g_atcWindowName, // WindowName
WS_OVERLAPPEDWINDOW | WS_HSCROLL, // Style
CW_USEDEFAULT, // x
0, // y
CW_USEDEFAULT, // Width
0, // Height
NULL, // WndParent
NULL, // Menu
hInstance,
NULL);
if (hWnd == NULL) {
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_PAINT:
OnPaint(hWnd);
break;
case WM_HSCROLL:
OnHScroll(hWnd, wParam, lParam);
break;
case WM_SIZE:
OnSize(hWnd);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void OnCreate(HWND hWnd)
{
RECT rcClient;
GetClientRect(hWnd, &rcClient);
g_siHorz.cbSize = sizeof g_siHorz;
g_siHorz.fMask = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL;
g_siHorz.nMin = 0;
g_siHorz.nMax = WIDTH - 1;
g_siHorz.nPage = rcClient.right;
g_siHorz.nPos = 0;
SetScrollInfo(hWnd, SB_HORZ, &g_siHorz, FALSE);
}
void OnSize(HWND hWnd)
{
RECT rcClient;
int iPosMax;
GetClientRect(hWnd, &rcClient);
g_siHorz.nPage = rcClient.right;
iPosMax = g_siHorz.nMax - g_siHorz.nPage + 1;
iPosMax = max(iPosMax, 0);
g_siHorz.nPos = min(g_siHorz.nPos, iPosMax);
SetScrollInfo(hWnd, SB_HORZ, &g_siHorz, TRUE);
}
void OnHScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
SCROLLINFO si;
int iPos;
int iPosMax;
iPos = g_siHorz.nPos;
switch (LOWORD(wParam)) {
case SB_LINEUP:
iPos -= 10;
break;
case SB_LINEDOWN:
iPos += 10;
break;
case SB_PAGEUP:
iPos -= g_siHorz.nPage;
break;
case SB_PAGEDOWN:
iPos += g_siHorz.nPage;
break;
case SB_THUMBTRACK:
si.cbSize = sizeof si;
si.fMask = SIF_TRACKPOS;
if (GetScrollInfo(hWnd, SB_HORZ, &si) != 0) {
iPos = si.nTrackPos;
}
break;
}
iPosMax = g_siHorz.nMax - g_siHorz.nPage + 1;
iPos = min(iPos, iPosMax);
iPos = max(iPos, 0);
if (iPos == g_siHorz.nPos) {
return;
}
ScrollWindowEx(hWnd, g_siHorz.nPos - iPos, 0,
NULL, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE);
g_siHorz.nPos = iPos;
SetScrollInfo(hWnd, SB_HORZ, &g_siHorz, TRUE);
UpdateWindow(hWnd);
}
void OnPaint(HWND hWnd)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rcClient;
TCHAR atcString[64];
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rcClient);
Ellipse(hDC, 0 - g_siHorz.nPos, 0, WIDTH - g_siHorz.nPos, HEIGHT);
_stprintf_s(atcString, _countof(atcString), _T("W=%d H=%d"),
rcClient.right, rcClient.bottom);
TextOut(hDC, 0 - g_siHorz.nPos, 0, atcString, _tcslen(atcString));
EndPaint(hWnd, &ps);
}