热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

菜虫的悲哀:搞不懂,编译链接均通过,一运行就关不掉,只好用任务管理器强关,结果导致CMyBitmapView的源程序打不开,到底是啥原因?

还是那个只能打开并显示任意的系统磁盘上的24位真彩bmp文件的问题,常规方法咱看不懂,什么文件头,什么信息头,什么句柄,什么参数表,一看头就晕.虽说CBitmap类只能显示VCMFC所生成的应用程序
还是那个只能打开并显示任意的系统磁盘上的24位真彩bmp文件的问题,常规方法咱看不懂,什么文件头,什么信息头,什么句柄,什么参数表,一看头就晕.虽说CBitmap类只能显示VC/MFC所生成的应用程序中资源的bmp文件,但是我仅仅把bitmap.LoadBitmap(dlg.GetFileName())加入程序,编译/链接/运行均没问题,我想再通过适当扩展一下,应该能够达到设计目的.只是,如此尝试的结果却是......
此GUI是基于文档/视图类的SDI:
手动添加部分:
void CMyBitmapDoc::OnFileOpen() 
{
// TODO: Add your command handler code here
CFileDialog dlg(TRUE, _T(".bmp"), NULL, OFN_FILEMUSTEXIST,
_T("位图文件(*.bmp)|*.bmp||"));
if(dlg.DoModal() == IDOK)
{
    dlg.GetPathName();//设定只能打开(位图文件(*.bmp))的模态对话框
CBitmap::operator HBITMAP;//如果调用成功的话,用CBitmap类中的bitmap对象代替 win32操作系统中的处理GDI接口的句柄(不知对否?)

CBitmap bitmap;
//bitmap.LoadBitmap(dlg.GetFileName());照着人家网上搬了一句,不知它能否成功装载系统磁盘上的DIB类型的bmp文件进入bitmap对象?

CDC MemDC;
MemDC.SelectObject(bitmap);//映射bmp图像文件到内存
//创建内存与系统显示兼容的设备上下文
MemDC.CreateCompatibleDC(NULL);

BITMAP bm;
bitmap.GetBitmap (&bm);
int bmWidth=bm.bmWidth,bmHeight=bm.bmHeight;//获得位图文件的宽/高信息
CRect rect;
rect.SetRect(0,0,bmWidth,bmHeight);
CWnd currentwindow;
currentwindow.GetClientRect(rect);//在当前视图窗口客户区创建一个与位图一样大小的显示文件的矩形窗
MemDC.StretchBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,
bmWidth,bmHeight,SRCCOPY);//位图可伸缩的从源设备上下文映射到目的设备上下文
return;
}
}
然后再在CBitmapView::OnDraw(CDC*pDC)(由于我已经打不开了,MFC自动生成的源代码就不COPY了)反正,就是在最后的添加代码处添了一句使无效函数:Invalidate();//立即显示位图
问题疹状如下:
1/ 编译虽没问题,但编译后马上会出现系统错误:"windows-延缓写入失败:windows无法为VC/MFC的SDI应用程序所在目录(F:\C++programs\MyBitmap\MyBitmap\MyBitmap.plg)文件保存所有数据.数据已经丢失.这个错误可能是由于您的计算机硬件或网络连接的失败而造成的.请尝试把这份文件保存到别处.
2/ 下面是调试报告:
--------------------Configuration: MyBitmap - Win32 Debug--------------------
Linking...
LINK : LNK6004: Debug/MyBitmap.exe not found or not built by the last incremental link; performing full link
.\Debug\MyBitmapView.obj : error : Internal error during ReadSymbolTable
  ExceptionCode            = C0000006
  ExceptionFlags           = 00000000
  ExceptionAddress         = 0040C842
  NumberParameters         = 00000003
  ExceptionInformation[ 0] = 00000000
  ExceptionInformation[ 1] = 00B70000
  ExceptionInformation[ 2] = C0000185
CONTEXT:
  Eax    = 00000008  Esp    = 0012F704
  Ebx    = 003796D0  Ebp    = 00000008
  Ecx    = 00000002  Esi    = 00B70000
  Edx    = 00000008  Edi    = 0012F730
  Eip    = 0040C842  EFlags = 00010202
  SegCs  = 0000001B  SegDs  = 00000023
  SegSs  = 00000023  SegEs  = 00000023
  SegFs  = 0000003B  SegGs  = 00000000
  Dr0    = 0012F704  Dr3    = 003796D0
  Dr1    = 00000008  Dr6    = 00000002
  Dr2    = 00000000  Dr7    = 00000000
Error executing link.exe.
Tool execution canceled by user.
3/ 一点"运行"按钮,就出现了计算机开机就死的那种黑屏(蓝屏)的等待C命令提示符界面.
如果要想打开CMyBitmapView源文件,若要从ClassView打开,鼠标处于等待状态一段长时间后,又回到光标状态,但界面并没有替换;若从FileView打开,疹状同上;外加一个系统错误报告对话框:"在对一未命名文件进行访问时发生了一个不明错误.

9 个解决方案

#1


更倒霉的是,下午关机时,屏幕中央出现一“正在关断网络连接”系统窗口,稍后此窗口区域黑屏,自动关机关不了,只好硬关机。晚上开机,系统报告“因以下文件的损坏或者丢失,windows无法启动\system32\hal.dll,请重新安装以上文件的拷贝。本想拿个系统安装盘修复一下,谁知给我来了个重新安装。前几天我的系统由于中标(中毒)了,刚装过。唉,程序又搞不出来,系统又老崩溃,最近真是“走运”啊?!hal.dll:Hardware Abstraction Layer dynamic link library:硬件抽象层链接库,到底是啥原因导致其损坏或丢失的?难不成是俺的编程误操作?

#2


虽然上述问题至今还没搞明白,但bmp的显示我总算蒙出来了,虽然不尽如人意,但总算告一段落了,虽然一次显示不全(甚至不显示),但最小化后,再恢复原大小,bmp原貌尽现:
引入24位CDib类,
头文件定义如下:
// DIB.h

#ifndef __DIB_H__
#define __DIB_H__

class CDib
{

public:
CDib();
~CDib();

BOOL Load( const char * );
BOOL Save( const char * );
BOOL Draw( CDC *, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1 );
BOOL SetPalette( CDC * );

private:
CPalette m_Palette;
unsigned char *m_pDib, *m_pDibBits;
DWORD m_dwDibSize;
BITMAPINFOHEADER *m_pBIH;
RGBQUAD *m_pPalette;
int m_nPaletteEntries;

};

#endif
源文件实现如下:
// DIB.cpp

#include "stdafx.h"
#include "DIB.h"

CDib::CDib()
{

// Set the Dib pointer to
// NULL so we know if it's
// been loaded.
m_pDib = NULL;

}

CDib::~CDib()
{

// If a Dib has been loaded,
// delete the memory.
if( m_pDib != NULL )
delete [] m_pDib;

}

BOOL CDib::Load( const char *pszFilename )
{

CFile cf;

// Attempt to open the Dib file for reading.
if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );

// Get the size of the file and store
// in a local variable. Subtract the
// size of the BITMAPFILEHEADER structure
// since we won't keep that in memory.
DWORD dwDibSize;
dwDibSize =
cf.GetLength() - sizeof( BITMAPFILEHEADER );

// Attempt to allocate the Dib memory.
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
return( FALSE );

BITMAPFILEHEADER BFH;

// Read in the Dib header and data.
try{

// Did we read in the entire BITMAPFILEHEADER?
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||

// Is the type 'MB'?
BFH.bfType != 'MB' ||

// Did we read in the remaining data?
cf.Read( pDib, dwDibSize ) != dwDibSize ){

// Delete the memory if we had any
// errors and return FALSE.
delete [] pDib;
return( FALSE );
}
}

// If we catch an exception, delete the
// exception, the temporary Dib memory,
// and return FALSE.
catch( CFileException *e ){
e->Delete();
delete [] pDib;
return( FALSE );
}

// If we got to this point, the Dib has been
// loaded. If a Dib was already loaded into
// this class, we must now delete it.
if( m_pDib != NULL )
delete m_pDib;

// Store the local Dib data pointer and
// Dib size variables in the class member
// variables.
m_pDib = pDib;
m_dwDibSize = dwDibSize;

// Pointer our BITMAPINFOHEADER and RGBQUAD
// variables to the correct place in the Dib data.
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =
(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];

// Calculate the number of palette entries.
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;

// Point m_pDibBits to the actual Dib bits data.
m_pDibBits =
&m_pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];

// If we have a valid palette, delete it.
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();

// If there are palette entries, we'll need
// to create a LOGPALETTE then create the
// CPalette palette.
if( m_nPaletteEntries != 0 ){

// Allocate the LOGPALETTE structure.
LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];

if( pLogPal != NULL ){

// Set the LOGPALETTE to version 0x300
// and store the number of palette
// entries.
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;

// Store the RGB values into each
// PALETTEENTRY element.
for( int i=0; i pLogPal->palPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}

// Create the CPalette object and
// delete the LOGPALETTE memory.
m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}

return( TRUE );

}

BOOL CDib::Save( const char *pszFilename )
{

// If we have no data, we can't save.
if( m_pDib == NULL )
return( FALSE );

CFile cf;

// Attempt to create the file.
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );

// Write the data.
try{

// First, create a BITMAPFILEHEADER
// with the correct data.
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );

// Write the BITMAPFILEHEADER and the
// Dib data.
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pDib, m_dwDibSize );
}

// If we get an exception, delete the exception and
// return FALSE.
catch( CFileException *e ){
e->Delete();
return( FALSE );
}

return( TRUE );

}

BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight )
{

// If we have not data we can't draw.
if( m_pDib == NULL )
return( FALSE );

// Check for the default values of -1
// in the width and height arguments. If
// we find -1 in either, we'll set them
// to the value that's in the BITMAPINFOHEADER.
if( nWidth == -1 )
nWidth = m_pBIH->biWidth;
if( nHeight == -1 )
nHeight = m_pBIH->biHeight;

// Use StretchDIBits to draw the Dib.
StretchDIBits( pDC->m_hDC, nX, nY,
nWidth, nHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY );

return( TRUE );

}

BOOL CDib::SetPalette( CDC *pDC )
{

// If we have not data we
// won't want to set the palette.
if( m_pDib == NULL )
return( FALSE );

// Check to see if we have a palette
// handle. For Dibs greater than 8 bits,
// this will be NULL.
if( m_Palette.GetSafeHandle() == NULL )
return( TRUE );

// Select the palette, realize the palette,
// then finally restore the old palette.
CPalette *pOldPalette;
pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
pDC->RealizePalette();
pDC->SelectPalette( pOldPalette, FALSE );

return( TRUE );

}
在别人指点下,在CVCBitmapDoc.h中定义全局公有变量:CDib mydibfilename;
void CVCBitmapDoc::OnFileOpen() 
{
// TODO: Add your command handler code here
CFileDialog dlg(TRUE, _T(".bmp"), NULL, OFN_FILEMUSTEXIST,
_T("位图文件(*.bmp)|*.bmp||"));
CString bitmapfilename;
if(dlg.DoModal() == IDOK)//利用模态对话框打开bmp/dib位图文件
{
CString mydibfilename; 
        mydibfilename=dlg.GetPathName();
mydibfilename=mydib.Load(mydibfilename);
mydib.Save(mydibfilename);
}
}
。。。。。。
void CVCBitmapView::OnDraw(CDC* pDC)
{
CVCBitmapDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDoc->mydib.Draw(pDC,0,0,-1,-1);

}
到现在我才知道,为什么必须在CView类里显示bmp,如在CDoc类显示,必须要动态绑定pDoc与pDC,估计比较难,向我这样的菜虫,基础的都不会,何来技术可言?我原来也试过在CView类里显示,但指向得到文档的指针pDoc没有指向响应OnDraw()消息的Draw(),所以我一直在混混沌沌,终于20天以后,搞到一个好类,让我差不多可以蒙混过关了——真是”踏破铁鞋无觅处,得来全不费功夫!”不过,就算这样,还是出我最开始说的问题,各位师兄、师姐,如有时间帮忙搞搞。我的邮箱是:hwzcjxhl@126.com.




#3


不能给自己分,看样子此贴结不了了,关于上述问题,算了,我就在这里热情地等待回复好了!

#4


有了这个dib类还有什么问题?

#5


问题还大着呢,第一次打开bmp,要么不显示,要么显示不全,非要最小化后再还原窗口,才显示的出来。

#6


佩服楼主的研究精神, 如果是我遇到这类问题最先的方法就是从网上找现成的代码直接移到自己的工程里用. 如果一条不通就再找另一条, 这类显示图片的代码应该还是不少的.

#7


BMP文件的格式应该属于最简单的了,楼主确实可以深究一下
我没仔细看您的代码,不过我有点怀疑是否是调色板出错了,检查一下相关部分?

#8


程序流程有问题
你是想在那里显示?

在void CVCBitmapDoc::OnFileOpen() 
里面你只要记录bmp文件名,然后在view里面对这个文件操作

看你的样子好象是只操作bmp文件,那就没有必要用cdib类

使用LoadImage从文件名得到bmp图的handle
创建内存dc选入这个handle,然后使用bitblt画出来

#9


原来如此,只须在 pDoc->mydib.Draw(pDC,0,0,-1,-1);之后加上 this->Invalidate(false);//立即显示即可,理论依据:参见MSDN中关于 this->Invalidate()函数的描述:CWnd::Invalidate
void Invalidate( BOOL bErase = TRUE );

Parameters

bErase

Specifies whether the background within the update region is to be erased.

Remarks

Invalidates the entire client area of CWnd. The client area is marked for painting when the next WM_PAINT message occurs. The region can also be validated before a WM_PAINT message occurs by the ValidateRect or ValidateRgn member function.

The bErase parameter specifies whether the background within the update area is to be erased when the update region is processed. If bErase is TRUE, the background is erased when the BeginPaint member function is called; if bErase is FALSE, the background remains unchanged. If bErase is TRUE for any part of the update region, the background in the entire region, not just in the given part, is erased. 

Windows sends a WM_PAINT message whenever the CWnd update region is not empty and there are no other messages in the application queue for that window.

老实说,老师给我们讲过程序设计流程,思路就类似我搬的CDib类,原来我太沉醉于CBitmap及CBitmapFile类了,前者根本不可能直接显示位图,后者到现在我还没搞懂,所以就找了一个我比较容易掌握的简单的类来辅助设计!不过,Thank everyone of you all the same!

推荐阅读
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文介绍如何通过注册表编辑器自定义和优化Windows文件右键菜单,包括删除不需要的菜单项、添加绿色版或非安装版软件以及将特定应用程序(如Sublime Text)添加到右键菜单中。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 基因组浏览器中的Wig格式解析
    本文详细介绍了Wiggle(Wig)格式及其在基因组浏览器中的应用,涵盖variableStep和fixedStep两种主要格式的特点、适用场景及具体使用方法。同时,还提供了关于数据值和自定义参数的补充信息。 ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • MySQL DateTime 类型数据处理及.0 尾数去除方法
    本文介绍如何在 MySQL 中处理 DateTime 类型的数据,并解决获取数据时出现的.0尾数问题。同时,探讨了不同场景下的解决方案,确保数据格式的一致性和准确性。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 分享一个简化版的Silverlight链接图项目:Link Map Simplified
    本文介绍了一个使用Silverlight开发的可视化工具,主要用于展示和操作复杂的实体关系图(Graph)。该工具在犯罪调查系统中得到了广泛应用,帮助用户直观地获取和理解相关信息。 ... [详细]
author-avatar
谢莹UiK_1928
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有