VC++问题集13

131.用CSplitterWnd产生的视图不能显示。
 分析代码:
 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 {
 if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  return -1;
 // create a view to occupy the client area of the frame
//原先的代码为:
//if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
//  CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))

 if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  CRect(0, 0, 0, 0), this, 0, NULL))
 {
  TRACE0("Failed to create view window/n");
  return -1;
 }
 ...... 
 }
 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
 CRect cr;
 GetClientRect(&cr);  //获得窗口客户区的位置坐标
//m_splitter.CreateStatic(this,3,1);
//函数原型为:
//BOOL CreateStatic( CWnd* pParentWnd, int nRows, int nCols,
// DWORD dwStyle = WS_CHILD | WS_VISIBLE, UINT nID = AFX_IDW_PANE_FIRST );
 m_splitter.CreateStatic(this,3,1,AFX_WS_DEFAULT_VIEW,AFX_IDW_PANE_FIRST );  //创建静态切分窗口
 m_splitter.CreateView(0,0,RUNTIME_CLASS(CStaticView),CSize(cr.Width(),200),pContext);
 m_splitter.CreateView(1,0,RUNTIME_CLASS(CSelectForm),CSize(cr.Width(),200),pContext);
 m_splitter.CreateView(2,0,RUNTIME_CLASS(CManager),CSize(cr.Width(),cr.Height()-400),pContext);
 
 return TRUE;
}
对比原先的代码和改正后的代码就会发现问题所在了。

132.参考资料:
《Visual c++程序开发 范例宝典》 实例018 Out look 导航界面。
                                实例032 不可移动的窗体。
                                实例037 拖动没有标题栏的窗体。

133.为什么在分割窗口中不能直接得到CMainFrame的指针。
 在此程序中分割窗口是通过CSplitterWnd来实现的。其每个子窗口中调用GetParent函数得到的是CSplitterWnd的
 指针(当然这还需要强制转换).而如果要想得到CMainFrame的指针还需要再次调用GetParent函数。

134.显示无模式对话框出现异常。
代码如下:
// m_memberman.Create(IDD_MEMBERMAN);
// m_memberman.ShowWindow(true);
m_memberman为类中定义的变量。
经过验证,错误的代码为:m_memberman.Create(IDD_MEMBERMAN);
解决:这个错误并不是这些代码的问题,而是定义对话框时,把对话框的样式改成“下层”了。只需要把样式属性改成“弹出”即可。

135.获取CSplitterWnd的子窗口出现异常。
代码如下:则个代码是在CSelectForm::Create函数中的代码
 CSplitterWnd * wnd=(CSplitterWnd *)GetParent();
 m_baseView=(CBaseView *)(wnd->GetPane(2,0));
在创建客户窗口中的代码为:
 m_splitter.CreateStatic(this,3,1,AFX_WS_DEFAULT_VIEW,AFX_IDW_PANE_FIRST );  //创建静态切分窗口
 m_splitter.CreateView(0,0,RUNTIME_CLASS(CStaticView),CSize(cr.Width(),80),pContext);
 m_splitter.CreateView(1,0,RUNTIME_CLASS(CSelectForm),CSize(cr.Width(),60),pContext);
 m_splitter.CreateView(2,0,RUNTIME_CLASS(CBaseView),CSize(cr.Width(),cr.Height()-173),pContext);
解决:这个问题的出现不是代码的语法的问题。如果把出现异常的代码放在其他函数体中就好着。这说明了CSplitterWnd创建窗口
 是一个一个创建的,在创建第二个窗口时第三个窗口还没有创建,而代码却要第三个窗口的指针。这样做当然就出错了。

136.如何去掉CSplitterWnd的分割线?
问题描述:
 用CSplitterWnd划分窗口,各个窗口之间有一条分界线。
 分割窗口我在OnCreateClient函数中是这样写的:
 CRect cr;
 GetClientRect(&cr);  //获得窗口客户区的位置坐标
 m_splitter.CreateStatic(this,3,1,AFX_WS_DEFAULT_VIEW,AFX_IDW_PANE_FIRST );  //创建静态切分窗口
 m_splitter.CreateView(0,0,RUNTIME_CLASS(CStaticView),CSize(cr.Width(),80),pContext);
 m_splitter.CreateView(1,0,RUNTIME_CLASS(CSelectForm),CSize(cr.Width(),60),pContext);
 m_splitter.CreateView(2,0,RUNTIME_CLASS(CManager),CSize(cr.Width(),cr.Height()-400),pContext);
问题的初步解决:
 参考网址:
 CSplitterWnd没有提供设置分割条尺寸的public函数,通过分析CSplitterWnd的源码得知:
 它里面有几个没有公开的受保护的成员变量:
 m_cxSplitter,
 m_cySplitter,
 m_cxBorderShare,
 m_cyBorderShare,
 m_cxSplitterGap,
 m_cySplitterGap,
 m_cxBorlder,
 m_cyBorlder
 通过重新构造m_cxSplitterGap,m_cySplitterGap变量的值,就可以实现改变分割条尺寸的功能。
 ————————————解决方案———————————————————
 1.从CSplitterWnd派生一个新类CMySplitterWnd;
 2.在.h文件中添加成员变量和函数如下:
 int m_cx;
 int m_cy;
 void HideSplitter();
 void ShowSplitter();
 3.在.cpp文件中添加实现代码如下:
 void CMySplitterWnd::HideSplitter()
 { 
 m_cx=m_cxSplitterGap;//save previous cx
 m_cy=m_cxSplitterGap;//save previous cy
 m_cxSplitterGap=0;
 m_cySplitterGap=0;
 }
 
 void CMySplitterWnd::ShowSplitter()
 {
 m_cxSplitterGap=m_cx;
 m_cySplitterGap=m_cy;
 }
 4.使用新类CMySplitterWnd生成分割器窗口,在需要的时候调用HideSplitter、ShowSplitter函数即可。
 
 //备注:如果直接运行会出错,需将想隐藏边框的视图隐藏。————–By Lonkil
 原文地址:http://blog.csdn.net/cx0928/archive/2004/10/11/131833.aspx
 这个解答尚有一点问题。m_cxSplitterGap=0;m_cySplitterGap=0;如果不隐藏视图会出现异常。所以在解决我的问题时我把
 m_cxSplitterGap=1;m_cySplitterGap=1;

137.如何设定视图窗口大大小。
 设定视图窗口的大小不能在OnCreate、OnCreateClient等函数中简单的用CREATESTRUCT的对象来设定,而应该在
 CMainFrame::PreCreateWindow调用::AdjustWindowRectEx函数来设定。然后把宽度传递给CREATESTRUCT的引用变量。
 如下代码:
 CRect rect(0,0,800,515);
 ::AdjustWindowRectEx(&rect,cs.style,TRUE,cs.dwExStyle);
 cs.cx=rect.Width();
 cs.cy=rect.Height();
138.MFC中消息映射的怪现象。
 我自定义了一个CEditListCtrl类,其相应的消息有ON_WM_LBUTTONDOWN()、ON_WM_CREATE()、
 ON_EN_KILLFOCUS(1001, DisposeEdit)三个。当我们多次按下鼠标键,跟踪其执行顺序时会发现一个比较奇怪的现象。
 先看为关联的三个函数:
 1.左键按下
 void CEditListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
 {
 // TODO: Add your message handler code here and/or call default
(1) LVHITTESTINFO info;
 info.pt=point;
 if(SubItemHitTest(&info)!=-1){
  m_row=info.iItem;
  m_col=info.iSubItem;
  ShowEdit();
 }
  
(2) CListCtrl::OnLButtonDown(nFlags, point);
 }
 2.显示edit控件
 void CEditListCtrl::ShowEdit()
 {
(3) MessageBox("1");
 CRect rect;
 GetSubItemRect(m_row,m_col,LVIR_LABEL,rect);
 CString str;
 str=GetItemText(m_row,m_col);
 m_edit.MoveWindow(rect);
 m_edit.SetWindowText(str);
 m_edit.ShowWindow(SW_SHOW);
 m_edit.SetSel(0,-1);
// m_edit.SetFocus();
(4) UpdateWindow();
 }
 3.控件失去焦点
 BOOL CEditListCtrl::DisposeEdit()
 {
(5) MessageBox("2");
 CString str;
 m_edit.GetWindowText(str);

(6) this->SetItemText(m_row,m_col,str);
 m_edit.ShowWindow(SW_HIDE);
 ::SendMessage(this->m_hWnd,NULL,NULL,NULL);
(7) return TRUE;
 }
当我第一次按下左键后,出现编辑框,然后在编辑框中输入文字,然后在别的地方按下左键奇怪的现象就出现了。
MFC先响应ON_WM_LBUTTONDOWN(),但还没当ON_WM_LBUTTONDOWN()响应的函数执行完ON_EN_KILLFOCUS(1001, DisposeEdit)
消息响应了。这样就造成了函数执行的错误。可能函数执行的顺序为(1)--(3)--(5)--(4)--(2)--(6)--(7).这也从一方面说明了
消息映射函数执行的独立性。其实这很像是多线程的执行。


139.CString和int连接出错.
 我定义一个CString str=“E2006”;
 然后把它与一个整形数int m_count/*=10*/;相连接。
 但老是不成功。为用的方法是:
 str.Format("%s%d",str,m_count);
 为什么产生的结果不是我所想要的,产生错误的原因是什么,应该如何操作。
解答: 
 str.Format没有连接的能力,CString的Format函数,不能用自身作为参数;sprintf等函数也一样。
MSDN中这样说:
 The call will fail if the string object itself is offered as a parameter to Format. For example, the following code:
 CString str = "Some Data";
 str.Format("%s%d", str, 123);   // Attention: str is also used in the parameter list.
 will cause unpredictable results.

140.类中的静态属性应该怎么初始化?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值