【MFC】模拟采集系统——图形按钮(18)

news2024/10/1 15:19:02

 左边可以简单地使用一个组框,贴上背景图。当然,也可以使用新的对话框。

图形按钮类

 1、类向导-》添加类-》选择MFC-》填入新类名称-》选择父类为 CButton

 

2、添加消息响应函数和虚函数:

消息响应mouse leave (离开) mouse move (移动)

 虚函数:DrawItem(绘制按钮)

 代码如下:

头文件

#pragma once


// CPicButton

class CPicButton : public CButton
{
	DECLARE_DYNAMIC(CPicButton)

public:
	CPicButton();
	virtual ~CPicButton();
	void LoadImage(UINT nResID,int _nStyleNum = 1);		
	void ChangeButtonStyle(int _style);  
    void MoveButtonTo(int left,int top);
protected:
	int m_Width;
	int m_Height;	
	CDC *m_lpMemoryDC;
	CBitmap *m_lpBackgroundBitmap;
    bool m_IsMoveOn;	
	TRACKMOUSEEVENT tme;
	void Init();
	void ClearUp();

	DECLARE_MESSAGE_MAP()


public:
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
	afx_msg void OnMouseLeave();
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};


CPP文件

// PicButton.cpp : 实现文件
//

#include "stdafx.h"
#include "MFC09.h"
#include "PicButton.h"


// CPicButton

IMPLEMENT_DYNAMIC(CPicButton, CButton)

CPicButton::CPicButton()
{
	m_lpMemoryDC = NULL;
	m_lpBackgroundBitmap = NULL;	
	m_Width = 0;
	m_Height = 0;
	m_IsMoveOn = false;
}

CPicButton::~CPicButton()
{
}


BEGIN_MESSAGE_MAP(CPicButton, CButton)
	ON_WM_MOUSELEAVE()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()



// CPicButton 消息处理程序


void CPicButton::LoadImage(UINT nResID,int _nStyleNum )
{
	Init();
	m_lpBackgroundBitmap->LoadBitmap(nResID);	
	m_lpMemoryDC->SelectObject(m_lpBackgroundBitmap);
	BITMAP bm;
	m_lpBackgroundBitmap->GetBitmap(&bm);
	m_Height = bm.bmHeight;
	m_Width = bm.bmWidth / _nStyleNum;
	SetWindowPos(this,0,0,m_Width,m_Height,	SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE);  
}

void CPicButton::ChangeButtonStyle(int _style)
{
	CClientDC dc(this);	
	dc.SetStretchBltMode(COLORONCOLOR);	
	dc.StretchBlt(0,0,m_Width,m_Height,m_lpMemoryDC,_style * m_Width,0, m_Width,m_Height,SRCCOPY);	
}
void CPicButton::Init()
{
	ClearUp();
    CDC *dc = this->GetDC();
	m_lpMemoryDC = new CDC();
	m_lpBackgroundBitmap = new CBitmap();
	m_lpMemoryDC->CreateCompatibleDC(dc);
	this->ReleaseDC(dc);	
	this->ModifyStyle(0,BS_OWNERDRAW|WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE);
    tme.cbSize = sizeof(TRACKMOUSEEVENT);
    tme.dwFlags = TME_LEAVE;
    tme.hwndTrack = this->m_hWnd;
}

void CPicButton::ClearUp()
{
	if (m_lpBackgroundBitmap != NULL)	delete m_lpBackgroundBitmap;
	if (m_lpMemoryDC != NULL)	delete m_lpMemoryDC;
	
}
void CPicButton::MoveButtonTo(int _Left,int _Top)
{
	this->MoveWindow(_Left, _Top, m_Width , m_Height);
}

void CPicButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

	// TODO:  添加您的代码以绘制指定项
	if (lpDrawItemStruct->itemState & ODS_DISABLED) //按钮不可用状态
	{
		this->ChangeButtonStyle(0);
	}
	else if (lpDrawItemStruct->itemState & ODS_SELECTED) //按钮按下状态
	{ 
		this->ChangeButtonStyle(1);
	}
	else if(m_IsMoveOn)
	{
		this->ChangeButtonStyle(1);	
	}
	else
		this->ChangeButtonStyle(0);
}


void CPicButton::OnMouseLeave()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	 m_IsMoveOn = false;
	 Invalidate(0);
	CButton::OnMouseLeave();
}


void CPicButton::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
    m_IsMoveOn = true;
	Invalidate(FALSE);		  
    ::_TrackMouseEvent(&tme);        
	CButton::OnMouseMove(nFlags, point);
}

 左边对话框的实现

首先添加对话框资源

对话框添加四个按钮,大小位置可以任意,设置对话框的属性为Child

并且取消对话框的标题栏等。

使用类向导给对话框添加四个按钮对象:

 手动修改成上面新建的CPicButton。

代码如下:

#pragma once

#include "PicButton.h"
// CLeftDlg 对话框

class CLeftDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CLeftDlg)

public:
	CLeftDlg(CWnd* pParent = NULL);   // 标准构造函数
	CBitmap m_BackGround;
	CDC *mdc;
	virtual ~CLeftDlg();

// 对话框数据
	enum { IDD = IDD_LEFTDLG };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	CPicButton m_Start;
	CPicButton m_Stop;
	CPicButton m_Save;
	CPicButton m_Exit;
};
// LeftDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MFC09.h"
#include "LeftDlg.h"
#include "afxdialogex.h"


// CLeftDlg 对话框

IMPLEMENT_DYNAMIC(CLeftDlg, CDialogEx)

CLeftDlg::CLeftDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CLeftDlg::IDD, pParent)
{

}

CLeftDlg::~CLeftDlg()
{
}

void CLeftDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON1, m_Start);
	DDX_Control(pDX, IDC_BUTTON2, m_Stop);
	DDX_Control(pDX, IDC_BUTTON3, m_Save);
	DDX_Control(pDX, IDC_BUTTON4, m_Exit);
}


BEGIN_MESSAGE_MAP(CLeftDlg, CDialogEx)
	ON_WM_PAINT()
END_MESSAGE_MAP()


// CLeftDlg 消息处理程序


BOOL CLeftDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	m_BackGround.LoadBitmap(IDB_LEFT);	
	BITMAP bm;
	m_BackGround.GetBitmap(&bm);	
	int cx = bm.bmWidth;
	int cy = bm.bmHeight + 30;
	
	this->MoveWindow(0,0,cx,cy);
	mdc = new CDC;
	CDC *dc = this->GetDC();
	mdc->CreateCompatibleDC(dc);
	mdc->SelectObject(&m_BackGround);

	m_Exit.LoadImage(IDB_EXIT,2);
	m_Save.LoadImage(IDB_SAVE,2);
	m_Stop.LoadImage(IDB_STOP,2);
	m_Start.LoadImage(IDB_START,2);

	int h = 65;
	m_Start.MoveButtonTo(22,h);
	m_Stop.MoveButtonTo(22,h*2);
	m_Save.MoveButtonTo(22,h *3);
	m_Exit.MoveButtonTo(22,h*4);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


void CLeftDlg::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	// 不为绘图消息调用 CDialogEx::OnPaint()
	CRect rect;
	this->GetClientRect(&rect);
	dc.SetStretchBltMode(STRETCH_HALFTONE);
	// TODO: Add your message handler code here
	dc.StretchBlt(0,0,rect.right,rect.bottom,mdc,0,0,336,435,SRCCOPY);
}

 响应资源:(可以用画图简单完成,两个图片分别是鼠标进入和离开的切换效果)

在主对话框里也添加任意一个Button,按照上面的方法,同样添加一个按钮到主对话框类,然后修改OnInitDialog函数,代码如下:


// MFC09Dlg.h : 头文件
//

#pragma once
#include "LeftDlg.h"
#include "picbutton.h"

// CMFC09Dlg 对话框
class CMFC09Dlg : public CDialogEx
{
// 构造
public:
	CMFC09Dlg(CWnd* pParent = NULL);	// 标准构造函数
	CBitmap m_BackGround;
	CBitmap m_top;
	CDC *mdc;
	CLeftDlg leftDlg;
	void InitDlg();
// 对话框数据
	enum { IDD = IDD_MFC09_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	CPicButton m_close;
};


// MFC09Dlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MFC09.h"
#include "MFC09Dlg.h"
#include "afxdialogex.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMFC09Dlg 对话框



CMFC09Dlg::CMFC09Dlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CMFC09Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMFC09Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON1, m_close);
}

BEGIN_MESSAGE_MAP(CMFC09Dlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()


// CMFC09Dlg 消息处理程序

BOOL CMFC09Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	m_top.LoadBitmap(IDB_TOP);
	m_BackGround.LoadBitmap(IDB_BK);
	mdc = new CDC;
	CDC *dc = this->GetDC();
	mdc->CreateCompatibleDC(dc);
	this->ReleaseDC(dc);

	int cxIcon = GetSystemMetrics(SM_CXFULLSCREEN);
	int cyIcon = GetSystemMetrics(SM_CYFULLSCREEN);
	BITMAP bm;
	m_BackGround.GetBitmap(&bm);
	int cx = bm.bmWidth;
	int cy = bm.bmHeight + 30;
	int x = (cxIcon - cx ) / 2;
	int y = (cyIcon - cy ) / 2;
	this->MoveWindow(x,y,cx,cy);
	
	leftDlg.Create(IDD_LEFTDLG);
	leftDlg.MoveWindow(0 , 30, 180, cy - 30, 0);
	leftDlg.ShowWindow(SW_SHOW);

	m_close.LoadImage(IDB_CLOSE,5);
	m_close.MoveButtonTo(cx - 35,5);
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。
void CMFC09Dlg::InitDlg()
{
	BITMAP bm;
	
	m_BackGround.LoadBitmap(IDB_BK);
	m_top.LoadBitmap(IDB_TOP);
	m_BackGround.GetBitmap(&bm);
	int cxIcon = GetSystemMetrics(SM_CXFULLSCREEN);
	int cyIcon = GetSystemMetrics(SM_CYFULLSCREEN);
	int cx = bm.bmWidth;
	int cy = bm.bmHeight + 30;
	int x = (cxIcon - cx ) / 2;
	int y = (cyIcon - cy ) / 2;
	this->MoveWindow(x,y,cx,cy);

	leftDlg.Create(IDD_LEFTDLG);
	leftDlg.MoveWindow(0 , 30, 180, cy - 30, 0);
	leftDlg.ShowWindow(SW_SHOW);

	mdc = new CDC;
	CDC *dc = this->GetDC();
	mdc->CreateCompatibleDC(dc);
	this->ReleaseDC(dc);

}
void CMFC09Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CPaintDC dc(this);
		CRect rect;
		GetClientRect(&rect);
		mdc->SelectObject(&m_top);
		dc.SetStretchBltMode(STRETCH_HALFTONE);
		dc.StretchBlt(0,0,rect.right,30,mdc,0,0,2,29,SRCCOPY);
	    mdc->SelectObject(&m_BackGround);
		dc.StretchBlt(180,30,rect.right - 150,rect.bottom - 30,mdc,0,0,735,549,SRCCOPY);
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFC09Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

退出按钮图片,放左上角:

运行后界面:

 以上资源可以自由编辑,注意添加到工程后修改相应的ID即可。

总结:

1、对话框可以作为主窗口,也可以作为子窗口,成为其他窗口的一部分;可以对MFC提供的按钮等类进行派生,增加功能;

2、按钮可以利用资源视图直接添加到对话框,添加变量的时候修改成指定的类即可,也可以动态生成,类似在主对话框中添加CLeftDlg,这时候,资源类(按钮、列表、文本框等等)需要手动Create创建。

3、总的来说,一种方法资源视图和类向导中添加窗口资源类的控件,不需要创建,直接使用,另外一种方法,则需要 定义对象-》创建窗口-》显示窗口的步骤来完成添加。如以下CLeftDlg的使用(很容易漏掉Create):

CLeftDlg leftDlg;       -》     leftDlg.Create(IDD_LEFTDLG); -》    设置窗口大小等等      -》leftDlg.ShowWindow(SW_SHOW);   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/348301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS3 animation-fill-mode详解

CSS3 animation-fill-mode详解 定义 animation-fill-mode 属性规定当动画不播放时&#xff08;当动画完成时&#xff0c;或当动画有一个延迟未开始播放时&#xff09;&#xff0c;要应用到元素的样式。 默认情况下&#xff0c;CSS 动画在第一个关键帧播放完之前不会影响元素&…

各CCFA类核心期刊的信息汇总与评价总结(科技领域)

CCF中文期刊投稿选择之篇章二:各CCFA类核心期刊的信息汇总与评价总结上一篇章总结一部分期刊的介绍自动化学报相关信息的介绍有关录用比、审稿速度及费用的相关数据收集相关学术论坛上网友的评价与讨论期刊年度出版概况与学术热点动态&#xff08;知网&#xff09;计算机学报相…

2023年可供学习的 10 大 SaaS 知识库工具!

客户迫切希望快速找到所需的信息。在软件行业尤其如此&#xff0c;因为软件行业节奏很快&#xff0c;公司经常销售学习曲线陡峭的产品。为了减缓流失率并提高盈利能力&#xff0c;SaaS 公司正在转向知识库&#xff0c;以帮助他们让客户了解情况。什么是知识库&#xff1f;您可以…

设计模式之代理模式详解和应用

目录1 代理模式定义2 代理模式的应用场景3 代理模式的通用写法4 从静态代理到动态代理5 静态模式在业务中的应用6 动态代理在业务中的应用7 手写JDK动态代理实现原理7.1 JDK动态代理的实现原理7.2 CGLib动态代理容易踩的坑8 CGLib代理调用API及原理分析9 CGLib和JDK动态代理对比…

JVM - 高效并发

目录 Java内存模型和内存间的交互操作 Java内存模型 内存间的交互操作 内存间交互操作的规则 volatile特性 多线程中的可见性 volatile 指令重排原理和规则 指令重排 指令重排的基本规则 多线程中的有序性 线程安全处理 锁优化 锁优化之自旋锁与自适应自旋 锁优…

jvisualvm工具使用

jdk自带的工具jvisualvm&#xff0c;可以分析java内存使用情况&#xff0c;jvm相关的信息。 1、设置jvm启动参数 设置jvm参数**-Xms20m -Xmx20m -XX:PrintGCDetails** 最小和最大堆内存&#xff0c;打印gc详情 2、测试代码 TestScheduleClassGc package com.core.schedule;…

LeetCode 82. 删除排序链表中的重复元素 II

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 给定一个已排序的链表的头 headheadhead &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,…

ASML逆袭史:人、资金、技术,缺一不可

前言 近年来&#xff0c;由于众所周知的原因&#xff0c;荷兰ASML&#xff08;阿斯麦&#xff09;公司的先进半导体制造设备——光刻机&#xff0c;进入普通大众视野&#xff0c;成为人们茶余饭后谈论的焦点话题之一。 1月底&#xff0c;“美日荷三方谈判达成协议&#xff0c;可…

Selenium自动化测试Python二:WebDriver基础

欢迎阅读WebDriver基础讲义。本篇讲义将会重点介绍Selenium WebDriver的环境搭建和基本使用方法。 WebDriver环境搭建 Selenium WebDriver 又称为 Selenium2。 Selenium 1 WebDriver Selenium 2 WebDriver是主流Web应用自动化测试框架&#xff0c;具有清晰面向对象 API&…

SAP ABAP 输出结果带有空格

方法一&#xff1a; 字段内容前增加空格&#xff0c;需使用全角空格&#xff0c;使用半角空格时&#xff0c;ALV显示无效&#xff0c;空格无法显示&#xff0c; 全角与半角的切换方法&#xff1a;shift空格切换&#xff0c; 如下的标记部分&#xff0c;要想通过ALV显示空格&…

mfc140u.dll丢失的解决方法,mfc140u.dll文件修复

mfc140u.dll丢失的解决方法&#xff0c;其实要解决这个问题一点都不难&#xff0c;我们主要知道是什么原因造成的&#xff0c;那么就可以轻松的解决。 一.mfc140u.dll是什么 "MFC140u.dll"是一个Windows动态链接库文件&#xff0c;它是Microsoft Visual C 2015运行…

TortoiseSVN的使用

基本概念 版本库 SVN保持数据的地方&#xff0c;所有的文件都保存在这个库中&#xff0c;Tortoise访问的就是远程服务器上的Subversion版本库。 工作拷贝 就是工作副本&#xff0c;可将版本库的文件拷贝到本地中&#xff0c;可以任意修改&#xff0c; 不会影响版本库。在你…

责任链模式(Chain of Responsibility Pattern)

意图&#xff1a;避免请求发送者与接收者耦合在一起&#xff0c;让多个对象都有可能接收请求&#xff0c;将这些对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有对象处理它为止。 主要解决&#xff1a;职责链上的处理者负责处理请求&#xff0c;客户只…

常用调试golang的bug以及性能问题的实践方法

文章目录如何分析程序运行时间和CPU利用率情况1.shell内置time指令/usr/bin/time指令如何分析golang程序的内存使用情况&#xff1f;1.内存占用情况查看如何分析golang程序的CPU性能情况1.性能分析注意事项2.CPU性能分析A.Web界面查看B.使用pprof工具查看如何分析程序运行时间和…

PHP(12)文件上传

PHP&#xff08;12&#xff09;文件上传一、文件上传原理二、表单写法三、预定义变量 $_FILES四、移动临时文件五、多文件上传1. 同名表单2. 不同名表单六、多文件处理1. 同名文件2. 不同名文件七、封装文件上传函数一、文件上传原理 文件从客户机上传至服务器指定目录。 步骤…

Redhat7.6升级openssh(超详细)

一、准备工作 从官网下载新版的openssh-7.9p1.tar.gz 准备rhel-server-7.6-x86_64-dvd.iso用于使用yum安装依赖 二、具体升级步骤 1.查看系统版本 [rootredhat ~]# cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.6 (Maipo) 2.查看openssh现有版本 …

金三银四面试必看,自动化测试如何解决日志问题

前言 前几天在员群里&#xff0c;有同学问了一个自动化测试实践中遇到的问题&#xff1a; 持续集成的自动化用例很多&#xff0c;测试环境日志level为debug&#xff0c;日志量大概40G/每天&#xff0c;定位问题时日志查询很慢&#xff0c;该怎么解决&#xff1f; 这个问题可…

pytorch基础入门教程

pytorch基础入门教程 Pytorch一小时入门教程 前言 机器学习的门槛并没有想象中那么高&#xff0c;我会陆续把我在学习过程中看过的一些文章和写过的代码以博客的形式分享给大家&#xff0c;和大家一起交流&#xff0c;这个是本系列的第一篇&#xff0c;pytoch入门教程&#x…

软件测试2-测试必须有策略和测试有哪些最高原则

什么是软件测试测试是为发现错误而执行程序的过程。软件测试一个破坏性的过程&#xff0c;甚至是一个施虐的过程&#xff0c;也就是第一天说的“找茬”游戏。 当一个输入框让我输入手机号码时&#xff0c;我偏不&#xff0c;我要输入非手机号码&#xff0c;甚至不填。 当界面提…

定时任务使用总结

定时任务表达式生成工具网站&#xff1a;https://cron.qqe2.com/定时任务选型&#xff1a;xxl-job 官方文档&#xff1a;https://www.xuxueli.com/xxl-job/安装定时任务调度中心 xxl-job-admin第一步、先导入xxl-job的数据库&#xff1a;地址&#xff1a;https://gitee.com/xux…