タイトル

コントロール2

タイトル

1,リスト 選択データの取得 ファイル表示
2,コンボボックス
3,スクロールバー よりスクロールバーらしく

1,リスト

リストは複数の項目を表示して、ユーザーに1つ(複数)をその中から
選択するというものです。選択した部分は色が反転しています。

前回と同じように基本クラスをCViewをCFormViewにしたアプリを作成します。

コントロールからリストボックスを選択して配置してください。
コントロールをダブルクリックするとプロパティウィンドウが現れます。
IDは「IDC_LIST1」にします。(おそらく自動でそうなっています。)
この時点でコンパイルをすると次のようになります。

初期のリスト

ここで、マウスのダブルクリックに対応するメッセージハンドラを作成してください。
次のような関数が作成されていると思います。

クラス メッセージ メンバ関数
CNamaeView 左ダブルクリック OnLButtonDblClk

void CNamaeView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	
	
	CFormView::OnLButtonDblClk(nFlags, point);
}

ここで、ListBoxのプロパティの「ソート」のチェックをはずしておいてください。
(自動的に昇順にソートされるため)
そして、次のように書き加えてください。


void CNamaeView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);
	b->InsertString(-1,"first word");
	b->InsertString(-1,"secound words");

	CFormView::OnLButtonDblClk(nFlags, point);
}

InsertString(-1,"word")というのは最後の行に「word」という語を加えるという意味です。
InsertString(0,"word")というのは最初の行に加えます。

リスト2

ただ、これではダブルクリックをするたびに語句が増えていってしまいます。
そこで、初期化もかねて次のようにします。


void CNamaeView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);

	int n,i;
	n=b->GetCount();
	for (i=n-1;i>=0; i--)
		b->DeleteString(i);

	b->InsertString(0,"first word");
	b->InsertString(1,"secound words");

	CFormView::OnLButtonDblClk(nFlags, point);
}

GetCount関数でリストに何項目のデータがあるかが得られます。
DeleteString(i)でi行目のデータを削除できます。
削除は後ろからやります。前の方を先に削除すると2行目がデータがなくて
3行目はあるといったようにデータが連続でなくなってしまいます。
これは、InsertStringでデータを書き加える場合も同じです。


選択データの取得

ユーザーが選択したデータは取得する必要があります。
そこで、クラスウィザードを使ってリストボックスが変化したときに呼び出される
OnDblclkList1というメッセージハンドラを作成してください。
そして次のようにコードを加えます。

クラス メッセージ メンバ関数
CNamaeView Window上で左ダブルクリック OnLButtonDblClk
CNamaeView IDC_LIST1ボックス内でダブルクリック OnDblclkList1

void CNamaeView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);

	int n,i;
	n=b->GetCount();
	for (i=n-1;i>=0; i--)
		b->DeleteString(i);

	b->InsertString(0,"first word");
	b->InsertString(1,"secound words");

	CFormView::OnLButtonDblClk(nFlags, point);
}

void CNamaeView::OnDblclkList1() 
{
	CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);
	CDC* pDC=GetDC();
	char buf[50];
	b->GetText(b->GetCurSel(),buf);
	pDC->TextOut(0,200,buf);
	ReleaseDC(pDC);
}

OnLButtonDblClk関数は変更はしていません。新たなメッセージハンドラとして
OnDblclkList1関数を以上のようにします。
GetCurSel関数は何行目が選択されたかという数字を返します。
GetText関数は指定された行に対応する文字データを変数に代入します。
実行すると以下のようになります。

データの取得


ファイル表示

ファイルの表示は以外と簡単にできます。

クラス メッセージ メンバ関数
CNamaeView Window上で左ダブルクリック OnLButtonDblClk
CNamaeView IDC_LIST1ボックス内でダブルクリック OnDblclkList1

void CNamaeView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);

	int n,i;
	n=b->GetCount();
	for (i=n-1;i>=0; i--)
		b->DeleteString(i);

	b->Dir(DDL_READWRITE,"a:\\windows\\*.*");

	CFormView::OnLButtonDblClk(nFlags, point);
}


void CNamaeView::OnDblclkList1() 
{
	CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);
	CDC* pDC=GetDC();
	char buf[50];
	b->GetText(b->GetCurSel(),buf);
	pDC->TextOut(0,200,buf);
	ReleaseDC(pDC);
}

先ほどのコードのOnLButtonDblClk関数を修正してDir関数を使っただけです。
Dir関数のDDL_READWRITEは読み書き可能ファイルを表示するというものです。
ソートプロパティをOnにしておくと昇順になります。
また、スクロールバーもOnにすることによって自動的に登場します。

ファイル表示

上上へ


2,コンボボックス

コンボボックスは、リストボックスとほぼ同じです。従って、


CListBox* b=(CListBox*)GetDlgItem(IDC_LIST1);


CComboBox* b=(CComboBox*)GetDlgItem(IDC_COMBO1);

に変更することによって対応できます。
ただし、GetText関数は、GetLBTextに変更する必要があります。

また、コンボボックスにはユーザー自身がデータの入力が行える「ドロップダウン」というタイプと、
データー入力が行えない「ドロップダウンリスト」という2種類があります。
「ドロップダウン」の場合、エディターとリストがセットになっているものと考えます。
従ってメンバ関数を定義すれはエディターのようにデータの取得、表示ができます。

上上へ


3,スクロールバー

これは、もうおなじみのスクロールバーのことです。
エディターでもリストボックスでも少し紹介しました。

まず前回と同じように基本クラスをCViewをCFormViewにしたアプリを作成します。
コントロールから以下のように配置してください。

初期のスクロール

文字がありますが、これは「スタティックテキスト」というもので「赤」「緑」「青」
を配置しています。このIDは自動ですべて「IDC_STATIC」になります。

スクロールバーのIDは上から「IDC_SCROLLBAR1」「IDC_SCROLLBAR2」「IDC_SCROLLBAR3」
になっています。

つぎに、クラスウィザードでメッセージ「WM_SHOWWINDOW」に対応するOnShowWindow関数
をつくります。
さらに、スクロールされた場合に呼び出される関数をつくるのですが個々にメッセージは
発行されません。まとめて処理するのです。
水平方向が「WM_VSCROLL」、垂直方向が「WM_HSCROLL」というメッセージです。
ここでは水平方向のメッセージハンドラOnHScrollをつくります。

クラス メッセージ メンバ関数
CNamaeView Windowが現れた OnShowWindow
CNamaeView 水平方向のスクロールがあった OnHScroll

void CNamaeView::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CFormView::OnShowWindow(bShow, nStatus);

	int id[3]={IDC_SCROLLBAR1,IDC_SCROLLBAR2,IDC_SCROLLBAR3};
	CScrollBar* s;
	
	for(int i=0;i<3;i++){
		s=(CScrollBar*)GetDlgItem(id[i]);
		s->SetScrollRange(0,255);
		s->SetScrollPos(0);
	}
}

void CNamaeView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	static int t,r=0,g=0,b=0;
	t=pScrollBar->GetScrollPos();
	if (nSBCode==SB_LINELEFT && t>=10)  t=t-10;
	if (nSBCode==SB_LINERIGHT && t<=245)t=t+10;
	pScrollBar->SetScrollPos(t);
	if (pScrollBar==GetDlgItem(IDC_SCROLLBAR1)) r=t;
	if (pScrollBar==GetDlgItem(IDC_SCROLLBAR2)) g=t;
	if (pScrollBar==GetDlgItem(IDC_SCROLLBAR3)) b=t;

	CDC* pDC=GetDC();
	CBrush brush(RGB(r,g,b));
	CBrush* oldbrush=pDC->SelectObject(&brush);
	pDC->Rectangle(10,10,80,200);
	pDC->SelectObject(oldbrush);
	ReleaseDC(pDC);
	
	CFormView::OnHScroll(nSBCode, nPos, pScrollBar);
}

OnShowWindow関数には、それぞれの最小,最大値を設定と初期位置を決めています。
OnHScroll関数でスクロールバーの位置を移動し、r,g,b変数に代入し描画しています。

スクロールの実行結果


よりスクロールバーらしく

ただ、これだけでは、矢印の部分を押したときしか動きません。
ここで、注目すべきはnSBCodeです。

nSBCode 何が起きたか
左の矢印ボタン
右の矢印ボタン
左側のつまみと矢印ボタン間
右側のつまみと矢印ボタン間
スクロールつまみがドラックされて離された
スクロールつまみがドラック中

また、nPosは現在のつまみの位置です。
これらを使ってOnHScroll関数を以下のようにするとスクロールバーらしくなります。

●namaeView.cpp


void CNamaeView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	static int t,r=0,g=0,b=0;
	t=pScrollBar->GetScrollPos();
	if (nSBCode==0 && t>=10)t=t-10;
	if (nSBCode==1 && t<=245)t=t+10;
	if (nSBCode==2 && t>=10)t=t-30;
	if (nSBCode==3 && t<=245)t=t+30;
	if (nSBCode==4)t=nPos;

	if (nSBCode>=0 && nSBCode<5)pScrollBar->SetScrollPos(t);
	if (pScrollBar==GetDlgItem(IDC_SCROLLBAR1)) r=t;
	if (pScrollBar==GetDlgItem(IDC_SCROLLBAR2)) g=t;
	if (pScrollBar==GetDlgItem(IDC_SCROLLBAR3)) b=t;

	CDC* pDC=GetDC();
	CBrush brush(RGB(r,g,b));
	CBrush* oldbrush=pDC->SelectObject(&brush);
	pDC->Rectangle(10,10,80,200);
	pDC->SelectObject(oldbrush);
	ReleaseDC(pDC);
	
	CFormView::OnHScroll(nSBCode, nPos, pScrollBar);
}

上上へ


戻るC++のPageに戻る