控件消息截获方法及运动方向控制
CButtonXq.h
#pragma once
#include <afxwin.h>
class CBossDlg;
class CButtonXq : public CButton
{
public:
CBossDlg* mpDlg;
DECLARE_MESSAGE_MAP()
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
};
CButtonXq.cpp
#include "pch.h"
#include "CButtonXq.h"
#include "BossDlg.h"
BEGIN_MESSAGE_MAP(CButtonXq, CButton)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
void CButtonXq::OnMouseMove(UINT nFlags, CPoint point)
{
mpDlg->Comeing();
}
BossDlg.h
#pragma once
#include "CButtonXq.h"
// CBossDlg 对话框
class CBossDlg : public CDialogEx
{
// 构造
CButtonXq m_ok;
int m_dir{ 1 };
public:
CBossDlg(CWnd* pParent = nullptr); // 标准构造函数
void Comeing();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_BOSS_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
BossDlg.cpp
void CBossDlg::Comeing()
{
CRect rect, rc;
m_ok.GetWindowRect(rect);
ScreenToClient(rect);
GetClientRect(rc);
if (rect.right >= rc.right || rect.left <= 0)
m_dir *= -1;
rect.OffsetRect(rect.Width()*m_dir, 0); //反向运动
m_ok.MoveWindow(rect);
}
/*
void CBossDlg::Comeing()
{
CRect rect, rc;
m_ok.GetWindowRect(rect);
ScreenToClient(rect);
GetClientRect(rc);
if (rect.right >= rc.right)
rect.OffsetRect(-rect.left, 0);
else
rect.OffsetRect(rect.Width(), 0);
m_ok.MoveWindow(rect);
}
*/
BOOL CBossDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_ok.mpDlg = this;
m_ok.SubclassDlgItem(IDOK, this); //关联到控件上
return TRUE;
}
手动封装的CTime时间类
struct tm结构体,用于表示日期和时间。通过使用结构体可以方便的对日期和时间进行操作处理。
struct tm {
int tm_sec; // 秒(0-61)
int tm_min; // 分(0-59)
int tm_hour; // 时(0-23)
int tm_mday; // 一月中的某一天(1-31)
int tm_mon; // 月份(0-11,0 表示一月)
int tm_year; // 年份(以1900为基准)
int tm_wday; // 一周中的某一天(0-6,0 表示星期天)
int tm_yday; // 一年中的某一天(0-365,0 表示一月一日)
int tm_isdst; // 夏令时标志(正数表示夏令时,0 表示不使用夏令时,负数表示无效)
};
mktime()函数用于将结构体struct tm类型的日期和时间转换为从1970年1月1日午夜开始计算的秒数。它的原型如下:
time_t mktime(struct tm *timeptr);
mktime()函数将传入的 struct tm 结构体表示的日期和时间转换为time_t类型的秒数,如果转换成功,则返回该秒数,否则返回-1。此函数可以用于计算两个日期之间的时间差,或者将日期和时间转换为时间戳。
localtime函数是C标准库中的一个函数,用于将时间戳(time_t类型)转换为当地时间的struct tm结构体表示。它的函数原型如下:
struct tm *localtime(const time_t *time);
localtime函数接受一个指向time_t类型的时间戳的指针作为参数,并返回一个指向struct tm结构体的指针。struct tm结构体包含了日期和时间的各个组成部分,如年、月、日、时、分、秒等。
下面是一个示例代码,展示了如何使用localtime函数获取当前时间的各个组成部分:
#include <stdio.h>
#include <time.h>
int main() {
time_t t = time(NULL); // 获取当前时间的时间戳
struct tm *lt = localtime(&t); // 将时间戳转换为当地时间的struct tm结构体表示
// 输出当地时间的各个组成部分
printf("Year: %d\n", lt->tm_year + 1900); // 年份需要加上1900
printf("Month: %d\n", lt->tm_mon + 1); // 月份需要加上1
printf("Day: %d\n", lt->tm_mday);
printf("Hour: %d\n", lt->tm_hour);
printf("Minute: %d\n", lt->tm_min);
printf("Second: %d\n", lt->tm_sec);
return 0;
}
CTime时间类的封装
#pragma once
class CTimeXq
{
time_t m_time;
public:
static CTimeXq GetCurrentTime()
{
return CTimeXq(::time(NULL)); //加上:: 相当于全局函数
}
static BOOL IsValidFILETIME(_In_ const FILETIME& ft)
{
}
CTimeXq() :m_time(0)
{
}
CTimeXq(time_t time) :m_time(time) //从这传导一个time_t出来经过这个m_time函数构造一个对象出来
{
}
CTimeXq( int nYear,int nMonth,int nDay,int nHour,int nMin,int nSec,int nDST = -1)
{
struct tm t{nSec,nMin,nHour,nDay,nMonth-1,nYear-1900};
m_time = mktime(&t);//转换成功,则返回值为非负数;如果转换失败,则返回值为 - 1
ASSERT(m_time!=-1);
}
CTimeXq& operator=(time_t time)
{
}
bool operator==(const CTimeXq &time) const
{
return m_time == time.m_time;
}
bool operator!=(const CTimeXq &time) const
{
return m_time != time.m_time;
}
bool operator<(const CTimeXq &time) const
{
return m_time < time.m_time;
}
bool operator>(const CTimeXq &time) const
{
return m_time > time.m_time;
}
bool operator<=(const CTimeXq &time) const
{
return m_time <= time.m_time;
}
bool operator>=(const CTimeXq &time) const
{
return m_time >= time.m_time;
}
time_t GetTime() const
{
return m_time;
}
int GetYear() const
{
return localtime(&m_time)->tm_year+1900;
}
int GetMonth() const
{
return localtime(&m_time)->tm_mon+1;
}
int GetDay() const
{
return localtime(&m_time)->tm_mday;
}
int GetHour() const
{
return localtime(&m_time)->tm_hour;
}
int GetMinute() const
{
return localtime(&m_time)->tm_min;
}
int GetSecond() const
{
return localtime(&m_time)->tm_sec;
}
int GetDayOfWeek() const
{
return localtime(&m_time)->tm_wday;
}
};
CDialog类简介
class CDialog : public CWnd
{
public:
virtual BOOL Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
动态创建对话框或者子对话框(分页)
virtual BOOL Create(UINT nIDTemplate, CWnd* pParentWnd = NULL);
virtual BOOL CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd = NULL,
void* lpDialogInit = NULL);
virtual BOOL CreateIndirect(HGLOBAL hDialogTemplate, CWnd* pParentWnd = NULL);
public:
explicit CDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
explicit CDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
virtual INT_PTR DoModal(); 弹出对话框
// support for passing on tab control - use 'PostMessage' if needed
void NextDlgCtrl() const;向后 跳转焦点
void PrevDlgCtrl() const;向前 跳转焦点
void GotoDlgCtrl(CWnd* pWndCtrl); 指定跳转
// default button access
void SetDefID(UINT nID); 设置默认按钮
DWORD GetDefID() const; 过去默认按钮
// termination
void EndDialog(int nResult); 关闭对话框
// Overridables (special message map entries)
virtual BOOL OnInitDialog();
virtual void OnSetFont(CFont* pFont);
protected:
virtual void OnOK();
virtual void OnCancel();
// Implementation
public:
virtual ~CDialog();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);
virtual BOOL CheckAutoCenter();
};
CDialogEx派生类
1、主要功能就是设置背景颜色和背景图:
SetBackgroundColor和SetBackgroundImage
2、颜色管理参见RGB
a)RGB:代表 Red Green 和 Blue 这三色分量,每个有256种(0-255)数值。
b)把以上三种数值随机组合就是24位真彩色。
a)常见的纯色包括:
黑色:RGB(0,0,0) 白色:RGB(255,255,255)
红色:RGB(255,0,0) 反色是青色:RGB(0,255,255)
绿色:RGB(0,255,0) 反色是紫色:RGB(255,0,255)
3、基础的MFC只支持.bmp位图文件格式,高级MFC GDI+支持所有常见格式png和jpg等。
class CDialogEx : public CDialog
{
public:
CDialogEx();
CDialogEx(UINT nIDTemplate, CWnd *pParent = NULL);
CDialogEx(LPCTSTR lpszTemplateName, CWnd *pParentWnd = NULL);//古代ID指针变量(字符串)
// Attributes:
public:
enum BackgroundLocation
{
BACKGR_TILE,
BACKGR_TOPLEFT,
BACKGR_TOPRIGHT,
BACKGR_BOTTOMLEFT,
BACKGR_BOTTOMRIGHT,
};
protected:
HBITMAP m_hBkgrBitmap;//图片句柄
CSize m_sizeBkgrBitmap;
CBrush m_brBkgr;//画刷(填充色)
BackgroundLocation m_BkgrLocation;
CDialogImpl m_Impl;
BOOL m_bAutoDestroyBmp;
// Operations:
public:
void SetBackgroundColor(COLORREF color, BOOL bRepaint = TRUE);
void SetBackgroundImage(HBITMAP hBitmap, BackgroundLocation location = BACKGR_TILE, BOOL bAutoDestroy = TRUE, BOOL bRepaint = TRUE);
BOOL SetBackgroundImage(UINT uiBmpResId, BackgroundLocation location = BACKGR_TILE, BOOL bRepaint = TRUE);
};
附录
MFC静态链接和动态链接是什么区别?
a)静态链接(Static Linking):是将MFC库的代码编译到应用程序中,生成一个独立的可执行文件。
b)动态链接(Dynamic Linking):是将MFC库的代码编译成动态链接库(DLL),在运行时,应用程序需要依赖于外部的MFC库文件。
c)静态链接占用执行文件的空间大,动态链接占用的执行文件空间小。但是不能独立运行有依赖性,可能存在产品安全问题。
d)动态链接因为代码都在很多个DLL中,在调试时按F11不可以见MFC源码,而静态链接一般按F11就能进入MFC的源码进行了解。