mfc attach函数mfc怎么添加成员函数

.一、Windows对象和MFC对象的区别?
MFC对象实际上并没有把整个Windows对象都包装在其中。
对于窗口:MFC对象它只是有一个窗口句柄而已,这个窗口句柄如果指向一个实际存在的窗口对象(窗口对象,也就是WNDCLASS,是一个Windows对象),那么这个MFC对象就是有效的,否则这个MFC对象是空的。
如果你还不明白,请回忆一下,当我们使用MFC创建一个窗口时,是分两步进行的:
第一步,new一个CWnd对象,这一步是创建MFC对象,但是其中的HWND还是非法的,因为对应的Windows对象还没有被创建出来;
第二步,调用CWnd的成员函数Create创建真正的Windows对象,同时,把先前创建的MFC的CWnd对象的HWND成员指向该窗口,这样才算创建完毕一个窗口。
而如果你是用SDK方式,那么只要创建一个WNDCLASS结构,然后调用Create或者CreateEx就创建了一个窗口。&
二、Attach&&Detach
【Attach】 假设你已经有了一个有效窗口句柄,那么你想把这个窗口和一个CWnd对象关联起来怎么办?很简单,用Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄。这就是Attach主要完成的任务。
【Detach】如前所述,WNDCLASS其实和CWnd根本没有什么关系。它们之间只是通过CWnd的成员HWND联系起来的。如果把Attach看做“联姻”的话,那么Detach就是“离婚”了,通俗地说,就是切断一个CWnd对象和一个有效窗口的脐带。为什么要切断呢?因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个“脐带”剪断,以免“城门失火,殃及池鱼”。
基本就是把一个句柄绑定和解绑定于一个类对象上,是其可以使用MFC的函数而不是API
&&&&&&if (oldbmp != NULL)
wdc.SelectObject(oldbmp);
DeleteObject(bmp.Detach());
// bmp自定义的一个位图句柄
HBITMAP hdib = CreateDIBSection(wdc.m_hDC,&m_bmi,DIB_RGB_COLORS,(void**)&m_pbyte,NULL,0);
ASSERT(hdib);
bmp.Attach(hdib);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1617次
排名:千里之外
努力是人生最好的信仰
奋斗过才不会有遗憾
你不是一个人在战斗
不登高山,不知天之高
不临深溪,不知地之厚
(1)(4)(1)(1)(4)MFC 里的 CWnd::Detach 做了哪些工作?
有一个CWnd对象 Attach了一个 HWND,在工作结束的时候,使用PostMessage通知它需要进行释放工作,而紧接着调用 Detach,有没有可能造成由于PostMessage没有完成导致的异常?有没有必要使用SendMessage?
按投票排序
这个问题,我没遇到过。推荐你在MSDN 中查看一下吧。MSDN是非常 强大 的一部字典。希望能解决你的问题。Detach 可以和Attach一起来比较:-------------------------------以下是从MSDN中 COPY的:// Using Attach and Detach to map to the MDI client windowclass CMainFrame : public CMDIFrameWnd{...public:
m_wndMDIC}CMainFrame::~CMainFrame(){
// detach MDI client window
m_wndMDIClient.Detach();}int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// attach MDI client window
if (m_wndMDIClient.Attach(m_hWndMDIClient) == 0)
TRACE0("Failed to attach MDIClient.\n");
return -1;
// fail to create
要回答题主的问题,首先要理解三个问题:CWnd 是什么?Attach/Detach 干了什么?PostMessage 和 SendMessage 的作用和区别?对于第一个问题,其实 CWnd 是 MFC 中继承自 CCmdTarget 的类,CCmdTarget 又继承自 CObject——所以,CWnd 首先是一个普通的 C++类。其次,CWnd 内部持有了一个 HWND 类型的窗口句柄(m_hWnd),并且对 Windows 底层针对 HWND 的 API 做了封装——所以,把 CWnd 可以简单理解为针对 HWND 以及对 HWND 所做操作的面向对象层面的封装。只要一个 CWnd 对象脱离了这个类型为 HWND 的内部成员(比如把 m_hWnd 置为 NULL),那么针对这个 CWnd 对象所调用的任何方法都是无意义的。第二个问题,我们可以在wincore.cpp(该文件位于 VC\atlmfc\src\mfc\wincore.cpp 这个路径)中看出端倪:Attach 其实就是把一个 HWND 句柄绑定到一个 CWnd 对象上(为 m_hWnd 赋值);Detach 其实是从一个 CWnd 对象上剥离掉 HWND(使 m_hWnd 为 NULL)。Attach 建立关联之后我们能从 CWnd 对象获得 HWND 句柄:CW// ...HWND hWnd = wnd.getSafeHwnd();::SetWindowText(hWnd, _T("Straw - blog"));也可以通过 HWND 句柄获得一个 CWnd 对象:HWND hWnd =// ...CWnd* pWnd = CWnd::FromHandle(hWnd);if (pWnd) {
pWnd-&SetWindowText(_T("Straw - blog"));
// ...}第三个问题呢,我们知道,PostMessage/SendMessage 都是用来把一个 Windows 消息发往一个窗口,让其进行处理。但区别在于 PostMessage 把消息发出去之后(发往消息队列)立即返回到调用点,并继续执行后续逻辑(异步);但 SendMessage 是一个同步操作,直接把消息发往窗口,也就是说必须等这个窗口处理完了这个消息,才返回调用点。我们又知道,一个 Windows 窗口对应有一个消息处理函数(WNDPROC)——这个处理函数最终处理各种各样的 Windows 消息,这个函数必须是全局方法或者一个类的 static 方法(这就意味着消息的最终处理和任何 C++ 对象无关)。而我们通过 PostMessage 发出一个消息后,只是把一个消息先投递到消息队列(MessageQueue)里面,然后由消息分发程序(呃,一般就是那个 while 循环)来进行消息分发,只要一个窗口没有被销毁(调用 ::DestoryWindow),那么,发往这个窗口的消息一定会被处理。结合上面的知识,我们再来看题主的问题。首先,一个 Windows 窗口的生命周期和 CWnd 对象的生命周期没有任何关系。所以,即使你为一个 CWnd 对象调用了 Detach 方法,也只是把这个 CWnd 对象和真实的 Windows 窗口的关联关系取消了而已,只要你不主动销毁那个窗口,那个窗口还会一直存在并和 Detach 之前表现一致;PostMessage 之后,消息发往消息队列,然后 Detach 掉,消息仍然会被窗口处理程序处理掉。不会出现异常情况,不必担心;改用 SendMessage 也是可以的,如果只是一个简单的发消息的话,没什么必要非得改 PostMessage 为 SendMessage。
已有帐号?
无法登录?
社交帐号登录windows程序设计(6)
一、Windows对象和MFC对象的区别?
MFC对象实际上并没有把整个Windows对象都包装在其中。
对于窗口:MFC对象它只是有一个窗口句柄而已,这个窗口句柄如果指向一个实际存在的窗口对象(窗口对象,也就是WNDCLASS,是一个Windows对象),那么这个MFC对象就是有效的,否则这个MFC对象是空的。
如果你还不明白,请回忆一下,当我们使用MFC创建一个窗口时,是分两步进行的:
第一步,new一个CWnd对象,这一步是创建MFC对象,但是其中的HWND还是非法的,因为对应的Windows对象还没有被创建出来;
第二步,调用CWnd的成员函数Create创建真正的Windows对象,同时,把先前创建的MFC的CWnd对象的HWND成员指向该窗口,这样才算创建完毕一个窗口。
而如果你是用SDK方式,那么只要创建一个WNDCLASS结构,然后调用Create或者CreateEx就创建了一个窗口。&
二、Attach&&Detach
【Attach】 假设你已经有了一个有效窗口句柄,那么你想把这个窗口和一个CWnd对象关联起来怎么办?很简单,用Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄。这就是Attach主要完成的任务。
【Detach】如前所述,WNDCLASS其实和CWnd根本没有什么关系。它们之间只是通过CWnd的成员HWND联系起来的。如果把Attach看做“联姻”的话,那么Detach就是“离婚”了,通俗地说,就是切断一个CWnd对象和一个有效窗口的脐带。为什么要切断呢?因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个“脐带”剪断,以免“城门失火,殃及池鱼”。
基本就是把一个句柄绑定和解绑定于一个类对象上,是其可以使用MFC的函数而不是API
&&&&&&if (oldbmp != NULL)
&&&&&& wdc.SelectObject(oldbmp);
&&&&&&DeleteObject(bmp.Detach());&&// bmp自定义的一个位图句柄
&&&&&&HBITMAP hdib = CreateDIBSection(wdc.m_hDC,&m_bmi,DIB_RGB_COLORS,(void**)&m_pbyte,NULL,0);
&&&&&&ASSERT(hdib);
&&&&&&bmp.Attach(hdib);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4316次
排名:千里之外
转载:31篇
(2)(4)(8)(11)(7)下次自动登录
现在的位置:
& 综合 & 正文
MFC中加载位图资源到窗口中
一、 从磁盘中加载位图到窗口中---操作步骤
1. 创建一个单文档的应用,工程名为LoadBmp。
2. 在视图类中添加一个成员变量m_hBmp.
3. 在视图类的构造函数中调用LoadImage方法从磁盘中加载文件。
CLoadBmpView::CLoadBmpView()
// TODO: add construction code here
m_hBmp=(HBITMAP)LoadImage(NULL,"lena.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
4. 在视图类的OnDraw方法中绘制位图。
void CLoadBmpView::OnDraw(CDC* pDC)
CLoadBmpDoc* pDoc = GetDocument();
//获取文档对象
ASSERT_VALID(pDoc);
//验证文档对象
// TODO: add draw code for native data here
//定义一个位图对象
bmp.Attach(m_hBmp);
//将位图关联到位图句柄上
CDC memDC;
//定义一个设备上下文
memDC.CreateCompatibleDC(pDC);
//创建兼容的设备上下文
memDC.SelectObject(&bmp);
//选中位图对象
BITMAP BitI
//定义位图结构
bmp.GetBitmap(&BitInfo);
//获取位图信息
pDC-&BitBlt(10,10,BitInfo.bmWidth,BitInfo.bmHeight,&memDC,0,0,SRCCOPY);
//向窗口中绘制位图
bmp.Detach();
//分离位图句柄
memDC.DeleteDC();
//释放设备上下文对象
5. 运行程序,结果如图,
二、使用函数介绍
1. LoadImage()函数
LoadImage()函数,它可以用来加载一个图标,位图,鼠标, 原型为:
HANDLE LoadImage(
HINSTANCE hinst,
| LPCTSTR lpszName,
UINT uType,
int cxDesired,
int cyDesired,
UINT fuLoad );
其使用格式为:
表示包含图像的实例句柄,可以为NULL。
lpszName 表示图像的资源名称,如果从磁盘加载,该参数表示图像的名称,包含完整路径。
uType 表示加载的图像类型。IMAGE_BITMAP 表示加载位图,IMAGE_CURSOR 表示加载鼠标指针,IMAGE_ICON 表示加载图标。
cxDesired 表示图标或鼠标指针的宽度,如果加载的是位图,则该参数必须为0;
cyDesired 表示图标或鼠标指针的高度,如果加载的是位图,则该参数必须为0;
fuLoad 表示加载类型,如果为LR_LOADFROMFILE,表示从磁盘文件中加载位图。
函数返回加载的图像资源的句柄。
2. BitBlt()函数
BitBlt 用于从原设备中复制位图到目标设备,语法格式如下:
BitBlt(int x,int y,int nWidth,int nHeight,CDC*pSrcDC,int xSrc,int ySrc,DWORDdwRop);
x:目标矩形区域的左上角x轴坐标点。
y:目标矩形区域的左上角y轴坐标点。
nWidth:在目标设备中绘制位图的宽度。
nHight:在目标设备中绘制位图的高度。
pSrcDC:源设备上下文对象指针。
xSrc:源设备上下文的起点x轴坐标,函数从该起点复制位图到目标设备。
ySrc:源设备上下文的起点y轴坐标,函数从该起点复制位图到目标设备。
dwRop:光栅操作。
dwRop 有如下选择:
使用黑色填充目标区域
目标矩阵区域颜色取反
使用与运算组合原设备矩形区域的颜色和目标设备的画刷
MERGEPAINT
使用或运算将反向的源矩形区域的颜色和目标矩形区域的颜色合并
NOTSRCCOPY
复制源设备区域的反色到目标设备中
NOTSRCERASE
使用或运算组合源设备区域与目标设备区域的颜色,然后对结果颜色取反
复制源设备当前选中的画刷到目标设备
使用异或运算组合目标设备选中的画刷和目标设备区域的颜色
通过或运算组合目标区域当前选中的画刷和源设备区域反转的颜色
使用与运算组合源设备和目标设备区域的颜色
直接复制源设备区域到目标设备中
使用与运算组合目标设备区域的反色与源设备区域的颜色
使用异或运算组合源设备区域颜色和目标设备区域颜色
使用或运算组合源设备区域颜色和目标设备区域颜色
使用白色填充目标区域
函数Attach()
BOOL Attach( HGDIOBJ hObject );
它是CgdiObject的函数。HGDIOBJ是个图形的句柄。
Attach是把一个C++对象与一个CWnd对象关联,直到用Detach则把关联去掉。
如果Attach了以后没有Detach,则C++对象销毁的时候CWnd对象跟着一起销毁。
&&&&推荐文章:
【上篇】【下篇】MFC&Attach()函数和Detach()函数
一、Windows对象和MFC对象的区别?
MFC对象实际上并没有把整个Windows对象都包装在其中。
对于窗口:MFC对象它只是有一个窗口句柄而已,这个窗口句柄如果指向一个实际存在的窗口对象(窗口对象,也就是WNDCLASS,是一个Windows对象),那么这个MFC对象就是有效的,否则这个MFC对象是空的。
如果你还不明白,请回忆一下,当我们使用MFC创建一个窗口时,是分两步进行的:
第一步,new一个CWnd对象,这一步是创建MFC对象,但是其中的HWND还是非法的,因为对应的Windows对象还没有被创建出来;
第二步,调用CWnd的成员函数Create创建真正的Windows对象,同时,把先前创建的MFC的CWnd对象的HWND成员指向该窗口,这样才算创建完毕一个窗口。
而如果你是用SDK方式,那么只要创建一个WNDCLASS结构,然后调用Create或者CreateEx就创建了一个窗口。
二、Attach Detach
【Attach】
假设你已经有了一个有效窗口句柄,那么你想把这个窗口和一个CWnd对象关联起来怎么办?很简单,用Attach,其实就是让一个CWnd对象的HWND成员指向这个窗口句柄。这就是Attach主要完成的任务。
【Detach】如前所述,WNDCLASS其实和CWnd根本没有什么关系。它们之间只是通过CWnd的成员HWND联系起来的。如果把Attach看做“联姻”的话,那么Detach就是“离婚”了,通俗地说,就是切断一个CWnd对象和一个有效窗口的脐带。为什么要切断呢?因为CWnd是C++的对象,C++的对象有一个生存期的概念,脱离了该对象的作用域,这个对象就要被销毁,但是Windows对象没有这个特点,当销毁CWnd对象的时候,我们不一定希望WNDCLASS一起被销毁,那么在此之前,我们就先要把这个“脐带”剪断,以免“城门失火,殃及池鱼”。
基本就是把一个句柄绑定和解绑定于一个类对象上,是其可以使用MFC的函数而不是API
if (oldbmp != NULL)
wdc.SelectObject(oldbmp);
DeleteObject(bmp.Detach()); // bmp自定义的一个位图句柄
HBITMAP hdib =
CreateDIBSection(wdc.m_hDC,&m_bmi,DIB_RGB_COLORS,(void**)&m_pbyte,NULL,0);
ASSERT(hdib);
bmp.Attach(hdib);
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 mfc ontimer函数添加 的文章

 

随机推荐