You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

689 lines
14 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// FastLookUpDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "FastLookUpDlg.h"
#include "afxdialogex.h"
#include "GlobalFunc.h"
#include "CvvImage.h"
#include "ImgShowDlg.h"
// CFastLookUpDlg 对话框
IMPLEMENT_DYNAMIC(CFastLookUpDlg, CDialogEx)
CFastLookUpDlg::CFastLookUpDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CFastLookUpDlg::IDD, pParent)
{
m_SrcFrame = nullptr;
m_iPage = 0;
m_ptrParent = nullptr;
}
CFastLookUpDlg::~CFastLookUpDlg()
{
m_ptrParent = nullptr;
// 情报队列销毁
if(m_ImgStruDeque.size() > 0)
{
for (size_t i = 0; i < m_ImgStruDeque.size(); i++)
{
SAFE_DELETE_ARRAY(m_ImgStruDeque[i].buff);
}
m_ImgStruDeque.clear();
}
if (m_SrcFrame != NULL)
{
cvReleaseImage(&m_SrcFrame);
m_SrcFrame = NULL;
}
}
void CFastLookUpDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFastLookUpDlg, CDialogEx)
ON_BN_CLICKED(IDC_BTN_PRE_PAGE, &CFastLookUpDlg::OnBnClickedBtnPrePage)
ON_BN_CLICKED(IDC_BTN_NEXT_PAGE, &CFastLookUpDlg::OnBnClickedBtnNextPage)
ON_WM_PAINT()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
// CFastLookUpDlg 消息处理程序
void CFastLookUpDlg::SetParentPt(void *pt)
{
m_ptrParent = pt;
}
// 设置图像数据
void CFastLookUpDlg::SetImgData(const ImgStru &img)
{
if(m_ImgStruDeque.size() >= 18)
{
std::deque<ImgStru>::iterator iter; // 定义迭代器
iter = m_ImgStruDeque.begin();
// 释放指针指向的内存
SAFE_DELETE_ARRAY(iter->buff);
iter->buff = NULL;
// 弹出
m_ImgStruDeque.pop_front();
}
// 入队列
ImgStru local; // 局部变量
CloneImgStru(img, local); // 深度复制
m_ImgStruDeque.push_back(local); // 入队,浅复制
// 从而使local中已入队的结构体成为野指针
local.buff = NULL;
return;
}
// 显示图像数据
int CFastLookUpDlg::ShowImgData()
{
if (m_ImgStruDeque.empty() == true)
{
return 0;
}
int showCount = 0;
// 当图像小于9张时一律在第1面显示
if (m_ImgStruDeque.size() <= 9)
{
m_iPage = 0;
}
if (m_iPage == 0)
{
if (m_ImgStruDeque.size() >= 9)
{
showCount = 9;
}
else
{
showCount = m_ImgStruDeque.size();
}
for (int i = 0; i < showCount; i++)
{
// 显示图像
showOneImg(i, m_ImgStruDeque[i]);
}
GetDlgItem(IDC_STATIC_ORDER1)->SetWindowText("1");
GetDlgItem(IDC_STATIC_ORDER2)->SetWindowText("2");
GetDlgItem(IDC_STATIC_ORDER3)->SetWindowText("3");
GetDlgItem(IDC_STATIC_ORDER4)->SetWindowText("4");
GetDlgItem(IDC_STATIC_ORDER5)->SetWindowText("5");
GetDlgItem(IDC_STATIC_ORDER6)->SetWindowText("6");
GetDlgItem(IDC_STATIC_ORDER7)->SetWindowText("7");
GetDlgItem(IDC_STATIC_ORDER8)->SetWindowText("8");
GetDlgItem(IDC_STATIC_ORDER9)->SetWindowText("9");
}
else
if (m_iPage == 1)
{
if (m_ImgStruDeque.size() > 9)
{
showCount = m_ImgStruDeque.size() - 9;
for (size_t i = 9; i < m_ImgStruDeque.size(); i++)
{
// 显示图像
showOneImg(i, m_ImgStruDeque[i]);
}
GetDlgItem(IDC_STATIC_ORDER1)->SetWindowText("10");
GetDlgItem(IDC_STATIC_ORDER2)->SetWindowText("11");
GetDlgItem(IDC_STATIC_ORDER3)->SetWindowText("12");
GetDlgItem(IDC_STATIC_ORDER4)->SetWindowText("13");
GetDlgItem(IDC_STATIC_ORDER5)->SetWindowText("14");
GetDlgItem(IDC_STATIC_ORDER6)->SetWindowText("15");
GetDlgItem(IDC_STATIC_ORDER7)->SetWindowText("16");
GetDlgItem(IDC_STATIC_ORDER8)->SetWindowText("17");
GetDlgItem(IDC_STATIC_ORDER9)->SetWindowText("18");
}
}
return showCount;
}
// 显示一幅图像
void CFastLookUpDlg::showOneImg(int IDtag, const ImgStru &imgStru)
{
if (IDtag < 0 || IDtag > 17)
{
return;
}
int nID = 0;
switch(IDtag)
{
case 0:
case 9:
nID = IDC_STATIC_IMG1;
break;
case 1:
case 10:
nID = IDC_STATIC_IMG2;
break;
case 2:
case 11:
nID = IDC_STATIC_IMG3;
break;
case 3:
case 12:
nID = IDC_STATIC_IMG4;
break;
case 4:
case 13:
nID = IDC_STATIC_IMG5;
break;
case 5:
case 14:
nID = IDC_STATIC_IMG6;
break;
case 6:
case 15:
nID = IDC_STATIC_IMG7;
break;
case 7:
case 16:
nID = IDC_STATIC_IMG8;
break;
case 8:
case 17:
nID = IDC_STATIC_IMG9;
break;
default:
break;
}
int imgWidth = imgStru.ImgWidth;
int imgHeight = imgStru.ImgHeight;
int nBitCount = imgStru.bitcount;
// 步长每行像素所占字节数必须扩展成4的倍数
int lineByte = (imgWidth * nBitCount / 8 + 3) / 4 * 4;
// 位图数据缓冲区的大小,即图像大小
unsigned int imgBufSize = static_cast<unsigned int>(imgHeight * lineByte);
if (imgWidth > 0
&& imgHeight > 0
&& imgStru.buff != NULL
&& (nBitCount == 8 || nBitCount == 24))
{
// 将图像数据转换到 m_SrcFrame 再显示
if (m_SrcFrame != NULL) // 如果有图像
{
// 情况1如果图像属性没有变化 直接更换原始图像数据即可,即复制图像数据,不需要再去创建一幅图像
// 情况2如果图像属性发生了变化需要先释放图像再创建图像
// 情况1
if ((m_SrcFrame->width == imgWidth) &&
(m_SrcFrame->height == imgHeight) &&
(m_SrcFrame->depth * m_SrcFrame->nChannels == nBitCount) )
{
// 内存复制机制
int RealLineByte = (imgWidth * nBitCount / 8);
if (RealLineByte == lineByte)
{
memcpy(m_SrcFrame->imageData, imgStru.buff, imgBufSize); // 图像数据复制
}
else
{
for (int i = 0; i < imgHeight; i++)
{
memcpy(m_SrcFrame->imageData + i * lineByte, imgStru.buff + i * RealLineByte, RealLineByte);
}
}
}
else // 情况2
{
// 释放图像
cvReleaseImage(&m_SrcFrame);
m_SrcFrame = NULL;
// 创建
m_SrcFrame = cvCreateImage(cvSize(imgWidth, imgHeight), 8, nBitCount/8); // 创建图像
if (m_SrcFrame != NULL) // 创建成功
{
// 内存复制机制
int RealLineByte = (imgWidth * nBitCount / 8);
if (RealLineByte == lineByte)
{
memcpy(m_SrcFrame->imageData, imgStru.buff, imgBufSize); // 图像数据复制
}
else
{
for (int i = 0; i < imgHeight; i++)
{
memcpy(m_SrcFrame->imageData + i * lineByte, imgStru.buff + i * RealLineByte, RealLineByte);
}
}
}
else
{
return;
}
}
}
else // 如果没有图像 需要先创建图像
{
m_SrcFrame = cvCreateImage(cvSize(imgWidth, imgHeight), 8, nBitCount/8); // 创建图像
if (m_SrcFrame != NULL) // 创建成功
{
// 内存复制机制
int RealLineByte = (imgWidth * nBitCount / 8);
if (RealLineByte == lineByte)
{
memcpy(m_SrcFrame->imageData, imgStru.buff, imgBufSize); // 图像数据复制
}
else
{
for (int i = 0; i < imgHeight; i++)
{
memcpy(m_SrcFrame->imageData + i * lineByte, imgStru.buff + i * RealLineByte, RealLineByte);
}
}
}
else
{
return;
}
}
// 显示图像
// 获得 pictrue 控件窗口的句柄
CWnd *pWnd = NULL;
pWnd = GetDlgItem(nID);
// 后面程序无需再判定
if (pWnd == NULL)
{
return;
}
// 获取图像控件HDC
CDC *pDC = NULL; // 函数退出时需要释放 ReleaseDC(pDC);
pDC = pWnd->GetDC();
// 后面程序无需再判定
if (pDC == NULL)
{
return;
}
HDC hdc = NULL;
hdc = pDC->GetSafeHdc();
if (hdc == NULL)
{
return;
}
// 当前图像尺寸
int imgWidth = m_SrcFrame->width;
int imgHeight = m_SrcFrame->height;
// 显示图像
IplImage* fitSizeImg = NULL;
// 显示图像尺寸
int fitSizeImgWidth = 0;
int fitSizeImgHeight = 0;
CRect rect;
pWnd->GetClientRect(&rect);
int PicCtrlWidth = rect.Width();
int PicCtrlHeight = rect.Height();
// 图像尺寸小于窗口尺寸
if ((imgWidth <= PicCtrlWidth) && (imgHeight <= PicCtrlHeight))
{
// 拉伸图像
double Ratio = 1.0;
double Ratio_Width = static_cast<double>(PicCtrlWidth) / static_cast<double>(imgWidth);
double Ratio_Height = static_cast<double>(PicCtrlHeight) / static_cast<double>(imgHeight);
Ratio = (Ratio_Width < Ratio_Height) ? Ratio_Width : Ratio_Height; // Ratio 大于 1
// 显示图像尺寸
fitSizeImgWidth = static_cast<int>(imgWidth * Ratio + 0.5);
fitSizeImgHeight = static_cast<int>(imgHeight * Ratio + 0.5);
}
else
{
// 压缩图像
double Ratio = 1.0;
double Ratio_Img = static_cast<double>(imgWidth) / static_cast<double>(imgHeight);
double Ratio_ClientRect = static_cast<double>(PicCtrlWidth) / static_cast<double>(PicCtrlHeight);
// 计算比例系数
if ( Ratio_Img > Ratio_ClientRect )
{
Ratio = static_cast<double>(PicCtrlWidth) / static_cast<double>(imgWidth); // Ratio 小于 1
}
else
{
Ratio = static_cast<double>(PicCtrlHeight) / static_cast<double>(imgHeight); // Ratio 小于 1
}
// 显示图像尺寸
fitSizeImgWidth = static_cast<int>(imgWidth * Ratio + 0.5);
fitSizeImgHeight = static_cast<int>(imgHeight * Ratio + 0.5);
}
// 最低尺寸判断,小于一个像素时直接返回
if(min(fitSizeImgWidth, fitSizeImgHeight) <= 1)
{
// 释放
ReleaseDC(pDC);
return;
}
// 创建fitSizeImg
fitSizeImg = cvCreateImage(cvSize(fitSizeImgWidth, fitSizeImgHeight), m_SrcFrame->depth, m_SrcFrame->nChannels);
if (fitSizeImg == NULL)
{
return;
}
// 改变图像尺寸
cvResize(m_SrcFrame, fitSizeImg);
// 为使显示界面不闪烁 增加中间变量 边界充满黑色
IplImage* fillblackImg = NULL;
fillblackImg = cvCreateImage(cvSize(PicCtrlWidth, PicCtrlHeight), fitSizeImg->depth, fitSizeImg->nChannels);
if (fillblackImg != NULL)
{
cvZero(fillblackImg); // 清零
}
else
{
// 释放缩放后图像
cvReleaseImage(&fitSizeImg);
fitSizeImg = NULL;
// 释放pdc
ReleaseDC(pDC);
return;
}
// 左上 起始点
CPoint LeftUp;
LeftUp.x = static_cast<int>((PicCtrlWidth - fitSizeImgWidth)/2);
LeftUp.y = static_cast<int>((PicCtrlHeight - fitSizeImgHeight)/2);
cvSetImageROI(fillblackImg, cvRect(static_cast<int>(LeftUp.x), static_cast<int>(LeftUp.y), fitSizeImgWidth, fitSizeImgHeight));
cvAdd(fillblackImg, fitSizeImg, fillblackImg);
cvResetImageROI( fillblackImg );
// 绘图
CvvImage img;
img.CopyOf(fillblackImg);
img.Show(hdc, 0, 0, fillblackImg->width, fillblackImg->height);
// 释放fitSizeImg
cvReleaseImage(&fitSizeImg);
fitSizeImg = NULL;
// 释放fillblackImg
cvReleaseImage(&fillblackImg);
fillblackImg = NULL;
// 释放
ReleaseDC(pDC);
pDC = NULL;
}
return;
}
// 向前翻页
void CFastLookUpDlg::OnBnClickedBtnPrePage()
{
// TODO: 在此添加控件通知处理程序代码
if (m_iPage == 0)
{
return;
}
else
{
m_iPage = 0;
ShowImgData();
}
}
// 向后翻页
void CFastLookUpDlg::OnBnClickedBtnNextPage()
{
if (m_iPage == 1)
{
return;
}
else
{
m_iPage = 1;
ShowImgData();
}
}
void CFastLookUpDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialogEx::OnPaint()
ShowImgData();
}
BOOL CFastLookUpDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
CRect rect;
GetDlgItem(IDC_STATIC_IMG1)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[0] = rect;
GetDlgItem(IDC_STATIC_IMG2)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[1] = rect;
GetDlgItem(IDC_STATIC_IMG3)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[2] = rect;
GetDlgItem(IDC_STATIC_IMG4)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[3] = rect;
GetDlgItem(IDC_STATIC_IMG5)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[4] = rect;
GetDlgItem(IDC_STATIC_IMG6)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[5] = rect;
GetDlgItem(IDC_STATIC_IMG7)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[6] = rect;
GetDlgItem(IDC_STATIC_IMG8)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[7] = rect;
GetDlgItem(IDC_STATIC_IMG9)->GetWindowRect(&rect);
ScreenToClient(&rect);
m_picCtrlRect[8] = rect;
m_bFastLookUpLeft.SubclassDlgItem(IDC_BTN_PRE_PAGE, this);
m_bFastLookUpLeft.SetIcon(IDI_ICON_LEFT);
m_bFastLookUpLeft.SetTooltipText("上一页");
m_bFastLookUpRight.SubclassDlgItem(IDC_BTN_NEXT_PAGE, this);
m_bFastLookUpRight.SetIcon(IDI_ICON_RIGHT);
m_bFastLookUpRight.SetTooltipText("下一页");
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
// 判断一个点是否在矩形框内
bool CFastLookUpDlg::pointRectTest(CPoint pt, CRect rect)
{
if (pt.x >= rect.left && pt.x <= rect.right
&& pt.y >= rect.top && pt.y <= rect.bottom)
{
return true;
}
else
{
return false;
}
}
void CFastLookUpDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int i = 0;
if (true == pointRectTest(point, m_picCtrlRect[0]))
{
i = 1;
}
else if (true == pointRectTest(point, m_picCtrlRect[1]))
{
i = 2;
}
else if (true == pointRectTest(point, m_picCtrlRect[2]))
{
i = 3;
}
else if (true == pointRectTest(point, m_picCtrlRect[3]))
{
i = 4;
}
else if (true == pointRectTest(point, m_picCtrlRect[4]))
{
i = 5;
}
else if (true == pointRectTest(point, m_picCtrlRect[5]))
{
i = 6;
}
else if (true == pointRectTest(point, m_picCtrlRect[6]))
{
i = 7;
}
else if (true == pointRectTest(point, m_picCtrlRect[7]))
{
i = 8;
}
else if (true == pointRectTest(point, m_picCtrlRect[8]))
{
i = 9;
}
else
{
i = 0;
}
if (i >= 1 && i <= 9 && m_iPage == 1)
{
i = i + 9;
}
if (m_ptrParent != nullptr)
{
CImgShowDlg *pt = nullptr;
pt = reinterpret_cast<CImgShowDlg*>(m_ptrParent);
if (pt != nullptr)
{
pt->ShowSelectedImgInMem(i);
}
}
CDialogEx::OnLButtonDblClk(nFlags, point);
}
// 清理内存记忆
void CFastLookUpDlg::ClearMemory()
{
try
{
// 如果有图像 需要释放该图像
if (m_SrcFrame != NULL)
{
cvReleaseImage(&m_SrcFrame);
m_SrcFrame = NULL;
}
// 情报队列销毁
if(m_ImgStruDeque.size() > 0)
{
for (size_t i = 0; i < m_ImgStruDeque.size(); ++i)
{
SAFE_DELETE_ARRAY(m_ImgStruDeque[i].buff);
}
m_ImgStruDeque.clear();
}
// 使窗口无效
if (this->GetSafeHwnd() != NULL)
{
Invalidate();
}
}
catch(cv::Exception &e)
{
e.msg;
return;
}
catch(...)
{
return;
}
}
// 是否有记忆图像
bool CFastLookUpDlg::isEmpty()
{
return m_ImgStruDeque.empty();
}