zoukankan      html  css  js  c++  java
  • 用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();
        }
    }

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

  • 相关阅读:
    linux中断处理浅析
    linux页面回收浅析
    linux线程同步浅析
    剖析一个由sendfile引发的linux内核BUG
    比memcpy更快的内存拷贝
    linux内核SMP负载均衡浅析
    sscanf,snprintf
    mysql中实现longblob数据流式读写
    sscanf
    substr复制字符串的一部分
  • 原文地址:https://www.cnblogs.com/freedesert/p/3021220.html
Copyright © 2011-2022 走看看