error C2660: “Gdiplus::GdiplusBase::operator new”: 函数不接受 3 个参数(转)

本文详细介绍了在VS2008环境下使用GDI+时遇到的内存分配问题及其解决方案。提供了四种解决方法,包括使用全局作用域的new操作符、修改GdiPlusBase.h文件等,并探讨了问题的根本原因在于命名空间冲突。

环境:xp sp3,vs2008

代码:

//使用了gdi,ImageEx继承于Image

ImageEx* m_image;

m_image = new ImageEx( L"d:\\loading.gif" );

//解决:

方法1,2(不推荐):

http://support.microsoft.com/kb/317799

http://blog.youkuaiyun.com/caiboisgreat/article/details/7210380

方法3(不推荐):在GDI+的new操作符前添加::域限定符,如:
Bitmap* temp = ::new Bitmap(L"c:\\1.bmp");

http://hi.baidu.com/heng_nailuo/blog/item/4a67d82a89759b305343c10e.html/cmtid/f41bfcdf451c3d1c6227985d

重要补充:

大牛胡哼哼揭开该问题的本质:

补充下,其实归根结底还是域名的问题!由于各名字空间中有同名的函数或者成员,而在用的时候没很明确的指明来自哪个名字空间,然后就会由于同名,而参数或者是实现不同而出错误。

今天之所以在release下通过编译而debug下无法通过编译是因为release和debug的设置不同,包括其中的链接库,头文件及编译时的设置不一样,所以就.........

而在debug下需要::是因为new在其下就被设置成全局作用域,::前的名字空间就给省略了。如果没有::就会被认为是内部的作用域,就如上面文档所说,由MFC里的重载的new 给代替了我们平时所用的new,所以就出错了。

由此得出,写代码的时候我们应该学会规范的使用名字空间,比如在头文件里面不要使用名字空间的using语句,尽量局部的使用名字空间等.......

方法四(推荐):

我们修改一下位于 Visual C++ 安装目录下的 \Vc7\PlatformSDK\Include\GdiPlusBase.h文件, 在 GdiPlusBase 类中加入以下橙色代码部分, 完成后GdiPlusBase.h 文件完整内容如下 :


#ifndef_GDIPLUSBASE_H
#define_GDIPLUSBASE_H

class GdiplusBase
{
public:
  void(operator delete)(void*in_pVoid)
  {
     DllExports::GdipFree(in_pVoid);
  }


  void* (operator new)(size_t in_size)
  {
     returnDllExports::GdipAlloc(in_size);
  }


  void (operator delete[])(void* in_pVoid)
  {
     DllExports::GdipFree(in_pVoid);
  }


  void * (operator new[])(size_t in_size)
  {
     return DllExports::GdipAlloc(in_size);
   }

 

  void * (operator new)(size_t nSize,LPCSTR lpszFileName, int nLine)
  {
     return DllExports::GdipAlloc(nSize);
  } 


  voidoperator delete(void* p, LPCSTR lpszFileName, int nLine)
  {
     DllExports::GdipFree(p);
  }

 

};

#endif

参考:http://blog.sina.com.cn/s/blog_54f001f701000bjs.html

有报错严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0167 "CDC *" 类型的实参与 "CPaintDC *" 类型的形参兼容 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 705 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0167 "HGDIOBJ" (aka "void *") 类型的实参与 "HBITMAP" (aka "HBITMAP__ *") 类型的形参兼容 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 720 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0413 存在从 "CBrush" 到 "CBrush *" 的适当函数 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 634 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0029 应输入表达式 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 288 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0434 无法用 "std::ifstream (CStringA filepath)" 类型的值初始化 "std::ifstream &" 类型的引用(非常量限定) GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 217 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0020 未定义标识符 "IDC_STATIC_DISPLAY" GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 515 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0304 没有与参数列表匹配的 重载函数 "ATL::CImage::Save" 实例 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 723 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0304 没有与参数列表匹配的 重载函数 "std::getline" 实例 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 220 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0349 没有与这些操作数匹配的 "[]" 运算符 GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 477 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误(活动) E0153 表达式必须具有类类型,但它具有类型 "std::ifstream (*)(CStringA filepath)" GNSS D:\DMZHSX\1\GNSS\GNSS\GNSSDlg.cpp 211
最新发布
10-23
这个错误是因为 `Graphics::DrawString` 方法的参数类型匹配。在 GDI+ 中,`DrawString` 有多个重载版本,但需要确保传入的参数类型正确。以下是修正后的代码和详细解释: --- ### **错误原因** `Graphics::DrawString` 的常见重载形式之一是: ```cpp Status DrawString( const WCHAR* string, INT length, const Font* font, const PointF& origin, const StringFormat* format, const Brush* brush ); ``` 或: ```cpp Status DrawString( const WCHAR* string, INT length, const Font* font, const RectF& layoutRect, const StringFormat* format, const Brush* brush ); ``` 您的代码中可能直接传入了 `CString` 或未正确换字符串类型。 --- ### **修正后的 `OnPaint` 方法** ```cpp void MyButton::OnPaint() { CPaintDC dc(this); Graphics graphics(dc.GetSafeHdc()); graphics.SetSmoothingMode(SmoothingModeAntiAlias); CRect clientRect; GetClientRect(&clientRect); RectF rect((REAL)clientRect.left, (REAL)clientRect.top, (REAL)clientRect.Width(), (REAL)clientRect.Height()); // 创建圆角路径 GraphicsPath path; AddRoundRectPath(&path, rect, 10.0f); // 填充背景色 SolidBrush brush(Color(255, GetRValue(m_bgColor), GetGValue(m_bgColor), GetBValue(m_bgColor))); graphics.FillPath(&brush, &path); // 绘制边框 Pen pen(Color(255, 0, 0, 0), 1.0f); graphics.DrawPath(&pen, &path); // 绘制文本(修正部分) CString strText; GetWindowText(strText); if (!strText.IsEmpty()) { // 将 CString 换为宽字符(WCHAR*) int len = strText.GetLength(); WCHAR* wideStr = new WCHAR[len + 1]; MultiByteToWideChar(CP_ACP, 0, strText, -1, wideStr, len + 1); // 设置文本格式 StringFormat format; format.SetAlignment(StringAlignmentCenter); format.SetLineAlignment(StringAlignmentCenter); // 使用正确的 DrawString 重载 Font font(L"Arial", 10); SolidBrush textBrush(Color(255, 0, 0, 0)); graphics.DrawString(wideStr, len, &font, rect, &format, &textBrush); delete[] wideStr; // 释放内存 } } ``` --- ### **关键修正点** 1. **字符串换** - `CString` 是 ANSI 字符串,而 `DrawString` 需要 `WCHAR*`(宽字符)。 - 使用 `MultiByteToWideChar` 进行换,或直接使用 `CStringW`(宽字符版 CString)。 2. **参数顺序和类型** - 确保 `DrawString` 的参数顺序为: `(字符串, 长度, 字体, 布局矩形, 格式, 画刷)`。 3. **内存管理** - 动态分配的 `wideStr` 需要在绘制完成后释放。 --- ### **优化版本(使用 `CStringW`)** 如果项目支持 Unicode,可以直接用 `CStringW` 简化代码: ```cpp void MyButton::OnPaint() { // ...(前面的路径和背景绘制代码变) CStringW strText; GetWindowText(strText); // 自动换为宽字符 if (!strText.IsEmpty()) { StringFormat format; format.SetAlignment(StringAlignmentCenter); format.SetLineAlignment(StringAlignmentCenter); Font font(L"Arial", 10); SolidBrush textBrush(Color(255, 0, 0, 0)); graphics.DrawString(strText, strText.GetLength(), &font, rect, &format, &textBrush); } } ``` --- ### **其他注意事项** 1. **字体和画刷的生命周期** - 确保 `Font` 和 `SolidBrush` 对象在 `DrawString` 调用期间有效(要使用局部变量后立即释放)。 2. **错误处理** - 检查 `DrawString` 的返回值(`Status` 类型),确保绘制成功。 3. **性能优化** - 如果按钮文本变,可以缓存换后的宽字符字符串,避免每次重绘时重复换。 --- ### **完整修正后的代码** ```cpp void MyButton::OnPaint() { CPaintDC dc(this); Graphics graphics(dc.GetSafeHdc()); graphics.SetSmoothingMode(SmoothingModeAntiAlias); CRect clientRect; GetClientRect(&clientRect); RectF rect((REAL)clientRect.left, (REAL)clientRect.top, (REAL)clientRect.Width(), (REAL)clientRect.Height()); // 绘制圆角按钮 GraphicsPath path; AddRoundRectPath(&path, rect, 10.0f); SolidBrush brush(Color(255, GetRValue(m_bgColor), GetGValue(m_bgColor), GetBValue(m_bgColor))); graphics.FillPath(&brush, &path); Pen pen(Color(255, 0, 0, 0), 1.0f); graphics.DrawPath(&pen, &path); // 绘制文本(优化版) CStringW strText; GetWindowText(strText); if (!strText.IsEmpty()) { StringFormat format; format.SetAlignment(StringAlignmentCenter); format.SetLineAlignment(StringAlignmentCenter); Font font(L"Arial", 10); SolidBrush textBrush(Color(255, 0, 0, 0)); graphics.DrawString(strText, strText.GetLength(), &font, rect, &format, &textBrush); } } ``` --- ### **总结** - 错误原因是 `DrawString` 参数类型匹配(主要是字符串格式问题)。 - 解决方法: 1. 使用 `MultiByteToWideChar` 或 `CStringW` 换字符串。 2. 确保参数顺序和类型符合 `DrawString` 的重载要求。 3. 管理好内存和对象生命周期。 如果仍有问题,请检查: 1. 项目字符集设置(建议使用 Unicode)。 2. GDI+ 是否正确初始化。 3. 按钮文本是否为空或包含特殊字符。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值