背景:
一个动态生成条码输入编辑框的界面,编辑框内容输入达到指定长度后,焦点自动依次跳转到下一个编辑框,最后一个编辑框则自动跳转焦点到确认按钮
除非焦点在确认按钮,否则不响应回车键和退出键ESC的按下事件
对话框头文件
#pragma once
#include <vector>
// CDlgManualInputBarcodes 对话框
typedef struct _DUT_CTRL_ITEM
{
int index;
CPoint basePoint;
int ctrlxGap;
int ctrlyGap;
CStatic staticCtrl;
int staticWidth;
int staticHeight;
CEdit editCtrl;
int editWidth;
int editHeight;
explicit _DUT_CTRL_ITEM(int index, CPoint locatingPoint)
{
this->index = index;
this->basePoint = locatingPoint;
this->ctrlxGap = 3;
this->ctrlyGap = -3;
this->staticWidth = 50;
this->staticHeight = 25;
this->editWidth = 200;
this->editHeight = 30;
}
bool Create(CWnd* pParentWnd)
{
do
{
CRect staticRect;
staticRect.SetRect(basePoint.x, basePoint.y, basePoint.x + staticWidth, basePoint.y + staticHeight);
CString strText;
strText.Format("DUT%d:", index);
if (!staticCtrl.Create(strText, WS_CHILD | WS_VISIBLE, staticRect, pParentWnd, IDC_STATIC_BAR_DUT_BEGINT + index))
{
return false;
}
CRect editRect;
editRect.SetRect(staticRect.BottomRight().x + ctrlxGap, staticRect.TopLeft().y + ctrlyGap, staticRect.BottomRight().x + ctrlxGap + editWidth, staticRect.TopLeft().y + ctrlyGap + staticHeight);
if (!editCtrl.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP, editRect, pParentWnd, IDC_EDIT_BAR_DUT_BEGINT + index))
{
return false;
}
return true;
} while (false);
return false;
}
int GetEditCtrlID()
{
return IDC_EDIT_BAR_DUT_BEGINT + index;
}
int GetItemWidth()
{
return staticWidth + ctrlxGap + editWidth;
}
int GetItemHeight()
{
if (editHeight > staticWidth)
{
return editHeight;
}
else
{
return staticWidth;
}
}
}DUT_CTRL_ITEM, *pDUT_CTRL_ITEM;
class CDlgManualInputBarcodes : public CDialog
{
DECLARE_DYNAMIC(CDlgManualInputBarcodes)
public:
CDlgManualInputBarcodes(int dutCount, std::vector<CString>* outBarcodes, CWnd* pParent = nullptr); // 标准构造函数
virtual ~CDlgManualInputBarcodes();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG_BARCODES_INPUT };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual BOOL OnInitDialog();
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);
virtual BOOL PreTranslateMessage(MSG* pMsg);
DECLARE_MESSAGE_MAP()
private:
int m_dutCount;
std::vector<pDUT_CTRL_ITEM> m_dutCtrlLists;
std::vector<CString>* m_outDutBarcodes;
void CDlgManualInputBarcodes::CreateDutCtrlx(int index, CPoint locatingPoint);
public:
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
};
对话框源文件
// CDlgManualInputBarcodes.cpp: 实现文件
//
#include "stdafx.h"
#include "CDlgManualInputBarcodes.h"
#include "afxdialogex.h"
#include "Global.h"
#include <iostream>
// CDlgManualInputBarcodes 对话框
IMPLEMENT_DYNAMIC(CDlgManualInputBarcodes, CDialog)
CDlgManualInputBarcodes::CDlgManualInputBarcodes(int dutCount, std::vector<CString>* outBarcodes, CWnd* pParent /*=nullptr*/)
: CDialog(IDD, pParent)
, m_dutCount(dutCount)
, m_outDutBarcodes(outBarcodes)
{
m_outDutBarcodes->clear();
}
CDlgManualInputBarcodes::~CDlgManualInputBarcodes()
{
std::vector<pDUT_CTRL_ITEM>::iterator item = m_dutCtrlLists.begin();
for (; item != m_dutCtrlLists.end(); ++item)
{
delete *item;
}
m_dutCtrlLists.clear();
}
void CDlgManualInputBarcodes::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDlgManualInputBarcodes, CDialog)
ON_BN_CLICKED(IDOK, &CDlgManualInputBarcodes::OnBnClickedOk)
ON_BN_CLICKED(IDCANCEL, &CDlgManualInputBarcodes::OnBnClickedCancel)
END_MESSAGE_MAP()
// CDlgManualInputBarcodes 消息处理程序
BOOL CDlgManualInputBarcodes::OnInitDialog()
{
CDialog::OnInitDialog();
DUT_CTRL_ITEM tempCtrl(-1, CPoint(0, 0));
int startX = 10;
int ytemp = 15;
int xtemp = startX;
int nCount = m_dutCount;
int nColumns = 3;
for (int i = 1; i <= nCount; i++)
{
if (i % nColumns == 1)
{
xtemp = startX;
if (i != 1)
{
ytemp += tempCtrl.GetItemHeight();
}
}
else
{
xtemp += tempCtrl.GetItemWidth() + 10;
}
CreateDutCtrlx(i, CPoint(xtemp, ytemp));
}
CRect btnRect;
GetDlgItem(IDOK)->GetWindowRect(btnRect);
CRect srcRect;
this->GetWindowRect(&srcRect);
this->MoveWindow(srcRect.TopLeft().x, srcRect.TopLeft().y, tempCtrl.GetItemWidth() * (nColumns + 0.3), tempCtrl.GetItemHeight() * nCount / nColumns + 3 * btnRect.Height());
this->CenterWindow();
UpdateData(FALSE);
this->GetWindowRect(&srcRect);
GetDlgItem(IDOK)->MoveWindow(srcRect.Width() - btnRect.Width() * 1.8, srcRect.Height() - btnRect.Height() * 3, btnRect.Width(), btnRect.Height());
//GetDlgItem(IDCANCEL)->MoveWindow(srcRect.Width() - btnRect.Width() * 3, srcRect.Height() - btnRect.Height() * 3, btnRect.Width(), btnRect.Height());
if (m_dutCtrlLists.size() > 0)
{
m_dutCtrlLists[0]->editCtrl.SetFocus();
}
UpdateData(FALSE);
return FALSE;
}
void CDlgManualInputBarcodes::CreateDutCtrlx(int index, CPoint locatingPoint)
{
pDUT_CTRL_ITEM pDutCtrlItem = new DUT_CTRL_ITEM(index, locatingPoint);
if (pDutCtrlItem->Create(this))
{
m_dutCtrlLists.push_back(pDutCtrlItem);
}
else
{
AfxMessageBox("子控件创建失败!!");
}
}
void CDlgManualInputBarcodes::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
std::vector<pDUT_CTRL_ITEM>::iterator item = m_dutCtrlLists.begin();
for (; item != m_dutCtrlLists.end(); ++item)
{
CString strDutBarcode;
(*item)->editCtrl.GetWindowText(strDutBarcode);
m_outDutBarcodes->push_back(strDutBarcode);
}
CDialog::OnOK();
}
void CDlgManualInputBarcodes::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
CDialog::OnCancel();
}
BOOL CDlgManualInputBarcodes::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
CWnd* focusCtrl = GetFocus();
if (focusCtrl != NULL
&& focusCtrl->GetDlgCtrlID() != IDOK)
{
if ((pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
|| (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN))
{
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
BOOL CDlgManualInputBarcodes::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
for (int i = 0; i < m_dutCtrlLists.size(); i++)
{
if (nID == m_dutCtrlLists[i]->GetEditCtrlID()
&& nCode == 768)
{
CString strDutBarcode;
m_dutCtrlLists[i]->editCtrl.GetWindowText(strDutBarcode);
if (strDutBarcode.GetLength() >= g_tWorkOrderData.nBarcodeLength)
{
if (i == m_dutCtrlLists.size() - 1)
{
GetDlgItem(IDOK)->SetFocus();
}
else
{
m_dutCtrlLists[i+1]->editCtrl.SetFocus();
}
}
}
}
return CDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
调用方法
std::vector<CString> InputBarcodes;
CDlgManualInputBarcodes inputDlg(m_nChildWinNumMax, &InputBarcodes);
if (inputDlg.DoModal() == IDOK)
{
if (!ManualLoadChildWinBarcode(InputBarcodes))
{
//AfxMessageBox("手动输入扫码后,加载条码并启动测试失败了。");
return;
}
}
资源ID定义