MFC动态生成控件、消息事件过滤器

背景:

一个动态生成条码输入编辑框的界面,编辑框内容输入达到指定长度后,焦点自动依次跳转到下一个编辑框,最后一个编辑框则自动跳转焦点到确认按钮

除非焦点在确认按钮,否则不响应回车键和退出键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定义

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值