List Control 可编辑任意item文本,设置行高

List Control 可编辑任意item文本,设置行高

 

邵盛松 20101122星期一

 

下载地址:http://download.csdn.net/source/2852621

本文使用Owner Draw实现List Control的重绘

可编辑任意item文本

1List Control 列表控件部分

List ControlOwner Draw Fixed的属性设置为True.编译器的说明是指定所有者窗口将在报表视图中绘制项。也可以使用ModifyStyle函数设置。

必须重载DrawItem函数,在这个函数中编写自己的自绘代码。否则插入数据会弹出一个调试框。

添加一个继承自CListCtrl的类,类名是COrangeListCtrl

在编译器的属性窗口的重写面板,添加DrawItem函数,编译器会自动添加代码

void COrangeListCtrl::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)

{

     // TODO:  添加您的代码以绘制指定项

}

需要将参数的注释符号去掉。启用参数。

在编写之前需要了解一些结构体,因为这个Demo是在Unicode编码下调试的,所以会看到有的结构体名称后面带个W

 

LPDRAWITEMSTRUCT包含项的信息。

LVITEM用于定义项结构。

 

LPDRAWITEMSTRUCT类型的结构

/*

 * DRAWITEMSTRUCT for ownerdraw

 */

typedef struct tagDRAWITEMSTRUCT {

    UINT        CtlType;

    UINT        CtlID;

    UINT        itemID;

    UINT        itemAction;

    UINT        itemState;

    HWND        hwndItem;

    HDC         hDC;

    RECT        rcItem;

    ULONG_PTR   itemData;

} DRAWITEMSTRUCT, NEAR *PDRAWITEMSTRUCT, FAR *LPDRAWITEMSTRUCT;

 

 

 

LVITEM类型的结构

typedef struct tagLVITEMW

{

    UINT mask;

    int iItem;

    int iSubItem;

    UINT state;

    UINT stateMask;

    LPWSTR pszText;

    int cchTextMax;

    int iImage;

    LPARAM lParam;

#if (_WIN32_IE >= 0x0300)

    int iIndent;

#endif

#if (_WIN32_WINNT >= 0x501)

    int iGroupId;

    UINT cColumns; // tile view columns

    PUINT puColumns;

#endif

} LVITEMW, *LPLVITEMW;

 

 

 

重绘部分代码

void COrangeListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

 

     // TODO:  添加您的代码以绘制指定项

     CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

 

     LVITEM lvi = {0};

     lvi.mask = LVIF_STATE;

     lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED ;

     lvi.iItem = lpDrawItemStruct->itemID;

     BOOL bGet = GetItem(&lvi);

 

     BOOL bHighlight =((lvi.state & LVIS_DROPHILITED)||((lvi.state & LVIS_SELECTED) && ((GetFocus() == this)|| (GetStyle() & LVS_SHOWSELALWAYS))));

 

     CRect rcBack = lpDrawItemStruct->rcItem;

 

     if( bHighlight ) //高亮显示

     {

         pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));

         pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));

         pDC->FillRect(rcBack, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));

     }

     else

     {

 

         pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));

         pDC->FillRect(rcBack, &CBrush(::GetSysColor(COLOR_WINDOW)));

 

 

     }

     //绘制文本

     CString strText=L"";

     CRect rcItem;

     if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)

     {

         for (int i = 0; i < GetHeaderCtrl()-> GetItemCount();i++)

         {            

              if ( !GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem ))

                   continue;

              strText = GetItemText( lpDrawItemStruct->itemID, i );

 

              pDC->DrawText(strText,strText.GetLength(), &rcItem, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_BOTTOM);

         }

     }

 

}

子类化之前设置List ControlOwner Draw风格,这样可以不用在资源视图设置Owner Draw Fixed的属性。

void COrangeListCtrl::PreSubclassWindow()

{

     // TODO: 在此添加专用代码和/或调用基类

     ModifyStyle(0,LVS_OWNERDRAWFIXED);

     CListCtrl::PreSubclassWindow();

 

}

 

在单击Item时出现编辑框, m_Edit_ctlItem是自定义的编辑框对象

void COrangeListCtrl::OnLButtonDown(UINT nFlags, CPoint point)

{

     // TODO: 在此添加消息处理程序代码和/或调用默认值

     CListCtrl::OnLButtonDown(nFlags, point);

     CRect rcCtrl;

     LVHITTESTINFO lvhti;

     lvhti.pt = point;

     m_nItem =SubItemHitTest(&lvhti);

     if (m_nItem == -1) return;

     m_nSubItem = lvhti.iSubItem;

     GetSubItemRect(m_nItem,m_nSubItem,LVIR_LABEL,rcCtrl);

     if (m_Edit_ctlItem.m_hWnd == NULL)

     {

         m_Edit_ctlItem.Create(ES_AUTOHSCROLL|WS_CHILD|ES_LEFT|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,99);

         m_Edit_ctlItem.ShowWindow(SW_HIDE);

 

         m_FontItem.CreateStockObject(DEFAULT_GUI_FONT);

         m_Edit_ctlItem.SetFont(&m_FontItem);

         m_FontItem.DeleteObject();

 

     }

     CString strItem=GetItemText(m_nItem,m_nSubItem);

     m_Edit_ctlItem.MoveWindow(&rcCtrl);

     m_Edit_ctlItem.ShowWindow(SW_SHOW);

     m_Edit_ctlItem.SetWindowText(strItem);

     m_Edit_ctlItem.SetFocus();

     m_Edit_ctlItem.SetSel(-1); 

}

添加自定义消息映射函数OnEndEdit表示完成编辑,将编辑框中的数据赋值给点击时所在的项。

消息映射函数声明

afx_msg LRESULT OnEndEdit(WPARAM wParam,LPARAM lParam);

消息映射

ON_MESSAGE(ORANGE_LVN_ENDEDIT, OnEndEdit)

消息映射函数实现部分

LRESULT COrangeListCtrl::OnEndEdit(WPARAM wParam,LPARAM lParam)

 

{

 

     CString strText;

     m_Edit_ctlItem.GetWindowText(strText);

     SetItemText(m_nItem,m_nSubItem,strText);

     m_Edit_ctlItem.ShowWindow(SW_HIDE);

 

 

     return 0;

 

}

2Edit Box 编辑框部分

添加一个继承自 CEdit的类,类名是COrangeEdit

当编辑框失去焦点时发送完成编辑消息

void COrangeEdit::OnKillFocus(CWnd* pNewWnd)

{

     CEdit::OnKillFocus(pNewWnd);

 

     // TODO: 在此处添加消息处理程序代码

     CWnd* pParent = this->GetParent();

 

     ::SendMessage(pParent->GetSafeHwnd(),ORANGE_LVN_ENDEDIT,0,0);

}

 

二 设置行高

 

1)重写MeasureItem函数

void COrangeListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)

{

     if (m_nRowHeight>0)

     {

         lpMeasureItemStruct->itemHeight = m_nRowHeight;

     }

}

注意不是OnMeasureItem函数,MeasureItem需要手动添加

 

2SetRowHeigt设置行高的接口函数

void COrangeListCtrl::SetRowHeigt(int nHeight)

{

     m_nRowHeight = nHeight;

 

     CRect rcWin;

     GetWindowRect(&rcWin);

     WINDOWPOS wp;

     wp.hwnd = m_hWnd;

     wp.cx = rcWin.Width();

     wp.cy = rcWin.Height();

     wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;

     SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);

}

 

以上程序在 VC++2005 Unicode字符集下调试通过

你可能感兴趣的:(struct,list,null,border,报表,编译器)