简介
本文参照VisionMaster的流程编辑器,粗略介绍了本小组如何基于矩阵坐标变换,实现一个拥有局部显示区域和全局缩略显示区域的流程编辑器框架。图1展示了该流程编辑器的界面布局。

设计思路
全局区域内存申请
在Windows GDI环境下,待渲染的图像通常以位图的形式存储于内存中。为了实现局部显示和缩略图功能,首先需要分配一块足够大的内存区域,用于存储整个编辑器的绘制内容。
/*
* 定义背景画布信息
*/
#define BKWIDTH 1440
#define BKHEIGHT 2560
#define BKCELLSIZE 20
//创建DC和CBitmap,并选入CBitmap
CBitmap* m_memBitmap = new CBitmap();
CDC* m_memCDC = new CDC();
m_memCDC->CreateCompatibleDC(clientDC);
m_memBitmap->CreateCompatibleBitmap(clientDC, BKWIDTH, BKHEIGHT);
CBitmap* m_mOldBitmap = m_memCDC->SelectObject(m_memBitmap);
局部窗口移动与事件转换
以移动窗口和点击模块为例,以下内容描述了如何实现坐标转换和事件处理。
窗口移动
在本小组设计的流程编辑器中,基于矩阵的坐标变换是实现窗口移动的关键技术。由于不涉及坐标系的旋转,仅涉及平移操作,因此实现起来相对简单。如图2所示,展示了窗口坐标系与内存坐标系之间的转换关系。仅需调整转换矩阵T的第三列值,可以方便地实现局部显示窗口的移动。

//创建画布DC和CBitmap,并选入CBitmap
CBitmap* m_dispBitmap = new CBitmap();
CDC* m_dispDC = new CDC();
m_dispDC->CreateCompatibleDC(clientDC);
m_dispBitmap->CreateCompatibleBitmap(clientDC, m_wndWidth, m_wndHeight);
CBitmap* m_dOldBitmap = m_dispDC->SelectObject(m_dispBitmap);
//根据实时转换矩阵将内存画面渲染至画布DC
//m_cTransformer为专门用来计算、保存坐标变换值的类
m_dispDC->BitBlt(0, 0, m_pDisplyWH->x, m_pDisplyWH->y, m_memDCManager->GetDC(), m_cTransformer->m_pInGlobal.left, m_cTransformer->m_pInGlobal.top, SRCCOPY);
模块点击
在窗口区域产生鼠标点击事件时,需判断是否点击了模块,由于Windows的API所获取的坐标是相对于窗口的,因此需要转换到内存坐标中以判断是否点击中模块,同上,只需求解窗口坐标系到内存坐标系的转换矩阵即可完成坐标转换。
//将基于窗口的坐标转换到内存的坐标
m_cTransformer->wnd2mem(currentPoint);
/判断是否点击到模块上
if (m_memDCManager->SetClickModule(currentPoint)) {
//具体事件实现...
}
全局缩放区域实现
通过定义一个固定矩阵,并设置好缩放比例,就可以实现全局区域的缩放显示。如图3所示,展示了缩放区域显示的效果。

/*
* 定义全局缩略区域相当于窗口区域的位置
*/
#define THUMBWIDTH 288
#define THUMBHEIGHT 512
#define RIGHTLIMIT 10 //距离右边界的距离
#define BOTTOMLIMIT 10 //距离下边界的距离
//将全局缩放到THUMBWIDTH * THUMBHEIGHT
m_thumbCDC->StretchBlt(0, 0, THUMBWIDTH, THUMBHEIGHT, memDC, 0, 0, BKWIDTH, BKHEIGHT, SRCCOPY);
//绘制银灰色边界
m_thumbCDC->SelectObject(m_grayPen);
m_thumbCDC->Rectangle(CRect(0, 0, THUMBWIDTH, THUMBHEIGHT));
//绘制窗口区域相对于全局区域的位置
m_thumbCDC->SelectObject(m_orangePen);
m_thumbCDC->Rectangle(m_cTransformer->m_pInThumb);
//把thumbDC拷贝到dispDC上
m_dispDC->BitBlt(m_cTransformer->m_thumb2wnd(0, 2), m_cTransformer->m_thumb2wnd(1, 2), THUMBWIDTH, THUMBHEIGHT, m_thumbDCManager->GetDC(), 0, 0, SRCCOPY);
总结
在本小组的开发过程中,基于矩阵变换实现一个拥有局部显示区域和全局缩略显示区域的流程编辑器框架在逻辑上更容易理解。