第10章 在MFC中创建应用程序的资源.

Slides:



Advertisements
Similar presentations
1 第 10 章 在 MFC 中创建应 用程序的资源. 2 在 Windows 的可执行文件中,资源是独 立于代码的,使用单独的 Resource Compiler 进行编译,并嵌入到可执行文 件中。 在编程过程中,代码是可复用的,资源 也是可复用的,通过资源的 “ 导入 ” 和 “ 导 出 ” 功能来实现资源的可复用。
Advertisements

插入超链接 高邮市第一实验小学 范太国 任务一:设置文本超链接 任务一:设置文字超链接 步骤:1、选定文字并右击,在快捷菜单 中选择“超链接”命令。 2、在弹出的对话框中选择左侧“链接到:”中的“本文档中的位置(A)”项,在“请选择文档中的位置(C):”中选择需要链接的幻灯片,单击“确定”按钮。
第三章 数据类型和数据操作 对海量数据进行有效的处理、存储和管理 3.1 数据类型 数据源 数据量 数据结构
PRESENTED BY OfficePLUS
Oracle数据库 Oracle 子程序.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
在PHP和MYSQL中实现完美的中文显示
第九章 字符串.
第5章 文本与字体 2018/11/14 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2018/11/14 Huang Weitong.
第5章 图形和文本输出.
Visual C++ Windows Programming
第八章 菜单设计 §8.1 Visual FoxPro 系统菜单 §8.2 为自己的程序添加菜单 §8.3 创建快捷菜单.
第5章 文本与字体 2018/12/3 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2018/12/3 Huang Weitong.
简要回顾 了解课程体系、课程目的和主要内容 掌握Windows编程涉及的一些主要概念 DOS程序和Windows程序的主要区别 窗口和程序
第1章 Windows应用程序框架的 创建与消息处理
走进编程 程序的顺序结构(二).
辅导课程六.
第十一讲 MFC常用控件的使用(3) 严宣辉 数学与计算机科学学院
MFC WinSock类的编程 为简化套接字网络编程,更方便地利用Windows的消息驱动机制,微软的基础类库(Microsoft Foundation Class Libary,简称MFC),提供了两个套接字类,在不同的层次上对Windows Socket API函数进行了封装,为编写Windows.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
PostgreSQL 8.3 安装要点 四川大学计算机学院 段 磊
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第4章 MFC编程 4.1 MFC概述 4.2 MFC和Win CObject类 4.4 消息映射的实现
第10章 高级用户界面设计 10.1 菜单设计 10.2 通用对话框 10.3 图像列表框控件 10.4 树形视图控件
Windows 7 的系统设置.
POWERPOINT TEMPLATE HI.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
第八章 文档/视图结构应用程序 8.1 文档/视图结构 8.2 图形与文字输出 8.3 定时器 8.4 鼠标和键盘消息处理 8.5 对话框
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
产品推广 PRODUCT PROMOTION PRESENTED BY OfficePLUS.
直接扫描保存成TIF格式, 其他图片格式用Windows XP自带的 Windows图片与传真查看器打开
第十二讲 菜单、工具栏和状态栏 严宣辉 数学与计算机科学学院
《面向对象程序设计与Visual C++6.0教程》
第1章 c++概述 1.1 C++语言的简史及特点 1.2 简单的C++程序 1.3 C++语言的基本组成
Visual C++ Windows Programming
VisComposer 2019/4/17.
实验四、TinyOS执行机制实验 一、实验目的 1、了解tinyos执行机制,实现程序异步处理的方法。
VB与Access数据库的连接.
分裂对象模型 C++ otcl.
项目二:HTML语言基础.
ES 索引入门
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第5章 文本与字体 2019/4/25 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2019/4/25 Huang Weitong.
第4章 Excel电子表格制作软件 4.4 函数(一).
功能表的建立 製作.
iSIGHT 基本培训 使用 Excel的栅栏问题
_13简单的GDI绘图操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
Visual Basic程序设计 第13章 访问数据库
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
VRP教程 2011.
第10章媒体控制接口 10.1 MCI设备类型 10.2 MCI编程步骤 10.3使用MCIWnd窗口类.
Python 环境搭建 基于Anaconda和VSCode.
MFC控件 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang 官网地址:
回归分析实验课程 (实验三) 多项式回归和定性变量的处理.
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
本课内容 接下来的几节课,我们要利用C语言开发一些游戏 本节课开发一个俄罗斯方块游戏 游戏规则.
第8章 创建与使用图块 将一个或多个单一的实体对象整合为一个对象,这个对象就是图块。图块中的各实体可以具有各自的图层、线性、颜色等特征。在应用时,图块作为一个独立的、完整的对象进行操作,可以根据需要按一定比例和角度将图块插入到需要的位置。 2019/6/30.
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
培训课件 AB 变频器的接线、操作及参数的备份 设备动力科.
《手把手教你学STM32-STemWin》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
Presentation transcript:

第10章 在MFC中创建应用程序的资源

在Windows的可执行文件中,资源是独立于代码的,使用单独的Resource Compiler进行编译,并嵌入到可执行文件中。 在编程过程中,代码是可复用的,资源也是可复用的,通过资源的“导入”和“导出”功能来实现资源的可复用。 程序的国际化,也是通过资源来实现的。

10.1获取资源的一个样例 查看Windows(98/2000)系统中自带的纸牌游戏中的图片资源: c:\Windows\cards.dll 或 c:\WINNT\System32

10.2 资源的应用

10.2.1 菜单资源的使用 创建一个“计算”菜单

【例10-1】创建一个基于单文档结构的应用程序,在视图中显示一行字符串“Hello World ID_OPER_SHOW ID_OPER_RED ID_OPER_GREEN ID_OPER_BLUE Hello World!

在My_ResView.h中的 class CMy_ResView : public Cview 中的public处加入如下声明:   COLORREF m_nColors[3]; //用户可选颜色数组 DWORD m_nColorIndex; // 当前所选颜色索引 CString m_strShow; // 显示的内容 BOOL m_bShow; // 是否显示

在CMy_ResView::CMy_ResView()中初始化成员变量: m_nColors[0] = RGB(255,0,0); m_nColors[1] = RGB(0,255,0); m_nColors[2] = RGB(0,0,255); m_nColorIndex = 0; m_strShow = "Hello World!"; m_bShow = TRUE; 在void CMy_ResView::OnDraw(CDC* pDC) 中加入如下代码绘制字符串: if(m_bShow) { pDC->SetTextColor(m_nColors[m_nColorIndex]); // 设置输出字符串颜色 pDC->TextOut(100,100,m_strShow); // 输出字符串 }

若编译运行程序,可看到程序输出一行红色的字符串,但颜色设置菜单项还没有起作用 下面将介绍如何通过菜单项来控制程序,在介绍菜单项的响应时,必须先了解几个消息响应机制: COMMAND消息的响应 UPDATE_COMMAND_UI消息的响应 ON_COMMAND_RANGE对COMMAND消息的响应 ON_UPDATE_COMMAND_UI_RANGE对UPDATE_COMMAND_UI消息的响应

(1) COMMAND消息的响应 添加了对COMMAND消息的响应之后, My_ResView.h发生如下变化: // Generated message map functions protected: //{{AFX_MSG(CMy_ResView) afx_msg void OnOperShow(); //}}AFX_MSG

重新编译运行程序,可看到“显示”菜单项工作正常 在My_ResView.cpp文件中,读者会看到ID_OPER_SHOW对应的COMMAND消息的绑定,代码如下 : BEGIN_MESSAGE_MAP(CMy_ResView, CView) //{{AFX_MSG_MAP(CMy_ResView) ON_COMMAND(ID_OPER_SHOW, OnOperShow) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() 在My_ResView.cpp文件的最后加入如下代码: void CMy_ResView::OnOperShow() {m_bShow = !m_bShow; Invalidate(); // 强制程序重新窗口 } 重新编译运行程序,可看到“显示”菜单项工作正常

(2) UPDATE_COMMAND_UI消息的响应 为ID_OPER_SHOW添加UPDATE_COMMAND_UI消息。在自动生成消息处理函数中加入如下代码: void CMy_ResView::OnUpdateOperShow(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bShow); } 此时可看到随着m_bShow的值的改变,显示菜单项的状态与实际是否显示字符串的状态一致了,通过菜单项前面的“√”标记来体现。

CCmdUI类常用的方法 void Enable( BOOL bOn = TRUE ) 禁止或者允许该菜单项 void SetCheck( int nCheck = 1 ) 设置菜单项/工具条按钮的check状态,显示标志为“√” void SetRadio( BOOL bOn = TRUE ) 与SetCheck功能类似,显示标志为“·” void SetText( LPCTSTR lpszText ) 设置菜单项的Caption属性 CCmdUI类常用的方法

(3) ON_COMMAND_RANGE对COMMAND消息的响应 ON_COMMAND_RANGE为处理具有连续Object ID的菜单项提供了方便的途径。 前面只响应了三种颜色操作,若有100种颜色可供选择,是否逐个定义其响应函数?显然工作量很大,我们可以使用ON_COMMAND_RANGE。 由于ClassWizard不支持ON_COMMAND_RANGE消息的自动映射,只能手工添加消息的处理。 在My_ResView.h中声明消息的处理函数 //{{AFX_MSG(CMy_ResView) afx_msg void OnOperShow(); afx_msg void OnUpdateOperShow(CCmdUI* pCmdUI); afx_msg void OnOperColorChange(WORD nID); //}}AFX_MSG 所处理的菜单项的ID。

在My_ResView.cpp的开头部分加入如下斜体标识的代码,完成消息映射 BEGIN_MESSAGE_MAP(CMy_ResView, CView) //{{…… ON_COMMAND_RANGE( ID_OPER_RED, // ID范围的最小值 ID_OPER_BLUE, // ID范围的最大值 OnOperColorChange) //消息处理函数 END_MESSAGE_MAP() 在My_ResView.cpp的最后加入消息处理函数: void CMy_ResView::OnOperColorChange(WORD nID) { m_nColorIndex = nID-ID_OPER_RED; Invalidate(); } 运行程序,可以通过菜单项来改变颜色了

(4) ON_UPDATE_COMMAND_UI_RANGE ON_UPDATE_COMMAND_UI_RANGE与ON_UPDATE_COMMAND_UI的关系类似和ON_COMMAND_RANGE与ON_COMMAND的关系 下面仿照手工加入ON_COMMAND_RANGE过程加入ON_UPDATE_COMMAND_UI_RANGE宏。 在My_ResView.h中加入如下代码: afx_msg void OnUpdateOperColorChange(CCmdUI * pCmdUI);

在My_ResView.cpp中加入如下代码: ON_UPDATE_COMMAND_UI_RANGE(ID_OPER_RED,ID_OPER_BLUE,OnUpdateOperColorChange) … void CMy_ResView::OnUpdateOperColorChange(CCmdUI * pCmdUI) { pCmdUI->SetRadio(m_nColorIndex== (pCmdUI->m_nID - ID_OPER_RED)); } 由于CCmdUI类的成员m_nID就是调用OnUpdateOperColorChange时当前的菜单项ID,因此OnUpdateOperColorChange函数没有nID这个参数

10.2.2快捷菜单的创建及其应用 【例10-2】在【例10-1】的基础上增加快捷菜单,实现“操作”菜单的功能 1. 创建菜单资源:在ResourceView菜单中右击Menu,选择Insert Menu,资源命名为IDR_MENU_POP

在My_ResView.h中声明快捷菜单中对应的变量。 CMenu m_PopMenu; // Pop-up快捷菜单 CMenu* m_pPop; // Pop-up快捷子菜单 …… afx_msg void OnRButtonDown(UINT nFlags, CPoint point); 在My_ResView.cpp中添加如下代码: ON_COMMAND(ID_POP_SHOW, OnOperShow) //消息响应 … CMy_ResView::CMy_ResView() { m_PopMenu.LoadMenu(IDR_MENU_VIEW); // 创建并加载菜单资源 }

CMy_ResView::~CMy_ResView() { m_PopMenu.DestroyMenu(); // 释放菜单资源 }   void CMy_ResView::OnRButtonDown(UINT nFlags, CPoint point) {m_pPop=m_PopMenu.GetSubMenu(0); //获得第一个子菜单 UINT nCheck = m_bShow?MF_CHECKED:MF_UNCHECKED; // 更新【Show】的check状态 m_pPop->CheckMenuItem(ID_POP_SHOW,MF_BYCOMMAND|nCheck); ClientToScreen(&point); //将坐标由客户坐标转化为屏幕坐标 m_pPop->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this); // 显示Pop-up菜单 CView::OnRButtonDown(nFlags, point);

10.2.3加速键资源的创建及其使用 【例10-3】在【例10-2】的基础上添加Ctrl+W来触发“显示”菜单项的功能。

10.2.4工具条资源的创建及其使用 在Windows应用程序中,工具条可以看作是图形化的菜单,是一种更快捷、更有效、更直观的人机交互方式。 1 工具条类的层次位置及其常用方法 工具条由CWnd类派生的,它们都连接到一个Windows应用程序窗口。因此,CWnd的所有功能如创建、移动、显示和隐藏窗口等在用控制条工作时都是可用的。

Create():创建一个工具条并把它附加到CToolBar对象上 CreateEx():创建一个定义了边界的工具条并附加到CToolBar对象上 SetSizes():设置按钮及位图大小 SetHeight():设置工具条的高度 LoadToolBar():装载工具条资源 LoadBitmap():装载包含工具按钮图像的位图 SetBitmap():设置位图图像 SetButtons():设置按钮并使每个按钮与位图图像相关 CToolBar的构造方法

InsertResource Toolbar  New插入新的工具条资源。 (2)将工具条添加到窗口中 2 加入用户自定义的工具条 (1)增加工具条资源 InsertResource Toolbar  New插入新的工具条资源。 (2)将工具条添加到窗口中 添加后,需把工具条的对象加入到应用程序框架窗口中(CMainFrame)。在应用程序的CMainFrame类中加入工具条对象m_wndToolBar。 protected: CToolBar m_wndToolBar; //自己定义的工具条

在框架窗口类的OnCreate()函数中调用工具条类的Create()或CreateEx()成员函数创建该工具条,并调用LoadToolBar()成员函数将工具条对象和前面创建的工具条资源连接在一起。 if(!m_wndToolBar.Create(this,WS_VISIBLE|CBRS_TOP) ||!m_wndToolBar.LoadToolBar(IDR_TOOLBAR)) //引入资源IDR_TOOLBAR { TRACE0("Failed to create toolbar\n"); return -1; // fail to create }

3 对工具条进行操作 创建完成工具条后,可调用工具条类中的成员函数对工具条进行操作,例如设定工具条风格,在窗口中移动工具条,控制工具条的显隐等。 当鼠标光标在按钮上暂停时,显示工具提示和命令描述,并设定工具条的大小是可变的。 m_wndToolBar.SetBarStyle(CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); 可在程序中设置允许用户在程序运行中在框架窗口内移动工具条。这是通过调用CToolBar::EnableDocking和CFrame::EnableDocking来实现的。二函数原型均如下: void EnableDocking( DWORD dwStyle )

【例10-4】在【例10-3】中添加工具条,工具条中包含四个按钮,分别对应菜单的“显示”、“红色”、“绿色”和“蓝色”菜单项。该工具条可以在窗口中任意位置停靠,当鼠标停留在工具条按钮上时,将显示该按钮的功能。

在ResourceView中加入工具条资源IDR_TOOLBAR_NEW。绘制四个按钮并设置相应ID。 在MainFrm.h中添加如下代码,声明一个CToolBar变量 CToolBar m_wndToolBarNew; 在MainFrm.cpp文件的 Int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 函数中添加如下代码: if (!m_wndToolBarNew.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBarNew.LoadToolBar(IDR_TOOLBAR_NEW)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create }

为了使新增的工具条可以在窗口中自由停靠,在OnCreate函数中,还要增加如下代码: m_wndToolBarNew.EnableDocking(CBRS_ALIGN_ANY); //工具条可以在父窗口内任何一边停靠EnableDocking(CBRS_ALIGN_ANY); // 父窗口允许子工具条窗口在任何一边停靠 DockControlBar(&m_wndToolBarNew); // 父窗口内按照前面指定的风格停靠该工具条

10.2.5 图标资源的创建及其使用 每个Windows应用程序在资源管理器中都有自己的图标,这个图标就是ICON资源。 【例10-5】在【例10-4】的基础上通过修改光标资源,使得执行程序的图标变为如图所示的样子。

ResourceViewIconIDR_MAINFRAME,就会看到图标编辑器,在这里可以选择图标的尺寸,默认的是16×16和32×32。 16×16的图标用于程序运行时左上角图标、任务条图标、资源管理器的列表和详细信息模式; 32×32的图标用于程序运行时默认对话框图标、资源管理器图标模式; 48×48的图标用于资源管理器的平铺和缩略图模式。

单击New Device Image按钮对光标资源进行修改

10.2.6 字符串资源的使用 字符串资源最主要的用途就是用于程序的多语言版本。如果要想动态切换界面语言,使用字符串资源是很好的选择。 在MFC中,可以通过CString类的LoadString方法来从资源载入字符串。 具体操作是打开ResourceViewString Table,在表中的空白高亮处双击,在弹出的String Properties对话框中的ID编辑框中输入IDS_STRING_HELLO,Caption编辑框中输入“Hello VC!”。

在My_ResView.cpp文件的构造函数中,将原来的 m_strShow = "Hello World!"; 改为: m_strShow.LoadString(IDS_STRING_HELLO); 这样我们的程序的输出就变为“Hello VC!”了 使用字符串资源的好处就是不需要在整个程序中去寻找某个字符串,如果某些字符串可能在将来会发生变更,那么最好将它写在字符串资源中。

10.2.7对话框资源的创建及其应用 【例10-6】在上例的基础上编写一个对话框用于接收用户输入,然后用这个输入来替换主程序原来显示的字符串

在创建完对话框资源之后,需要生成一个相关的对话框类。ViewClassWizard Create a New Class  OK,在Name中填入“CInputDlg”即可。

将对话框上的IDC_EDIT_INPUT控件与一个CString类型的m_strInput变量绑定,建立一种映射关系。 上面的操作使MFC在幕后作了些什么? 在InputDlg.h文件中,MFC加入了如下代码:  // Dialog Data //{{AFX_DATA(CInputDlg) enum { IDD = IDD_DIALOG_NEW }; CString m_strInput; //}}AFX_DATA

在InputDlg.cpp的构造函数中,MFC加入了如下代码:   //{{AFX_DATA_INIT(CInputDlg) m_strInput = _T(""); //}}AFX_DATA_INIT 在InputDlg.cpp文件的DoDataExchange函数中,MFC加入了如下代码: //{{AFX_DATA_MAP(CInputDlg) DDX_Text(pDX, IDC_EDIT_INPUT, m_strInput); //}}AFX_DATA_MAP 在函数DDX_Text调用中,完成了控件与变量之间的数据交换。 对m_strInput的初始化

下面要在CMy_ResView中使用新创建的对话框 首先为“操作”菜单增加菜单项“修改字符串”,其ID为ID_OPER_STRING。增加COMMAND消息响应函数OnOperString。然后在My_ResView.cpp文件头部include部分最后加入: #include "InputDlg.h" 在OnOperString中加入如下代码: void CMy_ResView::OnOperString() { CInputDlg dlgInput; // 声明对话框变量 if(dlgInput.DoModal() == IDOK) // 如果用户点击OK按钮 { m_strShow = dlgInput.m_strInput; // 更改字符串 Invalidate(); // 强制重绘 } }

10.2.8位图资源的创建及其应用 标准控件比较单调,若能通过一些精美的图片来点缀,就活泼了,这个问题,可以选择位图资源来实现。 位图是一种数字化的图形表示形式,基本数据结构是象素,一个像素表示一个离散点的颜色值。 常见位图有2色、4色、16色、256色、16位、24位。其中VC 6的资源编辑器只支持256色以下(包括256色)的位图的编辑,而最新的VC7已经支持24位真彩位图的编辑了。保存在文件中的位图可以看作是设备无关的,文件本身的数据用来描述位图的内容。

【例10-7】在【例10-6】的基础上显示两幅图片,一幅是256色,另一幅是24位真彩,两幅图片都是通过资源来显示

在CMy_ResView.cpp的OnDraw函数中加入如下代码: CDC dcMemory; // 创建内存缓冲DC dcMemory.CreateCompatibleDC(pDC); CBitmap bmp1; // 加载256位图 bmp1.LoadBitmap(IDB_BITMAP_256); BITMAP bmpInfo1; bmp1.GetBitmap(&bmpInfo1); // 获得位图的尺寸 CBitmap* pOldBitmap = dcMemory.SelectObject(&bmp1); // 选择位图到内存缓冲设备中 pDC->BitBlt(200,10,bmpInfo1.bmWidth,bmpInfo1.bmHeight, &dcMemory,0,0,SRCCOPY); // 绘制到屏幕

CBitmap bmp2; bmp2.LoadBitmap(IDB_BITMAP_24bit); // 加载24位位图 BITMAP bmpInfo2; bmp2.GetBitmap(&bmpInfo2); dcMemory.SelectObject(&bmp2); pDC->BitBlt(400,10,bmpInfo2.bmWidth, bmpInfo2.bmHeight, &dcMemory,0,0,SRCCOPY); dcMemory.SelectObject(pOldBitmap); // 恢复设备中原来的位图