关闭

VC++的一些PAD整理

544人阅读 评论(0) 收藏 举报
关于投票
发表于 2007-6-4 11:52:40
 
 
默认情况下,Edit Box是默认按了CtrlEnter换行,但是在输出数据的时候,这样很不方便,于是就需要设置成自动换行,设置方法是在属性的Styles中设置成Auto VScrollVertical scroll,把Auto HCcroll去掉,如下图:
点击看大图

 
论坛中搜索一下,你会发现不少类似的提问:我如何编辑list control的条目?如何直接编辑list control...等等;list control可用来做数据库表的视图,十分有用.
但报表风格的list control只能编辑第一列,其余的该死的微软没为vc做到.它怕VB卖不出.于是C++程序员只好DIY.主要思想是在list control中动态创建一个控件,动态移动该控件到相应位置.这些方法早有人讨论过了,本文也是基于如上思想的,但注重于可扩充性与使用的方便.
List control 这头主要是重载OnLButtonDown方法,计算出被点中的条目.这里重要的函数是SubItemHitTestGetSubItemRect,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_testCValidateList
你可以继承WinBlast,重载Create建立一个下拉框,加入你喜爱的验证方法.
注意我的设计漏洞:CValidateList应接收WinBlast**,而不是WinBlast*-----不理解这个漏洞其实也不要紧:但要记住,不改正的话你的WinBlast后继类就不能加数据成员了.
 
3. 如何在VC MFCList Control中实现拷贝功能?
我在单文档视图中加入一个List Control控件(Report形式),并关联类CListCtrl的一个对象,往里面写数据什么的都行,但在界面上无法实现对报表数据的拷贝(快捷或右键都不行),想请教如何实现拷贝该报表显示的数据?
1CListCtrl创建click事件,记录item
2在视图所在的类创建虚函数PreTranslateMessage
加入代码
if(pMsg->message == WM_KEYDOWN)
{
if(pMsg->wParam==13)//这里13是表示回车键盘,你也可以改成其他的
{
copy();
}
}
3.编写copy函数,取得item处的文本,保存只剪切板
 
4.更改列表控件样式
创建列表控件 (List Control) (CListCtrl) 后,可以在任何时间更改它的窗口样式。通过更改窗口样式来更改控件使用的视图类型。例如,为了模拟“资源管理器”,您可以提供菜单项或工具栏按钮以在不同的视图(图标视图、列表视图等)之间切换控件。
例如,用户选择您的菜单项后,您可以调用 GetWindowLong 来检索控件的当前样式,然后调用
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:164669次
    • 积分:2404
    • 等级:
    • 排名:第16022名
    • 原创:50篇
    • 转载:120篇
    • 译文:0篇
    • 评论:7条
    最新评论
    NO Problem