avatar

目录
MFC中如何实现软件启动画面&软件开机自启

MFC中如何实现软件启动画面&软件开机自启

1、新建一个dialog

新建一个dlg,取名叫 IDD_DLG_STARTBMP,并设置相关属性,如下

1602675599496

然后添加类,添加 init 属性,ontimer 属性等

2、添加位图

资源视图->Bitmap右键->添加资源->bitmap->导入 然后导入提前设置好的BMP格式图片。

3、代码编写

在 OnInitDialog() 里面,设置计时器

在 OnTimer() 里面设置图片响应时间

在 OnPaint() 里面绘制图像

如下:.cpp文件

c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// StartBmp.cpp : 实现文件
//

#include "stdafx.h"
#include "StartBmp.h"
#include "afxdialogex.h"
#include "MainFormDlg.h"


// CStartBmp 对话框

IMPLEMENT_DYNAMIC(CStartBmp, CDialogEx)

CStartBmp::CStartBmp(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DLG_STARTBMP, pParent)
{

}

CStartBmp::~CStartBmp()
{
}

void CStartBmp::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CStartBmp, CDialogEx)
ON_WM_PAINT()
ON_WM_TIMER()
END_MESSAGE_MAP()



void CStartBmp::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialogEx::OnPaint()
CRect rect;
GetClientRect(&rect);
CDC dcBmp; //定义并创建一个内存设备环境
dcBmp.CreateCompatibleDC(&dc); //创建兼容性DC
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_START_BITMAP); //此处ID为开机位图ID
BITMAP m_bitmap;
bmpBackground.GetBitmap(&m_bitmap); //将图片载入位图中
//将位图选入临时内存设备环境
CBitmap *pbmpOld = dcBmp.SelectObject(&bmpBackground);
dc.SetStretchBltMode(COLORONCOLOR);
//调用函数显示图片StretchBlt显示形状可变
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcBmp, 0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight, SRCCOPY);
dcBmp.SelectObject(pbmpOld);

}


void CStartBmp::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

//CWnd* hWnd = FindWindow(L"#32770", NULL);
//if (hWnd)
//{
// hWnd->PostMessage(WM_CLOSE, NULL, NULL);
//}
//else
//{
// MessageBox(L"ERROR");
//}
Sleep(2000);

KillTimer(1);
OnCancel();


CDialogEx::OnTimer(nIDEvent);
}


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

// TODO: 在此添加额外的初始化
SetTimer(1, 2000, NULL);

return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

如下:.h 文件

c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#pragma once
#include "resource.h"

// CStartBmp 对话框

class CStartBmp : public CDialogEx
{
DECLARE_DYNAMIC(CStartBmp)

public:
CStartBmp(CWnd* pParent = NULL); // 标准构造函数
virtual ~CStartBmp();

// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DLG_STARTBMP };
#endif

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

DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
afx_msg void OnTimer(UINT_PTR nIDEvent);
virtual BOOL OnInitDialog();
};

4、开软件自启

首先在主函数中实例化我们刚刚写的类
然后在主函数的勒种添加OnCreat事件

在create函数中如下写入

c++
1
2
3
4
5
6
7
8
9
10
11
12
int CMainFormDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: 在此添加您专用的创建代码
m_StartBmpDlg.DoModal();
OnBnClickedDiagnosisButton();
m_SYSTEM_DIAGNOSIS.ShowWindow(SW_HIDE);

return 0;
}

大功告成

在前面ontiner中的sleep函数时用来设置开机动画中图片的停留时间的。

关于软件开机自启的设置

方法一:

在每一个开始菜单里面的附件中有一个自启文件夹,将这个文件夹打开,将需要开机自启的软件丢进去即可。

方法二

代码实现,读写注册表:

c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 方法函数中写入如下代码
HKEY hKey;
CString strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

//1、找到系统的启动项
if (RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) ///打开启动项
{
//2、得到本程序自身的全路径
TCHAR strExeFullDir[MAX_PATH];
GetModuleFileName(NULL, strExeFullDir, MAX_PATH);

//3、判断注册表项是否已经存在
TCHAR strDir[MAX_PATH] = {};
DWORD nLength = MAX_PATH;
long result = RegGetValue(hKey, nullptr, L"GISRestart", RRF_RT_REG_SZ, 0, strDir, &nLength);

//4、已经存在
if (result != ERROR_SUCCESS || _tcscmp(strExeFullDir, strDir) != 0)
{
//5、添加一个子Key,并设置值,"GISRestart"是应用程序名字(不加后缀.exe)
RegSetValueEx(hKey, L"GISRestart", 0, REG_SZ, (LPBYTE)strExeFullDir, (lstrlen(strExeFullDir) + 1) * sizeof(TCHAR));

//6、关闭注册表
RegCloseKey(hKey);
m_PowerAuto.SetWindowText(_T("已自启"));
}
else
{
m_PowerAuto.SetWindowText(_T("已自启"));
}
}
else
{
MessageBox(_T("打开启动项失败"));
}

当然也可以在 init 函数中查看是否已被开机自启

c++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// =======================开机自启动
HKEY hKey;
//找到系统的启动项
CString lpRun = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
//打开启动项
long lRet = RegOpenKeyEx(HKEY_CURRENT_USER, lpRun, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS)
MessageBox(_T("打开启动项失败"));
//找到程序自身路径
TCHAR pFileName[MAX_PATH] = {};
GetModuleFileName(NULL, pFileName, MAX_PATH);
//判断是否已经设置开机启动
TCHAR PowerBoot[MAX_PATH] = {};
DWORD nLongth = MAX_PATH;
long result = RegGetValue(hKey, NULL, _T("PowerBoot"), RRF_RT_REG_SZ, 0, PowerBoot, &nLongth);
if (result == ERROR_SUCCESS)
{
m_PowerAuto.SetWindowText(_T("已自启"));
}
else
{
m_PowerAuto.SetWindowText(_T("未自启"));
}
////关闭注册表
RegCloseKey(hKey);

不积跬步无以至千里,不积小流无以成江河!

文章作者: Abraverman
文章链接: http://abraverman.gitee.io/2020/10/14/open-image/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Abraverman
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论