对象中的m_hWnd保存了窗口的句柄值,m_hWnd就是一种资源。可参考Notes中的18,21,23,66,74条,了解窗口类,窗口类对象及窗口之间的关系。与窗口类对象进行关联窗口的Create()命令不同,CGdiObject类是通过Select(Brush,pen)和DeleteObject来实现对象与资源的关联的(字体资源是使用CreateFontIndirect()函数来关联),m_hObject的值是否为空来判断。如在使用兼容位图时,CBitmap:CreateCompatibleBitmap()时也提到了要切断关联,以备下次使用。(147条)
以后只要一看到Create()函数就要想到,类对象在关联一个资源对象时,是否是重复关联,应先切断联系再关联。 135. 字体对话框1hour
136. Windows GDI是资源对象 CGdiObject是类的对象
使用DeleteObject()时只是删除了Windows GDI的资源,即切断了与CGdiObject的联系,CGdiObject的对象并没有受到影响。 137. 当用户改变edit框的内容时,ENChange消息处理。 138. ScreenToClient()将屏幕坐标转换为窗口坐标
GetWindowRect这个函数,获得的坐标是屏幕的坐标,而我们做图时使用的是客户区的坐标,屏幕坐标的值很大,导致图形画在了客户区的外边。 139. 当控件与一成员变量进行关联时,需要控件及时显示变量的变化,需要先调用UpDateData()函数。UpDateData()此函数在创建时和点击OK时都会自动调用。
140. WM_CTLCOLOR()消息,其响应函数CWnd::OnCtlColor(),返回画刷的句柄,绘制控件的背景色。当一个控件被绘制时,将发送此消息给其对话框的父窗口。自己制作一个画刷,在此函数中返回自己制作的画刷的句柄就可以了。(多个控件,多次调用) 141. CWnd::GetDlgCtlID()返回任何子窗口窗口或控件ID,注意是当前同一级别的子窗口的ID,函数的调用也是在同一级别的窗口下调用。设置某一窗口的文本颜色:CDC::SetTextColor(),CDC::SetBkMode()文字的背景模式。
142. 创建字体:CFont::CreatePointFont()
143. 当自绘制的控件(button控件)的表面发生改变时,FrameWork会调用CButton::DrawItem()虚函数,所以要先构造一button类,覆盖DrawItem这个函数。SetTextColor()调用完之后要重新设置会原来的颜色
144. CButtonST设置button的背景,文本色,包括活动和不活动的,将相关button控件与此类型关联变量,调用相关函数完成设置。 145. 在窗口中贴图:
创建位图:创建对象,加载位图 CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP);
创建兼容DC,先在内存中准备图像(将位图选入兼容DC中),在设备上下文中显示图像之前。
即CDC dcCompatible;dcCompatible.CreateCompatibleDC(pDC); dcCompatible.SelectObject(&bitmap)
拷贝内存图象到设备上下文中显示,即在兼容DC中调用输出函数。
Pdc->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
【孙鑫解释: CDC: CreateCompatibleDC()它创建一个内存设备上下文(Device context),与我们给定的实际的DC相兼容(由pDC指定的,内存设备上下文是一个内存块,表示的是要显示的表面),想要实现图像在实际的DC中显示之前,需先要在与之兼容的DC上先建立这样一幅图像。只有将一幅位图选择入内存设备上下文中(兼容DC)中时,GDI的输出函数才能使用. 】
CWnd* pWnd = GetDlgItem(IDC_PICBOX);//获得窗口指针 CDC *pDC = pWnd->GetDC(); //该窗口的DC指针 CBitmap memBitmap; CBitmap* pOldBmp = NULL; CDC memDC;memDC.CreateCompatibleDC(pDC);
在窗口中贴图1、创建位图CBitmapbitmap;bitmap.LoadBitmap(IDB_BITMAP1);3、将位图选到兼容DC中dcCompatible.SelectObject(&bitmap);③④兼容DC4、将兼容DC中的位图贴到当前DC中。pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);当前DC2、创建兼容DCCDC dcCompatible;dcCompatible.CreateCompatibleDC(pDC);位图http://www.sunxin.org CBitmap::CreateCompatibleBitmap ( CDC* pDC, int nWidth, int nHeight );
注释: Initializes a bitmap that is compatible with the device specified by pDC.(使用pDC指定的设备来初始化一个位图的大小.), It can be selected as the current bitmap for any memory device that is compatible with the one specified by pDC.(用于初始化使用的位图可以是为与某一实际pDC相兼容的内存兼容设备(即兼容DC)准备的位图)
If pDC is a memory device context, the bitmap returned has the same format as the currently selected bitmap in that device context. A ―memory device context‖ is a block of memory that represents a display surface. It can be used to prepare images in memory before copying them to the actual display surface of the compatible device. 因此我们可以:
在为某一实际pDC创建兼容CompatibleDC时,为了设置其大小,可以先创建兼容位图,获得pDC的实际大小,但CreateCompatibleBitmap返回的位图对象只包含相应设备描述表中的位图的位图信息头,不包含颜色表和象素数据块。因此,选入该位图对象的设备描述表不能像选入普通位图对象的设备描述表一样应用,必须在SelectObject函数之后,
调用BitBlt将原始设备描述表的颜色表及象素数据块拷贝到兼容设备描述表 程序解释(见MotorCtrlSys中的OnTimer()响应函数的相关代码,如下) CRect rect; CWnd* pWnd = GetDlgItem(IDC_PicShowBox);//获取动态显示窗口的指针; pWnd->GetClientRect(&rect); // //获取动态显示窗口的大小; CDC *pDC = pWnd->GetDC(); // //获取动态显示窗口的设备上下文,即实际DC; memDC.CreateCompatibleDC(pDC);///*为实际DC创建兼容DC,但此时兼容DC的GDI
函数HBITMAP, HPALETTE, HRGN, HBRUSH, HPEN, or HFONT等还不能使用,原始设备描述表的颜色表及象素数据块还未拷贝,通常的方法是选入一个位图并BitBilt像素块(当然你也可以使用兼容的DC在此位图上绘制图形,然后实际DC的BitBilt命令将把你绘制的图形连同原始的位图一同拷贝至实际DC中),但在动态绘图中如果选入固定的位图并BitBilt(若不BitBilt也不会重叠,但使用固定位图获得不了实际DC窗口的大小,因此才使用兼容位图),则位图中的原有图像将作为底色存在,满足不了动态绘图的要求,因此,我们创建一个兼容位图,这个兼容位图具有显示窗口的大小和设备描述表中的位图的位图信息头,不必包含颜色表和象素数据块即可,如下2句程序。*/
CBitmap CompatibleBitmap;//创建兼容位图 CompatibleBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());/*//兼容位图具有显示窗口的大小和设备描述表中的位图的位图信息头,不必包含颜色表和象素数据块*/
CBitmap* pOldBmp = memDC.SelectObject(&CompatibleBitmap); /*//将兼容位图选入兼容DC中
//memDC.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);
//BitBlt将原始设备描述表的颜色表及象素数据块拷贝到兼容设备描述表,只有这样兼容DC的
GDI才能使用,实际DC的BitBilt拷贝的兼容DC内的图像才能够正常显示,如果实际DC当前时空白图像,倒没关系,如果当前已经有图像,则拷贝时会把实际DC的现有图形拷贝至兼容DC,导致图形重叠,故此处不再用。*/
的, }
DyDrawPic(&memDC,rect);//将图像绘制在兼容DC上,然后拷贝至实际DC中 pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);////将兼容位图选出兼容DC,这是兼容位图所要求memDC.DeleteDC();//然后最后一步删除关联的资源对象,见136条 CompatibleBitmap.DeleteObject();
146. 在窗口绘制时会先发送WM_ERASEBKGND消息,因此设置背景应在此消息响应函数中添加,然后将其返回值设定为非零值。 147. CWnd::GetClientRect()获得客户端区域的大小。
148. 要随时全部显示位图,就不能使用BitBlt来拷贝,因其是1:1拷贝。应使用CDC::StretchBlt(),也可以将代码添加在OnDraw函数中。 149. CBitMap中有获得位图大小的信息的函数。GetMap()
第11课 图形的重绘
150. 所有的图形的绘制包含三要素:两个点,类型,定义一个图形的类! 151. 设置其构造函数为包含此三个要素。
152. 153.
集合类:CPtrArray支持void指针数组。
注意:CObjectArray和CPtrArray的使用类似(成员函数类似)。 CObject *CObjectArray::GetAt()增加CObject指针,这 void * CPtrArray::GetAt()增加是void指针
154. 凡是用new分配的内存都是在堆中分配的,堆中的内存只要不调用delete显式的删除,其生命周期与应用程序的是保持一致的。 Static int i;
=int * pi;pi=new int i;把地址存在全局变量中。 同样的,我们使用分配内存来定义指针
在OnLButtonU函数中p1244:EE00Gprhap*phGra;ph④m_ptrArray.Add);(p②GCra③pGraph=new CGraph(…);1244:EE000088:46601244:EE00pGra的ph内存pGraph的内存被回收CGra的ph对象在堆中的内存①CPtrArmra_yptrA;rray仍然能索引到CGraph的对象 155. on_draw函数实际上是在On_Paint函数调用的,二者都是虚函数。 156. CView::OnPrepareDC是在On_Paint函数调用的虚函数。
Called by the framework before the OnDraw member function is called for
screen display and before the OnPrint member function is called for each page during printing or print preview. The default implementation of this function does nothing if the function is called for screen display(什么也不干). However, this function is overridden in derived classes, such as CScrollView, to adjust attributes of the device context(调整设备上下文的属性); consequently, you should always call the base class implementation at the beginning of your override.
http://www.sunxin.org157. 重绘的过程是On_Paint 其中,第一步是CPaint类 第二步OnPrepareDC 第三步 on_draw
158. 窗口重绘,框架类就会调用WM_PAINT消息,如果用户自己定义了On_Paint虚函数,其中不调用on_draw函数,这用户编写的on_draw函数就永远不会调用了。
159. 设置窗口具有滚动条设置View类为CScrollView类 ,涉及到坐标空间

