MFC-进制转化器

来源:互联网 发布:克里希那穆提骗局 知乎 编辑:程序博客网 时间:2024/04/28 20:50

学习了一段时间的mfc,但是总是感觉学的比较零散,偶然发现一个MFC写的比较好的博客,因此打算在他的基础上来整体的学习MFC。

我自己的MFC编写环境为VS2010,如果存在版本的问题,请百度版本的修改方法。

本文在原文的基础上上添加了2进制到8进制的相互转化,原文:http://www.gymsaga.com/category/project/developc/mfc

运行界面如下:


在实现这个功能前,建立一个对话框的项目,自己命名,添加控件,建立类向导。

在头文件里面添加函数,分别如下:

afx_msg void OnBnClickedButton1();virtual BOOL PreTranslateMessage(MSG* pMsg);void HexConverter();CString BinToDec(CString strBin);CString DecToBin(CString strDec);CString BinToOct(CString strBin);CString OctToBin(CString strOct);

此时,源文件如下:

void CHexConverterDlg::OnBnClickedButton1(){HexConverter();GetDlgItem(IDC_EDIT)->HideCaret();}BOOL CHexConverterDlg::PreTranslateMessage(MSG* pMsg){if (pMsg->message==WM_KEYDOWN){if (pMsg->wParam==VK_RETURN){HexConverter();GetDlgItem(IDC_EDIT)->HideCaret();return TRUE;}else if (pMsg->wParam==VK_DELETE){SetDlgItemText(IDC_EDIT,"");GetDlgItem(IDC_EDIT)->HideCaret();return TRUE;}}return CDialogEx::PreTranslateMessage(pMsg);}void CHexConverterDlg::HexConverter(){CString strNum,strDes;GetDlgItemText(IDC_EDIT,strNum);if (((CButton *)GetDlgItem(IDC_10_TO_16))->GetCheck()==BST_CHECKED){__int64 num=_atoi64(strNum);strDes.Format("%x",num);SetDlgItemText(IDC_EDIT,strDes);}else if (((CButton *)GetDlgItem(IDC_16_TO_10))->GetCheck()==BST_CHECKED){DWORD num=strtoul(strNum,NULL,16);strDes.Format("%ld",num);SetDlgItemText(IDC_EDIT,strDes);}else if (((CButton *)GetDlgItem(IDC_10_TO_2))->GetCheck()==BST_CHECKED){SetDlgItemText(IDC_EDIT,DecToBin(strNum));}else if (((CButton *)GetDlgItem(IDC_2_TO_10))->GetCheck()==BST_CHECKED){SetDlgItemText(IDC_EDIT,BinToDec(strNum));}else if (((CButton *)GetDlgItem(IDC_2_TO_16))->GetCheck()==BST_CHECKED){long num=atol(BinToDec(strNum));strDes.Format("%x",num);SetDlgItemText(IDC_EDIT,strDes);}else if (((CButton *)GetDlgItem(IDC_16_TO_2))->GetCheck()==BST_CHECKED){DWORD num=strtoul(strNum,NULL,16);strDes.Format("%ld",num);SetDlgItemText(IDC_EDIT,strDes);}else if (((CButton *)GetDlgItem(IDC_2_TO_8))->GetCheck()==BST_CHECKED){SetDlgItemText(IDC_EDIT,BinToOct(strNum));}else if (((CButton *)GetDlgItem(IDC_8_TO_2))->GetCheck()==BST_CHECKED){SetDlgItemText(IDC_EDIT,OctToBin(strNum));}}CString CHexConverterDlg::BinToDec(CString strBin){long num=0;CString strDes;int nLen=strBin.GetLength();for(int i=0;i<nLen;i++){if (strBin[nLen-i-1]=='0'){continue;}else{int k=1;for (int j=0;j<i;j++){k=k*2;}num+=k;}}strDes.Format("%ld",num);return strDes;}CString CHexConverterDlg::DecToBin(CString strDec){CString strBin=_T(""),strTemp;TCHAR buf[2];int Yushu,Shang;bool flag=true;int num=atoi(strDec);while (flag){Yushu=num%2;Shang=num/2;sprintf(buf,_T("%d"),Yushu);strTemp=strBin;strBin.Format("%s%s",buf,strTemp);num=Shang;if (Shang==0)flag=false;}//MessageBox(strBin);/*int nTemp = strBin.GetLength()%4;switch(nTemp){case 1:strTemp.Format(TEXT("000%s"), strBin);strBin = strTemp;break;case 2:strTemp.Format(TEXT("00%s"), strBin);strBin = strTemp;break;case 3:strTemp.Format(TEXT("0%s"), strBin);strBin = strTemp;break;default:break;}*/return strBin;}CString CHexConverterDlg::BinToOct(CString strBin){CString strOct=_T(""),strTemp,strTemp1,strTemp2;int num=strBin.GetLength()%3;switch (num){case 0:strTemp.Format("%s",strBin);break;case 1:strTemp.Format("00%s",strBin);break;case 2:strTemp.Format("0%s",strBin);break;default:break;}//MessageBox(strTemp);num=strTemp.GetLength()/3;int i=0;while(num>0){strTemp1.Empty();sscanf(strTemp.Mid(i,3),"%s",strTemp1);strTemp1.Format("0%s",strTemp1);strTemp2=BinToDec(strTemp1);strOct+=strTemp2;i+=3;num--;}return strOct;}CString CHexConverterDlg::OctToBin(CString strOct){CString strBin="";CString strTemp,strTemp1;for (int i=0;i<strOct.GetLength();i++){strTemp.Empty();strTemp=DecToBin(strOct.Mid(i,1));//MessageBox(strTemp1);if (i==0){strBin+=strTemp;}else{int nLen=(strTemp.GetLength()%3);switch (nLen){case 0:strTemp1=strTemp;break;case 1:strTemp1.Format("00%s",strTemp);break;case 2:strTemp1.Format("0%s",strTemp);break;default:break;}strBin+=strTemp1;}}return strBin;}

在这儿,解释如下:

1、PreTranslateMessage(MSG* pMsg)  是对键盘部分按键的重写,主要是实现enter和backspace的功能实现,都通过HideCaret()来隐藏插入符,GetDlgItem()是获取编辑框控件的句柄;

2、HexConverter()是这个代码的核心,通过判断是哪个单选控件按下来决定操作,在这儿,单选按钮或者复选框都是通过这种方法来判断是否选中,此时GetCheck()的返回值有三种,分别为BST_CHECKED,BST_UNCHECKED和BST_INDETERMINATE,以此表示为选中,未选中,变灰不可操作,在相应的单选按钮选中后执行对应的操作

3、_atoi64(const char *str)这个函数式吧字符串转化为整数,在这儿返回值是__int64

4、strDes.Format("%x",num); 这句话是把__int64的整数转化为十六进制的数,并且格式化保存,在这儿%x表示十六进制

5、SetDlgItemText(IDC_EDIT,strDes),是把指定的数值显示在控件上面,在这儿是显示在编辑框

6、strtoul(const char *str,char **endptr,int radix)这个函数式吧CString转化为无符长整数,在这个函数的三个参数中,str表示要转化的字符,endptr一般设为NULL,radix是要转化的进制,在这儿是用的strtoul(strNum,NULL,16)就是把strNum转化为16进制

7、当然,用来进行类型转化的函数还有很多,比如atof,atoi,atol,strtod等等,关于他们的用法,你们可以自己百度

8、关于二进制转化十进制,为啥可说的,直接按照定义来求就行了,但是注意的是二进制字符的低位在最后面,所以你的判断过程是从后面开始的。

9、关于十进制转化2进制,那么就是模2取余,在这儿没有考虑小数的情况,对于%2的余数从下到上就是转化的二进制代码

10、关于二进制转8进制,就是从低位到高位每三位一组一次来求解,这儿就得考虑二进制串的位数,通过format函数就可以在高位补0,最后对于三位的处理就看你自己的方法,在这儿我的方法就是通过sscanf函数来获取三位二进制串,这儿mid函数的可以获取任意起始位置的k长度的字符串,再就是只要一次处理就行。

11、8进制转2进制的方法和上面差不多

12、2进制和16进制的相互转化,通过10进制来做中间过程。


如果你有更好的方法,希望提出!


0 0
原创粉丝点击