system: [SYSTEM]

user: 2. 可视化雷达数据处理软件平台设计 基于可视化技术设计的雷达数据处理软件平台架构如图1所示，可以看出平台基于Visual C++ 2010集成环境开发，包含波形图和文本窗两个核心构件。波形图是一个以图形方式显示数据的窗口，在这个窗口中，用户可以对图形进行自由平移、水平缩放、竖直缩放、图形数据动态选择、图形数据查看等操作；文本窗是一个以文本形式显示、编辑和处理数据的窗口，在这个窗口中，用户借助于快捷菜单操纵数据。为进一步提高处理速度，波形图和文本窗都采用快速显示算法。在可视化显示和处理数据方面，波形图和文本窗各有侧重，各有所长，两者结合起来使用，可以充分发挥各自优势，提高数据处理速度 [ 3 ] [ 4 ] 。 此外，图1中的雷达数据处理软件平台架构还包含面向对象程序设计技术、命令消息分发机制、微软基础类库(Microsoft Foundation Class， MFC)、多文档界面技术(Multiple Document Interface， MDI)模块，它们的作用是充分利用现代软件开发理念及开发工具，提高开发效率。举例来说，一批雷达数据既可以波形图显示，又可以文本窗形式显示。再考虑用户同时处理多批雷达数据的情形，不难理解为提高软件开发效率，应该基于MFC采用MDI界面设计技术，以使不同批数据采用不同的波形图和文本窗来容纳。从具体实现角度来看，所有波形图和文本窗都属于同一类对象 [ 5 ] [ 6 ] [ 7 ] 。 图1. 可视化雷达数据处理软件平台架构 2.1. 设计实现波形图 波形图实际上包括显示波形数据或曲线的窗口及处理消息的窗口过程两部分。从面向对象程序设计的技术出发，创建波形图一般包括注册窗口类、创建窗口和实现窗口消息分发机制三个步骤。 2.1.1. 注册窗口类 每个显示雷达数据的波形图都是在特定的窗口类的基础上创建的，而每个窗口类在使用前必须在操作系统中注册。注册窗口类使用函数RegisterClassEx实现 [ 8 ] ： ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx)； 这里lpwcx为一指向WNDCLASSEX结构体的指针。若RegisterClassEx函数执行成功，返回值是一个唯一标识已经注册了的窗口类的原子(Atom)类；否则返回值将是0。 WNDCLASSEX结构体中包含了窗口类的信息，其定义如下： typedef struct_WNDCLASSEX { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCEhInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; } WNDCLASSEX， *PWNDCLASSEX; 下面分别介绍WNDCLASSEX结构中各个字段的含义。 cbSize：给出本结构体的以字节为单位的大小。 style：指定窗口类的风格。 lpfnWndProc：指向窗口过程的指针。 cbClsExtra、cbWndExtra：分别指定本窗口类后面、实例后面额外分配的字节数，系统会将这些字节的内容全部初始化为零。 hInstance：本类窗口实例的句柄。 hIcon：窗口类图标的句柄。 hCursor：窗口类光标的句柄。 hbrBackground：窗口类背景画刷的句柄。 lpszMenuName：指向一个以零字符结尾的字符串，该字符串代表了窗口类菜单的资源名。若lpszMenuName为NULL，那么本窗口类产生的窗口将没有默认菜单。 lpszClassName：指向一个以零字符结尾的字符串，该字符串代表了窗口类的类名。 hIconSm：代表一个与窗口类关联的小图标的句柄。 2.1.2. 创建窗口 注册窗口类完成后，接下来调用CreateWindowEx函数创建窗口，函数原型如下所示 [ 8 ] ： HWND CreateWindowEx(DWORD dwExStyle， LPCTSTR lpClassName， LPCTSTR lpWindowName， DWORD dwStyle， int x， int y， int nWidth， int nHeight， HWND hWndParent， HMENU hMenu， HINSTANCE hInstance， LPVOID lpParam); CreateWindowEx函数的参数较多，各个参数的含义简述如下。 dwExStyle：指定所创建窗口的扩展样式，具体样式参见文献 [ 8 ] 。 lpClassName、lpWindowName：二者均为指向以零字符结尾的字符串，两个字符串分别标识窗口类的类名和窗口的标题。 dwStyle：指定所创建窗口的风格。 x、y：指定窗口的最初位置。对于层叠式或弹出式窗口来说，它们分别表示屏幕坐标系中窗口左上角的x、y坐标；而对于子窗口来说，它们则分别表示窗口左上角相对于其父窗口客户区的x、y坐标。 nWidth、nHeight：以设备单位表示的窗口的宽度和高度。 hWndParent：指定父窗口的句柄。 hMenu：其含义取决于窗口风格，即对于层叠式或弹出式窗口指的是窗口的菜单句柄，对于子窗口指的则是子窗口标识符。 hInstance：窗口关联模块的实例句柄。 lpParam：窗口创建后，窗口过程将接收到WM_CREATE消息，该消息的LPARAM类型的参数是一个指向CREATESTRUCT类型结构体的指针，该结构体的LPVOID成员即等于此lpParam。若创建的是MDI的客户窗口，则lpParam为一指向CLIENTCREATESTRUCT结构体的指针。 若CreateWindowEx函数创建窗口能成功，则函数返回值是所创建的新窗口的句柄，否则返回值为NULL。 2.1.3. 实现窗口消息分发机制 创建波形图的第三步是实现窗口消息分发机制。波形图显示的可以是不同类型的雷达数据，如斜距、方位角、俯仰角、目标RCS等，所有这些波形图都属于同一个窗口类，即它们都是基于同一个窗口类创建的不同窗口。为了使各个波形图在功能上相互区分，互不干扰，最好的方法是使用面向对象程序设计技术，使每个波形图都关联到不同的类对象，比如关联到不同的CPlot对象上。这样一来，就需要把同一个窗口过程接收到的消息，按对应关系分发给不同的CPlot对象，使得每一个CPlot对象只关心和处理与自己有关的数据，不影响其它CPlot对象的数据处理过程，即实现窗口消息分发机制。 为了实现窗口消息分发机制，定义CPlot类如下： #include #include using namespace std; class CPlot { public: CPlot(HWND hwnd); virtual ~CPlot(); protected: HWNDm_hWnd; static vector >m_svpPlots; static LRESULT CALLBACK WndProc(HWND hwnd， UINT message， WPARAM wParam， LPARAM lParam); LRESULT_WndProc(UINT message， WPARAM wParam， LPARAM lParam); …… }; 上面的代码定义了一个C++类CPlot。它有一个HWND类型的成员变量m_hWnd，代表波形图窗口的句柄。每一个CPlot类对象都与唯一一个这样的句柄相对应，换句话说CPlot是波形图的封装类或包裹类。静态矢量型成员变量m_svpPlots用来维护所有CPlot对象。静态成员函数WndProc是波形图的窗口过程，它通过窗口消息分发机制将消息转发到成员函数_WndProc来处理，消息分发过程如图2所示。 图2中，程序开始运行、初始化后，进入消息等待阶段。一旦检索到窗口消息，即在m_svpPlots中寻找消息处理窗口句柄。若能找到对应的CPlot对象，就将消息转交给该对象处理，之后再次进入消息等待阶段。若在m_svpPlots中无法找到对应的包裹类对象，说明创建的是一个新窗口，需新建一个CPlot关联对象，并将消息交付该对象去处理，之后同样进入消息等待阶段。当软件平台主程序运行结束时，所有波形图窗口均已销毁，所有的CPlot对象则由CPlot类静态成员m_svpPlots负责销毁，释放所占据的资源 [ 9 ] [ 10 ] 。 图2. 波形图窗口的消息分发机制 2.2. 设计实现文本窗 文本窗的使用方式参见图3给出的例子，它以数据行的方式显示雷达数据。文本窗的设计实现过程类似于波形图，也包括注册窗口类、创建窗口和实现窗口消息分发机制三个步骤，为节省篇幅这些内容不再赘述。 为便于处理雷达数据中的目标号、绝对时、相对时、20 Hz计数、雷达状态码、斜距R、方位角A、俯仰角E、信噪比、RCS、AGC、斜距误差、方位角误差、俯仰角误差、雷达发射功率等数据，较好的作法是通过鼠标右键点击，利用弹出的快捷菜单提供的功能实现 [ 7 ] [ 8 ] 。使用快捷菜单时，程序执行流程涉及下述步骤： 1) 用户在文本窗的字段区即标题区按下鼠标右键； 2) 程序代码判断鼠标指针指向了哪种数据(用指针指向的数据列来区分)； 3) 弹出相应的快捷菜单，例如图3表示用户在R数据列上按下了鼠标右键； 4) 执行相应的菜单命令，完成诸如角度弧度互化、查看数据波形、查看数据差分波形等功能。 图3. 文本窗设计举例