VC++的一些PAD整理

关于投票
发表于 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 后继类就不能加数据成员了 .
 
3. 如何在VC MFCList Control中实现拷贝功能?
我在单文档视图中加入一个 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 来检索控件的当前样式,然后调用
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值