用VS2005写MFC时遇到的问题汇总[转]

1.VC2005:无法执行添加/移除操作,因为代码元素是只读的....多个解决办法

最近在编程过程中偶尔会遇到这个错误, 非常烦人, 因为一旦添加事件处理函数就会弹出这个窗口

解决方案:
1、重启VC
2、打开Resource.h文件看看 一看就知道了 有些定义重复了 可以手动改掉 保存 编辑器重新加载。。。。。。。。
3、关闭解决方案,删除ncb文件重新添加即可
4、实在不行就手动添加消息处理
5、查看.h和.cpp文件的属性,有可能是只读的,修改属性后就可以了
6、把你要添加事件的对话框相应的类文件(*.h和*.cpp)给关了就可以了
上面几种方法网上搜罗的。推荐第3种。

PS:第三种办法确实是有效的!

2、mfc编程怎么用编辑框输入值并用另一个编辑框输出内容

void CMy11Dlg::OnButton1() 
{
// TODO: Add your control notification handler code here
CString str;
GetDlgItemText(IDC_EDIT1,str);

//用GetDlgItemText(文本框ID,字符串),将文本框内容存放到字符串中.
SetDlgItemText(IDC_EDIT2,str);

//用SetDlgItemText(文本框ID,字符串),将文本框的内容设置为字符串的内容.
}

至于需要用文本框的内容计算.

如果内容是数字的话. 可以通过int t=atoi(str);将其转换int类型.

计算完成后,将结果Format到字符串中.

如:

int t=atoi(str);
t+=2;
str.Format("%d",t);

//在文本框1输入12, 文本框2的内容就是14.

3、MFC中CString转换成char数组的问题

由于结构体中用到联合体(联合体需要确定分配内存分配大小)或其它因素,需要用char数组来保存字符串,但是在MFC中一般都是用CString来存放字条串。关于它们之间的转换,在VS2008中有时会出现异常情况。在MSDN是这样写的:

CString orig("Hello, World!");
    // Convert to a char*
    const size_t newsize = 100;
char nstring[newsize];
    strcpy_s(nstring, orig);

但在实际应用中,并不能通过,总会在strcpy_s()函数中出错,或者在nstring的后面跟着很多乱码尾巴。在网上查阅了一些方法。如下:

方法一:
char *p;
CString str="hello";
p=str.GetBuffer(str.GetLength());
str.ReleaseBuffer();
方法二:
CString str="hello";
char ch[20];
memcpy(ch,str,str.GetLength());
方法三:
char *ch;
CString str="hello";
ch=(LPSTR)(LPCTSTR)str;

但总达不到期望的结果。随后再在网上查,发现是Unicode字符集的问题。选择项目->项目属性(或直接按alt+F7)->配置属性,在右边找到“字符集”,将“使用Unicode字符集”改为“使用多字节字符集”。保存之后需要重新生成解决方案。这样上面的方法都可以通过并实现,但是在方法二中,最好不要使用memcpy,直接用strcpy_s(char*, CString)就可以了,因为用memcpy也会出现乱码尾巴。

如果不想改变Unicode字符集,网上也有介绍方法,在此列出来供网友们参考:

CString strPath = L"adfafs主声音文件fsfsa";
int nLength = strPath.GetLength();
int nBytes = WideCharToMultiByte(CP_ACP,0,strPath,nLength,NULL,0,NULL,NULL);
char* VoicePath = new char[ nBytes + 1];
memset(VoicePath,0,nLength + 1);
WideCharToMultiByte(CP_OEMCP, 0, strPath, nLength, VoicePath, nBytes, NULL, NULL);
VoicePath[nBytes] = 0;

用多字节编码的话可以试试这个

char temp[4];

CString str = _T("23");

char* pchar = str.GetBuffer(0);

strcpy(temp,pchar);

如果是unicode编码的话,用这个

char temp[4];

CString str = _T("23");

USES_CONVERSION;

char* pchar = _T("");

pchar = W2A(str);

strcpy(temp,pchar);

4、strcpy_s Buffer is too small 解决方法

错误信息如下:

Microsoft Visual C++ Debug Library

Debug Assertion Failed!

Program: ######.exe
File: ./tcscpy_s.inl
Line: 30

Expression: (L"Buffer is too small" && 0)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

Abort Retry Ignore

函数声明如下:

         strcpy_s(char *strDestination, size_t sizeInBytes, const char *strSource );

问题就出在第二个参数上,sizeInBytes的值必须比strSource 存放的字符数大1。比如strSource 有6个字符,sizeInBytes的值就应该为7,多出来这个用来添加字符串的结束符'/0';

一般用法如下:

strcpy_s(strDestination, strlen(strSource )+1, strSource );

注:strDestination必须有足够的空间存放strSource中的字符。

5、char型字符串转换为十六进制整数问题

int main()

{

char a[9]="1234567a";

long b=0x1;

sscanf(a,"%x",&b);

printf("%x",b);

return 0;

}

6、警告信息 warning C4018: 有符号/无符号不匹配

--------------------------------------------------------------------

仔细研究之后发现是进行了与v.size()有关的操作引起的,用其中容器中与size()是被定义为unsigned int 型,而我们在遍历时会用int型导致警告的产生,因此在int 前面添加 unsigned即可。

例子如下:

1. /**

2. 求向量中所有元素的交错和

3.     @param v欲求交错和的向量

4.     @return 返回所有元素的交错和

5. */

6. double alternating_sum(const vector<double>& v) 

7. { 

8. if(v.size()==0) return false

9. double sum=0.0; 

10. for(unsigned int i=0;i<v.size();i++) 

11.     { 

12. if(i%2==0) 

13.             sum+=v[i]; 

14. else sum-=v[i]; 

15.     } 

16. return sum; 

17. } 

-------------------------------------------------------------

上面的函数中 将for循环中的i设置为unsigned int 型

for(unsigned int i=0;i<v.size();i++)

 

 

最近在编程过程中偶尔会遇到这个错误, 非常烦人, 因为一旦添加事件处理函数就会弹出这个窗口
解决方案:
1、重启VC
2、打开Resource.h文件看看 一看就知道了 有些定义重复了 可以手动改掉 保存 编辑器重新加载 。。。。。。。。
3、关闭解决方案,删除ncb文件重新添加即可
4、实在不行就手动添加消息处理
5、查看.h和.cpp文件的属性,有可能是只读的,修改属性后就可以了
6、把你要添加事件的对话框相应的类文件(*.h和*.cpp)给关了就可以了
上面几种方法网上搜罗的。推荐第3种。 

PS:第三种办法确实是有效的!

上贴有人说这个在类视图中会看不到一些东西,到目前为止未见异常

 

 

怎样设置CListBox中的某一项为高亮显示,为何我用m_userlist.SetSel(0)不好用呢.m_userlist是CListBox的对象?

使用SetCurSel试试。。。SetSel貌似只能在多选时才使用。。。

 

 

 

慎用USES_CONVERSION

慎用USES_CONVERSION

USES_CONVERSION是ATL中的一个宏定义。用于编码转换(用的比较多的是CString向LPCWSTR转换)。在ATL下使用要包含头文件#include "atlconv.h"

使用USES_CONVERSION一定要小心,它们从堆栈上分配内存,直到调用它的函数返回,该内存不会被释放。如果在一个循环中,这个宏被反复调用几万次,将不可避免的产生stackoverflow。

在一个函数的循环体中使用A2W等字符转换宏可能引起栈溢出。

#include <atlconv.h>
void fn()
{
    while(true)
    {
        {
            USES_CONVERSION;
            DoSomething(A2W("SomeString"));
        }
    }
}

让我们来分析以上的转换宏

#define A2W(lpa) (\
   ((_lpa = lpa) == NULL) ? NULL : (\
      _convert = (lstrlenA(_lpa)+1),\
      ATLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert)))

#define ATLA2WHELPER AtlA2WHelper

inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp)
{
   ATLASSERT(lpa != NULL);
   ATLASSERT(lpw != NULL);
   // verify that no illegal character present
   // since lpw was allocated based on the size of lpa
   // don't worry about the number of chars
   lpw[0] = '\0';
   MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars);
   return lpw;
}

关键的地方在 alloca  内存分配内存上。
#define alloca  _alloca

_alloca
Allocates memory on the stack.

Remarks
_alloca allocates size bytes from the program stack. The allocated space is automatically freed when the calling function

exits. Therefore, do not pass the pointer value returned by _alloca as an argument to free.

问题就在这里,分配的内存是在函数的栈中分配的。而VC编译器默认的栈内存空间是2M。当在一个函数中循环调用它时就会不断的分配栈中的内存。

以上问题的解决办法:
1、自己写字符转换函数,不要偷懒
Function that safely converts a 'WCHAR' String to 'LPSTR':
char* ConvertLPWSTRToLPSTR (LPWSTR lpwszStrIn)
{
  LPSTR pszOut = NULL;
  if (lpwszStrIn != NULL)
  {
int nInputStrLen = wcslen (lpwszStrIn);

// Double NULL Termination
int nOutputStrLen = WideCharToMultiByte (CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
pszOut = new char [nOutputStrLen];

if (pszOut)
{
   memset (pszOut, 0x00, nOutputStrLen);
   WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
}
  }
  return pszOut;
}
等等一个一个的实现。

2、把字符转换部分放到一个函数中处理。

void fn2()
{
    USES_CONVERSION;
    DoSomething(A2W("SomeString"));
}

void fn()
{
    while(true)
    {
        fn2();
    }
}

如果不知道这点问题,在使用后崩溃时很难查出崩溃原因的。

转载于:https://www.cnblogs.com/freedesert/archive/2013/04/14/3021220.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值