2024年1月17日发(作者:)
用Microsoft Visual C++显示位图图片的几种方法总结
一, 用控件框架作为装载位图的容器来显示位图
用控件作为容器框架来显示位图是很多应用程序中都会遇到和用到的,因为它的方便可控制性
1)、首先,我们先了解几个用到的函数:
1、CWnd::GetDlgItem
CWnd* GetDlgItem( int nID ) const;
void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;
返回值:
指向给定的控件或子窗口的指针。如果没有控件具有nID给出的整数ID,则返回NULL。
返回的指针可能是临时的,不能被保存以供将来使用。
参数:
nID 指定了要获取的控件或子窗口的标识符。
phWnd 指向子窗口的指针。
说明:
这个函数获得对话框或其它窗口中指定控件或子窗口的指针。返回的指针通常被强制转换为nID所标识的控件类型。
2、CWnd::GetDC
CDC* GetDC( );
返回值:
如果调用成功,则返回CWnd客户区的设备环境;否则,返回NULL。这个指针可能是临时的,不能被保存以供将来使用。
说明:
这个函数获得一个指针,指向一个客户区的公用的、属于类的或者私有的设备环境,依赖于为CWnd指定的类风格。对于公用的设备环境,GetDC每次获得设备环境时都给它赋予缺省值。对于属于类的或者私有的设备环境,GetDC保持原来的属性不变。在随后的图形设备接口(GDI)函数中可以使用设备环境以在客户区中绘图。
除非设备环境属于一个窗口类,否则在绘图之后必须调用ReleaseDC成员函数以释放设备环境。由于在同一时刻只有五个公用设备环境可供使用,因此如果释放设备环境时失败,可能导致其它应用程序不能访问设备环境。
如果在注册窗口类的时候,在WNDCLASS的风格中指定了CS_CLASSDC,CS_OWNDC或CS_PARENTDC,则GetDC成员函数将返回属于CWnd类的设备环境。
3、CBitmap::LoadBitmap
BOOL LoadBitmap( LPCTSTR lpszRecourceName );
BOOL LoadBitmap( UINT nIDResource );
返回值:调用成功时返回非零值,否则为0。
参数:
lpszResourceName 指向一个包含了位图资源名字的字符串(该字符串以null结尾)。
nIDResource 指定位图资源中资源的ID号。
说明:
本函数从应用的可执行文件中加载由lpszResourceName指定名字或者由nIDResource指定的ID号标志的位图资源。加载的位图被附在CBitmap对象上。
如果由lpszResourceName指定名字的对象不存在,或者没有足够的内存加载位图,函数将返回0。
可以调用函数CgdiObject::DeleteObject删除由LoadBitmap加载的位图,否则CBitmap的析构函数将删除该位图对象。
警告:在删除位图对象之前,要保证它没有被选到设备上下文中。
在Windows3.1以及以后的版本中,增加了如下的位图:
OBM_UPARROWI
OBM_DNARROWI
OBM_RGARROWI
OBM_LFARROWI
在Windows3.0或者更早版本的设备驱动程序中不支持这些位图。位图的完整列表和图形请参阅“Win32程序员参考”。
4、LoadImage //Windows API 函数,有更好的打开图像功能!
函数功能:该函数装载目标,光标,或位图。共7个参数;
函数原型:HANDLE LoadImage(NINSTANCE hinst,LPCTSTR lpszName,UINT uType,int cxDesired,int CyDesired,UINT fuLoad);
参数:
hinst:处理包含被装载图像模块的特例。若要装载OEM图像,则设此参数值为O。
lpszName:处理图像装载。如果参数hinst为非空,而且参数fuLoad不包括LR_LOADFROMFILE的值时,那么参数lpszName是一个指向保留在hinst模块中装载的图像资源名称,并以NULL为结束符的字符串。
如果参数hinst为空,并且LR_LOADFROMFILE被指定,那么这个参数低位字一定是被装载的OEM图像标识的。OEM图像标识符是在WINUSER.H头文件中定义的,下面列举出前缀的含义:
OBM_ OEM:位图;OIC_OEM图标;OCR_OEM:光标。
如果参数fuLoad包含LR_LOADFROMFILE值,那么参数lpszName是包含有图像的文件名。
uType:指定被装载图像类型。此参数可以为下列值,其含义如下:
IMAGE_BITMAP:装载位图;IMAGE_CURSOR:装载光标;IMAGE_ICON:装载图标。
cxDesired:指定图标或光标的宽度,以像素为单位。如果此参数为零并且参数fuLoad值为LR_DEFAULTSIZE,那么函数使用SM_CXICON或SM_CXCURSOR系统公制值设定宽度;如果此参数为零并且值LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源宽度。
cyDesired:指定图标或光标的高度,以像素为单位。如果此参数为零并且参数fuLoad值为LR_DEFAULTSIZE,那么函数使用SM_CXICON或SM_CXCURSOR系统公制值设定高度;如果此参数为零并且值LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源高度。
fuLoad:根据下面复合值列表指定函数值,值含义如下:
LR_DEFAULTCOLOR:缺省标志;它不作任何事情。它的含义是“无LR_MONOCHROME”。
LR_CREATEDIBSECTION:当参数uType指定为IMAGE_BITMAP时,使得函数返回一个DIB部分位图,而不是一个兼容的位图。这个标志在装载一个位图,而不是映射它的颜色到显示设备时非常有用。
LRDIFAULTSIZE:若 cxDesired或cyDesired未被设为零,使用系统指定的公制值标识光标或图标的宽和高。如果这个参数不被设置且cxDesired或cyDesired被设为零,函数使用实际资源尺寸。如果资源包含多个图像,则使用第一个图像的大小。
LR_LOADFROMFILE:根据参数lpszName的值装载图像。若标记未被给定,lpszName的值为资源名称。
LW_LOADMAP3DCOLORS:查找图像的颜色表并且按下面相应的3D颜色表的灰度进行替换。
颜色替代:Dk Gray RGB(128,128,128)COLOR_3DSHADOW;Gray RGB(192,192,192)COLOR_3DFACELt Gray RGB(223,223,223) COLOR_3DLIGHT
LR_LOADTRANSPARENT;找到图像中的一个像素颜色值并且根据颜色表中系统的缺省颜色值替代其相应接口的值。图像中所有使用这种接口的像素的颜色都变为系统的缺省窗体颜色。此至仅用来申请相应的颜色表。
若fuLoad包括LR_LOADTRANSPARENT和LR_LOADMAP3DCOLORS两个值,则LRLOADTRANSPARENT优先。但是,颜色表接口由COLOR_3DFACE替代,而不是COLOR_WINDOW。
LR_MONOCHROME:装载黑白图。
LR_SHARED:若图像将被多次装载则共享。如果LR_SHARED未被设置,则再向同一个资源第二次调用这个图像是就会再装载以便这个图像且返回不同的句柄。
不要对不同标准尺寸的图像使用LR_SHARED,装载后可能会有改变,或是从文件中被装载。
Windows 95和Windows 98:函数根据缓存中被请求的资源名发现的第一个图像,不管被请求的大小。LR_VGACOLOR:使用VGA真彩色。
返回值:如果函数运行成功,返回值是相关资源的数据的句柄。如果函数运行失败,返回值为NULL。若想获得更多的错误信息,请调用GetLastError函数。
注意:当使用完资源后,必须通过调用函数以释放加速器表、位图、光标、图标以及菜单所占的内存资源;加速器表:DesteoyAcceleratorTable;位图:DeleteObject;光标:DestroyCursor;图标:Destroylcon;菜单:DestroyMenu
当过程创建终止时,系统将自动删除这些资源。但是调用相关函数也可以保留内存减少过程的工作设置所占空间。
Windows CE:对IMAGE_BITMAP来说,参数cxDesred和cyDesred p必须为零。Windows CE不支持图表跳跃或闪烁。
参数fuLoad必须为(=LR_DEFAULTCOLOR)。
如果的目标平台不支持鼠标光标,可以指定在参数cxDesred和cyDsired的SM_CXCURSOR和SM_CYCURSOR的值,但不能指定参数uType中IMAGE_CURSOR的值。
如果目标平台支持鼠标光标,可以指定在参数cxDesired和cyDesred的SM_CXCURSOR和SM_CYCURSOR的值,也能指定参数uType中IMAGE_CURSOR的值。
速查:Windows NT 3.1、Windows 95、Windows CE 1.0以上,头文件:minuser.h:库文件;;Unicode:在Windows NT上实现为Unicode和ANSI两种版本。
5、HINSTANCE AfxGetInstanceHandle( );
返回值:代表应用程序的当前实例的HINSTANCE值。如果是从与MFC的USRDLL版本连接的DLL内调用的,则返回代表DLL的HINSTANCE值。
说明:这个函数使你能够获得当前应用程序的实例句柄。AfxGetInstanceHandle总是返回代表你的可执行文件(.EXE)的HINSTANCE值,除非它从与MFC的USRDLL版本连接的DLL内调用的。在这种情况下,它返回的是DLL的HINSTANCE值。
请参阅:AfxGetResourceHandle, AfxSetResourceHandle
6、CFileDialog::GetPathName
CString GetPathName( )const;
返回值:文件的全路径。
说明:调用此成员函数获取输入到对话框中文件的全路径,路径包括文件标题和文件的全部目录路径。如果对文件“C:”调用此成员函数,GetRathMane则会返回“C:”。
如果m_具有OFN_ALLOWMULTISELECT标志设置,则此字符串包含一系列以空终止符结束的字符串,第一个为选中文件组的目录路径,然后是用户选中的文件。因此,可以用GetStartPosition和GetNextPathName成员函数获取列表中的下一个文件名。
7、CFileDialog::GetFileTitle
CString GetFileTitle() const;
返回值:文件的题目。
说明:
调用此函数检取输入对话框中的文件主题。文件题目只包括它的词头,并不含有路径和扩展名。例如:对文件以c:,GetFileTitle将返回“TEXT”。
如果m_具有OFN_ALLOWMULTISELECT标志设置,则此字符串包含一系列以空终止符结束的字符串。第一个字符串是所选文件的目录路径,然后是用户选择的所有文件名。因此,可以用GetStartPosition和GetNext-PathName成员函数检取列表中的下一个文件名。
8、SetSTretchBltMode //Windows API 函数
函数功能:该函数可以设置指定设备环境中的位图拉伸模式。
函数原型:int SetSTretchBltMode(HDC hdc, int iStretchMode);
参数:hdc:设备环境句柄。
LStretchMode:指定拉伸模式。它可以取下列值,这些值的含义如下:
BLACKONWHITE:使用消除和现在的像素颜色值进行逻辑AND(与)操作运算。如果该位图是单色位图,那么该模式以牺牲白色像素为代价,保留黑色像素点。
COLORONCOLOR:删除像素。该模式删除所有消除的像素行,不保留其信息。
HALFTONE:将源矩形区中的像素映射到目标矩形区的像素块中,覆盖目标像素块的一般颜色与源像素的颜色接近。在设置完HALFTONE拉伸模之后,应用程序必须调用SetBrushOrgEx函数来设置刷子的起始点。如果没有成功,那么会出现刷子没对准的情况。
STRETCH_ANDSCANS:与BLACKONWHITE一样。
STRETCH_DELETESCANS:与COLORONCOLOR一样。
STRECH_HALFTONE:与HALFTONE相同。
STRETCH_ORSCANS:与WHITEONBLACK相同。
WHITEONBLACK:使用颜色值进行逻辑OR(或)操作,如果该位图为单色位图,那么该模式以牺牲黑色像素为代价,保留白色像素点。
返回值:如果函数执行成功,那么返回值就是先前的拉伸模式,如果函数执行失败,那么返回值为0。
Windows NT:若想获得更多错误信息,请调用GetLastError函数。
备注:拉伸模式在应用程序调用StretchBit函数时定义系统如何将位图的行或列与显示设备上的现有像素点进行组合。
BLACKONWHITE(STRETCH_ANDSCANS)和WHITEONBLACK(STRETCH_ORSCANS)模式典型地用来保留单色位图中的前景像素。COLORONCOLOR(STRETCH_DELETESCANS)模式则典型地用于保留彩色位图中的颜色。
HALFTONE模式比其他三种模式需要对源图像进行更多的处理,也比其他模式慢,但它能产生高质量图像,也应注意在设置HALFTONE模式之后,应调用SetBrushOrgEx函数以避免出现刷子没对准现象。
根据设备驱动程序的功能不同,其他一些拉伸模式也可能有效。
9、StretchBlt ////Windows API 函数
函数功能:函数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩。
函数原型:BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest,
int nWidthDest, int nHeighDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int
nWidthSrc, int nHeightSrc, DWORD dwRop);
参数:
hdcDest:指向目标设备环境的句柄。
nXOriginDest:指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
nYOriginDest:指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
nWidthDest:指定目标矩形的宽度,按逻辑单位表示宽度。
nHeightDest:指定目标矩形的高度,按逻辑单位表示高茺。
hdcSrc:指向源设备环境的句柄。
nXOriginSrc:指向源矩形区域左上角的X轴坐标,按逻辑单位表示坐标。
nYOriginSrc:指向源矩形区域左上角的Y轴坐标,按逻辑单位表示坐标。
nWidthSrc:指定源矩形的宽度,按逻辑单位表示宽度。
nHeightSrc:指定源矩形的高度,按逻辑单位表示高度。
dwRop:指定要进行的光栅操作。光栅操作码定义了系统如何在输出操作中组合颜色,这些操作包括刷子、源位图和目标位图等对象。参考BitBlt可了解常用的光栅操作码列表。
返回值:如果函数执行成功,那么返回值为非零,如果函数执行失败,那么返回值为零。Windows NT:若想获得更多的错误信息,请调用GetLastError函数。
速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:wingdi.h:库文件:。
10、GetObject ////Windows API 函数
函数功能:该函数得到指定图形对象的信息,根据图形对象,函数把填满的或结构,或表项(用于逻辑调色板)数目放入一个指定的缓冲区。
函数原型:int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
参数:
hgdiobj:指向感兴趣的图形对象的句柄,它可以是这样的一个句柄:一个逻辑位图、一个刷子、一种字体、一个调色板、笔或通过调用CreateDIBsection函数创建的与设备无关位图。
cbBuffer:指定将要写到缓冲区的信息的字节数目。
lpvObject:指向一个缓冲区的指针,该缓冲区将要检索指定图形对象的信息。
下面列出的是缓冲区为每种图形对象类型可接收的信息和类型,可用hgdiobj来指定,写入*lpvObject: HBITMAP BITMAP。
HBITMAP:如果cbBjffer被设置为sizeof(DIBSECTION)或sizeof(BITMAP),则从对GreatDIBSection函数的DIBSECTION调用中返回。
HPALETTE:逻辑调色板入口数的WORD数目。
HPEN:从对ExtCreatePen函数的LXTLOGPEN调用中返回。
HPENLOGPEN; HBRUSH LOGBRUSH; HFONT LOGFONT
如果lpvObject参数为Null,则函数返回值为指定图形对象需要把信息贮存到缓冲区的字节数目。
返回值:如果函数调用成功,且lpvObject为一个有效指针,则返回值为贮存到缓冲区的字节数目;如果函数调用成功,且lprObject为Null,则返回值为需要容纳的贮存到缓冲区的信息字节数目;如果函数调用失败,则返回值为0。
Windows NT:若想获得更多错误信息,可调用GetLastError函数。
注释:lpvObject参数指向的缓冲区一定要足够大以接收图形对象的信息。
如果hgdiobj标识一个由调用GreateDIBSection创建的位图,且指定的缓冲区足够大,则GetObject函数返回一个DIBSECTION结构。另外,DIBSECTION中的BITMAP结构中的bmBits元素含有一个指向位图位值的指针。
如果hgdiobj标识了一个通过其他途径创建的位图,则GetObject只返回位图的宽、高和颜色格式信息,通过调用GetDIBits或GetBitmapBits函数可以得到位置的位值。
如果hgdiobj标识了一个逻辑调色板,则GetObject检索一个2字节的整数,该整数指定调色板中的项数,函数不检索定义调色板的LOGPALETTE结构,为检索有关调色板项的信息,应用程序可以调用GetPaletteEntries函数。
Windows CE:在Windows CE 1.0中,当用在DIB上中,GetObject总返回一个BITMAP。Windows CE 1.0不支持lpvObject参数的HPALETTE值。此函数在Windows CE 2.0与在Windows桌面上一样。
速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:wingdi.h;库文件:;Unicode:在Windows NT上实现为Unicode和ANSI两种版本。
11、SelectObject ////Windows API 函数
函数功能:该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
函数原型:HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);
参数:
hdc:设备上下文环境的句柄。
hgdiobj:被选择的对象的句型,该指定对象必须由如下的函数创建。
位图:CreateBitmap, CreateBitmapIndirect, CreateCompatible Bitmap,
CreateDIBitmap, CreateDIBsection(只有内存设备上下文环境可选择位图,并且在同一时刻只能一个设备上下文环境选择位图)。
画笔:CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt,
CreateHatchBrush, CreatePatternBrush, CreateSolidBrush。
字体:CreateFont, CreateFontIndirect。
笔:CreatePen, CreatePenIndirect。
区域:CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect,
CreatePolygonRgn, CreateRectRgn, CreateRectRgnIndirect。
返回值:如果选择对象不是区域并且函数执行成功,那么返回值是被取代的对象的句柄;如果选择对象是区域并且函数执行成功,返回如下一值;
SIMPLEREGION:区域由单个矩形组成;COMPLEXREGION:区域由多个矩形组成。NULLREGION:区域为空。
如果发生错误并且选择对象不是一个区域,那么返回值为NULL,否则返回GDI_ERROR。
注释:该函数返回先前指定类型的选择对象,一个应用程序在它使用新对象进行绘制完成之后,应该用新对象替换原始的缺省的对象。
应用程序不能同时选择一个位图到多个设备上下文环境中。
ICM:如果被选择的对象是画笔或笔,那么就执行颜色管理。
速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:wingdi.h;库文件:。
12、CWnd::SetTimer
UINT SetTimer(UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT*lpfnTimer) (HWND, UINT,
UINT, DWORD) );
返回值:如果函数成功,则返回新定时器的标识符。应用程序可以将这个值传递给KillTimer成员函数以销毁定时器。如果成功,则返回非零值;否则返回0。
参数:
nIDEvent
指定了不为零的定时器标识符。
nElapse
指定了定时值;以毫秒为单位。
lpfnTimer
指
定了应用程序提供的TimerProc回调函数的地址,该函数被用于处理WM_TIMER消息。如果这个参数为NULL,则WM_TIMER消息被放入应用程序的消息队列并由CWnd对象来处理。
说明:
这个函数设置一个系统定时器。指定了一个定时值,每当发生超时,则系统就向设置定时器的应用程序的消息队列发送一个WM_TIMER消息,或者将消息传递给应用程序定义的TimerProc回调函数。
lpfnTimer回调函数不需要被命名为TimerProc,但是它必须按照如下方式定义:
void CALLBACK EXPORT TimerProc(
HWND hWnd, // 调用SetTimer的CWnd的句柄
UINT nMsg, // WM_TIMER
UINT nIDEvent // 定时器标识
DWORD dwTime // 系统时间
);
定时器是有限的全局资源;因此对于应用程序来说,检查SetTimer返回的值以确定定时器
是否可用是很重要的。
请参阅:WM_TIMER, CWnd::KillTimer, ::SetTimer
findwindow
FindWindow,Win32 API函数。
FindWindow函数返回与指定字符创相匹配的窗口类名或窗口名的最顶层窗口的窗口句柄。这个函数不会查找子窗口。
函数原型:
HWND FindWindow
(
LPCTSTR lpClassName,
LPCTSTR lpWindowName
);
参数表:
lpClassName
指向一个以null结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。
lpWindowName
指向一个以null结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。
返回值:
如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
如果函数执行失败,则返回值为 NULL 。可以通过调用GetLastError函数获得更加详细的错误信息。
快捷信息:
导入库:
头文件:winuser.h
2)、接下来,我们要分析一下我们的程序需要完成的功能及如何在编程过程中把握一个有规律、有顺序的设计技巧,对于Visual C++以及Windows这样工程性的编程制作,没有一个好的工程思想,在编程过程中会遇到很多不必要的麻烦。
1、我的目的程序外观: ○
2我的目的程序的功能:
○很简单:点击打开文件能成功地打开一个.bmp的位图文件,并在下面的编辑框中显示文件名、文件完整路径、文件标题、文件扩展名,并且由滚动条控制打开当前文件夹中的.bmp文件——单击向左的图标打开上一张图片,单击向右的图标打开下一张图片,并有一个文本框指示当前打开的文件标识和当前文件夹中的总位图文件个数!
3分析要实现相应的目的所需的程序数据及其事件处理函数的实现:
○1、 根据程序功能要求选择合适的MFC框架:
本例从应用程序外观上看,选用基于对话框的可执行程序。
2、 程序所需类、数据、资源
首先肯定需要一个用户自定义的对话框类,再加入相应的一些资源,成员员函数、成员变量;
对话框类:class CMyDlg : public CDialog{}
添加资源:4个静态文本资源,用于标识编辑框所显示的内容,4个编辑控件用于获取文件完整路径、文件名、文件标题、文件扩展名信息,为所添加的编辑框设置相应的字符串(用于显示字符串,所以设置为字符串型)值变量(如表),再添加一个静态文本框用于显示当前操作的位图文件在所属文件夹中的信息,一个图像控件框用于显示位图文件;
资源ID
IDC_EDIT1
IDC_EDIT2
IDC_EDIT3
IDC_EDIT4
IDC_OPEN
IDC_PIC
IDC_PICNUM
变量(句柄)
m_filepath
m_filename
m_fileexname
m_filetitle
m_num
功能用处
得到文件路径
得到文件名
得到文件扩展名
得到文件标题
所属类
CMyDlg
CMyDlg
CMyDlg
CMyDlg
单击打开文件操作
CMyDlg
CMyDlg
显示位图文件
显示文件个数信息
CMyDlg
IDC_SCROLLBAR m_ScrollBar
滚动条控制文件
CMyDlg
这样,这个应用程序使用的一个特殊的对话框类就初步创建完了,可以在这时后用Ctrl+F5运行一下程序,如下图:
此时还没有给按钮添加一定的事件,所以出现这个画面仅仅说明:前面我们的操作都是正确的,程序可以执行,但是单击打开按钮是什么用也没有的 ,要使事件产生一定的反应就要给按钮事件添加一定的消息处理函数!
接下来,我们给程序添加事件处理函数,也是整个程序设计最重要,最麻烦的一步!在这一步里,要做的是:首先,明确要处理怎样一个事件,通过类的哪些方法,以及这些方法需要有哪些数据准备(以便在应用程序类中添加相应的成员函数“几个消息处理函数都要用的要考虑放在相应的类中作为成员变量”或者处理函数中添加相应所需的变量“只有个别处理函数用到且在应用程序中没有很大关联性的变量可以考虑将它设为函数的局部变量,在函数调用完毕后会释放,降低内存损耗!”),进而对类的结构体系进行进一步的改写,最后,编写消息处理函数及消息处理函数的支撑类成员函数,调试运行,—〉完工!
本应用程序的消息处理函数有:
1、用于单击打开按钮,用来打开位图文件;
void CMyDlg::OnOpen()
{
CFileDialog dlg(TRUE,"bmp",".bmp",OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT,"位图文件(*.BMP)|*.BMP||");
if(l()==IDOK)
{
caculate();
//遍历该文件夹找出所有的bmp文件,进行相应的记录,是需要编写的成员支撑函数
hwnd = GetDlgItem(IDC_PIC);
//返回一个窗口类的指针,IDC_PIC是窗口中的一个图像控件框
hDesDC = hwnd->GetDC()->m_hDC;
//HDC m_hDC是属于CDC类的输出设备上下文句柄;
//hDesDC目的矩形区域;
//hSrcDC源矩形区域;
//语句
hSrcDC = CreateCompatibleDC(hDesDC);
UpdateData(true);
//是数据更新可用,编辑框中的内容能够及时刷新
hBitmap=(HBITMAP)LoadImage(
AfxGetInstanceHandle(),
//获取当前处理图像的实例句柄
m_filepath=hName(),
//从文件对话框类获得要装载位图文件的句柄
IMAGE_BITMAP,//装载位图
0,//图标宽度
0,//图标高度
LR_LOADFROMFILE|LR_CREATEDIBSECTION);//从文件装载位图或者创建部分位图;
m_filename=eName();//显示文件名
m_fileexname=eExt();//显示文件扩展名!
m_filetitle=eTitle();//显示文件标题!
//LoadImage();是windows API函数!通过它向
GetObject(hBitmap, sizeof BITMAP, &bm);
//该函数得到指定图形对象的信息,根据图形对象,函数把填满的或结构
//或表项(用于逻辑调色板)数目放入一个指定的缓冲区。
SelectObject(hSrcDC, hBitmap);
//该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
hwnd->GetClientRect(&rect);
//执行成员函数获得客户区大小;RECT rect是CMyDlg的成员变量
::SetStretchBltMode(hDesDC,COLORONCOLOR);
//hDesDC变量由语句hDesDC = hwnd->GetDC()->m_hDC;指定设备:窗口矩形区的句柄
//COLORONCOLOR:拉伸模式中的删除象素:该模式删除所有消除的像素行,不保留其信息。
::StretchBlt(hDesDC,
, , , ,
hSrcDC,
0, 0, h, ht,
+SRCCOPY);
//函数从源矩形中复制一个位图到目标矩形,
//必要时按目前目标设备设置的模式进行图像的拉伸或压缩。
SetTimer(IDT_TIMER,50,NULL);
//-----确定当前位图的位置
iPos=0;
while(family[iPos]!=hName())
{iPos++;
}
m_ollRange(0,picnum-1);
m_ollPos(iPos);
}
{
//刷新
}
}
m_("第 %d 张,共 %d 张",iPos+1,picnum);
UpdateData(false);
else
SetTimer(IDT_TIMER,30,NULL);
从上面的程序中我们可以看到打开一个位图文件所必须的额外类成员变量有:
RECT rect; //要绘制的客户区矩形框
BITMAP bm;//位图
HBITMAP hBitmap;//位图指针
HDC hSrcDC;//源设备指针
HDC hDesDC;//目的设备指针
CWnd *hwnd;//窗口类指针,用于得到要绘制的区域;
//遍历文件夹
void CMyDlg::caculate()
{
picnum=0;
CFileFind finder;
Work = le("*.BMP");
while(Work)
{
char FileName[250];
}
Work=xtFile();
sprintf(FileName,"%s",ePath());
family[picnum]=FileName;
picnum+=1;
}
iPos=-1;
//处理滚动条事件
void CMyDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
switch(nSBCode)
{
case SB_LINERIGHT: //如果滚动条点的是向右;
{ UpdateData(true);
if(iPos { iPos+=1; m_ollPos(iPos); m_("第 %d 张,共 %d 张",iPos+1,picnum); hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),family[iPos],IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); GetObject(hBitmap, sizeof BITMAP, &bm); SelectObject(hSrcDC, hBitmap); ::SetStretchBltMode(hDesDC,COLORONCOLOR); ::StretchBlt(hDesDC, , , , , hSrcDC, 0, 0, h, ht,+SRCCOPY); } } UpdateData(false); break; case SB_LINELEFT: //如果滚动条点的是向左; { UpdateData(true); if(iPos>0) { iPos-=1; m_ollPos(iPos); m_("第 %d 张,共 %d 张",iPos+1,picnum); hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),family[iPos],IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); GetObject(hBitmap, sizeof BITMAP, &bm); SelectObject(hSrcDC, hBitmap); ::SetStretchBltMode(hDesDC,COLORONCOLOR); ::StretchBlt(hDesDC, , , , , hSrcDC, 0, 0, h, ht,+SRCCOPY); } } UpdateData(false); break; case SB_THUMBTRACK://应该是鼠标拖动吧 { UpdateData(true); iPos=nPos; m_ollPos(iPos); hBitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),family[iPos],IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); GetObject(hBitmap, sizeof BITMAP, &bm); SelectObject(hSrcDC, hBitmap); ::SetStretchBltMode(hDesDC,COLORONCOLOR); ::StretchBlt(hDesDC, , , , , hSrcDC, 0, 0, h, ht,+SRCCOPY); m_("第 %d 张,共 %d 张",iPos+1,picnum); } UpdateData(false);//这条语句让静态文本标识及时更新! break; } CDialog::OnHScroll(nSBCode, nPos, pScrollBar); } //定时器OnTimer方法 void CMyDlg::OnTimer(UINT nIDEvent) { ::StretchBlt(hDesDC, , , , , hSrcDC, 0, 0, h, ht,+SRCCOPY); CDialog::OnTimer(nIDEvent); }


发布评论