今回はエディットに縦スクロールバーのほかに、横(水平)スクロールバーもつけます。
スクロールバー1:縦スクロール - インコのWindowsSDK で作成したソースを修正します。
流れ
WM_CREATE
1.CreateWindowEx()のウインドウスタイルにWS_HSCROLLをつける。
WM_SIZE
1.SetScrollRange()で、スクロールボックス(つまみ)の最大位置と最小位置を設定。
2.SetScrollPos()で、スクロールボックス(つまみ)の現在位置を設定。
WM_HSCROLL
WM_HSCROLLメッセージは、横スクロールバーが操作されたとき実行されます。
● WM_HSCROLLメッセージ発生時のwParam
| wParamの下位ワード | 内容 |
|---|---|
| SB_LINELEFT |
1 行左へスクロール スクロール・バーの両端にある三角形のついたボタンを押したとき |
| SB_LINERIGHT |
1 行右へスクロール スクロール・バーの両端にある三角形のついたボタンを押したとき |
| SB_PAGELEFT |
1 ページ左へスクロール スクロール矢印とスクロールボックスの間を押したとき |
| SB_PAGERIGHT |
1 ページ右へスクロール スクロール矢印とスクロールボックスの間を押したとき |
| SB_THUMBPOSITION |
絶対位置へスクロール スクロールボックスが押されたとき wParamの下位ワードにスクロールボックスの現在位置を示します。 |
| SB_THUMTRACK |
指定位置へスクロール ボックスをドラッグ。 スクロールボックスが離されたとき wParamの下位ワードにスクロールボックスの現在位置を示します。 |
| SB_ENDSCROLL | スクロールが終了 |
wParamの上位ワード:SB_THUMPOSITIONとSB_THUMTRACKのときスクロールボックスの現在位置
● WM_HSCROLLメッセージ発生時のlParam:スクロールバーのハンドル
1.ScrollWindow()で、クライアント領域の内容をスクロールします。
2.SetScrollPos()で、スクロールボックス(つまみ)の現在位置を設定。
3.UpdateWindow()で、ウインドウを更新します。
ソースコードの入力
ソースコードは下記のように入れてください。
test.cpp
#include <windows.h>
#include "resource.h"
// グローバル変数:
HINSTANCE hInst; // 現在のインターフェイス
// このコード モジュールに含まれる関数の宣言を転送します:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
// アプリケーションの初期化を実行します:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// メイン メッセージ ループ:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
//
// 関数: MyRegisterClass()
//
// 目的: ウィンドウ クラスを登録します。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
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 = MAKEINTRESOURCE(IDC_HP);
wcex.lpszClassName = TEXT("HP");
wcex.hIconSm = LoadIcon(NULL , IDI_APPLICATION);
return RegisterClassEx(&wcex);
}
//
// 関数: InitInstance(HINSTANCE, int)
//
// 目的: メイン ウィンドウを作成します。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hWnd = CreateWindow(TEXT("HP"), TEXT("HP"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: メイン ウィンドウのメッセージを処理します。
//
// WM_CREATE - ウインドウ作成時の処理
// WM_SIZE - ウインドウサイズ変更時の処理
// WM_VSCROLL - スクロール時の処理
// WM_COMMAND - アプリケーション メニューの処理
// WM_DESTROY - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
HWND static hEdit;
static int wx; // 画面の幅
static int wy; // 画面の高さ
static int y; // スクロール位置
static int dy; // 増分
static int x; // スクロール位置
static int dx; // 増分
static int range; // 最大スクロール範囲
static int yclient; // 現在のクライアント領域の高さ
static int xclient; // 現在のクライアント領域の幅
switch (message)
{
case WM_CREATE:
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, // 拡張ウィンドウスタイル
TEXT("EDIT"),
TEXT("ここに入力"),
WS_CHILD | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL,
0, 0,
0, 0,
hWnd,
(HMENU)IDC_EDIT1,
hInst,
NULL);
wx = GetSystemMetrics(SM_CXSCREEN);
wy = GetSystemMetrics(SM_CYSCREEN);
break;
case WM_SIZE:
yclient = HIWORD(lParam);
range = wy - yclient;
y = min(y, range);
SetScrollRange(hEdit, SB_VERT, 0, range, FALSE);
SetScrollPos(hEdit, SB_VERT, y, TRUE);
xclient = LOWORD(lParam);
range = wx - xclient;
x = min(x, range);
SetScrollRange(hEdit, SB_HORZ, 0, range, FALSE);
SetScrollPos(hEdit, SB_HORZ, x, TRUE);
MoveWindow(hEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
break;
case WM_VSCROLL:
switch (LOWORD(wParam))
{
case SB_LINEUP:
dy = -1;
break;
case SB_LINEDOWN:
dy = 1;
break;
case SB_THUMBPOSITION:
dy = HIWORD(wParam) - y;
break;
case SB_PAGEDOWN:
dy = 10;
break;
case SB_PAGEUP:
dy = -10;
break;
default:
dy = 0;
break;
}
dy = max(-y, min(dy, range - y));
if (dy != 0)
{
y += dy;
ScrollWindow(hEdit, 0, -dy, NULL, NULL);
SetScrollPos(hEdit, SB_VERT, y, TRUE);
UpdateWindow(hEdit);
}
break;
case WM_HSCROLL:
switch (LOWORD(wParam))
{
case SB_LINEUP:
dx = -1;
break;
case SB_LINEDOWN:
dx = 1;
break;
case SB_THUMBPOSITION:
dx = HIWORD(wParam) - x;
break;
case SB_PAGEDOWN:
dx = 10;
break;
case SB_PAGEUP:
dx = -10;
break;
default:
dx = 0;
break;
}
dx = max(-x, min(dx, range - x));
if (dx != 0)
{
x += dx;
ScrollWindow(hEdit, 0, -dx, NULL, NULL);
SetScrollPos(hEdit, SB_HORZ, x, TRUE);
UpdateWindow(hEdit);
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 選択されたメニューの解析:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
上記の太線で示している箇所のみ追加です。
resource.h (変更なし)
#define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDC_HP 109 #define IDC_EDIT1 1001
test.rc リソースファイル (変更なし)
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
//
// メニュー
//
IDC_HP MENU
BEGIN
POPUP "ファイル(&F)"
BEGIN
MENUITEM "アプリケーションの終了(&X)", IDM_EXIT
END
POPUP "ヘルプ(&H)"
BEGIN
MENUITEM "バージョン情報(&A)...", IDM_ABOUT
END
END