リストコントロール初期化

初期化

STEP0

リストコントロールは初期化をしなければ使えません。リストコントロールに対する初期化は非常に重要な物です。下記の画像はシングルドドキュメントの理論で自動的にプロジェクトを作成した後にリストボックスを二つ配置しています、このプロジェクトを使い色々な事柄を確認して行きたいと思います。まずは一番最初にリストコントロールを扱いながらコントロールの概念を御説明したいと思います。

初期化コンテンツ

  1. リストコントロール 初期化 初期化2 初期化3 初期化4
  2. ストコントローラ内部に 罫線1 罫線2 画面
  3. リストの高さを変えるコード
  4. 選択されたセルの制御コード
  5. セルに入力設定を組み込むコード
  6. BMPイメージをリスト内に表示するコード
  7. BMPファイルをアクセスするコード

STEP1

メッセージマップ内に項目番号3、4行の様に記載します。

BEGIN_MESSAGE_MAP(ControlPracticeView, CFormView)
     ON_WM_SIZE()
     ON_WM_DRAWITEM()
     ON_WM_MEASUREITEM()
 END_MESSAGE_MAP()

STEP2

この初期化の中で項目13、24行の記載コードは特に重要でこれらが抜けている場合には表示制御が行えないばかりかシステムのダウンにもつながり皆さんがパニックになるヶ所でもあります、特に注意して下さい。

CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); //============================================================ LV_COLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; //============================================================ for (int i=0;i<3;i++){ lvc.iSubItem= i; lvc.pszText=ControlPracticeColumnLabel[i]; lvc.cx =(int)(ControlPracticeWidth[i]); lvc.fmt =ControlPracticeFmt[i]; CtlistControl1.InsertColumn(i,&lvc); } //============================================================ //============================================================ //============================================================ LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_PARAM ; lvi.iSubItem =0; for(int i=0;i<5;i++){ lvi.iItem =i; lvi.pszText =ControlPracticeView_buffDim[i][0]; CtlistControl1.InsertItem(&lvi); } //============================================================ //======================ツリ-構築============================ //============================================================ int cunt=(int)arrayDirectoryList.GetCount();//ファイル総数の確認 for(int i=0;i<cunt;i++){ CString vl=arrayDirectoryList.GetAt(i); TreeMenberChck(vl);//ツリ-に項目を追加して行きます } ctTreeCtr1.MoveWindow(5,90,270,250); ctTreeCtr1.ShowWindow(SW_SHOW) ;

STEP3

下記のコードはスタティツクエリヤに定義する物で必ず準備する必要があります。

static int MS_HE[] = { -7,-8,-9,-10,-11,-12,-13,-15,-16,-19,-21,-24,-27,-29,-32,-35,-37 };//MSゴシック

STEP4

下記の画像はDrawItemと言いリストコントロールの表示を制御する為にウインドウズシステムから呼ばれます、呼ばれる条件は、画面に更新が必要な場合、プログラムユザーがシステムに向けて画面更新を要求した場合に分かれて呼び出されます。

ユザーが任意に呼び出す場合にはListControl.Invalidate(FALSE)を記載しても間接的にOnDrawItemを呼び出す事が出来ます。

public:
     afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);

void ControlPracticeView::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CControlPracticeDoc* pDoc = GetDocument();

//========================================================

CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcItem(lpDrawItemStruct->rcItem);
int nItem = lpDrawItemStruct->itemID  ;

//=============================================
LV_ITEM     lvi;
switch(lpDrawItemStruct->CtlID) {
        case IDC_LIST1:
                        lvi.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_PARAM ; 
                        lvi.iSubItem =0;
                        //=========================================
                        lvi.iItem    =nItem;
                        lvi.pszText =ControlPracticeView_buffDim[nItem][0];
                        CtlistControl1.SetItem(&lvi);
                        for(int sub=0;sub<7;sub++){
                                    CString sb=CtlistControl1.GetItemText(nItem,sub);
                                    if(sb!=(CString)ControlPracticeView_buffDim[nItem][sub]){
                                                CtlistControl1.SetItemText(nItem,sub,ControlPracticeView_buffDim[nItem][sub]);
                                                }
                                    }
                        //=========================================
                        List1RowListControl(pDC,nItem);
                        break;
        }

}

時分割(疑似マルチタスク)

システム側は時分割処理を行っています。例えば10種類の仕事がある時を考えて見ますこの場合、仮に一種類の作業時間10分×10種類で全部で100分係ります、ウィンドウズの場合10分で処理が終わりますが後90分待つ必要が有りますがこれでは物凄く都合が悪いので10分の仕事を5秒にして10回転(10種類の作業)させれば見かけ上5×10で50秒で終わりますこれを延々と繰り返せば見かけ上システムの待機は45秒で良い計算になります、このやり方が時分割と呼ばれています(疑似マルチタスクです)。

時は金なり

STEP5

この関数はシステム側から呼ばれます、例えば画面が重なった時とか更新の必要が有る場合にアイテムの番号も指示されて来ますが処理は指示された行数にだけ処理を行わなければ行けません(表示にはコストが係るのです)。

step5
関数実装

STEP6

罫線を引きます

STEP7

綺麗に引けましたが問題が有ります、スクロールを動かすと罫線が消えてしまいますこれはスクロルの動きではシステム側では更新が必要だとは認識しない為にこの様な事がおきます、この場合はプログラムユザーが明示的にシステムに対して更新要求を出す必要があります。

それを解決するのがctListControl1.Invalidate(FALSE)と言う関数ですこれを呼び出すとDrawItem()が強制的に自動で起動されて来ますから罫線を引けば良いのです。

step6
この様になりました

ビュー切り替え(続2) ツリーコントロール(CTreeCtrl)の初期化 VC++ MFCに印刷機構を組み込む手順の解説