ウィンドウコントロールに追加したスクロールバーのイベントを取得する方法を紹介します。
ウィンドウコントロールに追加したスクロールバーのイベントを取得します。イベントの検出はWndProcメソッドをオーバーライドしWindowメッセージを取得することで実現します。
コントロールへのスクロールバーの追加方法はこちらの記事を参照してください。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowControlWithScrollBarAndEvent
{
public partial class MyComponent : Control
{
public enum ScrollBarsMode { None, Vertical, Horizontal, Both }
private ScrollBarsMode scrollBarsMode;
private TextBox debugTextBox;
public ScrollBarsMode ScrollBars {
set
{
scrollBarsMode = value;
this.UpdateStyles();
}
get
{
return scrollBarsMode;
}
}
public TextBox DebugTextBox {
set
{
debugTextBox = value;
}
get
{
return debugTextBox;
}
}
public MyComponent()
{
InitializeComponent();
}
public MyComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
switch (message.Msg) {
case WindowsConst.WM_HSCROLL:
if (debugTextBox != null) {
debugTextBox.Text += "WM_HSCROLL\r\n";
short lo = LoWord((long)message.WParam);
switch (lo) {
case WindowsConst.SB_ENDSCROLL:
debugTextBox.Text += "SB_ENDSCROLL\r\n";
break;
case WindowsConst.SB_LEFT:
debugTextBox.Text += "SB_LEFT\r\n";
break;
case WindowsConst.SB_RIGHT:
debugTextBox.Text += "SB_RIGHT\r\n";
break;
case WindowsConst.SB_LINELEFT:
debugTextBox.Text += "SB_LINELEFT\r\n";
break;
case WindowsConst.SB_LINERIGHT:
debugTextBox.Text += "SB_LINERIGHT\r\n";
break;
case WindowsConst.SB_PAGELEFT:
debugTextBox.Text += "SB_PAGELEFT\r\n";
break;
case WindowsConst.SB_PAGERIGHT:
debugTextBox.Text += "SB_PAGERIGHT\r\n";
break;
case WindowsConst.SB_THUMBPOSITION:
debugTextBox.Text += "SB_THUMBPOSITION\r\n";
break;
case WindowsConst.SB_THUMBTRACK:
debugTextBox.Text += "SB_THUMBTRACK\r\n";
break;
}
}
break;
case WindowsConst.WM_VSCROLL:
if (debugTextBox != null) {
debugTextBox.Text += "WM_VSCROLL\r\n";
short lo = LoWord((long)message.WParam);
switch (lo) {
case WindowsConst.SB_BOTTOM:
debugTextBox.Text += "SB_BOTTOM\r\n";
break;
case WindowsConst.SB_ENDSCROLL:
debugTextBox.Text += "SB_ENDSCROLL\r\n";
break;
case WindowsConst.SB_LINEDOWN:
debugTextBox.Text += "SB_LINEDOWN\r\n";
break;
case WindowsConst.SB_LINEUP:
debugTextBox.Text += "SB_LINEUP\r\n";
break;
case WindowsConst.SB_PAGEDOWN:
debugTextBox.Text += "SB_PAGEDOWN\r\n";
break;
case WindowsConst.SB_PAGEUP:
debugTextBox.Text += "SB_PAGEUP\r\n";
break;
case WindowsConst.SB_THUMBPOSITION:
debugTextBox.Text += "SB_THUMBPOSITION\r\n";
break;
case WindowsConst.SB_THUMBTRACK:
debugTextBox.Text += "SB_THUMBTRACK\r\n";
break;
case WindowsConst.SB_TOP:
debugTextBox.Text += "SB_TOP\r\n";
break;
}
}
break;
}
}
protected override CreateParams CreateParams {
get
{
CreateParams cp = base.CreateParams;
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 short LoWord(long input)
{
return (short)((int)input & 0xFFFF);
}
protected short HiWord(long input)
{
return (short)((int)input >> 16);
}
protected long MakeWParam(short l, short h)
{
return MakeLong(l, h);
}
protected long MakeLong(short a, short b)
{
return a & 0xFFFF | b & 0XFFF << 16;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowControlWithScrollBarAndEvent
{
internal class WindowsConst
{
// window style constants for scrollbars
public const int WS_VSCROLL = 0x00200000;
public const int WS_HSCROLL = 0x00100000;
public const int WM_LBUTTONDOWN = 0x00000201;
public const int WM_RBUTTONDOWN = 0x00000204;
public const int WM_HSCROLL = 0x00000114;
public const int WM_VSCROLL = 0x00000115;
/*
* Scroll Bar Commands
*/
public const int SB_LINEUP = 0;
public const int SB_LINELEFT = 0;
public const int SB_LINEDOWN = 1;
public const int SB_LINERIGHT = 1;
public const int SB_PAGEUP = 2;
public const int SB_PAGELEFT = 2;
public const int SB_PAGEDOWN = 3;
public const int SB_PAGERIGHT = 3;
public const int SB_THUMBPOSITION = 4;
public const int SB_THUMBTRACK = 5;
public const int SB_TOP = 6;
public const int SB_LEFT = 6;
public const int SB_BOTTOM = 7;
public const int SB_RIGHT = 7;
public const int SB_ENDSCROLL = 8;
}
}
コントロールへスクロールバーを表示する部分のコードはこちらの記事を参照してください。
WndProcメソッドをオーバーライドしWindowメッセージを取得します。
コントロールのスクロールバーがクリックされると、縦方向スクロールバーの場合はWM_VSCROLLが、横方向スクロールバーの場合はWM_VSCROLLメッセージがコントロールに送られます。
WndoProcメソッドでそれらのイベントを受け取り、デバッグ用のテキストボックスにその値を表示します。
縦方向スクロールバーでの上下ボタン判別、横方向スクロールバーでの左右ボタンの判別は、WindowメッセージのWParamの値で判別します。
WParamの値を判定することで、ボタンがクリックされたか、ページスクロールか、Thumbがドラッグされたかを調べることができます。
コンポーネントを配置するアプリケーション部は以下のUIとコードを用意します。
下図のフォームを作成します。作成したウィンドウコントロールのコンポーネントとボタンを配置します。
MyComponentのScrollBarsプロパティをBoth
に設定します。
以下のコードを記述します。ButtonコントロールのClickイベントを実装します。
namespace WindowControlWithScrollBarAndEvent
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
FormLogView f = new FormLogView();
myComponent1.DebugTextBox = f.textBox1;
f.Show();
}
}
}
Button1をクリックするとコンポーネントのDebugTextBoxにログビューのテキストボックスを設定し、ログビューのフォームを表示します。
下図のフォームを作成します。MutilineプロパティをTrueに設定したテキストボックスを配置します。
ログビューのコードは以下です。追加するコードはありません。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowControlWithScrollBarAndEvent
{
public partial class FormLogView : Form
{
public FormLogView()
{
InitializeComponent();
}
}
}
プロジェクトを実行します。下図のウィンドウが表示されます。
Button1をクリックします。ログビューのウィンドウが表示され、下図の状態になります。
コントロールのスクロールバーをクリックするとデバッグウィンドウにメッセージが表示されます。