天天看点

MFC下小问题解决

1.MFC下分割屏(左边为A对话框和A类,右边为B对话框和B类),菜单栏控制A对话框的按钮定义在A类;菜单栏控制B对话框的按钮定义在B类中。在菜单栏中默认情况下控制B对话框相关操作的按钮为灰色,A对话框的正常;当鼠标点击B对话框任意处,发现菜单栏上A对话框的相关操作按钮变灰,B的正常。这是什么原因?

答:这是因为焦点问题。就好比有多个对话框,你点击A对话框,A上的编辑框才能输入,而B对话框的控件是无法输入的,需要通过点击控件即将焦点设置在该对话框上才能使用对话框上的控件。

2.关于Updatedata()的效用范围。

答:Updatedata()函数可以更新应用此句代码的类中,所有控件的数据更新,而不更新其他类、其他线程的数据。

3.关于GetDlgItem()参数的问题。

答:GetDlgItem(IDC_XXXX)参数只能是运行此句的类中的控件,其他类的控件、对话框、本类对话框的ID都无法通过GetDlgItem获取其指针等。

4.MessageBox的巧用。

MFC下可以通过加入Messagebox弹出对话框,来完成COUT 函数功能。如,在任意处加入以下语句:

       MessageBox(_T("程序已运行到此处"));

   或用MessageBox输变量:

       int posX = 100;

       int posY = 100;

       CString STemp;

       STemp.Format( _T("%d %d"),posX,posY );

       MessageBox( STemp );

5.关于单文档Ribbon类型中滑动条和编辑框的使用。

 滑动条利用:

       第一步,给滑动条添加消息类型为:UPDATE_COMMAND-UI的消息处理函数,并在类列表中选择“CMainFrame”类(且只能选此,见注1),在生成的函数中输入:

void CMainFrame::OnUpdateSlider1(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->Enable(TRUE); //即激活滑动条。
}
           

第二步,添加消息类型为:COMMAND类型的消息处理函数,并在类列表中选择“CMainFrame”类(且只能选次),在生成的函数中输入:

void CMainFrame::OnSlider1()
{
     // TODO: 在此添加命令处理程序代码
     CMFCRibbonSlider* pSlider = DYNAMIC_DOWNCAST(CMFCRibbonSlider, m_wndRibbonBar.FindByID(ID_SLIDER1));//见注2
     int position =pSlider->GetPos();//将此时滑动条所在位置的值赋给position。
}
           

完。

注(1):关于滑动条的两个函数必须生成在CMainFrame类的原因。

     因为CMFCRibbonSlider类型的变量m_wndRibbonBar是在”MainFrm.h”中定义,包括”MainFrm.cpp”中,还有很多变量初始化的东西,所以不好改。

注(2):关于第二步中第一行代码的函数说明。

DYNAMIC_DOWNCAST(class, pointer)函数:

     函数作用为:如果pointer指针所指向的对象是class类型的,就返回这个指针;否则返回NULL。

     第二步第一行代码,在使用时只需更改括号内ID即可。滑动条属于CMFCRibbonSlider类,变量为m_wndRibbonBar,这是MFC自动生成的,一般不需要改。

编辑框的使用:

 给滑动条添加消息类型为:UPDATE_COMMAND-UI的消息处理函数,并在类列表中选择“CMainFrame”类(且只能选此),在生成的函数中输入:

void CMainFrame::OnUpdateEdit2(CCmdUI *pCmdUI)
{
     // TODO: 在此添加命令更新用户界面处理程序代码
     pCmdUI->Enable(TRUE);//即激活滑动条。
     pCmdUI->SetText(_T("512*512"));//在编辑框中显示“512*512”。
}
           

完。

6.关于初始化时窗口大小、位置的设置。

6.1 当为对话框时:

   在CXXXDlg::OnInitDialog()中,添加以下代码:

BOOL CHandDlg::OnInitDialog()
{
         CDialogEx::OnInitDialog();
 
         MoveWindow(0,0,512,512);//只添加此句即可。
 
         returnTRUE;  // return TRUE unless you set thefocus to a control
         //异常: OCX 属性页应返回 FALSE
}
           

不在PreCreateWindow()函数中改的原因如下,有兴趣可以看下:

        一般的窗口的创建是使用Create函数,这个函数在创建窗口之前调用了PreCreateWindow函数,并且允许在创建创建之前在 PreCreateWindow注册一个拥有自定义窗口样式的新的窗口类,来创建一个拥有自定义类名新的窗口。而模式对话框是通过 CreateDialogIndirect来创建的,在这当中并没有调用PreCreateWindow函数,重载的PreCreateWindow函数根本就不被执行,因此在这个函数里修改对话框的窗口类是没有用的。

6.2当为非对话框时:

第一步:在在App类的InitInstance()函数中ShowWindow();UpdateWindow()函数之前添加此句:CleanState(_T("WorkSpace"));用以清除保存的上次的状态,否则在PreCreateWindow()设置窗口的参数都无效。代码如下:

BOOL CMFCive18App::InitInstance()
{
……
……
         CleanState(_T("WorkSpace"));//加此句,且一定要在下面if、showWindow、UpdateWindow之前,否则无效。</span>
         if (!ProcessShellCommand(cmdInfo))
           return FALSE;         
         m_pMainWnd->ShowWindow(SW_SHOW);
         m_pMainWnd->UpdateWindow();
……
……
return TRUE;
}
           

第二步:在Mainfrm.cpp中的PreCreateWindow()函数中添加以下代码:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT&cs)
{
         if(!CFrameWndEx::PreCreateWindow(cs) )
                   returnFALSE;
         //TODO: 在此处通过修改
         //  CREATESTRUCT cs 来修改窗口类或样式
         cs.cx= 1024;//主框架宽度(width)
         cs.cy= 1024;//主框架高度(height)
         cs.x= 0;//窗口起始x坐标
         cs.y= 0;//窗口起始y坐标
         returnTRUE;
}
           

完成。

另:

对于非对话框窗口,还可利用此方法:在App类的InitInstance中ShowWindow();UpdateWindow()之前修改窗口大小,例如  m_pMainWnd->MoveWindow(CRect(100, 100,600, 400), FALSE);,代码如下:

BOOL CMFCive18App::InitInstance()
{
……
……
         m_pMainWnd->MoveWindow(0,0,1024,1024);//加此句即可,m_pMainWnd为主窗口默认指针,此句要保证在下面两行代码前。
         m_pMainWnd->ShowWindow(SW_SHOW);
         m_pMainWnd->UpdateWindow();
……
……
return TRUE;
}
           

6完结。

MFC