绘制问题:如何在制定矩形区域取反色绘制

coxfilur_2008 2010-09-06 07:16:42
问题:如何在制定矩形区域取反色绘制.
相关的类和函数是什么,举例说明一下.谢谢.

例如下面的情况:

protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (mBitmap != null) {
Paint paint = new Paint();
canvas.drawBitmap(mBitmap, mOffsetX, mOffsetY, paint);



// 高手请告诉这里怎么把Rect r内的颜色取反。
Rect r;
...
Paint paint1 = new Paint();
canvas.drawRect(r, paint1);

}
}

我不想自己把mBitmap的指定区域r自己设置一遍,但是如果这是唯一的方法,请告知。
还有,最好别闪烁。是不是上面drawBitmap后又drawRect会闪烁?
...全文
185 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
coxfilur_2008 2010-10-09
  • 打赏
  • 举报
回复
浏览帖子,竟然浏览到自己的,看了半天,才醒悟过来.
俺自己更该了需求,解决了.
用 alpha blend解决了。
one2zero 2010-09-10
  • 打赏
  • 举报
回复
颜色是16进制

取反
nj_dobetter 2010-09-10
  • 打赏
  • 举报
回复
Xor绘制模式?
纠结的木棉花 2010-09-07
  • 打赏
  • 举报
回复
x=-x
ccll_4177 2010-09-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhq56030207 的回复:]

x=-x
[/Quote]

这个,颜色取反是什么意思? 是 x=-x 这个意思??我没懂起了LZ的意思
<项目介绍> 一、功能说明: 1、图形绘制 实现铅笔、画笔(书法画笔、喷枪、蜡笔、记号笔、水彩画笔)的绘制效果。 实现直线、曲线、椭圆(圆)、矩形(圆角矩形)、三角形(直角三角形、等边三角形、任意三角形)、多边形的绘制绘制过程中,可以选择颜,选择颜有两种方式:颜选择、颜拾取。可以进行颜填充,即对选定区域,用选择的颜进行填充。 2、图像处理 能够实现的效果有:黑白、模糊、亮度/透明度、反、雾化、锐化、浮雕、雕刻、柔化、油画、积木、怀旧、蒙版. 蒙 - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。
Visual C++MFC入门教程 目录 +-- 第一章 VC入门 |------ 1.1 如何学好VC |------ 1.2 理解Windows消息机制 |------ 1.3 利用Visual C++/MFC开发Windows程序的优势 |------ 1.4 利用MFC进行开发的通用方法介绍 |------ 1.5 MFC中常用类,宏,函数介绍 +-- 第二章 图形输出 |------ 2.1 和GUI有关的各种对象 |------ 2.2 在窗口中输出文字 |------ 2.3 使用点,刷子,笔进行绘图 |------ 2.4 在窗口中绘制设备相关位图,图标,设备无关位图 |------ 2.5 使用各种映射方式 |------ 2.6 多边形和剪贴区域 +-- 第三章 文档视结构 |------ 3.1 文档 视图 框架窗口间的关系和消息传送规律 |------ 3.2 接收用户输入 |------ 3.3 使用菜单 |------ 3.4 文档,视,框架之间相互作用 |------ 3.5 利用序列化进行文件读写 |------ 3.6 MFC中所提供的各种视类介绍 +-- 第四章 窗口控件 |------ 4.1 Button |------ 4.2 Static Box |------ 4.3 Edit Box |------ 4.4 Scroll Bar |------ 4.5 List Box/Check List Box |------ 4.6 Combo Box/Combo Box Ex |------ 4.7 Tree Ctrl |------ 4.8 List Ctrl |------ 4.9 Tab Ctrl |------ 4.A Tool Bar |------ 4.B Status Bar |------ 4.C Dialog Bar |------ 4.D 利用AppWizard创建并使用ToolBar StatusBar Dialog Bar |------ 4.E General Window |------ 4.F 关于WM_NOTIFY的使用方法 +-- 第五章 对话框 |------ 5.1 使用资源编辑器编辑对话框 |------ 5.2 创建有模式对话框 |------ 5.3 创建无模式对话框 |------ 5.4 在对话框中进行消息映射 |------ 5.5 在对话框中进行数据交换和数据检查 |------ 5.6 使用属性对话框 |------ 5.7 使用通用对话框 |------ 5.8 建立以对话框为基础的应用 |------ 5.9 使用对话框作为子窗口 +-- 第六章 网络通信开发 |------ 6.1 WinSock介绍 |------ 6.2 利用WinSock进行无连接的通信 +------ 6.3 利用WinSock建立有连接的通信   第一章 VC入门 1.1 如何学好VC 这个问题很多朋友都问过我,当然流汗是必须的,但同时如果按照某种思路进行有计划的学习就会起到更好的效果。万事开头难,为了帮助朋友们更快的掌握VC开发,下面我将自己的一点体会讲一下: 1、需要有好的C/C++基础。正所谓“磨刀不误砍柴工”,最开始接触VC时不要急于开始Windows程序开发,而是应该进行一些字符界面程序的编写。这样做的目的主要是增加对语言的熟悉程度,同时也训练自己的思维和熟悉一些在编程中常犯的错误。更重要的是理解并能运用C++的各种特性,这些在以后的开发中都会有很大的帮助,特别是利用MFC进行开发的朋友对C++一定要能熟练运用。 2、理解Windows的消息机制,窗口句柄和其他GUI句柄的含义和用途。了解和MFC各个类功能相近的API函数。 3、一定要理解MFC中消息映射的作用。 4、训练自己在编写代码时不使用参考书而是使用Help Online。 5、记住一些常用的消息名称和参数的意义。 6、学会看别人的代码。 7、多看书,少买书,买书前一定要慎重。 8、闲下来的时候就看参考书。 9、多来我的主页。^O^ 后面几条是我个人的一点意见,你可以根据需要和自身的情况选用适用于自己的方法。 此外我将一些我在选择参考书时的原则: 对于初学者:应该选择一些内容比较全面的书籍,并且书籍中的内容应该以合理的方式安排,在使用该书时可以达到循序渐进的效果,书中的代码要有详细的讲解。尽量买翻译的书,因为这些书一般都比较易懂,而且语言比较轻松。买书前一定要慎重如果买到不好用的书可能会对自己的学习积极性产生击。 对于已经掌握了VC的朋友:这种程度的开发者应该加深自己对系统原理,技术要点的认识。需要选择一些对原理讲解的比较透彻的书籍,这样一来才会对新技术有更多的了解,最好书中对技术的应用有一定的阐述。尽量选择示范代码必较精简的书,可以节约银子。 此外最好涉猎一些辅助性的书籍。 1.2 理解Windows消息机制 Windows系统是一个消息驱动的OS,什么是消息呢?我很难说得清楚,也很难下一个定义(谁在嘘我),我下面从不同的几个方面讲解一下,希望大家看了后有一点了解。 1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。 2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。 3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。 4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。 5、示例:下面有一段伪代码演示如何在窗口过程中处理消息 LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM) { switch(uMessageType) { //使用SWITCH语句将各种消息分开 case(WM_PAINT): doYourWindow(...);//在窗口需要重新绘制时进行输出 break; case(WM_LBUTTONDOWN): doYourWork(...);//在鼠标左键被按下时进行处理 break; default: callDefaultWndProc(...);//对于其它情况就让系统自己处理 break; } } 接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法: while(1) { id=getMessage(...); if(id == quit) break; translateMessage(...); } 当该程序没有消息通知时getMessage就不会返回,也就不会占用系统的CPU时间。 下图为消息投递模式 在16位的系统中系统中只有一个消息队列,所以系统必须等待当前任务处理消息后才可以发送下一消息到相应程序,如果一个程序陷如死循环或是耗时操作时系统就会得不到控制权。这种多任务系统也就称为协同式的多任务系统。Windows3.X就是这种系统。而32位的系统中每一运行的程序都会有一个消息队列,所以系统可以在多个消息队列中转换而不必等待当前程序完成消息处理就可以得到控制权。这种多任务系统就称为抢先式的多任务系统。Windows95/NT就是这种系统。 1.3 利用Visual C++/MFC开发Windows程序的优势 MFC借助C++的优势为Windows开发开辟了一片新天地,同时也借助ApplicationWizzard使开发者摆脱离了那些每次都必写基本代码,借助ClassWizard和消息映射使开发者摆脱了定义消息处理时那种混乱和冗长的代码段。更令人兴奋的是利用C++的封装功能使开发者摆脱Windows中各种句柄的困扰,只需要面对C++中的对象,这样一来使开发更接近开发语言而远离系统。(但我个人认为了解系统原理对开发很有帮助) 正因为MFC是建立在C++的基础上,所以我强调C/C++语言基础对开发的重要性。利用C++的封装性开发者可以更容易理解和操作各种窗口对象;利用C++的派生性开发者可以减少开发自定义窗口的时间和创造出可重用的代码;利用虚拟性可以在必要时更好的控制窗口的活动。而且C++本身所具备的超越C语言的特性都可以使开发者编写出更易用,更灵活的代码。 在MFC中对消息的处理利用了消息映射的方法,该方法的基础是宏定义实现,通过宏定义将消息分派到不同的成员函数进行处理。下面简单讲述一下这种方法的实现方法: 代码如下 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //}}AFX_MSG_MAP ON_COMMAND(ID_FONT_DROPDOWN, DoNothing) END_MESSAGE_MAP() 经过编译后,代码被替换为如下形式(这只是作讲解,实际情况比这复杂得多): //BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) CMainFrame::newWndProc(...) { switch(...) { //{{AFX_MSG_MAP(CMainFrame) // ON_WM_CREATE() case(WM_CREATE): OnCreate(...); break; //}}AFX_MSG_MAP // ON_COMMAND(ID_FONT_DROPDOWN, DoNothing) case(WM_COMMAND): if(HIWORD(wP)==ID_FONT_DROPDOWN) { DoNothing(...); } break; //END_MESSAGE_MAP() } } newWndProc就是窗口过程只要是该类的实例生成的窗口都使用该窗口过程。 所以了解了Windows的消息机制在加上对消息映射的理解就很容易了解MFC开发的基本思路了。 1.4 利用MFC进行开发的通用方法介绍 以下是我在最初学习VC时所常用的开发思路和方法,希望能对初学VC的朋友有所帮助和启发。 1、开发需要读写文件的应用程序并且有简单的输入和输出可以利用单文档视结构。 2、开发注重交互的简单应用程序可以使用对话框为基础的窗口,如果文件读写简单这可利用CFile进行。 3、开发注重交互并且文件读写复杂的的简单应用程序可以利用以CFormView为基础视的单文档视结构。 4、利用对话框得到用户输入的数据,在等级提高后可使用就地输入。 5、在对多文档要求不强烈时尽量避免多文档视结构,可以利用分隔条产生单文档多视结构。 6、在要求在多个文档间传递数据时使用多文档视结构。 7、学会利用子窗口,并在自定义的子窗口包含多个控件达到封装功能的目的。 8、尽量避免使用多文档多视结构。 9、不要使用多重继承并尽量减少一个类中封装过多的功能。 1.5 MFC中常用类,宏,函数介绍 常用类 CRect:用来表示矩形的类,拥有四个成员变量:top left bottom right。分别表是左上角和右下角的坐标。可以通过以下的方法构造: CRect( int l, int t, int r, int b ); 指明四个坐标 CRect( const RECT& srcRect ); 由RECT结构构造 CRect( LPCRECT lpSrcRect ); 由RECT结构构造 CRect( POINT point, SIZE size ); 有左上角坐标和尺寸构造 CRect( POINT topLeft, POINT bottomRight ); 有两点坐标构造 下面介绍几个成员函数: int Width( ) const; 得到宽度 int Height( ) const; 得到高度 CSize Size( ) const; 得到尺寸 CPoint& TopLeft( ); 得到左上角坐标 CPoint& BottomRight( ); 得到右下角坐标 CPoint CenterPoint( ) const; 得当中心坐标 此外矩形可以和点(CPoint)相加进行位移,和另一个矩形相加得到“并”操作后的矩形。 CPoint:用来表示一个点的坐标,有两个成员变量:x y。 可以和另一个点相加。 CString:用来表示可变长度的字符串。使用CString可不指明内存大小,CString会根据需要自行分配。下面介绍几个成员函数: GetLength 得到字符串长度 GetAt 得到指定位置处的字符 operator + 相当于strcat void Format( LPCTSTR lpszFormat, ... ); 相当于sprintf Find 查找指定字符,字符串 Compare 比较 CompareNoCase 不区分大小写比较 MakeUpper 改为小写 MakeLower 改为大写 CStringArray:用来表示可变长度的字符串数组。数组中每一个元素为CString对象的实例。下面介绍几个成员函数: Add 增加CString RemoveAt 删除指定位置CString对象 RemoveAll 删除数组中所有CString对象 GetAt 得到指定位置的CString对象 SetAt 修改指定位置的CString对象 InsertAt 在某一位置插入CString对象 常用宏 RGB TRACE ASSERT VERIFY 常用函数 CWindApp* AfxGetApp(); HINSTANCE AfxGetInstanceHandle( ); HINSTANCE AfxGetResourceHandle( ); int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );用于弹出一个消息框 第二章 图形输出 2.1 和GUI有关的各种对象 在Windows中有各种GUI对象(不要和C++对象混淆),当你在进行绘图就需要利用这些对象。而各种对象都拥有各种属性,下面分别讲述各种GUI对象和拥有的属性。 字体对象CFont用于输出文字时选用不同风格和大小的字体。可选择的风格包括:是否为斜体,是否为粗体,字体名称,是否有下划线等。颜和背景不属于字体的属性。关于如何创建和使用字体在2.2 在窗口中输出文字中会详细讲解。 刷子CBrush对象决定填充区域时所采用的颜或模板。对于一个固定的刷子来讲它的属性为颜,是否采用网格和网格的类型如水平的,垂直的,交叉的等。你也可以利用8*8的位图来创建一个自定义模板的刷子,在使用这种刷子填充时系统会利用位图逐步填充区域。关于如何创建和使用刷子在2.3 使用刷子,笔进行绘图中会详细讲解。 画笔CPen对象在画点和画线时有用。它的属性包括颜,宽度,线的风格,如虚线,实线,点划线等。关于如何创建和使用画笔在2.3 使用刷子,笔进行绘图中会详细讲解。 位图CBitmap对象可以包含一幅图像,可以保存在资源中。关于如何使用位图在2.4 在窗口中绘制设备相关位图,图标,设备无关位图中会详细讲解。 还有一种特殊的GUI对象是多边形,利用多边形可以很好的限制作图区域或是改变窗口外型。关于如何创建和使用多边形在2.6 多边形和剪贴区域中会详细讲解。 在Windows中使用GUI对象必须遵守一定的规则。首先需要创建一个合法的对象,不同的对象创建方法不同。然后需要将该GUI对象选入DC中,同时保存DC中原来的GUI对象。如果选入一个非法的对象将会引起异常。在使用完后应该恢复原来的对象,这一点特别重要,如果保存一个临时对象在DC中,而在临时对象被销毁后可能引起异常。有一点必须注意,每一个对象在重新创建前必须销毁,下面的代码演示了这一种安全的使用方法: OnDraw(CDC* pDC) { CPen pen1,pen2; pen1.CreatePen(PS_SOLID,2,RGB(128,128,128));//创建对象 pen2.CreatePen(PS_SOLID,2,RGB(128,128,0));//创建对象 CPen* pPenOld=(CPen*)pDC->SelectObject(&pen1);//选择对象进DC drawWithPen1... (CPen*)pDC->SelectObject(&pen2);//选择对象进DC drawWithPen2... pen1.DeleteObject();//再次创建前先销毁 pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));//再次创建对象 (CPen*)pDC->SelectObject(&pen1);//选择对象进DC drawWithPen1... pDC->SelectObject(pOldPen);//恢复 } 此外系统中还拥有一些库存GUI对象,你可以利用CDC::SelectStockObject(SelectStockObject( int nIndex )选入这些对象,它们包括一些固定颜的刷子,画笔和一些基本字体。 • BLACK_BRUSH Black brush. • DKGRAY_BRUSH Dark gray brush. • GRAY_BRUSH Gray brush. • HOLLOW_BRUSH Hollow brush. • LTGRAY_BRUSH Light gray brush. • NULL_BRUSH Null brush. • WHITE_BRUSH White brush. • BLACK_PEN Black pen. • NULL_PEN Null pen. • WHITE_PEN White pen. • ANSI_FIXED_FONT ANSI fixed system font. • ANSI_VAR_FONT ANSI variable system font. • DEVICE_DEFAULT_FONT Device-dependent font. • OEM_FIXED_FONT OEM-dependent fixed font. • SYSTEM_FONT The system font. By default, Windows uses the system font to draw menus, dialog-box controls, and other text. In Windows versions 3.0 and later, the system font is proportional width; earlier versions of Windows use a fixed-width system font. • SYSTEM_FIXED_FONT The fixed-width system font used in Windows prior to version 3.0. This object is available for compatibility with earlier versions of Windows. • DEFAULT_PALETTE Default color palette. This palette consists of the 20 static colors in the system palette. 这些对象留在DC中是安全的,所以你可以利用选入库存对象来作为恢复DC中GUI对象。 大家可能都注意到了绘图时都需要一个DC对象,DC(Device Context设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它。这个环境是设备无关的,所以你在对不同的设备输出时只需要使用不同的设备环境就行了,而作图方式可以完全不变。这也就是Windows耀眼的一点设备无关性。如同你将对一幅画使用照相机或复印机将会产生不同的输出,而不需要对画进行任何调整。DC的使用会穿插在本章中进行介绍。 2.2 在窗口中输出文字 在这里我假定读者已经利用ApplicationWizard生成了一个SDI界面的程序代码。接下来的你只需要在CView派生类的OnDraw成员函数中加入绘图代码就可以了。在这里我需要解释一下OnDraw函数的作用,OnDraw函数会在窗口需要重绘时自动被调用,传入的参数CDC* pDC对应的就是DC环境。使用OnDraw的优点就在于在你使用打印功能的时候传入OnDraw的DC环境将会是打印机绘图环境,使用打印预览时传入的是一个称为CPreviewDC的绘图环境,所以你只需要一份代码就可以完成窗口/打印预览/打印机绘图三重功能。利用Windows的设备无关性和M$为打印预览所编写的上千行代码你可以很容易的完成一个具有所见即所得的软件。 输出文字一般使用CDC::BOOL TextOut( int x, int y, const CString& str )和CDC::int DrawText( const CString& str, LPRECT lpRect, UINT nFormat )两个函数,对TextOut来讲只能输出单行的文字,而DrawText可以指定在一个矩形中输出单行或多行文字,并且可以规定对齐方式和使用何种风格。nFormat可以是多种以下标记的组合(利用位或操作)以达到选择输出风格的目的。 • DT_BOTTOM底部对齐 Specifies bottom-justified text. This value must be combined with DT_SINGLELINE. • DT_CALCRECT计算指定文字时所需要矩形尺寸 Determines the width and height of the rectangle. If there are multiple lines of text, DrawText will use the width of the rectangle pointed to by lpRect and extend the base of the rectangle to bound the last line of text. If there is only one line of text, DrawText will modify the right side of the rectangle so that it bounds the last character in the line. In either case, DrawText returns the height of the formatted text, but does not draw the text. • DT_CENTER中部对齐 Centers text horizontally. • DT_END_ELLIPSIS or DT_PATH_ELLIPSIS Replaces part of the given string with ellipses, if necessary, so that the result fits in the specified rectangle. The given string is not modified unless the DT_MODIFYSTRING flag is specified. You can specify DT_END_ELLIPSIS to replace characters at the end of the string, or DT_PATH_ELLIPSIS to replace characters in the middle of the string. If the string contains backslash (\) characters, DT_PATH_ELLIPSIS preserves as much as possible of the text after the last backslash. • DT_EXPANDTABS Expands tab characters. The default number of characters per tab is eight. • DT_EXTERNALLEADING Includes the font抯 external leading in the line height. Normally, external leading is not included in the height of a line of text. • DT_LEFT左对齐 Aligns text flush-left. • DT_MODIFYSTRING Modifies the given string to match the displayed text. This flag has no effect unless the DT_END_ELLIPSIS or DT_PATH_ELLIPSIS flag is specified. Note Some uFormat flag combinations can cause the passed string to be modified. Using DT_MODIFYSTRING with either DT_END_ELLIPSIS or DT_PATH_ELLIPSIS may cause the string to be modified, causing an assertion in the CString override. • DT_NOCLIP Draws without clipping. DrawText is somewhat faster when DT_NOCLIP is used. • DT_NOPREFIX禁止使用&前缀 Turns off processing of prefix characters. Normally, DrawText interprets the ampersand (&) mnemonic-prefix character as a directive to underscore the character that follows, and the two-ampersand (&&) mnemonic-prefix characters as a directive to print a single ampersand. By specifying DT_NOPREFIX, this processing is turned off. • DT_PATH_ELLIPSIS • DT_RIGHT右对齐 Aligns text flush-right. • DT_SINGLELINE单行输出 Specifies single line only. Carriage returns and linefeeds do not break the line. • DT_TABSTOP设置TAB字符所占宽度 Sets tab stops. The high-order byte of nFormat is the number of characters for each tab. The default number of characters per tab is eight. • DT_TOP定部对齐 Specifies top-justified text (single line only). • DT_VCENTER中部对齐 Specifies vertically centered text (single line only). • DT_WORDBREAK每行只在单词间被折行 Specifies word-breaking. Lines are automatically broken between words if a word would extend past the edge of the rectangle specified by lpRect. A carriage return杔inefeed sequence will also break the line. 在输出文字时如果希望改变文字的颜,你可以利用CDC::SetTextColor( COLORREF crColor )进行设置,如果你希望改变背景就利用CDC::SetBkColor( COLORREF crColor ),很多时候你可能需要透明的背景你可以利用CDC::SetBkMode( int nBkMode )设置,可接受的参数有 • OPAQUE Background is filled with the current background color before the text, hatched brush, or pen is drawn. This is the default background mode. • TRANSPARENT Background is not changed before drawing. 接下来讲讲如何创建字体,你可以创建的字体有两种:库存字体CDC::CreateStockObject( int nIndex )和自定义字体。 在创建非库存字体时需要填充一个LOGFONT结构并使用CFont::CreateFontIndirect(const LOGFONT* lpLogFont ),或使用CFont::CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, LPCTSTR lpszFacename )其中的参数和LOGFONT中的分量有一定的对应关系。下面分别讲解参数的意义: nHeight 字体高度(逻辑单位)等于零为缺省高度,否则取绝对值并和可用的字体高度进行匹配。 nWidth 宽度(逻辑单位)如果为零则使用可用的横纵比进行匹配。 nEscapement 出口矢量与X轴间的角度 nOrientation 字体基线与X轴间的角度 nWeight 字体粗细,可取以下值 Constant Value FW_DONTCARE 0 FW_THIN 100 FW_EXTRALIGHT 200 FW_ULTRALIGHT 200 FW_LIGHT 300 FW_NORMAL 400 FW_REGULAR 400 FW_MEDIUM 500 FW_SEMIBOLD 600 FW_DEMIBOLD 600 FW_BOLD 700 FW_EXTRABOLD 800 FW_ULTRABOLD 800 FW_BLACK 900 FW_HEAVY 900 bItalic 是否为斜体 bUnderline 是否有下划线 cStrikeOut 是否带删除线 nCharSet 指定字符集合,可取以下值 Constant Value ANSI_CHARSET 0 DEFAULT_CHARSET 1 SYMBOL_CHARSET 2 SHIFTJIS_CHARSET 128 OEM_CHARSET 255 nOutPrecision 输出精度 OUT_CHARACTER_PRECIS OUT_STRING_PRECIS OUT_DEFAULT_PRECIS OUT_STROKE_PRECIS OUT_DEVICE_PRECIS OUT_TT_PRECIS OUT_RASTER_PRECIS nClipPrecision 剪辑精度,可取以下值 CLIP_CHARACTER_PRECIS CLIP_MASK CLIP_DEFAULT_PRECIS CLIP_STROKE_PRECIS CLIP_ENCAPSULATE CLIP_TT_ALWAYS CLIP_LH_ANGLES nQuality 输出质量,可取以下值 • DEFAULT_QUALITY Appearance of the font does not matter. • DRAFT_QUALITY Appearance of the font is less important than when PROOF_QUALITY is used. For GDI raster fonts, scaling is enabled. Bold, italic, underline, and strikeout fonts are synthesized if necessary. • PROOF_QUALITY Character quality of the font is more important than exact matching of the logical-font attributes. For GDI raster fonts, scaling is disabled and the font closest in size is chosen. Bold, italic, underline, and strikeout fonts are synthesized if necessary. nPitchAndFamily 字体间的间距 lpszFacename 指定字体名称,为了得到系统所拥有的字体可以利用EmunFontFamiliesEx。 此外可以利用CFontDialog来得到用户选择的字体的LOGFONT数据。 最后我讲一下文本坐标的计算,利用CDC::GetTextExtent( const CString& str )可以得到字符串的在输出时所占用的宽度和高度,这样就可以在手工输出多行文字时使用正确的行距。另外如果需要更精确的对字体高度和宽度进行计算就需要使用CDC::GetTextMetrics( LPTEXTMETRIC lpMetrics ) 该函数将会填充TEXTMETRIC结构,该结构中的分量可以非常精确的描述字体的各种属性。 2.3 使用点,刷子,笔进行绘图 在Windows中画点的方法很简单,只需要调用COLORREF CDC::SetPixel( int x, int y, COLORREF crColor )就可以在指定点画上指定颜,同时返回原来的颜。COLORREF CDC::GetPixel( int x, int y)可以得到指定点的颜。在Windows中应该少使用画点的函数,因为这样做的执行效率比较低。 刷子和画笔在Windows作图中是使用最多的GUI对象,本节在讲解刷子和画笔使用方法的同时也讲述一写基本作图函数。 在画点或画线时系统使用当前DC中的画笔,所以在创建画笔后必须将其选入DC才会在绘图时产生效果。画笔可以通过CPen对象来产生,通过调用CPen::CreatePen( int nPenStyle, int nWidth, COLORREF crColor )来创建。其中nPenStyle指名画笔的风格,可取如下值: • PS_SOLID 实线 Creates a solid pen. • PS_DASH 虚线,宽度必须为一 Creates a dashed pen. Valid only when the pen width is 1 or less, in device units. • PS_DOT 点线,宽度必须为一 Creates a dotted pen. Valid only when the pen width is 1 or less, in device units. • PS_DASHDOT 点划线,宽度必须为一 Creates a pen with alternating dashes and dots. Valid only when the pen width is 1 or less, in device units. • PS_DASHDOTDOT 双点划线,宽度必须为一 Creates a pen with alternating dashes and double dots. Valid only when the pen width is 1 or less, in device units. • PS_NULL 空线,使用时什么也不会产生 Creates a null pen. • PS_ENDCAP_ROUND 结束处为圆形 End caps are round. • PS_ENDCAP_SQUARE 结束处为方形 End caps are square. nWidth和crColor为线的宽度和颜。 刷子是在画封闭曲线时用来填充的颜,例如当你画圆形或方形时系统会用当前的刷子对内部进行填充。刷子可利用CBrush对象产生。通过以下几种函数创建刷子: • BOOL CreateSolidBrush( COLORREF crColor ); 创建一种固定颜的刷子 • BOOL CreateHatchBrush( int nIndex, COLORREF crColor ); 创建指定颜和网格的刷子,nIndex可取以下值: • HS_BDIAGONAL Downward hatch (left to right) at 45 degrees • HS_CROSS Horizontal and vertical crosshatch • HS_DIAGCROSS Crosshatch at 45 degrees • HS_FDIAGONAL Upward hatch (left to right) at 45 degrees • HS_HORIZONTAL Horizontal hatch • HS_VERTICAL Vertical hatch • BOOL CreatePatternBrush( CBitmap* pBitmap ); 创建以8*8位图为模板的刷子 在选择了画笔和刷子后就可以利用Windows的作图函数进行作图了,基本的画线函数有以下几种 • CDC::MoveTo( int x, int y ); 改变当前点的位置 • CDC::LineTo( int x, int y ); 画一条由当前点到参数指定点的线 • CDC::BOOL Arc( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 画弧线 • CDC::BOOL Polyline( LPPOINT lpPoints, int nCount ); 将多条线依次序连接 基本的作图函数有以下几种: • CDC::BOOL Rectangle( LPCRECT lpRect ); 矩形 • CDC::RoundRect( LPCRECT lpRect, POINT point ); 圆角矩形 • CDC::Draw3dRect( int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight ); 3D边框 • CDC::Chord( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); 扇形 • CDC::Ellipse( LPCRECT lpRect ); 椭圆形 • CDC::Pie( LPCRECT lpRect, POINT ptStart, POINT ptEnd ); • CDC::Polygon( LPPOINT lpPoints, int nCount ); 多边形 对于矩形,圆形或类似的封闭曲线,系统会使用画笔绘制边缘,使用刷子填充内部。如果你不希望填充或是画出边缘,你可以选入空刷子(NULL_PEN)或是(NULL_BRUSH)空笔。 下面的代码创建一条两象素宽的实线并选入DC。并进行简单的作图: { ... CPen pen; pen.CreatePen(PS_SOLID,2,RGB(128,128,128)); CPen* pOldPen=(CPen*)dc.SelectObject(&pen); dc.SelectStockObject(NULL_BRUSH);//选入空刷子 dc.Rectangle(CRect(0,0,20,20));//画矩形 ... } 2.4 在窗口中绘制设备相关位图,图标,设备无关位图 在Windows中可以将预先准备好的图像复制到显示区域中,这种内存拷贝执行起来是非常快的。在Windows中提供了两种使用图形拷贝的方法:通过设备相关位图(DDB)和设备无关位图(DIB)。 DDB可以用MFC中的CBitmap来表示,而DDB一般是存储在资源文件中,在加载时只需要通过资源ID号就可以将图形装入。BOOL CBitmap::LoadBitmap( UINT nIDResource )可以装入指定DDB,但是在绘制时必须借助另一个和当前绘图DC兼容的内存DC来进行。通过CDC::BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop )绘制图形,同时指定光栅操作的类型。BitBlt可以将源DC中位图复制到目的DC中,其中前四个参数为目的区域的坐标,接下来是源DC指针,然后是源DC中的起始坐标,由于BitBlt为等比例复制,所以不需要再次指定长宽,(StretchBlt可以进行缩放)最后一个参数为光栅操作的类型,可取以下值: • BLACKNESS 输出区域为黑 Turns all output black. • DSTINVERT 反输出区域 Inverts the destination bitmap. • MERGECOPY 在源和目的间使用AND操作 Combines the pattern and the source bitmap using the Boolean AND operator. • MERGEPAINT 在反后的目的和源间使用OR操作 Combines the inverted source bitmap with the destination bitmap using the Boolean OR operator. • NOTSRCCOPY 将反后的源拷贝到目的区 Copies the inverted source bitmap to the destination. • PATINVERT 源和目的间进行XOR操作 Combines the destination bitmap with the pattern using the Boolean XOR operator. • SRCAND 源和目的间进行AND操作 Combines pixels of the destination and source bitmaps using the Boolean AND operator. • SRCCOPY 复制源到目的区 Copies the source bitmap to the destination bitmap. • SRCINVERT 源和目的间进行XOR操作 Combines pixels of the destination and source bitmaps using the Boolean XOR operator. • SRCPAINT 源和目的间进行OR操作 Combines pixels of the destination and source bitmaps using the Boolean OR operator. • WHITENESS 输出区域为白 Turns all output white. 下面用代码演示这种方法: CYourView::OnDraw(CDC* pDC) { CDC memDC;//定义一个兼容DC memDC.CreateCompatibleDC(pDC);//创建DC CBitmap bmpDraw; bmpDraw.LoadBitmap(ID_BMP) ;//装入DDB CBitmap* pbmpOld=memDC.SelectObject(&bmpDraw) ; //保存原有DDB,并选入新DDB入DC pDC->BitBlt(0,0,20,20,&memDC,0,0,SRCCOPY) ; //将源DC中(0,0,20,20)复制到目的DC(0,0,20,20) pDC->BitBlt(20,20,40,40,&memDC,0,0,SRCAND); //将源DC中(0,0,20,20)和目的DC(20,20,40,40)中区域进行AND操作 memDC.SelectObject(pbmpOld) ;//选入原DDB } (图标并不是一个GDI对象,所以不需要选入DC)在MFC中没有一个专门的图标类,因为图标的操作比较简单,使用HICON CWinApp::LoadIcon( UINT nIDResource )或是HICON CWinApp::LoadStandardIcon( LPCTSTR lpszIconName ) 装入后就可以利用BOOL CDC::DrawIcon( int x, int y, HICON hIcon )绘制。由于在图标中可以指定透明区域,所以在某些需要使用非规则图形而且面积不大的时候使用图标会比较简单。下面给出简单的代码: OnDraw(CDC* pDC) { HICON hIcon1=AfxGetApp()->LoadIcon(IDI_I1); HICON hIcon2=AfxGetApp()->LoadIcon(IDI_I2); pDC->DrawIcon(0,0,hIcon1); pDC->DrawIcon(0,40,hIcon2); DestroyIcon(hIcon1); DestroyIcon(hIcon2); } 同样在MFC也没有提供一个DIB的类,所以在使用DIB位图时我们需要自己读取位图文件中的头信息,并读入数据,并利用API函数StretchDIBits绘制。位图文件以BITMAPFILEHEADER结构开始,然后是BITMAPINFOHEADER结构和调版信息和数据,其实位图格式是图形格式中最简单的一种,而且也是Windows可以理解的一种。我不详细讲解DIB位图的结构,提供一个CDib类供大家使用,这个类包含了基本的功能如:Load,Save,Draw。DownLoad CDib 4K 2.5 使用各种映射方式 所谓的映射方式简单点讲就是坐标的安排方式,系统默认的映射方式为MM_TEXT即X坐标向右增加,Y坐标向下增加,(0,0)在屏幕左上方,DC中的每一点就是屏幕上的一个象素。也许你会认为这种方式下是最好理解的,但是一个点和象素对应的关系在屏幕上看来是正常的,但到了打印机上就会很不正常。因为我们作图是以点为单位并且打印机的分辨率远远比显示器高(800DPI 800点每英寸)所以在打印机上图形看起来就会很小。这样就需要为打印另做一套代码而加大了工作量。如果每个点对应0.1毫米那么在屏幕上的图形就会和打印出来的图形一样大小。 通过int CDC::SetMapMode( int nMapMode )可以指定映射方式,可用的有以下几种: • MM_HIENGLISH 每点对应0.001英寸 Each logical unit is converted to 0.001 inch. Positive x is to the right; positive y is up. • MM_HIMETRIC 每点对应0.001毫米 Each logical unit is converted to 0.01 millimeter. Positive x is to the right; positive y is up. • MM_LOENGLISH 每点对应0.01英寸 Each logical unit is converted to 0.01 inch. Positive x is to the right; positive y is up. • MM_LOMETRIC 每点对应0.001毫米 Each logical unit is converted to 0.1 millimeter. Positive x is to the right; positive y is up. • MM_TEXT 象素对应 Each logical unit is converted to 1 device pixel. Positive x is to the right; positive y is down. 以上几种映射默认的原点在屏幕左上方。除MM_TEXT外都为X坐标向右增加,Y坐标向上增加,和自然坐标是一致的。所以在作图是要注意什么时候应该使用负坐标。而且以上的映射都是X-Y等比例的,即相同的长度在X,Y轴上显示的长度都是相同的。 DownLoad Sample 另外的一种映射方式为MM_ANISOTROPIC,这种方式可以规定不同的长宽比例。在设置这中映射方式后必须调用CSize CDC::SetWindowExt( SIZE size )和CSize CDC::SetViewportExt( SIZE size )来设定长宽比例。系统会根据两次设定的长宽的比值来确定长宽比例。下面给出一段代码比较映射前后的长宽比例: OnDraw(CDC* pDC) { CRect rcC1(200,0,400,200); pDC->FillSolidRect(rcC1,RGB(0,0,255)); pDC->SetMapMode(MM_ANISOTROPIC ); CSize sizeO; sizeO=pDC->SetWindowExt(5,5); TRACE("winExt %d %d\n",sizeO.cx,sizeO.cy); sizeO=pDC->SetViewportExt(5,10); TRACE("ViewExt %d %d\n",sizeO.cx,sizeO.cy); CRect rcC(0,0,200,200); pDC->FillSolidRect(rcC,RGB(0,128,0)); } 上面代码在映射后画出的图形将是一个长方形。 DownLoad Sample 最后讲讲视原点(viewport origin),你可以通过调用CPoint CDC::SetViewportOrg( POINT point )重新设置原点的位置,这就相对于对坐标进行了位移。例如你将原点设置在(20,20)那么原来的(0,0)就变成了(-20,-20)。 2.6 多边形和剪贴区域 多边形也是一个GDI对象,同样遵守其他GDI对象的规则,只是通常都不将其选入DC中。在MFC中多边形有CRgn表示。多边形用来表示一个不同与矩形区域,和矩形具有相似的操作。如:检测某点是否在内部,并操作等。此外还得到一个包含此多边形的最小矩形。下面介绍一下多边形类的成员函数: • CreateRectRgn 由矩形创建一个多边形 • CreateEllipticRgn 由椭圆创建一个多边形 • CreatePolygonRgn 创建一个有多个点围成的多边形 • PtInRegion 某点是否在内部 • CombineRgn 两个多边形相并 • EqualRgn 两个多边形是否相等 在本节中讲演多边形的意义在于重新在窗口中作图时提高效率。因为引发窗口重绘的原因是某个区域失效,而失效的区域用多边形来表示。假设窗口大小为500*400当上方的另一个窗口从(0,0,10,10)移动到(20,20,30,30)这时(0,0,10,10)区域就失效了,而你只需要重绘这部分区域而不是所有区域,这样你程序的执行效率就会提高。 通过调用API函数int GetClipRgn( HDC hdc, HRGN hrgn)就可以得到失效区域,但是一般用不着那么精确而只需得到包含该区域的最小矩形就可以了,所以可以利用int CDC::GetClipBox( LPRECT lpRect )完成这一功能。 第三章 文档视结构 3.1 文档 视图 框架窗口间的关系和消息传送规律 在MFC中M$引入了文档-视结构的概念,文档相当于数据容器,视相当于查看数据的窗口或是和数据发生交互的窗口。(这一结构在MFC中的OLE,ODBC开发时又得到更多的拓展)因此一个完整的应用一般由四个类组成:CWinApp应用类,CFrameWnd窗口框架类,CDocument文档类,CView视类。(VC6中支持创建不带文档-视的应用) 在程序运行时CWinApp将创建一个CFrameWnd框架窗口实例,而框架窗口将创建文档模板,然后有文档模板创建文档实例和视实例,并将两者关联。一般来讲我们只需对文档和视进行操作,框架的各种行为已经被MFC安排好了而不需人为干预,这也是M$设计文档-视结构的本意,让我们将注意力放在完成任务上而从界面编写中解放出来。 在应用中一个视对应一个文档,但一个文档可以包含多个视。一个应用中只用一个框架窗口,对多文档界面来讲可能有多个MDI子窗口。每一个视都是一个子窗口,在单文档界面中父窗口即是框架窗口,在多文档界面中父窗口为MDI子窗口。一个多文档应用中可以包含多个文档模板,一个模板定义了一个文档和一个或多个视之间的对应关系。同一个文档可以属于多个模板,但一个模板中只允许定义一个文档。同样一个视也可以属于多个文档模板。(不知道我说清楚没有) 接下来看看如何在程序中得到各种对象的指针: • 全局函数AfxGetApp可以得到CWinApp应用类指针 • AfxGetApp()->m_pMainWnd为框架窗口指针 • 在框架窗口中:CFrameWnd::GetActiveDocument得到当前活动文档指针 • 在框架窗口中:CFrameWnd::GetActiveView得到当前活动视指针 • 在视中:CView::GetDocument得到对应的文档指针 • 在文档中:CDocument::GetFirstViewPosition,CDocument::GetNextView用来遍历所有和文档关联的视。 • 在文档中:CDocument::GetDocTemplate得到文档模板指针 • 在多文档界面中:CMDIFrameWnd::MDIGetActive得到当前活动的MDI子窗口 一般来讲用户输入消息(如菜单选择,鼠标,键盘等)会先发往视,如果视未处理则会发往框架窗口。所以定义消息映射时定义在视中就可以了,如果一个应用同时拥有多个视而当前活动视没有对消息进行处理则消息会发往框架窗口。 3.2 接收用户输入 在视中接收鼠标输入: 鼠标消息是我们常需要处理的消息,消息分为:鼠标移动,按钮按下/松开,双击。利用ClassWizard可以轻松的添加这几种消息映射,下面分别讲解每种消息的处理。 WM_MOUSEMOVE对应的函数为OnMouseMove( UINT nFlags, CPoint point ),nFlags表明了当前一些按键的消息,你可以通过“位与”操作进行检测。 • MK_CONTROL Ctrl键是否被按下 Set if the CTRL key is down. • MK_LBUTTON 鼠标左键是否被按下 Set if the left mouse button is down. • MK_MBUTTON 鼠标中间键是否被按下 Set if the middle mouse button is down. • MK_RBUTTON 鼠标右键是否被按下 Set if the right mouse button is down. • MK_SHIFT Shift键是否被按下 Set if the SHIFT key is down. point表示当前鼠标的设备坐标,坐标原点对应视左上角。 WM_LBUTTONDOWN/WM_RBUTTONDOWN(鼠标左/右键按下)对应的函数为OnLButtonDown/OnRButtonDown( UINT nFlags, CPoint point )参数意义和OnMouseMove相同。 WM_LBUTTONUP/WM_RBUTTONUP(鼠标左/右键松开)对应的函数为OnLButtonUp/OnRButtonUp( UINT nFlags, CPoint point )参数意义和OnMouseMove相同。 WM_LBUTTONDBLCLK/WM_RBUTTONDBLCLK(鼠标左/右键双击)对应的函数为OnLButtonDblClk/OnRButtonDblClk( UINT nFlags, CPoint point )参数意义和OnMouseMove相同。 下面我用一段伪代码来讲解一下这些消息的用法: 代码的作用是用鼠标拉出一个矩形 global BOOL fDowned;//是否在拉动 global CPoint ptDown;//按下位置 global CPoint ptUp;//松开位置 OnLButtonDown(UINT nFlags, CPoint point) { fDowned=TRUE; ptUp=ptDown=point; DrawRect(); ... } OnMouseMove(UINT nFlags, CPoint point) { if(fDowned) { DrawRect();//恢复上次所画的矩形 ptUp=point; DrawRect();//画新矩形 } } OnLButtonUp(UINT nFlags, CPoint point) { if(fDowned) { DrawRect();//恢复上次所画的矩形 ptUp=point; DrawRect();//画新矩形 fDowned=FALSE; } } DrawRect() {//以反屏幕的方法画出ptDown,ptUp标记的矩形 CClientDC dc(this); MakeRect(ptDown,ptUp); SetROP(NOT); Rect(); } 坐标间转换:在以上的函数中point参数对应的都是窗口的设备坐标,我们应该将设备坐标和逻辑坐标相区别,在图32_g1由于窗口使用了滚动条,所以传入的设备坐标是对应于当前窗口左上角的坐标,没有考虑是否滚动,而逻辑坐标必须考虑滚动后对应的坐标,所以我以黄线虚拟的表达一个逻辑坐标的区域。可以看得出同一点在滚动后的坐标值是不同的,这一规则同样适用于改变了映射方式的窗口,假设你将映射方式设置为每点为0.01毫米,那么设备坐标所对应的逻辑坐标也需要重新计算。进行这种转换需要写一段代码,所幸的是系统提供了进行转换的功能DC的DPtoLP,LPtoDP,下面给出代码完成由设备坐标到逻辑坐标的转换。 图32_g1 CPoint CYourView::FromDP(CPoint point) { CClientDC dc(this); CPoint ptRet=point; dc.PrepareDC();//必须先准备DC,这在使用滚动时让DC重新计算坐标 //如果你作图设置了不同的映射方式,则在下面需要设置 dc.SetMapMode(...) // dc.DPtoLP(&ptRet);//DP->LP进行转换 return ptRet; } 在图32_g1中以蓝线标记的是屏幕区域,红线标记的客户区域。利用ScreenToClient,ClientToScreen可以将坐标在这两个区域间转换。 在视中接收键盘输入: 键盘消息有三个:键盘被按下/松开,输入字符。其中输入字符相当于直接得到用户输入的字符这在不需要处理按键细节时使用,而键盘被按下/松开在按键状态改变时发送。 WM_CHAR对应的函数为OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ),其中nChar为被按下的字符,nRepCnt表明在长时间为松开时相当于的按键次数,nFlags中的不同位代表不同的含义,在这里一般不使用。 WM_KEYDOWN/WM_KEYUP所对应的函数为OnKeyDown/OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags )nChar代表按键的虚拟码值,如VK_ALT为ALT键,VK_CONTROL为Ctrl键。nFlags各位的含义如下: Value Description 0? Scan code (OEM-dependent value). 8 Extended key, such as a function key or a key on the numeric keypad (1 if it is an extended key). 9?0 Not used. 11?2 Used internally by Windows. 13 Context code (1 if the ALT key is held down while the key is pressed; otherwise 0). 14 Previous key state (1 if the key is down before the call, 0 if the key is up). 15 Transition state (1 if the key is being released, 0 if the key is being pressed). 3.3 使用菜单 利用菜单接受用户命令是一中很简单的交互方法,同时也是一种很有效的方法。通常菜单作为一中资源存储在文件中,因此我们可以在设计时就利用资源编辑器设计好一个菜单。关于使用VC设计菜单我就不再多讲了,但你在编写菜单时应该尽量在属性对话框的底部提示(Prompt)处输入文字,这虽然不是必要的,但MFC在有状态栏和工具条的情况下会使用该文字,文字的格式为“状态栏出说明\n工具条提示”。 图33_g1 我们要面临的任务是如何知道用户何时选择了菜单,他选的是什么菜单项。当用户选择了一个有效的菜单项时系统会向应用发送一个WM_COMMAND消息,在消息的参数中表明来源。在MFC中我们只需要进行一次映射,将某一菜单ID映射到一处理函数,图33_g2。在这里我们在CView的派生类中处理菜单消息,同时我对同一ID设置两个消息映射,接下来将这两种映射的作用。 图33_g2 ON_COMMAND 映射的作用为在用户选择该菜单时调用指定的处理函数。如:ON_COMMAND(IDM_COMMAND1, OnCommand1)会使菜单被选择时调用OnCommand1成员函数。 ON_UPDATE_COMMAND_UI(IDM_COMMAND1, OnUpdateCommand1) 映射的作用是在菜单被显示时通过调用指定的函数来进行确定其状态。在这个处理函数中你可以设置菜单的允许/禁止状态,其显示字符串是什么,是否在前面打钩。函数的参数为CCmdUI* pCmdUI,CCmdUI是MFC专门为更新命令提供的一个类,你可以调用 • Enable 设置允许/禁止状态 • SetCheck 设置是否在前面打钩 • SetText 设置文字 下面我讲解一个例子:我在CView派生类中有一个变量m_fSelected,并且在视中处理两个菜单的消息,当IDM_COMMAND1被选时,对m_fSelected进行逻辑非操作,当IDM_COMMAND2被选中时出一提示;同时IDM_COMMAND1根据m_fSelected决定菜单显示的文字和是否在前面打上检查符号,IDM_COMMAND2根据m_fSelected的值决定菜单的允许/禁止状态。下面是代码和说明:下载示例代码 17K void CMenuDView::OnCommand1() { m_fSelected=!m_fSelected; TRACE("command1 selected\n"); } void CMenuDView::OnUpdateCommand1(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_fSelected);//决定检查状态 pCmdUI->SetText(m_fSelected?"当前被选中":"当前未被选中");//决定所显示的文字 } void CMenuDView::OnUpdateCommand2(CCmdUI* pCmdUI) {//决定是否为允许 pCmdUI->Enable(m_fSelected); } void CMenuDView::OnCommand2() {//选中时给出提示 AfxMessageBox("你选了command2"); } 接下来再讲一些通过代码操纵菜单的方法,在MFC中有一个类CMenu用来处理和菜单有关的功能。在生成一个CMenu对象时你需要从资源中装如菜单,通过调用BOOL CMenu::LoadMenu( UINT nIDResource )进行装入,然后你就可以对菜单进行动态的修改,所涉及到的函数有: • CMenu* GetSubMenu( int nPos ) 一位置得到子菜单的指针,因为一个CMenu对象只能表示一个弹出菜单,如果菜单中的某一项也为弹出菜单,就需要通过该函数获取指针。 • BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ) 在末尾添加一项,nFlag为MF_SEPARATOR表示增加一个分隔条,这样其他两个参数将会被忽略;为MF_STRING表示添加一个菜单项uIDNewItem为该菜单的ID命令值;为MF_POPUP表示添加一个弹出菜单项,这时uIDNewItem为另一菜单的句柄HMENU。lpszNewItem为菜单文字说明。 • BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于在指定位置插入一菜单,位置由变量nPosition指明。如果nFlags包含MF_BYPOSITION则表明插入在nPosition位置,如果包含MF_BYCOMMAND表示插入在命令ID为nPosition的菜单处。 • BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于修改某一位置的菜单,如果nFlags包含MF_BYPOSITION则表明修改nPosition位置的菜单,如果包含MF_BYCOMMAND表示修改命令ID为nPosition处的菜单。 • BOOL RemoveMenu( UINT nPosition, UINT nFlags )用于删除某一位置的菜单。如果nFlags包含MF_BYPOSITION则表明删除nPosition位置的菜单,如果包含MF_BYCOMMAND表示删除命令ID为nPosition处的菜单。 • BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ) 和 BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp )可以添加一位图菜单,但这样的菜单在选中时只是反显示,并不美观。 视图中是没有菜单的,在框架窗口中才有,所以只有用AfxGetApp()->m_pMainWnd->GetMenu()才能得到应用的菜单指针。 最后我讲一下如何在程序中弹出一个菜单,你必须先装入一个菜单资源,你必需得到一个弹出菜单的指针然后调用BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL )弹出菜单,你需要指定(x,y)为菜单弹出的位置,pWnd为接收命令消息的窗口指针。下面有一段代码说明方法,下载示例代码 17K。当然为了处理消息你应该在pWnd指明的窗口中对菜单命令消息进行映射。 CMenu menu; menu.LoadMenu(IDR_POPUP); CMenu* pM=menu.GetSubMenu(0); CPoint pt; GetCursorPos(&pt); pM->TrackPopupMenu(TPM_LEFTALIGN,pt.x,pt.y,this); 另一种做法是通过CMenu::CreatePopupMenu()建立一个弹出菜单,然后使用TrackPopupMenu弹出菜单。使用CreatePopupMenu创建的菜单也可以将其作为一个弹出项添加另一个菜单中。下面的伪代码演示了如何创建一个弹出菜单并进行修改后弹出: CMenu menu1,menu2; menu1.CreatePopupMenu menu1.InsertMenu(1) menu1.InsertMenu(2) menu1.InsertMenu(3) menu2.CreatePopupMenu menu2.AppendMenu(MF_POPUP,1,menu1.Detach()) 将弹出菜单加入 or InsertMenu... menu2.InsertMenu("string desc"); menu.TrackPopupMenu(...) 3.4 文档,视,框架之间相互作用 一般来说用户的输入/输出基本都是通过视进行,但一些例外的情况下可能需要和框架直接发生作用,而在多视的情况下如何在视之间传递数据。 在使用菜单时大家会发现当一个菜单没有进行映射处理时为禁止状态,在多视的情况下菜单的状态和处理映射是和当前活动视相联系的,这样MFC可以保证视能正确的接收到各种消息,但有时候也会产生不便。有一个解决办法就是在框架中对消息进行处理,这样也可以保证当前文档可以通过框架得到当前消息。 在用户进行输入后如何使视的状态得到更新?这个问题在一个文档对应一个视图时是不存在的,但是现在有一个文档对应了两个视图,当在一个视上进行了输入时如何保证另一个视也得到通知呢?MFC的做法是利用文档来处理的,因为文档管理着当前和它联系的视,由它来通知各个视是最合适的。让我们同时看两个函数: • void CView::OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint ) • void CDocument::UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL ) 当文档的UpdateAllViews被调用时和此文档相关的所有视的OnUpdate都会被调用,而参数lHint和pHint都会被传递。这样一来发生改变视就可以通知其他的兄弟了。那么还有一个问题:如何在OnUpdate中知道是那个视图发生了改变呢,这就可以利用pHint参数,只要调用者将this指针赋值给参数就可以了,当然完全可以利用该参数传递更复杂的结构。 视的初始化,当一个文档被打开或是新建一个文档时视图的CView::OnInitialUpdate()会被调用,你可以通过重载该函数对视进行初始化,并在结束前调用父类的OnInitialUpdate,因为这样可以保证OnUpdate会被调用。 文档中内容的清除,当文档被关闭时(比如退出或是新建前上一个文档清除)void CDocument::DeleteContents ()会被调用,你可以通过重载该函数来进行清理工作。 在单文档结构中上面两点尤其重要,因为软件运行文档对象和视对象只会被产生并删除一次。所以应该将上面两点和C++对象构造和构析分清楚。 最后将一下文档模板(DocTemplate)的作用,文档模板分为两类单文档模板和多文档模板,分别由CSingleDocTemplate和CMultiDocTemplate表示,模板的作用在于记录文档,视,框架之间的对应关系。还有一点就是模板可以记录应用程序可以打开的文件的类型,当打开文件时会根据文档模板中的信息选择正确的文档和视。模板是一个比较抽想的概念,一般来说是不需要我们直接进行操作的。 当使用者通过视修改了数据时,应该调用GetDocument()->SetModifiedFlag(TRUE)通知文档数据已经被更新,这样在关闭文档时会自动询问用户是否保存数据。 好象这一节讲的有些乱,大家看后有什么想法和问题请在VCHelp论坛上留言,我会尽快回复并且会对本节内容重新整理和修改。 3.5 利用序列化进行文件读写 在很多应用中我们需要对数据进行保存,或是从介质上读取数据,这就涉及到文件的操作。我们可以利用各种文件存取方法完成这些工作,但MFC中也提供了一种读写文件的简单方法——“序列化”。序列化机制通过更高层次的接口功能向开发者提供了更利于使用和透明于字节流的文件操纵方法,举一个例来讲你可以将一个字串写入文件而不需要理会具体长度,读出时也是一样。你甚至可以对字符串数组进行操作。在MFC提供的可自动分配内存的类的支持下你可以更轻松的读/写数据。你也可以根据需要编写你自己的具有序列化功能的类。 序列化在最低的层次上应该被需要序列化的类支持,也就是说如果你需要对一个类进行序列化,那么这个类必须支持序列化。当通过序列化进行文件读写时你只需要该类的序列化函数就可以了。 怎样使类具有序列化功能呢?你需要以下的工作: • 该类从CObject派生。 • 在类声明中包括DECLARE_SERIAL宏定义。 • 提供一个缺省的构造函数。 • 在类中实现Serialze函数 • 使用IMPLEMENT_SERIAL指明类名和版本号 下面的代码建立了一个简单身份证记录的类,同时也能够支持序列化。 in H struct strPID { char szName[10]; char szID[16]; struct strPID* pNext; }; class CAllPID : public CObject { public: DECLARE_SERIAL(CAllPID) CAllPID(); ~CAllPID(); public:// 序列化相关 struct strPID* pHead; //其他的成员函数 void Serialize(CArchive& ar); }; in CPP IMPLEMENT_SERIAL(CAllPID,CObject,1) // version is 1,版本用于读数据时的检测 void CAllPID::Serialize(CArchive& ar) { int iTotal; if(ar.IsStoring()) {//保存数据 iTotal=GetTotalID();//得到链表中的记录数量 arr<26;i++) ar<>iTotal; for(int i=0;i26;j++) ar>>*(((BYTE*)pID)+j);//读一个strPID中所有的数据 //修改链表 } } } 当然上面的代码很不完整,但已经可以说明问题。这样CAllPID就是一个可以支持序列化的类,并且可以根据记录的数量动态分配内存。在序列化中我们使用了CArchive类,该类用于在序列化时提供读写支持,它重载了<>运算符号,并且提供Read和Write函数对数据进行读写。 下面看看如何在文档中使用序列化功能,你只需要修改文档类的Serialize(CArchive& ar)函数,并调用各个进行序列化的类的Serial进行数据读写就可以了。当然你也可以在文档类的内部进行数据读写,下面的代码利用序列化功能读写数据: class CYourDoc : public CDocument { void Serialize(CArchive& ar); CString m_szDesc; CAllPID m_allPID; ...... } void CYourDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) {//由于CString对CArchive定义了<>操作符号,所以可以直接利用>>和<< ar<>m_szDesc; } m_allPID.Serialize(ar);//调用数据类的序列化函数 3.6 MFC中所提供的各种视类介绍 MFC中提供了丰富的视类供开发者使用,下面对各个类进行介绍: CView类是最基本的视类只支持最基本的操作。 CScrollView类提供了滚动的功能,你可以利用void CScrollView::SetScrollSizes( int nMapMode, SIZE sizeTotal, const SIZE& sizePage = sizeDefault, const SIZE& sizeLine = sizeDefault )设置滚动尺寸,和坐标映射模式。但是在绘图和接收用户输入时需要对坐标进行转换。请参见3.2 接收用户输入。 CFormView类提供用户在资源文件中定义界面的能力,并可以将子窗口和变量进行绑定。通过UpdateData函数让数据在变量和子窗口间交换。 CTreeView类利用TreeCtrl界面作为视界面,通过调用CTreeCtrl& CTreeView::GetTreeCtrl( ) const得到CTreeCtrl的引用。 CListView类利用ListCtrl界面作为视界面,通过调用CTreeCtrl& CTreeView::GetTreeCtrl( ) const得到CListCtrl的引用。 CEditView类利用Edit接收用户输入,它具有输入框的一切功能。通过调用CEdit& CEditView::GetEditCtrl( ) const得到Edit&的引用。void CEditView::SetPrinterFont( CFont* pFont )可以设置打印字体。 CRichEditView类作为Rich Text Edit(富文本输入)的视类,提供了可以按照格式显示文本的能力,在使用时需要CRichEditDoc的支持。 第四章 窗口控件 4.1 Button 按钮窗口(控件)在MFC中使用CButton表示,CButton包含了三种样式的按钮,Push Button,Check Box,Radio Box。所以在利用CButton对象生成按钮窗口时需要指明按钮的风格。 创建按钮:BOOL CButton::Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );其中lpszCaption是按钮上显示的文字,dwStyle为按钮风格,除了Windows风格可以使用外(如WS_CHILD|WS_VISUBLE|WS_BORDER)还有按钮专用的一些风格。 • BS_AUTOCHECKBOX 检查框,按钮的状态会自动改变 Same as a check box, except that a check mark appears in the check box when the user selects the box; the check mark disappears the next time the user selects the box. • BS_AUTORADIOBUTTON 圆形选择按钮,按钮的状态会自动改变 Same as a radio button, except that when the user selects it, the button automatically highlights itself and removes the selection from any other radio buttons with the same style in the same group. • BS_AUTO3STATE 允许按钮有三种状态即:选中,未选中,未定 Same as a three-state check box, except that the box changes its state when the user selects it. • BS_CHECKBOX 检查框 Creates a small square that has text displayed to its right (unless this style is combined with the BS_LEFTTEXT style). • BS_DEFPUSHBUTTON 默认普通按钮 Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style enables the user to quickly select the most likely option (the default option). • BS_LEFTTEXT 左对齐文字 When combined with a radio-button or check-box style, the text appears on the left side of the radio button or check box. • BS_OWNERDRAW 自绘按钮 Creates an owner-drawn button. The framework calls the DrawItem member function when a visual aspect of the button has changed. This style must be set when using the CBitmapButton class. • BS_PUSHBUTTON 普通按钮 Creates a pushbutton that posts a WM_COMMAND message to the owner window when the user selects the button. • BS_RADIOBUTTON 圆形选择按钮 Creates a small circle that has text displayed to its right (unless this style is combined with the BS_LEFTTEXT style). Radio buttons are usually used in groups of related but mutually exclusive choices. • BS_3STATE 允许按钮有三种状态即:选中,未选中,未定 Same as a check box, except that the box can be dimmed as well as checked. The dimmed state typically is used to show that a check box has been disabled. rect为窗口所占据的矩形区域,pParentWnd为父窗口指针,nID为该窗口的ID值。 获取/改变按钮状态:对于检查按钮和圆形按钮可能有两种状态,选中和未选中,如果设置了BS_3STATE或BS_AUTO3STATE风格就可能出现第三种状态:未定,这时按钮显示灰。通过调用int CButton::GetCheck( ) 得到当前是否被选中,返回0:未选中,1:选中,2:未定。调用void CButton::SetCheck( int nCheck );设置当前选中状态。 处理按钮消息:要处理按钮消息需要在父窗口中进行消息映射,映射宏为ON_BN_CLICKED( id, memberFxn )id为按钮的ID值,就是创建时指定的nID值。处理函数原型为afx_msg void memberFxn( ); 4.2 Static Box 静态文本控件的功能比较简单,可作为显示字符串,图标,位图用。创建一个窗口可以使用成员函数: BOOL CStatic::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff ); 其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对静态控件指明专门的风格。 • SS_CENTER,SS_LEFT,SS_RIGHT 指明字符显示的对齐方式。 • SS_GRAYRECT 显示一个灰矩形 • SS_NOPREFIX 如果指明该风格,对于字符&将直接显示,否则&将作为转义符,&将不显示而在其后的字符将有下划线,如果需要直接显示&必须使用&&表示。 • SS_BITMAP 显示位图 • SS_ICON 显示图标 • SS_CENTERIMAGE 图象居中显示 控制显示的文本利用成员函数SetWindowText/GetWindowText用于设置/得到当前显示的文本。 控制显示的图标利用成员函数SetIcon/GetIcon用于设置/得到当前显示的图标。 控制显示的位图利用成员函数SetBitmap/GetBitmap用于设置/得到当前显示的位图。下面一段代码演示如何创建一个显示位图的静态窗口并设置位图 CStatic* pstaDis=new CStatic; pstaDis->Create("",WS_CHILD|WS_VISIBLE|SS_BITMAP|SSCENTERIMAGE, CRect(0,0,40,40),pWnd,1); CBitmap bmpLoad; bmpLoad.LoadBitmap(IDB_TEST); pstaDis->SetBitmap(bmpLoad.Detach()); 4.3 Edit Box Edit窗口是用来接收用户输入最常用的一个控件。创建一个输入窗口可以使用成员函数: BOOL CEdit::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff ); 其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对输入控件指明专门的风格。 • ES_AUTOHSCROLL,ES_AUTOVSCROLL 指明输入文字超出显示范围时自动滚动。 • ES_CENTER,ES_LEFT,ES_RIGHT 指定对齐方式 • ES_MULTILINE 是否允许多行输入 • ES_PASSWORD 是否为密码输入框,如果指明该风格则输入的文字显示为* • ES_READONLY 是否为只读 • ES_UPPERCASE,ES_LOWERCASE 显示大写/小写字符 控制显示的文本利用成员函数SetWindowText/GetWindowText用于设置/得到当前显示的文本。 通过GetLimitText/SetLimitText可以得到/设置在输入框中输入的字符数量。 由于在输入时用户可能选择某一段文本,所以通过void CEdit::GetSel( int& nStartChar, in
第1章 开发环境 1 1.1 环境设置 2 0001 如何定制工具栏 2 0002 如何定制组件面板 2 0003 如何定制代码编辑器 3 0004 保存自定义开发环境桌面 4 1.2 组件安装 4 0005 安装ActiveX组件 4 0006 安装不同类型的第三方组件 5 0007 在Delphi中加载QReport报表组件 7 1.3 创建DLL文件 8 0008 生成一个DLL文件 8 0009 调用DLL文件 8 1.4 窗体相关操作 9 0010 将组件置前/置后 9 0011 如何锁定窗体中的组件 9 0012 如何改变窗体上的网格大小 10 0013 组件的选取 10 0014 改变窗体Hint背景 11 0015 以原始风格显示控件的滚动条 11 0016 使用快捷键打开对象观察器中的“...”按钮 11 1.5 其他相关应用技巧 11 0017 安装合适的Delphi版本 11 0018 熟练掌握Delphi中的菜单项 12 0019 构成Delphi项目的主要文件 12 0020 如何在程序中调用帮助文件 12 第2章 语言基础 17 2.1 基础语言 18 0021 如何对代码进行注释 18 0022 Exit语句的使用 18 0023 有效地使用Self对象 19 0024 声明局部变量、类变量和全局变量 19 0025 有效利用条件语句和嵌套条件语句 20 0026 有效利用循环语句和嵌套循环语句 21 0027 使用GoTo跳转语句 21 0028 有效使用Case Else语句 22 0029 保证数组循环的安全性 22 0030 获取枚举值列表 23 0031 使两个变量位于同一个地址空间 23 0032 利用动态数组作为函数参数 24 0033 调用Register过程的注意事项 24 0034 在Delphi中禁止使用result 24 0035 如何在Delphi中录制代码 24 0036 如何编译器会提示数组太大时的处理技巧 25 0037 如何对超大数字进行计算 25 0038 强类型的定义及使用 25 2.2 类、函数、重载 25 0039 在函数的定义中正确使用var 25 0040 如何实现类的转形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 0046 通过指针读写数据 30 0047 在过程中使用常量参数 31 0048 在过程中使用数组参数 31 0049 在过程中使用默认参数 31 2.4 其他 32 0050 如何在字符串中使用单引号 32 0051 结构对象的定义与使用 32 0052 使用数组为TlistView组件动态创建字段 33 0053 解决程序的死锁问题 34 0054 怎样实现接口委托 34 0055 在Delphi中使用汇编 35 0056 为程序设置版本和帮助信息 36 0057 动态链接库的创建与调用 36 0058 String类型和Pchar类型的用法和区别 36 0059 如何捕获异常 37 0060 TStrings与TStringList的使用 37 0061 如何实现窗体文件转换 37 第3章 程序算法 39 3.1 计算类算法 40 0062 如何计算1~100的阶乘和 40 0063 如何实现最大公约数 40 0064 如何实现最小公倍数 41 0065 如何实现裴波纳契数列求和 42 0066 如何实现百钱百鸡算法 42 0067 如何实现哥德巴赫猜想 43 0068 如何实现韩信点兵 44 0069 求水仙花数的算法 44 0070 求1000以内的完数 45 0071 如何计算x的y次方 46 3.2 复杂计算类算法 46 0072 如何实现金额大小写转换的算法 46 0073 如何计算时钟的指针位置 47 0074 如何计算汉字笔划 48 0075 如何计算两个日期之间的天数、周数、分钟数 49 0076 如何实现数字斜塔 50 0077 如何实现杨辉三角 51 0078 如何实现CRC算法 52 0079 如何将B转换成GB、MB和KB 52 3.3 判断及转换类算法 53 0080 判断IP地址是否合法的算法 53 0081 判断身份证是否合法的算法 54 0082 判断素数的算法 55 0083 将字符串转换成Unicode格式 56 3.4 排序及分组类算法 56 0084 利用回溯法将一组数平均分成两组 56 0085 利用冒泡法对数字进行排序 58 0086 用回溯法找出n个自然数中取r个数的所有组合 58 0087 0~N位数的任意组合 59 0088 在数组中快速查找近似值 60 0089 实现直接插入法排序 61 第4章 函数应用 63 4.1 字符串处理函数 64 0090 使用Uppercase函数将小写字母转换为大写字母 64 0091 使用Lowercase函数将大写字母转换为小写字母 64 0092 使用Copy函数获取一个字符串的子串 64 0093 使用LeftStr函数从左边取得指定个数的字符串 65 0094 使用RightStr函数从右边取得指定个数的字符串 65 0095 使用Length函数取得一段字符串的长度 65 0096 使用Pos函数返回子字符串第一次出现的索引值 66 0097 使用Quotedstr函数返回字符串的引证串 66 0098 使用Trim函数删除字符串的首尾空格 66 4.2 数学计算函数 67 0099 使用Abs函数返回指定数值的绝对值 67 0100 使用Mod函数计算1~10之间的奇数和 67 0101 使用Div函数做整除操作 68 0102 使用DivMod函数返回两个操作数相除的商和余数 68 0103 使用Power函数返回底数的任何次幂 69 0104 使用Round函数将实数四舍五入为整数 69 0105 使用Sqr函数计算指定数的平方 70 0106 使用Mean函数计算平均数 70 0107 求最大浮点数和最小浮点数 71 4.3 序数函数 72 0108 使用Odd函数改变StringGrid组件的奇偶行颜 72 0109 使用Pred函数获取顺序类型表达式的前驱 72 0110 使用Succ函数获取顺序类型表达式的后继 73 4.4 进制转换相关函数 73 0111 如何将二进制转换为八进制 73 0112 如何将二进制转换为十进制 75 0113 如何将二进制转换为十六进制 76 0114 如何将十进制转换为二进制 77 0115 如何将十进制转换为十六进制 78 0116 如何将十六进制转换为十进制 79 4.5 类型转换函数 80 0117 使用IntToHex函数将整数转换为十六进制数 80 0118 使用Int函数返回实数的整数部分 80 0119 使用IntToStr函数将整数转换为字符串类型 80 0120 使用StrToInt函数将字符串转换成整数 81 0121 使用StrToBool函数将字符串转换为布尔类型 81 4.6 对话框函数 81 0122 使用InputBox函数显示输入对话框 81 0123 使用MessageDlg函数显示不同风格的对话框 81 0124 使用CreateMessageDialog函数创建消息对话框 82 0125 如何在指定的位置显示信息框 82 0126 使用ShowException函数显示一个异常信息 82 4.7 异常处理函数 83 0127 将错误编号转换为错误信息字符串 83 0128 使用ExceptAddr函数获得异常被抛出的地址 83 0129 格式化异常处理信息 84 4.8 图形图像相关函数 85 0130 将TColor类型的颜值转换为RGB值 85 0131 使用Bounds函数获得某矩形的TRect 86 0132 从已有的位图上创建位图 86 0133 使用Frame3D过程在画布上创建3D效果 87 4.9 文件操作的相关函数 87 0134 使用CopyFile函数复制文件 87 0135 使用CreateDir函数创建一个目录 88 0136 使用FileCreate函数创建一个图形文件 88 0137 使用GetCurrentDir函数返回当前目录 89 0138 在指定路径中搜索指定的文件 89 0139 使用FileExists函数判断指定文件是否存在 90 0140 使用FileGetAttr函数返回文件的属性 90 0141 使用FileGetDate函数返回文件的修改日期 90 0142 使用FileWrite函数将缓冲区中的内容写入文件 91 4.10 其他函数 91 0143 使用Random函数产生7个随机数 91 0144 使用DiskFree函数返回磁盘驱动器的剩余空间 91 0145 如何使用Printer函数 92 0146 使用SetPriner函数修改打印机信息 93 0147 使用BeginThread函数产生线程 94 0148 使用EndThread过程终止一个线程 95 0149 使用ForegroundTask函数检测线程是否运行 96 第5章 字符与字符串处理技术 99 5.1 ASCII码与编码转换 100 0150 如何获得汉字的区位码 100 0151 通过区位码获取汉字 100 0152 根据ASCII码获得字母 101 0153 获得字母的ASCII码 101 5.2 字符中的转换 101 0154 如何将数字转换成字符串 101 0155 如何将字符串全部大写 102 0156 如何将字符串全部小写 102 0157 如何将字符串中的任意字符转换成大写 103 0158 如何将字符串中的任意字符转换成小写 103 0159 如何将字符串首字母大写 104 5.3 字符串的相关判断 105 0160 判断某一字符是否在字符串中 105 0161 判断字符串是由数字、大写字母或小写字母组成 105 0162 判断字符串中的某一字符是否大写 106 0163 判断字符串中是否有小写字母 107 0164 判断字符串中是否有指定的字符 107 0165 判断字符是否可以转换成整数 108 0166 判断字符中是否有汉字 108 0167 判断字符中是否有双字节 109 0168 判数输入的字符串是否为整数 109 5.4 字符串的个数问题 110 0169 获取文字中英文单词的个数 110 0170 如何统计两个子字符串之间的字符的个数 111 0171 判断字符在字符串中出现的个数 111 0172 在语句中查找汉字的个数 112 0173 如何统计中英文个数 112 5.5 字符串的其他操作 113 0174 返回指定字符串的起始位置 113 0175 获得汉字的拼音简码 113 0176 如何将字符串翻转 114 0177 截取指定位置的字符串 115 0178 清除字符串中指定的字符 115 0179 如何实现文本的加密与解密 116 0180 提取字符串中指定子字符串后的字符串 117 0181 替换指定的字符串 117 0182 在文本中删除指定的汉字或句子 118 0183 指定符号分割字符串 119 0184 如何使用随机密码和字符串 120 第6章 日期和时间 121 0185 获得系统当前时间 122 0186 获得系统当前日期 122 0187 将日期时间格式化为指定格式 122 0188 计算两个日期之间相差的天数 123 0189 根据指定日期返回星期几 123 0190 将日期转换为字符串 124 0191 判断日期是否改变 124 0192 判断字符串是否为日期或时间 125 0193 获得指定月的最后一天 127 0194 在指定的日期上加上3月 127 0195 实现倒计时功能 128 0196 判断指定年份是否为闰年 129 0197 调用系统设置日期对话框 129 0198 将秒数转化成hh:mm:ss格式 129 0199 修改操作系统日期 130 0200 获取全球标准时间 130 第7章 数据处理技术 133 7.1 组件数据处理技术 134 0201 让两个文本框中的内容同时改变 134 0202 格式化DataGrid表格中的数据 134 0203 控制文本框只能录入数字 135 0204 如何在DataGrid中嵌入LookupComboBox 135 0205 在DBGrid中设置不滚动的列 136 0206 如何在DBGrid中实现复制、粘贴功能 137 0207 在DBGrid中将选中的多行删除 137 0208 在DataGrid中如何使标题文字居中 138 0209 如何把ListBox中的内容拖曳到另一个ListBox中 139 0210 把DBGrid中的数据赋给数组 139 0211 如何获取DataGrid单元格中的内容 140 0212 如何锁定文本框中的文本 141 0213 如何设置光标到文本框的末尾 141 0214 如何改变表格列的矩形区域 142 0215 控制在文本框中只能输入两位小数 143 0216 如何把选择的文件图标显示在列表中 143 0217 根据表格中的数据长度自动调整表格宽度 144 7.2 ADO数据处理技术 145 0218 如何把ADO中的数据导入到ListBox中 145 0219 使用SQL语句保存数据 146 0220 使用赋值方式保存数据 147 0221 当ADO循环删除数据时需要注意的问题 147 0222 把Excel中的数据保存到数据库中 147 0223 怎样弹出ConnectionString设置页 148 0224 利用ADO获取DELETE后所影响的记录数 148 7.3 业务实现数据处理技术 149 0225 随机产生中奖号码 149 0226 使用快捷键保存数据 150 0227 密码只允许输入8位或超过8位 150 0228 如何获取汉字拼音简码 151 0229 根据用户输入需求自动调整输入法 152 0230 根据生日自动计算年龄 153 0231 实现找零功能 153 0232 设计带记忆的数据录入窗口 154 0233 在窗体关闭时提示有未保存的数据 155 0234 设置只允许3次密码错误 156 0235 如何读取Word中的文本 156 0236 通过身份证号获取年龄 157 0237 如何实现一个应用程序只能打开一个进程 158 7.4 其他数据处理技术 159 0238 对计算结果四舍五入 159 0239 获取一个字符的ASCII值 159 0240 判断字符串中是否有文字符 160 0241 如何从字符串中提取数字 160 0242 判断内容是否为日期 161 0243 使字符串显示为自定义的格式 161 0244 实现拼音大小写转换 162 0245 怎样实现数据输入为空提示 162 0246 读取Memo1中指定行的文本信息 163 0247 自动调节ComboBox列表宽度 164 0248 如何转换数据库表为CSV文件格式 164 0249 删除文本文件中的多余空格 165 0250 创建和使用资源文件 166 第8章 窗体与界面设计 169 8.1 窗体标题栏控制 170 0251 如何实现标题栏闪烁的窗体 170 0252 如何实现不可移动的窗体 170 0253 如何在不使用标题栏的情况下移动窗体 170 0254 使窗体标题栏文字右对齐 170 0255 在窗体标题栏上添加按钮 171 0256 取消窗体标题栏的关闭按钮 172 0257 如何实现闪动的标题栏文字 172 0258 怎样动态修改窗体图标 172 8.2 窗体的动态显示 173 0259 如何实现QQ窗体 173 0260 实现窗体的淡入淡出 173 0261 实现窗体的幻灯片效果 174 0262 实现窗体的伸展效果 174 0263 实现窗体的下拉效果 175 0264 以放大的圆形显示窗体 175 8.3 MDI窗体 176 0265 在MDI中显示动态窗体 176 0266 在MDI中真正关闭子窗体 176 0267 给MDI主窗体添加背景 176 0268 动态显示像MDI的子窗体 177 0269 打开MDI窗体时其他窗体会显示出来的原因 177 8.4 窗体的大小及位置 178 0270 控制窗体的最大化、最小化 178 0271 无标题栏时改变窗体的大小 178 0272 无标题栏最大化时不覆盖任务栏 178 0273 限制窗体的大小 179 0274 重定义去掉标题栏并最大化窗体 179 0275 使窗体一直居中 179 0276 控制窗体不可移动 180 0277 限制窗体的最大化 180 0278 使窗体自动居中 181 8.5 窗体的特殊形状 181 0279 实现窗体颜渐变 181 0280 如何使窗体透明 182 0281 制作特殊形状的窗体 182 0282 为窗体增加边框 183 0283 显示圆角窗体 183 0284 制作多边形窗体 184 0285 以文字的形式显示窗体 185 0286 如何实现窗体半透明 185 0287 制作立体窗口阴影效果 186 8.6 工具栏、状态栏及下拉列表 187 0288 制作带历史信息的菜单 187 0289 制作可以拉伸的菜单界面 188 0290 制作类似于XP颜的下拉页 188 0291 在系统菜单中添加菜单项 189 0292 在状态栏中放置其他组件 189 0293 改变下拉列表的文字颜 190 8.7 窗体的特殊效果 191 0294 如何动态分割窗体 191 0295 如何将应用程序背景与桌面融合 191 0296 如何在屏幕最前面显示滚动字幕 192 0297 制作磁性窗体 193 0298 制作浮动窗口 194 0299 制作另类提示窗口 195 0300 将窗体放入Panel组件中 196 8.8 窗体的快速操作 197 0301 使窗体始终在最上面 197 0302 显示所有的可视化窗体 197 0303 关闭所有窗体 198 0304 关闭多余的窗体 198 8.9 窗体的调用方法 199 0305 在关闭窗体前显示提示对话框 199 0306 创建一个启动闪现窗口 199 0307 动态创建窗体 200 0308 动态创建窗体和释放窗体 200 0309 在显示主窗体前显示登录窗体 201 8.10 窗体相关操作的其他技巧 202 0310 无窗体的半透明控件 202 0311 修改提示字体及颜 202 0312 在窗口中显示动态画布 202 0313 如何实现中英文切换 203 0314 在一个子窗体中获得另一个子窗体的组件信息 204 第9章 组件技术 205 9.1 优化组件外观 206 0315 利用TXPManifest组件美化程序界面 206 0316 使用Canvas美化列表项 206 0317 利用Canvas在Chart组件中画一幅图片 207 0318 如何为TListBox添加水平滚动条 207 0319 折行显示按钮标题 208 0320 为组件制作立体效果 208 0321 利用ActiveX控件实现Office助手 209 9.2 菜单、工具栏、状态栏 209 0322 在PopupMenu中动态加入新菜单 209 0323 在状态栏中显示进度条组件 210 0324 为工具栏添加背景图片 210 9.3 文本框及列表框的应用技巧 211 0325 使TEdit组件获取焦点后将文本全部选中 211 0326 使TEdit组件获取焦点时改变文本框颜 211 0327 查找列表框中的选项 212 0328 在ComboBox组件中显示QQ头像 212 0329 为Edit组件添加列表选择框 213 0330 在ListBox中显示位图 214 0331 获取TMemo中的可见行数 214 0332 如何在Memo组件上实现光标定位 215 0333 控制Memo组件中的滚动条 216 9.4 数据感知控件应用技巧 217 0334 如何在DBGrid中显示不同的记录颜 217 0335 单击DBGrid标题进行排序 218 0336 使DBGrid支持鼠标滚轮 218 0337 在DBGrid中添加静态字段 218 0338 在DBGrid中实现下拉列表 219 0339 改变DBGrid被选中时的颜 220 0340 用TDBNavigator组件删除数据显示自定义信息 220 0341 使用Excel组件将数据导出为Excel格式 221 9.5 表格组件使用技巧 222 0342 将StringGrid中指定行的数据添加到Memo中 222 0343 使TStringGrid组件自动移动及增加行 223 0344 单击StringGrid列进行排序 224 9.6 TreeView组件使用技巧 225 0345 如何动态创建TreeView节点 225 0346 如何将TreeView中的节点全部选中 226 0347 将菜单项添加到Tree View中 226 0348 使TreeView组件与数据库关联 227 0349 应用TTreeView组件遍历磁盘目录 228 0350 在TreeView组件中实现拖曳操作 229 9.7 ListView组件使用技巧 229 0351 向TListView组件中添加项目 229 0352 删除ListView中的选项 230 0353 实现ListView滚动 230 0354 将数组中的数值遍历到ListView中 231 0355 ListView组件的高级应用 231 0356 使ListView的不同列显示不同颜 232 0357 对ListView中的项目进行汇总 233 0358 单击列表标题进行排序 233 9.8 应用组件制作导航 234 0359 用ListView制作导航界面 234 0360 利用Panel组件制作QQ导航栏 235 9.9 其他组件使用技巧 237 0361 动态创建组件 237 0362 创建控件数组 237 0363 用组件来移动窗体 238 0364 实现组件的批量访问 238 0365 使同类组件进行同样的操作 239 0366 使用Ttrackbar组件改变画布颜值 239 0367 设置TopAxis属性在图表上面显示标签 240 0368 动态向ImageList组件中添加图标 240 0369 设置DateTimePicker组件的外观颜 241 0370 利用Timer组件显示当前系统时间 241 0371 获取用户在Month Calendar组件中选择的日期 242 0372 在Panel上播放视频文件 242 0373 Win3.1组件的综合应用 242 0374 制作一个信息上传控件 243 0375 使用Gauge组件制作启动程序 245 第10章 鼠标和键盘 247 10.1 鼠标和键盘 248 0376 鼠标和键盘在一定时间没有动作时关闭程序 248 0377 如何锁定鼠标和键盘 248 0378 如何实现键盘鼠标动作记录与回放 249 10.2 鼠标的相关操作 250 0379 将鼠标锁定在指定范围内 250 0380 模拟鼠标操作 251 0381 显示或隐藏鼠标 252 0382 获取鼠标按键状态 252 0383 获取窗口标题 253 0384 单击鼠标左键弹出右键菜单 253 0385 改变当前鼠标的样式 254 0386 模拟键盘的复制与粘贴 255 0387 如何定义自己的鼠标事件 255 0388 利用鼠标绘制矩形焦点 256 0389 将鼠标移动到指定控件 257 0390 ANI动画鼠标的制作 257 0391 自制动画鼠标 258 0392 获取鼠标滑轮的消息 258 0393 制作鼠标跟随 259 0394 利用鼠标滑轮查看组件中的数据 259 10.3 键盘的相关操作 260 0395 按回车键移动焦点 260 0396 如何屏蔽Win键 261 0397 如何控制键盘指示灯 261 0398 如何屏蔽Sleep和Wake Up键 262 0399 设置自己的热键 262 0400 用键盘钩子封锁Win dows热键 263 0401 如何用Esc键退出程序 263 0402 在TDBGrid中用回车键移至下一个字段 264 0403 用Esc键停止循环 264 0404 如何判断左右 Shift 按键 265 0405 替换一个键盘按钮 265 10.4 鼠标的其他应用技巧 266 0406 实现超级链接效果 266 0407 用鼠标隐藏显示窗口(仿QQ) 267 0408 获取鼠标的桌面坐标 267 0409 用鼠标双击TStatusBar时判断是哪一个Panels 268 0410 使Canvas上直线的一个端点跟着鼠标跑 268 第11章 文件与文件管理 271 11.1 文件及文件夹的创建和移动 272 0411 创建并删除文件 272 0412 如何移动文件 272 0413 将文件放入回收站 273 0414 复制文件夹到其他路径中 273 0415 用API函数进行文件的复制 274 0416 用内存块复制文件 275 0417 用文件流对文件进行复制 275 11.2 文件的打开及读取 276 0418 打开指定格式的文件 276 0419 获取文件中指定符号中的字符串 277 0420 如何输出文本内容 277 0421 根据文件名中的部分名称打开该文件 278 0422 怎样合并文件 280 0423 创建和使用资源文件 281 11.3 文件及文件夹的相关属性 281 0424 如何获取文件的访问时间 281 0425 获取文件的剩余空间 282 0426 获取文件修改时间 283 0427 怎样修改文件属性 283 11.4 文件及文件夹的相关目录 285 0428 得到系统当前目录 285 0429 改变当前目录 285 0430 获取System目录 286 0431 获取Windows目录 286 0432 获取临时文件的目录 287 11.5 文件属性的相关判断 287 0433 判断文件是否被使用 287 0434 判断文件是否存在 288 0435 判断文件是否为文本文件 288 0436 判断文件名是否有效 289 11.6 文件及文件夹的遍历 289 0437 如何查询文件 289 0438 提取文件夹中的文件 291 0439 遍历文件夹下的所有文件(包含子文件夹) 291 11.7 INI文件 292 0440 如何读写INI文件 292 0441 利用INI文件查看工作日志 294 0442 用INI文件创建菜单 295 11.8 文件的其他应用技巧 296 0443 调用帮助文件 296 0444 对文件进行比较 296 0445 更改文件名称 297 0446 字符网格和文本间转换 297 第12章 磁盘管理 299 12.1 获取磁盘的相关信息 300 0447 获取磁盘总空间 300 0448 获取光盘的盘符 300 0449 获取系统盘符 301 0450 获得光盘的卷标 301 0451 获取磁盘卷标 302 0452 获取磁盘编号 302 0453 获取磁盘详细信息 303 0454 获取硬盘序列号 303 0455 获取驱动器类型 304 0456 获取驱动器列表 304 0457 获取磁盘的文件系统名称、长度及系统标记 305 0458 获取移动硬盘 305 12.2 磁盘设置与操作 306 0459 将文件存到磁盘中 306 0460 如何实现盘格式化 307 0461 打开磁盘时先弹出文本文件 308 0462 怎样进行磁盘碎片整理 308 12.3 磁盘监控与分析 308 0463 判断光驱中是否有光盘 308 0464 如何打开和关闭光驱 309 0465 判断软驱中是否有软盘 310 0466 判断磁盘是否存在 311 第13章 图形图像技术 313 13.1 基本操作 314 0467 对窗体进行刷新 314 0468 在TImage组件上显示透明文字 314 0469 清空TImage组件中的图片 314 0470 生成两个颜的中间 315 0471 改变文字的背景颜 315 13.2 绘制图形 316 0472 制作空心文字 316 0473 如何实现十字光标定位 316 0474 制作旋转的文字 317 0475 波形图的绘制 318 0476 制作动画背景的窗体 319 0477 如何涂抹窗体 320 0478 如何万花筒 320 13.3 图片格式转换 321 0479 ICO转换成位图(BMP) 321 0480 JPG转换成位图(BMP) 322 0481 WMF转换成位图(BMP) 323 0482 位图(BMP)转换成JPG 323 0483 位图(BMP)转换成WMF 324 0484 批量转换图像 324 13.4 颜格式的转换 326 0485 将TColor换算成RGB 326 0486 将TColor换算成HTML 326 0487 将HTML换算成TColor 327 0488 将CMYK换算成RGB 327 0489 将RGB换算成CMYK 328 0490 将RGB换算成TColor 329 13.5 图片的滤镜效果 329 0491 将图片以灰度形式显示 329 0492 提高图像的亮度 330 0493 图像浮雕效果 331 0494 图片的反效果 332 13.6 翻转与缩放 333 0495 如何放大和缩小图像 333 0496 实现图形反转 333 0497 如何旋转图像 334 0498 将图像局部放大 335 13.7 图片的动态效果 336 0499 制作百叶窗效果 336 0500 垂直交错显示图像 337 0501 水平交错显示图像 338 0502 制作积木效果 338 0503 制作推拉效果 340 0504 如何实现雨滴式的效果 340 0505 图片颜逐渐加深 341 13.8 获取及调整图片的像素 342 0506 如何实现定点取 342 0507 获取指定点的RGB值 343 0508 制作红绿眼镜三维立体画 343 0509 调整图片的RGB对比度 344 0510 图片的加密与解密 345 13.9 图片的处理技术 346 0511 复制局部图片 346 0512 在图片中加入文字 347 0513 如何实现图片扭曲 348 0514 图片的网格效果 350 13.10 图片的存储 350 0515 将BMP图片重画到窗体上 350 0516 将JPG图片重画到窗体上 351 0517 使位图图片透明 352 0518 对大图片的操作 352 13.11 图片的其他应用技巧 353 0519 怎样浏览大图片 353 0520 获取图像信息 353 0521 在图片上平滑移动文字 354 0522 制作随鼠标拖动的图像 355 0523 在TMainMenu组件上绘制图片 356 第14章 动画与多媒体 357 14.1 动画播放 358 0524 单帧动画播放 358 0525 多帧动画播放 358 0526 模拟石英钟 360 0527 设计字幕程序 361 0528 设计屏幕保护程序 361 14.2 文字效果 363 0529 文字的立体字效果 363 0530 文字滚动效果 364 0531 文字旋转效果 365 0532 制作空心文字 365 14.3 播放媒体文件 366 0533 播放AVI文件 366 0534 播放Flash动画 367 0535 播放WAV文件 368 0536 播放GIF文件 368 14.4 利用API播放媒体 369 0537 与多媒体相关的API函数 369 0538 利用sndPlaySound函数播放音频文件 370 0539 利用mciSendString函数播放AVI 370 14.5 音频及视频 372 0540 使电脑发出声音 372 0541 显示MP3文件的播放时间 372 0542 显示文件的播放进度 373 0543 循环播放媒体文件 374 0544 显示AVI文件的播放帧数 375 0545 指定视频显示窗口 375 0546 全屏播放视频文件 376 0547 设计一个精美的播放器 377 0548 播放背景音乐 380 0549 利用RealPlayer播放器播放音乐 381 14.6 媒体控制 382 0550 如何实现静音与声道控制 382 0551 调用声音控制对话框 383 0552 使播放的Flash随窗口大小改变 383 0553 打开和关闭光驱 383 第15章 API函数 385 15.1 操作系统 386 0554 关闭显示器 386 0555 获取系统启动模式 386 0556 使程序不出现在任务栏上 387 0557 修改系统时间 387 0558 修改系统颜 388 0559 使用API函数拨号 389 0560 获取内存使用状态的信息 389 0561 清空回收站 390 0562 设置系统日期 390 0563 如何设定屏幕分辨率设定 391 0564 修改系统的刷新率 391 0565 隐藏桌面图标 392 0566 获取Windows主题文件 392 15.2 窗体 393 0567 利用API创建窗体 393 0568 利用API创建画刷 394 0569 利用API绘制弧形 394 0570 利用API控制窗体显示 395 0571 制作闪动标题的窗体 396 0572 拖动无标题栏窗体 396 0573 获取拖动到窗体中的文件路径 396 0574 在窗口的任意地方弹出主菜单项 397 0575 获取工程中的所有窗体名称 398 15.3 其他相关应用技巧 399 0576 锁定计算机 399 0577 启动控制面板 400 0578 如何实现屏幕抓图 401 0579 计算Windows从启动后所运行的总时间率 401 0580 巧用GetSystemMetrics函数 402 0581 显示密码编辑框中的密码 402 0582 添加、删除系统托盘图标 402 0583 如何在系统菜单中添加新项目 403 0584 监测程序多久未被使用 404 第16章 注册表 405 16.1 注册表基本操作 406 0585 创建注册表项 406 0586 删除注册表项 406 0587 向注册表中写入数据 407 0588 读取注册表中的数据 407 0589 列出指定注册表项下全部键值 408 0590 备份与恢复注册表 409 16.2 桌面 410 0591 设置系统墙纸 410 0592 修改桌面“我的电脑”的提示信息 410 0593 如何在桌面的任意位置显示墙纸 411 0594 在任务栏中添加自定义信息 412 16.3 优化系统性能 413 0595 如何实现自动登录 413 0596 如何快速显示窗口 414 0597 优化二级缓存 414 0598 优化系统关机速度 415 0599 禁止用户对虚拟内存的访问 415 16.4 IE浏览器设置 416 0600 设置IE默认首页 416 0601 清空IE网址中的历史记录 416 0602 设计修改IE标题栏和工具栏背景的程序 418 0603 隐藏IE属性中的选项 419 0604 禁止查看网页中的源文件 421 0605 禁止IE播放多媒体文件 421 0606 禁止对IE浏览器设置默认首页 422 16.5 “开始”菜单的相关设置 422 0607 如何在“开始”菜单中隐藏“关机”菜单项 422 0608 如何在“开始”菜单中隐藏“文档”菜单项 423 0609 如何在“开始”菜单中隐藏“运行”菜单项 423 0610 退出系统时清除“文档”中的历史记录 424 0611 禁止文档子菜单记录最近的工作信息 425 16.6 其他设置 426 0612 设计开机欢迎文字 426 0613 防止应用程序窗口失去焦点 426 0614 隐藏“添加/删除Windows组件”按钮 427 0615 隐藏计算机中的盘符 428 0616 禁止使用控制面板 430 0617 禁止使用注册表编辑器 431 0618 通过注册表获取时区信息 431 0619 通过注册表获取系统信息和用户注册信息 432 第17章 Windows相关开发技术 435 17.1 CPU 436 0620 获取CPU频率 436 0621 获取从开机到现在CPU运行的周期数 436 0622 获取CPU名称 437 0623 判断CPU是否支持MMX 438 17.2 系统控制 438 0624 计算机的关闭、重启和注销 438 0625 开关屏幕保护 439 0626 设计更换屏幕保护的程序 440 0627 设计屏幕保护的程序 441 0628 设置屏幕分辨率 442 0629 设置墙纸 443 0630 显示桌面 444 0631 让InputBox也能使用密码掩码 444 0632 控制系统菜单 445 0633 动态改变屏幕的显示模式 446 0634 在桌面上创建指定网址的快捷方式 446 0635 建立批处理文件的快捷方式 447 0636 Windows菜单字体的设置 448 17.3 系统状态栏的相关操作 448 0637 隐藏和显示任务栏 448 0638 隐藏、显示托盘图标 449 0639 隐藏状态栏中的时间 449 0640 如何设置“开始”按钮不可用 450 17.4 获取系统信息 450 0641 查看当前系统版本 450 0642 更改系统日期及时间 451 0643 获取系统字体的列表 452 0644 获取指定盘符中的路径 452 0645 获取系统内存信息 454 0646 如何使用DOS获取计算机的网络信息 454 17.5 获取Windows的相关文件 455 0647 按文件类型获取其图标 455 0648 监控剪贴板的文字内容 456 0649 输出Shell32.dll的图标 457 0650 从剪贴板中读取图片 458 17.6 Windows消息的相关控制 458 0651 程序最小时在任务栏中显示托盘图标 458 0652 动态最小化到状态栏托盘区 459 0653 屏幕取图(包含鼠标) 459 17.7 其他相关技巧 460 0654 如何让电脑发出滴声 460 0655 打开记事本和计算器 461 0656 对汉字输入法进行操作 461 0657 在组件中执行控制面板 462 0658 在Windows界面上不显示程序 464 0659 清空回收站 464 0660 给桌面加上一层阴影 465 第18章 程序应用控制 467 第19章 数据库技术 485 第20章 SQL查询相关技术 523 第21章 打印与报表技术 583 第22章 图表技术 617 第23章 硬件相关技巧 633 第24章 网络开发技术 645 第25章 Web相关技巧 689 第26章 安全技术 707 第27章 程序调试与错误处理 717 第28章 程序打包与安装 727 第29章 第三方控件 737

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧