发表于 2007-6-4 11:52:40
默认情况下,
Edit Box
是默认按了
Ctrl
+
Enter
换行,但是在输出数据的时候,这样很不方便,于是就需要设置成自动换行,设置方法是在属性的
Styles
中设置成
Auto VScroll
和
Vertical scroll
,把
Auto HCcroll
去掉,如下图:
论坛中搜索一下
,
你会发现不少类似的提问
:
我如何编辑
list control
的条目
?
如何直接编辑
list control...
等等
;list control
可用来做数据库表的视图
,
十分有用
.
但报表风格的
list control
只能编辑第一列
,
其余的该死的微软没为
vc
做到
.
它怕
VB
卖不出
.
于是
C++
程序员只好
DIY.
主要思想是在
list control
中动态创建一个控件
,
动态移动该控件到相应位置
.
这些方法早有人讨论过了
,
本文也是基于如上思想的
,
但注重于可扩充性与使用的方便
.
List control
这头主要是重载
OnLButtonDown
方法
,
计算出被点中的条目
.
这里重要的函数是
SubItemHitTest
和
GetSubItemRect,
看
msdn
上有相关说明
.
用户点中后
,
就要负责显示控件了
:
如果之前选中了其他
,
就要验证之前的改动是否成功
.
不成功就要回到原来的地方
,
成功就应用修改并移到新位置
.
看代码
:
static const UINT IDCHAILD="3000";
void CValidateList::OnLButtonDown(UINT nFlags, CPoint point)
{
CListCtrl::OnLButtonDown(nFlags, point);
LVHITTESTINFO hi;
hi.pt = point;
if(SubItemHitTest(&hi) != -1 )//
没有点中条目就不管
{if(m_col==-1||//-1
还没被选过
true==(m_col+m_validate)->Validate (m_row))
{
m_row = hi.iItem, m_col= hi.iSubItem;//m_row,m_col
成
//
员分别跟踪选中的行列
}
((m_col+m_validate))->Move (_GetRect(),m_row);
}
}
WinBlast* CValidateList::SetValidate( WinBlast*in)//
设置验证的
//
控件群
,in
对应第一列
,in+1
第二列
……
{
WinBlast*ret=m_validate;
m_validate=in;
int counts="GetHeaderCtrl"()->GetItemCount();;
RECT rect;
memset(&rect,0,sizeof(rect));
for(int i="0";i
(in+i)->Create (this,rect,IDCHAILD+i,i);
m_col=-1;//
没有被选中的
return ret;
}
RECT CValidateList::_GetRect()//
内部使用
,
得到相应显示位置
{
CRect ret;
GetSubItemRect(m_row,m_col,LVIR_BOUNDS,ret);
return ret;
}
void CValidateList::NoSelect()//
置未选中状态
{
m_col=-1;//
没有被选中的
}
看到了
WinBlast*ret=m_validate
吧
.WinBlast
是用来修改和验证数据的控件看它的实现
:
class WinBlast
{
int m_col;//
跟踪列
,
为什么要这个
?
因为你可以让一种控件对
//
不同列用不同的验证策略
CWnd* m_win;//
你的控件窗口
CListCtrl *m_parent;//
用它获得文本
public:
WinBlast(){m_win=NULL;}
~WinBlast(){m_win->DestroyWindow();delete m_win;}
virtual bool Create( CWnd* pParentWnd,
const RECT& rect, UINT nID,
int col)
{
m_col=col;m_parent=(CListCtrl *)pParentWnd;
m_win=new CEdit;
return ((CEdit*)m_win)->
Create(ES_NOHIDESEL,rect,pParentWnd,nID);
}
void Move(const RECT &rect,int row)//
最重要的函数但前面
//
两个动作是必作的
,SetText
为虚
,
你在那做你喜欢的
; {
m_win->ShowWindow(SW_SHOW);
m_win->MoveWindow(&rect);
SetText(row);
}
virtual bool Validate(int row)//
验证
,
虚函数
.
这里永远返回
true
{
m_win->ShowWindow(SW_HIDE);
CString set;
m_win->GetWindowText(set);
m_parent->SetItemText(row,m_col,set);
return true;
}
virtual void SetText(int row)
{
m_win->SetWindowText(m_parent->GetItemText(row,m_col));
((CEdit*)m_win)->SetSel (0,-1);
}
};
实际使用通常是这样的
:
WinBlast*p=new WinBlast[sizeof(col)/sizeof(col[0])];//col
是
//
列名字符数组
,sizeof(col)/sizeof(col[0])
计算列数
m_test.SetValidate (p);//m_test
是
CValidateList
类
你可以继承
WinBlast,
重载
Create
建立一个下拉框
,
加入你喜爱的验证方法
.
注意我的设计漏洞
:CValidateList
应接收
WinBlast**,
而不是
WinBlast*-----
不理解这个漏洞其实也不要紧
:
但要记住
,
不改正的话你的
WinBlast
后继类就不能加数据成员了
.
我在单文档视图中加入一个
List Control
控件
(Report
形式
)
,并关联类
CListCtrl
的一个对象,往里面写数据什么的都行,但在界面上无法实现对报表数据的拷贝(快捷或右键都不行),想请教如何实现拷贝该报表显示的数据?
1
对
CListCtrl
创建
click
事件,记录
item
2
在视图所在的类创建虚函数
PreTranslateMessage
加入代码
if(pMsg->message == WM_KEYDOWN)
{
if(pMsg->wParam==13)//
这里
13
是表示回车键盘,你也可以改成其他的
{
copy();
}
}
3.
编写
copy
函数,取得
item
处的文本,保存只剪切板
4.更改列表控件样式
创建列表控件
(List Control) (CListCtrl)
后,可以在任何时间更改它的窗口样式。通过更改窗口样式来更改控件使用的视图类型。例如,为了模拟“资源管理器”,您可以提供菜单项或工具栏按钮以在不同的视图(图标视图、列表视图等)之间切换控件。
例如,用户选择您的菜单项后,您可以调用
GetWindowLong
来检索控件的当前样式,然后调用