首先是我使用VC2005在不通阶段的不通感受:
刚开始安装VS2005时候感觉:真是大啊!装了我一个上午!!而且运行个VC有时能耗我好大的内存。。
刚使用VC2005时候的感受:界面挺不错,貌似功能更强大,对C++标准支持的很好,还可以用我最喜欢的Comic Sans MS字体,还支持代码收缩等等。。虽然比较慢,但是不像VC6.0那样老是出现编译死机的情况。
开始用VC2005学习写东西的时候的感受:实在没有6.0好用,限制太多,很多地方跟VC6.0不一样,而且很多功能似乎都找不到了。。还不如6.0方便。。。
使用一段时间的感受:虽然经常遇到问题但是都是有很好的解决方案的,而且相对6.0,2005的BUG少很多,总体来说如果机器配置还算可以的话,用2005是挺不错的。。
下面就是我使用VC2005遇到的以及解决了的问题:
VC遇到的以及解决了的问题
1,对于Radio控件如何正确设置属性Group?
首先要确保几个Radio控件的Tab是按顺序的(可以在对话框编辑器中按Ctrl+D将三个控件TABORDER设置在一起)。然后对第一个Radio控件选择Group属性,其他的不用选。对第一个
控件添加关联变量int m_test,并且设置初值-1,则当我们点击第一个控件m_test值是0,点击第二个m_test值是1....依此类推。
2,VC2005中添加虚函数问题:
在VC6.0中可以对类右键添加虚函数,在VC2005中需要在类属性中点击一个重写按钮,在那里添加虚函数。
3,VC2005动态添加右键菜单问题:
在VC6.0中我们可以在Project->Add To Project->Component and Control中添加组件,如添加Pop-up Menu可以实现添加右键快捷菜单的功能。但是在VC2005中我们没有这个功能
,但是我们可以手动自己添加,也不是很复杂。步骤如下(假设工程是一般MFC视图工程命名Menu):
1,自己添加一个Menu资源,例如命名为IDR_MENU1,编辑之。顶级菜单是不出现的我们可以随便设置不妨为abc。然后添加两个弹出菜单项:显示(IDM_SHOW)和退出(IDM_EXIT).
2,给CMenuView类中添加WM_RBUTTONDOWN消息的响应函数。代码如下:
void CMenuView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CMenu menu;
menu.LoadMenuA(IDR_MENU1);
CMenu* pPopup = menu.GetSubMenu(0);
ClientToScreen(&point); //客户坐标转换成屏幕坐标
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
CView::OnRButtonDown(nFlags, point);
}
对菜单项添加事件很Easy。动态菜单添加主要用到如下的函数:
BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL);
4,下面转帖自:
http://hi.baidu.com/freedomknightduzhi/blog/item/60a5012e512bba554fc226e9.html
恶心的2005
用VC2003一直很爽,到新公司要用2005,早听说其检查严格,没想到,完全是没事找事型的编译器.
且不说满屏幕的:
"警告 4 warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 "
运行个MFC的东西就报"由于应用程序的配置不正确,应用程序未能启动"
一查才知道,这是05的特权,缺少动态库也不说,直接报个配置不正确,Fuck.不如直接弹出个警告框"程序无法运行"适用性更大呢.
这里是重置2005配置的方法:
命令行输入:devenv /resetuserdata
[[
开始执行程序时出现错误提示:
没有找到MSVCP80D.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。
解决方法:
项目->属性->配置属性->清单工具->常规->使用FAT32解决办法
改为“是”即可
此时,应该将上次产生的debug文件夹删除才能正确运行。
]]
原因大致是由于2005编译时,FAT32格式硬盘会给程序加以时间戳,换机器运行时由于时间戳不符的原因导致无法运行,如果编译机器格式为NTFS格式则也不会出现该问题。
这两天有点焦头烂额, 我们这边运行的好好的程序, 到了测试的机器上就不能启动(是根本运行不了, 而不是运行出错), 弄得我异常郁闷。 经过了一番摸索, 发现和 winxp、
win2003中为解决dll hell而引入的manifest机制有关系。而以前我们用vs2003开发, 它并没有强制程序使用manifest, 但到了vs2005中, 这已经改成必需的了, 而我们并没有按照
需要进行相关的配置, 所以程序启动不了了。 根据目前的经验, vs2005编译的程序不能启动大致有两个原因, 下面简单介绍解决办法。
1、在开发组的机器上(安装有vs2005)有时都不能启动
这一般是项目的文件被放在了fat/fat32分区上导致的, 解决方法是把它们都移动到ntfs分区上, 或者把“项目属性|Manifest Tool|General|Use FAT32 Work-around”设为yes。
2、开发组运行正常, 换到其它机器上就不行了
这一般就是系统dll(包括crt,mfc,atl等)没有正确配置导致的。 如果程序是release版, 那么很简单, 只要把“/SDK/v2。0/BootStrapper/Packages/vcredist_x86”下
的"vcredist_x86。exe"拷贝到目标机器上运行即可, 这是以x86平台为例的, 如果你用的是别的cpu平台(amd64或ia64)把x86替换成相应的内容就可以了。
注:[[ ]] 内信息转自http://hi.baidu.com/crafter%5Fxmu/blog/item/104040b44b4876768bd4b281.html
这里是"general error c101008a: Failed to save the updated manifest to the file "网上普遍的解决方法:
在用vs2005时,默认编码为unicode,如果在项目中途改变,则编译时会碰到错误general error c101008a: Failed to save the updated manifest to the file
"./Debug/Menu.exe.embed.manifest". Bpcn mt.exe .这时清理解决方案,再重新生成项目便可解决.
这里是"warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 "网上普遍的解决方法:
一般来说,这个警告没有什么影响。要想去掉这个警告的方法有:
(1)转换Code文件为Unicode格式;
(2)在Project -> Properties -> Configuration Properties -> C/C++ -> Advance 的 Disable Specific Warnings 中添加相应的警告编号:4819;
(3)或找出不符合Unicode格式的文件,然后在该文件的开始处加入下面的语句:
# pragma warning (disable:4819)
2005断点无法命中的解决方案
1:重新编译该工程.
2:文件的编码格式不匹配造成的;修改步骤: 菜单->文件->XXX文件另存为->编码保存(保存按钮旁边的下拉菜单)->Unicode (UTF-8 带签名)->确定
这里是"由于应用程序的配置不正确,应用程序未能启动"网上普遍的解决方法:
方法一:在类似C:/Program Files/Microsoft Visual Studio 8/VC/redi st/Debug_NonRedist/x86/Microsoft.VC80.DebugCRT 下找到了下列文件: msvcm80d.dll msvcp80d.dll
msvcr80d.dll Microsoft.VC80.DebugCRT.manifest 把这几个文件拷贝到目标机器上,与运行程序同一文件夹或放到system32下,就可以正确运行了。 其他release版、MFC程序什
么的都是拷redist下相应文件夹下的文件就可以了,文件夹后都有标识!
结果: 把这几个Dll Copy过去,无效....
方法二:工程-》属性-》配置属性-》c/c++ -〉代码生成里,修改运行时库选项,将/MD或/MDd 改为 /MT或/MTd,这样就实现了对VC运行时库的静态链接,在运行时就不再需要
VC的dll了。
结果:由于我的程序使用了DLL输出,使用多线程调试是不行的,必须多线程调试DLL,这招也无效....
方法三: 工程-》属性-》配置属性-》常规-》MFC的使用,选择“在静态库中使用mfc” 这样生成的exe文件应该就可以在其他机器上跑了。
结果: 告诉我缺少Boost库,编译一次Boost够我吃顿饭回来了- -
方法四: 你的vc8安装盘上找到再分发包vcredist_xxx.exe和你的程序捆绑安装
结果: 搜索都没搜到该EXE,谁叫咱用的是盗版...
最终没有解决,下午再说.TMMD,2005.
解决了:
期间发生的问题包括:
1: Ogre的2005 Debug版本无法在其他机器上运行
错误描述为:”应用程序配置不正确……”
解决方法为:
需要开发者安装430MB左右的VS80sp1-KB926604-X86-CHS.exe库。
需要使用者安装2.59MB的VCRedist_x86.exe库。
2: Ogre的2005 Debug版本无法在其他机器上运行
错误描述为:” 应用程序正常初始化(0xc150002)失败”
解决方法为:
需要开发者安装430MB左右的VS80sp1-KB926604-X86-CHS.exe库。
需要使用者安装2.59MB的VCRedist_x86.exe库。
3:安装VCRedist_x86.exe库时报错
错误描述为:”Command Line option syntax error, Type Command /? For help”
解决方法为:
自己从VC2005目录下找到运行时目录,将其dll库拷贝出来,粘贴到应用程序目录下。
结论:
所以,想要运行2005编译后的Ogre引擎支持的相关Demo,尽量做到以下两点:
1:给予Release 版本
2:将VC运行时库的动态连接库一起拷贝过去。
VC遇到的以及解决了的问题(二)
1,控件和变量相关联之后,没有发生数据交换:
当控件和一个变量相关联之后,控件与成员变量的数据交换是通过DoDataExchange函数来完成的,然而程序中并不直接调用这个函数,二十通过调用UpdateData函数来调用它的!!UpdateData函数是的参数是TRUE的时候从空间得到成员变量的值,参数是FALSE时候,使用成员变量的值初始化控件。
2,在VC2005中如何添加WM_INITDIALOG响应
这个响应应该是重写虚函数:OnInitDailog()来获得。
3, 在VC2005中给工具栏按钮添加消息映射的方法
在VC6.0中很简单类向导直接添加就行了,但是在VC2005中无论属性页中还是右键点击都不能添加消息事件处理,只有两种方法:
1,按照类向导添加的代码自己写就行了,三个需要修改的地方,函数声明,消息映射,函数定义。
2,在菜单中建立同样ID的菜单项,通过这个菜单项来添加。
开始我很郁闷,这么麻烦,后来想想这个修改也是为了程序的严格,直白说就是工具栏的按钮都应该和菜单栏的功能对应才好。
4, VC中删除工具栏按钮
按Delete键只能清除按钮图标的颜色,要删除按钮只要把按钮用鼠标拖出工具栏就行了。
5, VC中给菜单项添加复选标记
给当前按钮添加一个UpdateView的事件处理,如下:
void CMainFrame::OnUpdateViewNewtoolbar(CCmdUI *pCmdUI)
{
// TODO: 在此添加命令更新用户界面处理程序代码
pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
}
6,在VC2005中自定义一个消息时候出现错误:error C2440: “static_cast”: 无法从“void (__thiscall CMainFrame::* )(void)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”的问题解决:
在定义时候我就是用:
头文件MainFrm.h:
#define UM_PROGRESS WM_USER+1 //定义消息
afx_msg void OnProgress(); // 生成的消息映射函数
源文件MainFrm.cpp:
//消息映射
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_MESSAGE(UM_PROGRESS,OnProgress)
END_MESSAGE_MAP()
//消息实现
void CMainFrame::OnProgress()
{
//todo:
}
然后出现如上的错误原因是: VC6.0编译器有个BUG,就是允许你用:afx_msg void OnProgress();我们应该把函数改成LRESULT OnProgress(WPARAM, LPARAM).
这样问题就解决了。然而MFC中一些向导生成的有许多是用void的,其实这个很多是继承了虚函数的,具体要参见MFC底层代码。注意定义函数时候的返回值(返回一个0就行)。
7,一个优先级注意的地方:
(CMainFrame*)GetParent()->m_wndStatusBar.SetWindowText(str);意味着:(CMainFrame*)(GetParent()->m_wndStatusBar.SetWindowText(str))。
所以要是调用CMainFrame的m_wndStatusBar,应该:((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);还注意m_wndStatusBar的访问权限要是public。
8,如何读取一个Eidt控件里面多行的浮点数据,并将它每行存到一个Vector容器中。
CString strLine;
int lineCount, lineLen;
vector<double> array;
lineCount = m_edit.GetLineCount();
this->m_calculate.array.clear();
for (int i = 0; i < lineCount; i++)
{
lineLen = m_edit.LineLength(m_edit.LineIndex(i))+1;
m_edit.GetLine(i, strLine.GetBuffer(lineLen), lineLen);
strLine.ReleaseBuffer(lineLen);
this->m_calculate.array.push_back(atof(strLine));
}
注意:上面的代码参考自MSDN:http://msdn.microsoft.com/zh-cn/library/s7zy7cwk(VS.80).aspx,但是,源代码中第10行是:
lineLen = m_edit.LineLength(m_edit.LineIndex(i))
这是每当第一行数据只有1位的时候,例如5,变成了0。我加了一个1,之后就没有类似问题了。
9,下面附加一些MFC中和标准库中类型转换的问题:
CString转换为int, double...
int: _wtoi(CString*) long int: _wtol(CString*) double/float: _wtof(Cstring*)
CString和double相互转换:
CString m;
double num = atof(m);
m.format("%f",num);
10,有关C++ int,char,string,CString类型转换
转自: http://blog.sina.com.cn/s/blog_4c22ff8d01000ati.html [查看原文]
C++ int,char,string,CString类型转换(整理总结)
#include <string> //使用C++标准库的string类时
using namespace std; //同上
#include <sstream>
#include <iostream>
#include <stdlib.h> //要将string类和int类型直接转换最好有这些包含,
//因为自己写一个转换函数比较方便,函数定义参考如下
string getstring ( const int n )
{
std::stringstream newstr;
newstr<<n;
return newstr.str();
}
string 转 CString
CString.format(”%s”, string.c_str());
char 转 CString
CString.format(”%s”, char*);
char 转 string
string s(char *);
string 转 char *
char *p = string.c_str();
CString 转 string
string s(CString.GetBuffer());
1,string -> CString
CString.format(”%s”, string.c_str());
用c_str()确实比data()要好.
2,char -> string
string s(char *);
只能初始化,在不是初始化的地方最好还是用assign().
3,CString -> string
string s(CString.GetBuffer());
GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.
《C++标准函数库》中说的
有三个函数可以将字符串的内容转换为字符数组和C―string
1.data(),返回没有”/0“的字符串数组
2,c_str(),返回有”/0“的字符串数组
3,copy()
―――――――――――――――――――――
CString与int、char*、char[100]之间的转换- -
CString与int、char*、char[100]之间的转换- -
CString互转int
将字符转换为整数,可以使用atoi、_atoi64或atol。
而将数字转换为CString变量,可以使用CString的Format函数。如
CString s;
int i = 64;
s.Format(”%d”, i)
Format函数的功能很强,值得你研究一下。
void CStrDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CString
ss=”1212.12″;
int temp=atoi(ss);
CString aa;
aa.Format(”%d”,temp);
AfxMessageBox(”var is ” + aa);
}
sart.Format(”%s”,buf);
CString互转char*
///char * TO cstring
CString strtest;
char * charpoint;
charpoint=”give string a value”;
strtest=charpoint;
///cstring TO char *
charpoint=strtest.GetBuffer(strtest.GetLength());
标准C里没有string,char *==char []==string
可以用CString.Format(”%s”,char *)这个方法来将char *转成CString。要把CString转成char *,用操作符(LPCSTR)CString就可以了。
CString转换 char[100]
char a[100];
CString str(”aaaaaa”);
strncpy(a,(LPCTSTR)str,sizeof(a));