MFC学习总结

个人财务管理软件设计中MFC控件的使用(List)

1.添加内容

//将添加的信息在列表中显示
	CString sName, sDate, sPlace, sSalary, sBonus, sAlimony;
	ifstream addfin("adduse.txt", ios::in);
	string a1, a2, a3, a4, a5, a6;
	while(addfin >> a1>> a2 >> a3 >> a4 >> a5 >> a6)
	{
	sName=a1.c_str();
	sDate = a2.c_str();
	sPlace = a3.c_str();
	sSalary = a4.c_str();
	sBonus = a5.c_str();
	sAlimony = a6.c_str();
	myList1.InsertItem(0, NULL);//插入一个行
	myList1.SetItemText(0, 0, sName);//填充数据
	myList1.SetItemText(0, 1, sDate);
	myList1.SetItemText(0, 2, sPlace);
	myList1.SetItemText(0, 3, sSalary);
	myList1.SetItemText(0, 4, sBonus);
	myList1.SetItemText(0, 5, sAlimony);
	}

2.删除内容

//判断列表框中是否有记录
	if (!myList1.GetItemCount())	{
		MessageBox(L"暂无记录", L"警告",  MB_OKCANCEL | MB_ICONEXCLAMATION);
		return;
	}
	//判断是否选中一项,若选中则删除
	POSITION ps;
	int index = 0;
	ps = myList1.GetFirstSelectedItemPosition();
	index = myList1.GetNextSelectedItem(ps);//标记行号
	if (-1 == index)
	{
		MessageBox(L"请选中一行数据", L"警告", MB_OKCANCEL | MB_ICONEXCLAMATION);
		return;
	}
	else
	{
		if (IDOK == MessageBox(L"确定删除?", L"提示", MB_OKCANCEL | MB_ICONQUESTION))
		{
			myList1.DeleteItem(index);
		}
	}

3.修改内容

// 删除再添加

4.查询内容

CString str, cbsel;
	int nIndex = myCombo.GetCurSel();
	myCombo.GetLBText(nIndex, str);
	GetDlgItemText(IDC_CBSEL, cbsel);
	UpdateData(TRUE);
	int i,flag = 0;
	if (str == "姓名")
	{
		for (i = 0; i<myList1.GetItemCount(); ++i)
		{
			if (cbsel == myList1.GetItemText(i, 0))
			{
				myList2.InsertItem(0, NULL);
				myList2.SetItemText(0, 0, myList1.GetItemText(i, 0));
				myList2.SetItemText(0, 1, myList1.GetItemText(i, 1));
				myList2.SetItemText(0, 2, myList1.GetItemText(i, 2));
				myList2.SetItemText(0, 3, myList1.GetItemText(i, 3));
				myList2.SetItemText(0, 4, myList1.GetItemText(i, 4));
				myList2.SetItemText(0, 5, myList1.GetItemText(i, 5));
				UpdateData(FALSE);
				flag = 1;
			}
		}
	}
	else if (str == "...")//其他查询条件的实现方法基本相同,不再赘述

5.保存到文档

USES_CONVERSION;
	char* save1;
	ofstream savefile;
	savefile.open("SAVEFILE.txt", ios::out);
	for(int j=0;j<myList1.GetItemCount();++j)
	{
		save1 = W2A(myList1.GetItemText(j, 0));
		savefile << save1 << " ";
		save1 = W2A(myList1.GetItemText(j, 1));
		savefile << save1 << " ";
		save1 = W2A(myList1.GetItemText(j, 2));
		savefile << save1 << " ";
		save1 = W2A(myList1.GetItemText(j, 3));
		savefile << save1 << " ";
		save1 = W2A(myList1.GetItemText(j, 4));
		savefile << save1 << " ";
		save1 = W2A(myList1.GetItemText(j, 5));
		savefile << save1 << " " << endl;
	}
	savefile.close();
	MessageBox(L"保存成功", L"提示", MB_OKCANCEL);

这个里功能更全面:百度文库-MFC学生信息管理系统详解

list control控件的使用

1.设置listctrl 风格及扩展风格

      LONG lStyle;
      lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口style
      lStyle &= ~LVS_TYPEMASK; //清除显示方式位
      lStyle |= LVS_REPORT; //设置style
      SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle);//设置style
  	  DWORD dwStyle = m_list.GetExtendedStyle();
      dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
      dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
      dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
      m_list.SetExtendedStyle(dwStyle); //设置扩展风格

2.插入数据

	m_list.InsertColumn( 0, "id", LVCFMT_LEFT, 40 );//插入列
    m_list.InsertColumn( 1, "name", LVCFMT_LEFT, 50 );
    int nRow = m_list.InsertItem(0, “”);//插入行
    m_list.SetItemText(nRow, 0,12138);//设置数据,第1列
    m_list.SetItemText(nRow, 1, “Jack”);//设置数据,第2列

3.选中和取消选中一行

	int nIndex = 0;
    //选中
    m_list.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
    //取消选中
    m_list.SetItemState(nIndex, 0, LVIS_SELECTED|LVIS_FOCUSED);

4.得到listctrl中所有行的checkbox的状态

      m_list.SetExtendedStyle(LVS_EX_CHECKBOXES);
      CString str;
      for(int i=0; i<m_list.GetItemCount(); i++)
      {
           if( m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED || m_list.GetCheck(i))
           {
                str.Format(_T("第%d行的checkbox为选中状态"), i);
                AfxMessageBox(str);
           }
      }

5.得到listctrl中所有选中行的序号

      POSITION pos = m_list.GetFirstSelectedItemPosition();
      if (pos == NULL)
           TRACE0("No items were selected!\n");
      else
      {
           while (pos)
           {
                int nItem = m_list.GetNextSelectedItem(pos);
                TRACE1("Item %d was selected!\n", nItem);
                // you could do your own processing on nItem here
           }
      }

6.得到单击的listctrl的行列号

     //添加listctrl控件的NM_CLICK消息相应函数
      void CTest6Dlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
      {
           // 方法一:
           /*
           DWORD dwPos = GetMessagePos();
           CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
           m_list.ScreenToClient(&point);
           LVHITTESTINFO lvinfo;
           lvinfo.pt = point;
           lvinfo.flags = LVHT_ABOVE;
           int nItem = m_list.SubItemHitTest(&lvinfo);
           if(nItem != -1)
           {
                CString strtemp;
                strtemp.Format("单击的是第%d行第%d列", lvinfo.iItem, lvinfo.iSubItem);
                AfxMessageBox(strtemp);
           }
          */
   
          // 方法二:
          /*
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           if(pNMListView->iItem != -1)
           {
                CString strtemp;
                strtemp.Format("单击的是第%d行第%d列",
                                pNMListView->iItem, pNMListView->iSubItem);
                AfxMessageBox(strtemp);
           }
          */
           *pResult = 0;
      }

7.得到listctrl的所有列的header字符串内容

      LVCOLUMN lvcol;
      char  str[256];
      int   nColNum;
      CString  strColumnName[4];//假如有4列

      nColNum = 0;
      lvcol.mask = LVCF_TEXT;
      lvcol.pszText = str;
      lvcol.cchTextMax = 256;
      while(m_list.GetColumn(nColNum, &lvcol))
      { 
           strColumnName[nColNum] = lvcol.pszText;
           nColNum++;
      }

8.右键点击listctrl的item弹出菜单

      //添加listctrl控件的NM_RCLICK消息相应函数
      void CTest6Dlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
      {
           NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
           if(pNMListView->iItem != -1)
           {       
                m_pRClickMenu = new CMenu();
         ASSERT(m_pRClickMenu != NULL);
                m_pRClickMenu->CreatePopupMenu();
              m_pRClickMenu->AppendMenu(MF_STRING, IDC_BTN_SEND_EMAIL, "发送邮件");
         m_pRClickMenu->AppendMenu(MF_STRING, IDC_BTN_COPY, "复制到剪切板");
                // DWORD dwPos = GetMessagePos();
               // CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
                CPoint point;
  GetCursorPos(&point);
  m_pRClickMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this, NULL);
           } 
           *pResult = 0;
  }

combo box控件的使用

1.改变下拉框大小
  1)直接在控件上操作,先点向下的箭头,就可以调整下拉框大小;

2)为了让列表框变的更宽,可以用setdroppedwidth(int width)函数来调整列表框的宽度。

2.定义控件对应变量

假定已经创建了一个Dialog,并且从控件工具箱将Combo Box 控件拖放到上面。打开 Class Wizard,添加控件对应变量,如:CComboBox m_combo。

3.向控件添加 Items

1)在Combo Box控件属性的Data标签里面添加,一行表示Combo Box下拉列表中的一行。换行用ctrl+回车。若在VS2005中,Items间用";"隔开即可;

2)利用函数 AddString()向 Combo Box 控件添加Items,如:

m_combo.AddString(“StringData1”);

m_combo.AddString(“StringData2”);

m_combo.AddString(“StringData3”);

3) 也可以调用函数 InsertString() 将 Item 插入指定位置 nIndex,如:

m_combo.InsertString(nIndex, “StringData” );

4)int GetCount( )可以得到当前列表框中行的数量。

示例代码:程序初始化时动态添加Items

CString strTemp;

m_combo.ResetContent();//消除现有所有内容

for(inti=1;i<=100;i++)

{

strTemp.Format("%d",i);

m_combo.AddString(strTemp);

}

4.从控件得到选定的Item

假设在控件列表中已经选定某项,现在要得到被选定项的内容,首先要得到该项的位置,然后得到对应位置的内容。这里会用到两个函数,如:

int nIndex = m_combo.GetCurSel();

CString strText;

m_combo.GetLBText( nIndex, strText);

这样,得到的内容就保存在 strText 中。若要选取当前内容,可调用函数GetWindowText(strText)。

5.在控件中查找给定Item

这种操作一般用于在程序中动态修改控件中该项的值,可以用函数FindStringExact() 精确匹配,如:

int nIndex = m_combo.FindStringExact( nStartAfter, “value to befound”);

nStartAfter指明从哪一行开始查找。如果查找成功,返回的是该项的位置;否则,返回CB_ERR。

也可以选中包含指定字符串的项,如:

int nIndex = m_combo.SelectString( nStartAfter, “value to beselected”);

6.删除控件中的Item

该操作可以利用函数DeleteString(),需要指定被删除项的位置,如:

m_combo.DeleteString(nIndex);

也可以使用函数ResetContent(),清除目前的所有项,如:

m_combo.ResetContent();

文件保存

//法1.C++,fstream类的操作

//法2.MFC的CFile操作:
CFile test;
CFileException e;
TCHAR* pszFileName = "test.txt";
if(!test.Open(pszFileName,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite, &e))//建立、打开test.txt文件
{
   AfxMessageBox("File could not be opened %d\n", e.m_cause);
}

CString m_str;
pm_dedit=(CEdit*)GetDlgItem(IDC_edit);
pm_dedit->GetWindowText(m_str);
test.Write(m_str,m_str.GetLength());                       
m_str.Close();//关闭文件

//法3.MFC的CStdioFile操作

CFile文件操作详见:VS2010/MFC编程入门之四十五(MFC常用类:CFile文件操作类)

登录对话框的建立

1.在资源视图中添加一个窗体资源。插入Dialog。(此处窗体的ID选用的是默认的,可根据自己的情况进行修改)

2.在对话框区域右键,选择添加类,则会弹出一个添加类的对话框,基类选择CDialog,类名自己起个名字。这里取名为CSignIn。然后确认。(新建一个对话框以后一定要添加类,否则上面的控件都不能添加变量,可能还会出现一些其他的问题。)

3.将登录对话框的名字在属性窗口中修改为“登录”。并为其添加两个静态文本框,两个文本编辑框和两个按钮控件( 登录、退出 )。

4.依次为各个控件修改属性或者添加程序。

  • a.静态文本框
    修改两个静态文本框的ID,要不相同;修改其文本内容,例如“用户名”,“密码”。
  • b.文本编辑框
    为两个编辑框分别添加变量,如 m_Name,m_Password,;方法:选中编辑框,右键,选择添加变量,输入变量的名字,且此时变量的类型为Value。并将密码文本编辑框的password属性改为Ture ( 注意此时的Multiline属性应为False,否则可能会出现password属性不能编辑的情况 )。
  • c.按钮控件
//登录按钮
void CSignIn::OnBnClickedOk1()
{
   // TODO: 在此添加控件通知处理程序代码
   UpdateData(TRUE);
   if (m_name!="CSDN" || m_Password!="CSDN")
   {
       MessageBox("用户名或密码错误!");
   		return;
   }
   CDialog::OnOK();
}

//要在 主窗体的OnInitDialog 中添加登录窗体显示代码如下
CSignIn dlg;
if(dlg.DoModal()!=IDOK)
{
   OnOK();
}
return TRUE;//这句代码一定要放在OnInitDialog的结尾。

//退出按钮
OnCancel();

问题-MFC读取文件在EditControl中显示乱码

Visual Studio2008以上的版本和VC6生成的项目默认编码不同,visual studio项目默认使用的是UNICODE编码,但是我们在读取文件的时候读取的是ANSI的文本,因此直接设置到edit control中就出现乱码了。
解决这个的办法也很简单,只要在SetWindow Text的时候使用SetWindowTexeA函数,强迫使用ANSI格式就可以了。如:
在这里插入图片描述

添加bmp文件和ICO文件

左侧-资源视图-文件名.rc-右键-添加资源-选择资源类型-导入-窗口选择显示全部类型文件-可将res文件中的资源导入

画图实现实时显示图形轨迹


//1.在类里定义变量和消息:
 
bool m_bClickEmpty; //判断是否点击了空白的地方,以实现拖动框选择 
 
CPoint OldEmptyBegin;//点击空白开始的座标
 
CPoint NowEmptyEnd;//移动时保存座标
 
afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
 
//2.在鼠标相关的消息里面写代码:
 
void XX::OnLButtonDown(UINT nFlags, CPoint point){
 
       m_bClickEmpty = true;
 
      OldEmptyBegin = point;
 
       NowEmptyEnd = point;
 
}
 
void XX::OnMouseMove(UINT nFlags, CPoint point)
 
{
 
     if ( m_bClickEmpty )     {          CClientDC dc(this);
 
          CBrush *pBrush = CBrush::FromHandle( (HBRUSH)GetStockObject( NULL_BRUSH) );
 
          CBrush *POldBrush = dc.SelectObject( pBrush );
 
          int nOldMode = dc.SetROP2(R2_NOTXORPEN);
 
          dc.Rectangle( &CRect( OldEmptyBegin, NowEmptyEnd ) );
 
          dc.Rectangle( &CRect( OldEmptyBegin, point ) );
 
          NowEmptyEnd = point;
 
         dc.SelectObject( POldBrush );
 
         dc.SetROP2( nOldMode );
 
    }
 
}
 
void XX::OnLButtonUp(UINT nFlags, CPoint point){
 
      if ( m_bClickEmpty )      {           m_bClickEmpty = false;
 
           CClientDC dc(this);
 
           CBrush *pBrush = CBrush::FromHandle( (HBRUSH)GetStockObject( NULL_BRUSH) );
 
           CBrush *POldBrush = dc.SelectObject( pBrush );
 
           int nOldMode = dc.SetROP2(R2_NOTXORPEN);
 
          dc.Rectangle( &CRect( OldEmptyBegin, NowEmptyEnd ) );
 
          dc.SelectObject( POldBrush );
 
         dc.SetROP2( nOldMode );
 
      }}

MessageBox()的使用

功能: 显示一个消息对话框。
语法: MessageBox(text,title{,icon{,button{,default}}})
参数:
title:string类型,指定消息对话框的标题;
text:指定消息对话框中显示的消息,该参数可以是数值数据类型、字符串或boolean值;
icon:Icon枚举类型,可选项,指定要在该对话框左侧显示的图标;
button:Button枚举类型,可选项,指定显示在该对话框底部的按钮
default:数值型,可选项,指定作为缺省按钮的按钮编号,按钮编号自左向右依次计数,缺省值为1,如果该参数指定的编号超过了显示的按钮个数,那么MessageBox()函数将使用缺省值返回值Integer。函数执行成功时返回用户选择的按钮编号(例如1、2、3等),发生错误时返回-1。如果任何参数的值为NULL,MessageBox()函数返回NULL。
**用法:**当你的应用程序需要显示一段简短信息(比如显示出错、警告等信息)时,没有必要自己从头创建窗口、安排控件,使用MessageBox()函数既简单又方便。用户只有响应该窗口后,程序才能继续运行下去。MessageBox()函数的icon参数指定显示在窗口中的图标,它是枚举类型,可能取值为: 取值 图标Information! StopSign! Exclamation! Question! None! 无图标其中Information!是Icon参数的缺省值。Button参数指定在窗口中显示哪些按钮,有效取值为:取值中文Windows 95下显示OK!“确定”按钮OKCancel!“确定”、“取消”按钮YesNo!“是”、“否”按钮 YesNoCancel!“是”、“否”、“取消”按钮RetryCancel!“重试”、“取消”按钮AbortRetryIgnore!“终止”、“重试”、“忽略”按钮
函数功能: 该函数创建、显示、和操作一个消息框。消息框含有应用程序定义的消息和标题,加上预定义图标与Push(下按)按钮的任何组合。

Invalidate,UpdateWindow,UpdateDate

详见;Invalidate和UpdateWindow,UpdateData区别联系

Invalidate():
该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘。例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。

InvalidateRect():
该函数的功能与Invalidate基本一样,不同的是,它是使指定的某个区域无效,需要输入一个区域,如果参数为NULL,则设置整个窗口为无效区。

UpdateData():
该函数的作用是对空间进行更新。
当你使用了ClassWizard建立了控件和变量之间的联系后,当你修改了变量的值,而希望对话框控件更新显示,就应该在修改变量后调用UpdateData(FALSE);如果你希望知道用户在对话框中到底输入了什么,就应该在访问变量前调用UpdateData(TRUE),将控件的输入映射到变量中。

UpdateWindow():
该函数的作用是使窗口立即重绘。
调用Invalidate等函数后窗口不会立即重绘(这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理)。
调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。

UpdateWindow:如果有无效区,则马上sending a WM_PAINT message到窗口处理过程,不进消息队列进行排队等待,立即刷新窗口,否则,什么都不做。
InvalidateRect:设置无效区,如果为NULL参数,则设置整个窗口为无效区。当应用程序的那个窗口的消息队列为空时,则sending a WM_PAINT message(即使更新区域为空).在sending a WM_PAINT message的所有InvalidateRect的更新区域会累加。

引用一下文章,侵删
list control控件:https://www.cnblogs.com/crearo-ssy/archive/2012/11/05/2754641.html
Combo Box控件:https://www.cnblogs.com/ggbailei/articles/2769504.html
登录框:https://blog.csdn.net/qq_31275519/article/details/52120910
读取文件在EditControl中显示乱码:https://blog.csdn.net/xuyangcao123/article/details/44057003
实时显示轨迹:https://blog.csdn.net/mikasoi/article/details/81415564
MessageBox()用法简介:https://blog.csdn.net/weixin_37605770/article/details/79049986
Invalidate和UpdateWindow,UpdateData区别联系:https://blog.csdn.net/komtao520/article/details/49491687

发布了2 篇原创文章 · 获赞 0 · 访问量 30
展开阅读全文
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览