ウィンドウコントロールのスクロールバー情報の取得と設定
ウィンドウコントロールのスクロールバーの情報を取得、設定するコードを紹介します。
ウィンドウコントロールのスクロールバーの情報の取得はGetScrollInfo() Windows APIを、スクロールバーの設定はSetScrollInfo() Windows APIを用います。
コード
VisualComponent.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Permissions;
using System.Drawing;
using System.Runtime.InteropServices;
namespace WinformVisualComponent
{
public partial class VisualComponent : Control
{
[StructLayout(LayoutKind.Sequential)]
struct SCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
private enum ScrollBarDirection
{
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2,
SB_BOTH = 3
}
private enum ScrollInfoMask
{
SIF_RANGE = 0x0001,
SIF_PAGE = 0x0002,
SIF_POS = 0x0004,
SIF_DISABLENOSCROLL = 0x0008,
SIF_TRACKPOS = 0x0010,
SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
//SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);
[DllImport("user32.dll")]
static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi,
bool fRedraw);
public enum ScrollBarsMode { None, Vertical, Horizontal, Both }
private ScrollBarsMode scrollBarsMode;
public ScrollBarsMode ScrollBars
{
set
{
scrollBarsMode = value;
this.UpdateStyles();
}
get
{
return scrollBarsMode;
}
}
public VisualComponent()
{
InitializeComponent();
}
public VisualComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
protected override CreateParams CreateParams
{
get
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
CreateParams cp = base.CreateParams;
//cp.Style = cp.Style + WS_HSCROLL + WS_VSCROLL;
int ScrollBarFlag = 0;
switch (scrollBarsMode) {
case ScrollBarsMode.None:
ScrollBarFlag = 0;
break;
case ScrollBarsMode.Horizontal:
ScrollBarFlag = WindowsConst.WS_HSCROLL;
break;
case ScrollBarsMode.Vertical:
ScrollBarFlag = WindowsConst.WS_VSCROLL;
break;
case ScrollBarsMode.Both:
ScrollBarFlag = WindowsConst.WS_HSCROLL + WindowsConst.WS_VSCROLL;
break;
}
cp.Style |= ScrollBarFlag;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
public void SetVScrollBar(int Position, uint Page, int nMin, int nMax, out int TrackPosition)
{
SCROLLINFO VScrInfo = new SCROLLINFO();
GetScrollInfo(this.Handle, (int)ScrollBarDirection.SB_VERT, ref VScrInfo);
VScrInfo.cbSize = (uint)Marshal.SizeOf(VScrInfo);
VScrInfo.nPos = Position;
VScrInfo.nPage = Page;
VScrInfo.nMin = nMin;
VScrInfo.nMax = nMax;
TrackPosition = VScrInfo.nTrackPos;
VScrInfo.fMask = (int)ScrollInfoMask.SIF_POS + (int)ScrollInfoMask.SIF_PAGE
+ (int)ScrollInfoMask.SIF_RANGE + (int)ScrollInfoMask.SIF_DISABLENOSCROLL;
SetScrollInfo(this.Handle, (int)ScrollBarDirection.SB_VERT, ref VScrInfo, true);
}
}
}
アプリケーション部(UI)
下図のUIを用意します。使用するのは配置したカスタムコンポーネントと"SetVScrollBar"のボタンです。
アプリケーション部(コード)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WinformVisualComponent
{
public partial class SubFormScroll : Form
{
public SubFormScroll()
{
InitializeComponent();
}
private void button_SetVScrollBar_Click(object sender, EventArgs e)
{
visualComponent1.ScrollBar = ScrollBarsMode.Vertical;
int TrackPos;
visualComponent1.SetVScrollBar(0, 100,0,200, out TrackPos);
}
}
}
解説
SetVScrollBarメソッドで縦方向スクロールバーの情報を設定します。SCROLLINFOのnPosはスクロールバーのスクロール(つまみ)位置、nPageはスクロールバーのページスクロール(つまみの上下をクリックした際)でのスクロール量、nMinはスクロールバーの最小値の値、nMaxはスクロールバーの最大値の値になります。
nTrackPosはGetScrollInfo()関数をSIF_TRACKPOSフラグを設定して呼び出した場合、現在のスクロールバーのつまみの位置を返します。
補足
横方向スクロールバーの情報取得、設定をする場合はGetScrollInfo, SetScrollInfoの台に引数にSB_HORZを指定します。
public void SetHScrollBar(int Position, uint Page, int nMin, int nMax, out int TrackPosition)
{
SCROLLINFO VScrInfo = new SCROLLINFO();
GetScrollInfo(this.Handle, (int)ScrollBarDirection.SB_HORZ, ref VScrInfo);
VScrInfo.cbSize = (uint)Marshal.SizeOf(VScrInfo);
VScrInfo.nPos = Position;
VScrInfo.nPage = Page;
VScrInfo.nMin = nMin;
VScrInfo.nMax = nMax;
TrackPosition = VScrInfo.nTrackPos;
VScrInfo.fMask = (int)ScrollInfoMask.SIF_POS + (int)ScrollInfoMask.SIF_PAGE
+ (int)ScrollInfoMask.SIF_RANGE + (int)ScrollInfoMask.SIF_DISABLENOSCROLL;
SetScrollInfo(this.Handle, (int)ScrollBarDirection.SB_HORZ, ref VScrInfo, true);
}
実行結果
実行直後で縦方向スクロールバーを表示した状態です。
"SetVScrollBar"ボタンを押しスクロールバーのスクロール範囲を設定後の画面です。スクロール範囲が0~200に対してページ幅が100なのでつまみがスクロールバーの長さの半分になっています。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用