博文

Visual C++ 6.0的文档/视结构(2006-09-24 12:44:00)

摘要: Visual C++ 6.0的文档/视结构 来自未知  作者佚名          
      Visual C++ 6.0 以其功能强大、用户界面友好而倍受程序员们的青睐。但是,在当前的Microsoft 基本类库4.2 版本中,大约有将近200 个类,数千个函数,加之Microsoft 公司隐藏了一些技术细节,使得人们深入学习MFC变得十分困难。 

  MFC的AppWizard可以生成三种类型的应用程序:基于对话框的应用、单文档应用(SDI)和多文档应用(MDI)。前两者的结构较简单,本文不再赘叙。笔者拟从MFC中的文档/视结构入手,分析一些函数的流程,并解决编制MDI 应用程序过程中的一些常见问题。 

(一)、了解文档/视结构 

  MFC应用程序模型历经多年以有了相当大的发展。有一个时期,它只是个使用应用程序对象和主窗口对象的简单模型。在这个模型中,应用程序的数据作为成员变量保持在框架窗口类中,在框架窗口的客户区中,该数据被提交显示器。随着MFC2。0的问世,一种应用程序结构的新方式----MFC文档/视结构出现了。在这种结构中,CFrameWnd繁重的任务被委派给几个不同类,实现了数据存储和显示的分离。一般情况下,采用文档/视结构的应用程序至少应由以下对象组成: 

。应用程序是一个CwinApp派生对象,它充当全部应用程序的容器。应用程序沿消息映射网络分配消息给它的所有子程序。 
。框架窗口是一CfrmeWnd派生对象。 
。文档是一个CDocument派生对象,它存储应用程序的数据,并把这些信息提供给应用程序的其余部分。 
。视窗是Cview派生对象,它与其父框架窗口用户区对齐。视窗接受用户对应用程序的输入并显示相关联的文档数据。 

      通常,......

阅读全文(322) | 评论:0

VC++中使用内存映射文件处理大文件(2006-09-24 12:43:00)

摘要: VC++中使用内存映射文件处理大文件   来自yesky  作者郎锐          
  摘要: 本文给出了一种方便实用的解决大文件的读取、存储等处理的方法,并结合相关程序代码对具体的实现过程进行了介绍。

  引言

  文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC提供的CFile类等。一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB、几百GB、乃至几TB的海量存储,再以通常的文件处理方法进行处理显然是行不通的。目前,对于上述这种大文件的操作一般是以内存映射文件的方式来加以处理的,本文下面将针对这种Windows核心编程技术展开讨论。

  内存映射文件

  内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

  内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理......

阅读全文(277) | 评论:0

千奇百怪的窗体(窗口) VC(2006-09-24 12:41:00)

摘要: 千奇百怪的窗体(窗口)  来自czvc  作者佚名         
VC++对话框的任意扩展
 
BULL77  YESKY

  我们在信息输入的时候,可能有很大的信息量,而这些信息又不是必须的,这时我们就需要给信息输入人员一个选择的接口。例如一个人事部门的职工信息录入系统就有这样的问题,其中的姓名、性别、年龄、政治面目、职务、学历、部门和联系电话是必须输入的信息,而婚姻状况、毕业学校、籍贯和健康状况是可输可不输的信息且大多数情况下不需要录入,如何为信息录入人员提供一个方便的输入接口,下面我们就针对这个问题提供一个我认为比较好的方法。

  第一步:在VC编程环境下建立一个基于对话框的工程,工程名为ExpandDlg,所有的选项都取默认值。

  第二步:建立我们都对话框,其中必须要有这样两个控件,一个是PICTURE控件,一个为按钮,其ID值分别为IDC_DIVIDER和IDC_MORE。其它的控件可以任意布局,最终结果就是对话框被IDC_DIVIDER控件分成了两部分,其中下半部分可以根据你的爱好动态显示或不显示,对话框如下图:

  第三步:生成按钮IDC_MORE的消息映射函数OnMore,在ExpandDlgDlg.h中定义两个函数如下:

public:
void EnableVisibleChildren();
void ExpandDialog (int nResourceID, BOOL bExpand); 

  第四步:在ExpandDlgDlg.cpp中定义函数的实现代码如下:

void CExpandDlgDlg::ExpandDialog (int nResourceID, BOOL bExpand)
{
      // 对话框被nResourceID分成上下......

阅读全文(274) | 评论:0

用VC实现小型矢量图形系统的开发(2006-09-24 12:39:00)

摘要: 用VC实现小型矢量图形系统的开发(上) 来自未知  作者曹勇刚          
  大家学习了VC的MFC的一些基础知识后,如果能用VC开发一个比较实用的软件,对熟悉VC各方面编程和面向对象的软件设计和开发都是很有帮助的。

  本文旨在通过对一个作者自己开发的小型矢量图形系统全面讲述而达到让读者了解一个小软件从设计到实现的阶段的解决的问题。同时也从界面和功能上对MFC和Windows系统功能的挖掘,同样,对于学习计算机图形学的读者,也可以看到本文有很多对图形学算法和实现的有益探讨。

  一. 功能和界面设计

  首先,让大家对一个本软件功能的大概了解。当你着手开发一个软件时,首先要解决的当然是本软件的功能(软件工程常称作用例,具体概念可以参考有关资料,不妨简单理解为用户使用它能完成哪些工作)。由于写这篇文章时,本软件已经具有比较完整的原型。我们可以结合它的界面(图1)来介绍软件设计的过程。


图 1 软件界面
            
  可以看到,本软件是实现了一个绘图功能的子集。最初就确定了开发环境为VC6.0,界面采用IE风格。在使用上为了给用户最大的便利,采用了三种工具条(普通文件、打印操作等标准工具,对图形对象属性设置的工具条式对话框,带文字说明的大按钮式可浮动或任意船坞- Dock定位的绘图工具条)。

  操作上采用左键点击建立图形对象起始点,移动动态调整图形大小和位置(随手画采用按住左键拖动的方式,再次点击左键确定位置,右键取消操作,双击确定(结束)多步图形对象(如多边形)的绘制。在功能设计方面基本符合一般图形软件的惯例,但出于作者的便利和保护鼠标的考虑,整个功能体现了基本无需按住左键拖动的思想。这也是很容易让人接受的,因为即便习惯拖动的用户拖动时也会产生位置调整,只是释放后还是出于拖动状态,再次点击或双击才最终确定。

  功能上选择了画线、框、圆、多边形、立体、文字、曲线、填充以及删除的功能,根据是否填充和光照又增加了几个类别,填充方式根据图形学的概念提供了两种方式(以后介绍)。根据对图形属性取了线宽......

阅读全文(422) | 评论:0

谈谈MFC中的消息映射(2006-09-24 12:36:00)

摘要: 谈谈MFC中的消息映射  来自yesky  作者向桢          
  引言:

  众所周知,windows是基于消息驱动的,作好消息处理是WINDOWS编程的关键任务之一,用VC制作WINDOWS程式同样离不开消息的处理。虽然VC++6的类向导可以完成绝大部分工作,但不幸的是,它并不能完成所有的工作。这就要求我们对 VC中消息的处理有一个比较清淅的认识。只有这样才可能在必要的时候亲自动手完成一些复杂的消息映射处理。

  在MFC中消息是通过一种所谓的消息映射机制来处理的。其实质是一张消息及其处理函数的一一对应表以及分析处理这张表的应用框架内部的一些程序代码.这样的好处是可以避免像早期的SDK编程一样需要罗列一大堆的CASE语句来处理各种消息.由于不同种类的消息其处理方法是不同的,所以我们有必要先弄清楚 WINDOWS消息的种类。 

  背景:

  WINDOWS 消息的种类

  WINDOWS中消息主要有以下三种类型:

  1、标准的WINDOWS消息:这类消息是以WM_为前缀,不过WM_COMMAND例外。 例如: WM_MOVE、WM_QUIT等.

  2、命令消息:命令消息以WM_COMMAND为消息名.在消息中含有命令的标志符ID,以区分具体的命令.由菜单,工具栏等命令接口对象产生.

  3、控件通知消息:控件通知消息也是以WM_COMMAND为消息名.由编辑框,列表框,子窗口发送给父窗口的通知消息.在消息中包含控件通知码.以区分具体控件的通知消息.

  其中标准的WINDOWS消息及控件通知消息主要由窗口类即直接或间接由CWND类派生类处理.相对标准WINDOWS消息及控件通知消息而言,命令消息的处理对象范围就广得多.它不仅可以由窗口类处理,还可以由文档类,文档模板类及应用类所处理。
 
  方法:

  不同种类消息的映射方法。

  在以上三种消息中,标准的WINDOW......

阅读全文(262) | 评论:0

用Visual C++中实现混合分割视图(2006-09-24 12:34:00)

摘要: 用Visual C++中实现混合分割视图 来自yesky  作者寇欣宇          

  在图像处理等多窗口应用程序中,通常要在屏幕上同时显示若干个窗口,以显示进行图像处理前和处理后的图像信息,或者在每个窗口中分别显示图像的细节和概貌。为了实现上述功能,可以采用MDI的多文档模式进行处理,但是多文档的程序设计和维护相对单文档应用程序而言相对复杂,而且如果要在屏幕上同时显示窗口,通常要调用窗口重叠函数进行管理,窗口的位置也往往需要用鼠标人为设定,过多的人为干预也降低了程序使用的效率。因此,对于某些应用程序,如果能够用分割视图来实现屏幕绘图和显示,无疑会降低程序使用者的操作强度,显示更加直观和方便。

  本文介绍了一种混合分割视图的实现方法,即在Visual C++中,同时出现基于CView类的普通视图和基于CFormView类的窗体视图,且视图之间存在着二次(或多次)再分割,即视窗里面又包含视窗,如图所示为要涉设计的界面形式。



  界面内共含有一个框架和五个视窗,视窗Left、视窗Right、视窗Zoom、视窗Control和视窗 Info。视窗Left、 Right和 Zoom分别显示左右图像窗口的图像和经过高倍放大后的图像,这几个视窗的基类都是CView;视窗Control用来 进行仪器控制和图像操作,视窗Info用来显示系统的当前信息和工作进程和状态,这两个视窗都从CFormView派生出来。
为了实现上述功能,首先用AppWizard生成一单文档应用程序,并自定义生成的默认视类为CZoomView,用来显放大的图像。

  接下来,通过如下步骤,创建另外四个视窗:

   1、用ClassWizard为应用程序创建一个新类CFixedSplitter,基类为CMDIChildWnd,然后在该类中将所有CMDIChildWnd的地方替换为CsplitterWnd(因为ClassWizard不支持直接从CsplitterWnd类派生子类);

  2、在CMainFrame类里声明分割视图的变量:
CFixedSpl......

阅读全文(2718) | 评论:0

制作系统托盘程序 VC(2006-09-24 12:32:00)

摘要:其实,在任务条上添加托盘比较容易实现,调用VC中的函数就可以解决,只是注意协调。接下来,我将给大家提供一个类,可以很容易的达到我们的目的,希望它能给大家一点帮助,如果你发现BUG也欢迎你和我联系。运行程序,左键双击或者右键单击任务条上的托盘,我们可以看到效果。

  1. 有关类CsystemTray的说明:(文章的最后有本类的具体实现代码)

  CSystemTray是CObject的扩展类,实现以下功能:

   1、在任务条显示托盘图标。

   2、设置提示Tip

   3、设置图标的形状 

  主要函数说明:

Create(CWnd* pWnd, UINT uCallbackMessage, LPCTSTR szTip, HICON icon, UINT uID); 

  功能:

   生成一个图标。 

  参数说明:

   pWnd:程序的主窗口,

   uCallbackMessage:对应的消息映射,

   szTip:鼠标停留时的提示文字,

   icon:显示的图标,

   uID:与之对应的菜单ID

  · BOOL CSystemTray::SetIcon(HICON hIcon) 

    BOOL CSystemTray::SetIcon(LPCTSTR lpszIconName)

    BOOL CSystemTray::SetIcon(UINT nIDResource)

    BOOL CSystemTray::SetStandardIcon(LPCTSTR lpIconName)

    BOOL CSystemTray::SetStandardIcon(UINT nIDRe......

阅读全文(2932) | 评论:0

在VC++ 6.0下利用共享内存、消息实现内部进程通讯(2006-09-24 12:17:00)

摘要:在VC++ 6.0下利用共享内存、消息实现内部进程通讯                                                                 张中军  张忠英 关键词: 共享内存、WINDOWS用户自定义消息、同步、同机通讯 摘 要: 通过实例,介绍了如何利用共享内存方式和windows自定义消息实现两个进程的同机通讯 一、 引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换. 内部进程间通讯(即:同机通讯)和数据交换有多种方式:消息、共享内存、匿名(命名)管道、邮槽、Windows套接字等多种技术。“共享内存”(shared memory)可以定义为对一个以上的进程是可见的内存或存在于多个进程的虚拟地址空间。例如:如果两个进程使用相同的DLL,只把DLL的代码页装入内存一次,其他所有映射这个DLL的进程只要共享这些代码页就可以了;利用消息机制实现IPC虽然有交换的数据量小、携带的信息少等缺点,但由于其实现方便、应用灵活而广泛应用于无须大量、频繁数据交换的内部进程通讯系统之中。本文通过共享内存实现进程间的数据交换,利用windows消息机制实现进程间的同步,两种机制结合使用,不仅解决了交换数据量小的问题,还解决了进程并发存取数据的问题。 二、 同机进程间共享内存的实现 采用内存映射文件实现WIN32进程间的通讯:Window......

阅读全文(5566) | 评论:0

应用程序之间互相通讯的几种方法 (2006-09-24 12:12:00)

摘要:  应用程序之间互相通讯的几种方法   沈炜 应用程序之间的数据交换(互相通讯)一直是困扰广大程序员的难题,尽管已经出现了各式各样的解决方案,但迄今为止没有哪一种方案是完美无缺的。因此,只有学习并了解了它们的优缺点后,才能在特定的情况下选择最佳方案,以满足最终的要求。   1、共享   在硬盘上建立一个文件,一个应用程序往该文件里写数据(可以不关闭文件,但必须刷新缓冲区),另一个应用程序以共享方式打开这个文件并读取其中的内容,这便是最简单的一种数据交换方式。对于网络用户而言,只要两台终端上安装的都是Win311 For Workgroup或Windows 95(或NT),则只要设置一下目录共享,映射成网络驱动器,同样可以简单地实现数据交换。但它的缺点也是显而易见的:只能采取轮询的方式获得最新数据(效率低下),网络映射的驱动器绝对不能变动或取消(可靠性差),所以这是一种“低级”的通讯方式。   2、DDE   每个Windows程序员都不会对DDE(动态数据交换)感到陌生,它是最早的基于Windows的数据交换方法,有三种方式可供选择:冷连接、温连接和热连接。一般都是由客户端向服务器端发出连接申请,并且必须指明服务器端的名字和标题。在连接建立后,数据可以双向流动。典型的例子如抓图软件SnagIt,它提供了DDE接口,能够让其它应用程序来控制它。DDE是完全向后兼容的,从16位平台转到32位,源代码几乎不用修改。   DDE还有网络功能。使用过Win311 For Workgroup的人大概都还记得,它自带一个非常吸引人的小程序“Chat”,能使两台计算机通过网络实时交谈,这在当时几乎是一项创举。可是很少有人知道“Chat”使用的是一种特殊的DDE,即NetDDE。它的基本工作原理仍然是DDE,但它能使一台计算机向在同一个网络中的另一台终端发消息,而不像普通DDE 只能局限在同一台机器上。与其它的数据交换方式相比,DDE已不够先进,而且Microsoft也不再积极支持DDE,所以它的前景不被看好。   3、WM_COPYDATA   Windows消息WM_COPYDATA功能强大,知之者却甚少。它的确切定义是:一个应用程序向另一个应用程序传递数据时所发出的消息。众所周知,Windows 在很大程度上依赖于消息机制,那么我......

阅读全文(1552) | 评论:0

VC++中用内存映射文件(2006-09-24 12:08:00)

摘要:VC++中用内存映射文件
2000-01-30· 粟利民·电脑报   在软件的开发过程中,有时需要控制一些程序使他们不能同时运行,也就是多个程序间互斥运行(还包括禁止同一程序运行多个实例)。针对这一问题,我们在Visual C++6.0中利用内存映射文件实现了多个程序间的互斥运行。内存映射文件可以创建一个没有和磁盘文件相联系的内存对象,将文件的信息映射到一个进程的地址空间上,我们可以访问该文件中的数据,就如同它位于内存中一样。同时,在程序设计中可以给内存映射文件对象起一个名字,这个名字在整个系统中是唯一的,这个名字可以在多个进程之间共享,通过名字共享能实现进行信息交换,进而实现多个程序间的互斥运行。 在讲述具体的编程方法之前,让我们先介绍和内存映射文件操作有关的几个重要的函 CreateFileMapping的函数为指定的文件创建一个文件映射对象,该函数的原形如下: HANDLE CreateFileMapping(HANDLE hFile,//用于映射的文件句柄 LPSECURITY?ATTRIBUTES FileMappingAttributes,//内存映射文件的安全描述符 DWORD Flprotect,//文件映射对象的最大长度的高32位 DWORD dwMaximumSizelow,//最大长度的低32位 LPCTSTR IPNAME//指定这个内存映射文件的名字) 值得注意的是,参数如果是OXFFFFFFFF,将在操作系统虚拟内存页面替换文件中创建文件映射对象,而不是使用磁盘文件,同时必须给出这个映射对象的大小。 NAO VUEWIFFILE函数将文件的视图映射到一个进程地址空间上,返回LPVOID类型的内存指针。通过它,就可以直接访问文件视图中的信息。 LPVOID MAP VIEWLFFILE(HANDLE HFILEMAPPINGOBUCT,//映射文件对象句柄 DWORD DWDESIREDACCESS,//访问模式 DWORD DWFILEOFFSETHIGH,//文件偏移地址的高32位 DWORD DWFILEOFFSETHIGH,//文件偏移地址的低32位 DWORD DWNUMBEROFBYTESTOMAP//映射视图的大小) 在Visual c++6.0中我们用默认方式生成基于对话框的应用程序,......

阅读全文(198) | 评论:0