在文章开始之前,推荐一篇值得阅读的好文章!感兴趣的也可以去看一下,并关注作者!
题目:Go语言中的加解密利器:go-crypto库全解析
好事文章地址:https://cloud.tencent.com/developer/article/2470499
在软件开发中,数据安全和隐私保护越来越受到重视。Go 语言以其简洁高效的特性,成为了许多开发者的首选。然而,在实际项目中使用加解密时,还是需要在标准库的基础上做一些封装。go-crypto
库应运而生,它是一个专为 Golang 设计的加密解密工具库,提供了 AES 和 RSA 等多种加密算法的支持。
VC++6.0入门——第九讲 定制应用功能程序外观
本章将讲述如何修改MFC AppWizard自动生成的应用程序的外观,包括工具栏和状态栏的编程,以及如何为应用程序添加一个启动画面。
在日常生活中,建筑商在盖楼时,通常都是在楼房建成之前先设计好它的外观和大小。当楼房建成之后,还可以对其外观进行翻新或改造。同样,对于MF℃应用程序来说,为了改变MFC AppWizard自动生成的应用程序外观和大小,我们既可以在应用程序窗口创建之前进行,也可以在该窗口创建之后进行。
在MFC程序中,如果想在窗口创建之后改变其外观,可以在框架类(CMainFrame)的OnCreate函数中添加具体的实现代码。读者可以查看该函数的代码,将会发现它首先调用了基类的OnCreate函数,以完成窗口的创建,这样,我们就可以在该函数的最后,但要在return语句之前添加改变窗口外观的代码。
方式一:自己写类覆盖原有
我们不能修改F℃底层代码,但是,我们可以编写自己的窗口类并注册,然后让随后的窗口按照我们编写的窗口类去创建。下面,我们在Syle程序的CMainFrame类的 PreCreate Window函数中编写一个自己的窗口类并注册。
应用程序实例的句柄(hInstance):在本书第一章的示例中,WinMain函数是我们自己编写的,当系统调用应用程序时,它为该应用程序分配了一个句柄,并把该句柄作为WinMain函数的参数传递进来,于是,我们可以直接通过该参数来对窗口类的hInstance成员赋值。但在这里,程序代码是通过AppWizard自动生成的, WinMain函数被隐藏了。那么我们如何才能获取到当前应用程序的句柄呢?MFC为我们提供了一个全局函数:AfxGetInstanceHandle,可以用来获取当前应用程序的实例句柄。
方式二:AfxRegisterWndClass
MFC又为我们提供了一个全局函数:AfxRegisterWndClass,用来设定窗口的类型、光标、背景和图标。该函数的原型声明如下所示:
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 0,0,
LoadIcon(NULL,IDI_WARNING));
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
LoadCursor(NULL,IDC_HELP),
(HBRUSH) GetStockObject(BLACK_BRUSH),
0);
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
对于CStyleView类来说, AppWizard并没有自动为它创建OnCreate函数,因此,我们需要为该类添加WM_CREATE消息的响应函数,然后在这个响应函数(OnCreate函数)中,调用SetClassLong函数修改视类窗口的光标和背景
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));
我们平常在使用一些软件时,发现它们的图标一直在不断地循环变化,给人一种动画的效果。这种功能的实现比较简单,就是预先准备好几幅图标,然后在程序中每隔一定的时间按顺序循环显示这几幅图标,从而就实现了一种动画的效果。在实际编码实现时,利用定时器和SetClassLong函数就可以完成这个功能。因为SetClassLong函数可以在窗口创建完成之后修改窗口的图标,所以我们可以在程序中每隔一定时间就调用一次这个函数,让其显示预先已准备好的一组图标中的下一幅,从而就可以实现所需的动画效果。
可以看到,这个宏的返回值是一个字符串类型,也就是字符指针类型。
句柄获取方式
接下来,加载第二幅图标,本例中利用另一种方法来获得应用程序当前的实例句柄。我们已经知道,在MFC SDI应用程序中,有一个表示应用程序本身的类,本例中就是 CStyleApp,它派生于CWinApp类。该类有一个数据成员:m hInstance,标识了应用程序当前的实例,也就是说,如果我们能获取到应用程序的CWinApp对象,就可以利用这个对象来调用它的m_hInstance数据成员,从而得到应用程序当前的实例句柄。根据前面的知识,我们知道在CStyleApp的源文件中已经定义了一个CStyleApp类型的全局变量: theApp。这样,我们就可以利用这个全局对象来调用其内部的数据成员。但是,在一个源文件中要想调用另一个源文件中定义的全局变量,必须在调用这个变量之前声明这个变量是在外部定义的,声明代码如下所示,读者可以把它放到CMainFrame类的OnCreate函数定义之前:
接着,加载第三幅图标,这里我们再换一种方式来获取应用程序当前的实例句柄。 MFC提供了一个全局函数:AfxGetApp,可以获得当前应用程序对象的指针。因为这个函数是全局函数,所以在应用程序的任意地方都可以调用它。在本程序中,利用AfxGetApp函数的返回值来访问应用程序的m hInstance数据成员。
// 加载图标
m_hIcon[0] = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
m_hIcon[1] = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON2));
m_hIcon[2] = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON3));
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[0]);
// 设置定时器
SetTimer(1,1000,NULL);
然后,为CMainFrame类添加定时器消息(WM TIMER)的响应函数,并在该响应函数中调用SetClassLong函数改变应用程序窗口的图标。
小技巧:如果希望把某个数值始终限定在一个范围内,那么最好的办法当然就是进行取模运算(%)。例如,如果希望某个变量的取值在0-10之间变化,因为0-10之间有11个数,所以就应该把这个变量对11取模。实际上,取模运算就是取余。
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
static int index = 0; // 静态化
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[index]);
index = ++index%3; // 值保持在某个范围不断变化0,1,2
CFrameWnd::OnTimer(nIDEvent);
}
工具栏是Windows应用程序中一个非常重要的图形界面元素,它提供了一组顺序排列的带有位图图标的按钮。工具栏是把常用的菜单命令集合起来,以按钮的形式提供给用户使用,目的是为了方便用户的操作。在Style工程中,在Resource View选项卡的Toolbar文件夹下有一个工具栏资源:DR MAINFRAME,双击这个资源D,即可在资源编辑窗口中打开工具栏资源,如图9.13所示。可以看到,这是一些带有位图图标的按钮,用户通过这些位图就能大概知道每个按钮的功能。
按钮之间添加了一条分隔符用以区分这两组按钮。为了在刚才新添加的按钮和已有的【帮助】按钮之间添加一条分隔符,我们可以在资源编辑窗口中,用鼠标把T按钮向右拖动一点距离后再松开鼠标,此时可以看到,在帮助按钮和工按钮之间就有了一点空隙。
插入工具栏的两种方式
void CMainFrame::OnNewTool()
{
// TODO: Add your command handler code here
// 判断当前是显示,还是隐藏;如果显示,则隐藏;如果隐藏,则显示;
if(m_newToolBar.IsWindowVisible()){
m_newToolBar.ShowWindow(SW_HIDE);
}else{
m_newToolBar.ShowWindow(SW_SHOW);
}
RecalcLayout();
DockControlBar(&m_newToolBar);
}
ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);
void CMainFrame::OnUpdateNewTool(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
}
// 获得一下时间, 设置为窗格显示内容
CTime t=CTime::GetCurrentTime();
CString str = t.Format("%H:%M:%S");
int index = 0;
index = m_wndStatusBar.CommandToIndex(IDS_TIMER);
// 字体宽度
CClientDC dc(this);
CSize sz = dc.GetTextExtent(str);
m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);
m_wndStatusBar.SetPaneText(index,str);
CProgressCtrl m_progress; // 进度条
// 创建进度栏
m_progress.Create(WS_CHILD | WS_VISIBLE,CRect(100,100,200,120),this,1234);
m_progress.SetPos(50);
m_progressv.Create(WS_CHILD | WS_VISIBLE | PBS_VERTICAL,CRect(100,150,120,300),this,12345);
m_progressv.SetPos(70);
// 定义一个消息
#define UM_PROGRESS WM_USER+1
// 声明消息响应函数
afx_msg void OnProgress();
// 建立消息和消息响应函数的映射关系
ON_MESSAGE(UM_PROGRESS,OnProgress)
// 发送一个消息
PostMessage(UM_PROGRESS);
// 实现消息响应函数
void CMainFrame::OnProgress()
{
// 进度条放到右下角窗格中
int index1 = 0;
index1 = m_wndStatusBar.CommandToIndex(IDS_PROGESS);
// 获得一下矩形区域的大小
CRect rect;
m_wndStatusBar.GetItemRect(index1,&rect);
m_progressm.Create(WS_CHILD | WS_VISIBLE,rect,&m_wndStatusBar,1234567);
m_progressm.SetPos(50);
}
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// 进度条放到右下角窗格中
int index1 = 0;
index1 = m_wndStatusBar.CommandToIndex(IDS_PROGESS);
// 获得一下矩形区域的大小
CRect rect;
m_wndStatusBar.GetItemRect(index1,&rect);
if(!m_progressm.m_hWnd){
m_progressm.Create(WS_CHILD | WS_VISIBLE,rect,&m_wndStatusBar,1234567);
}else{
m_progressm.MoveWindow(rect);
}
m_progressm.SetPos(50);
// Do not call CFrameWnd::OnPaint() for painting messages
}
// 进度栏每间隔1s前进
m_progressm.StepIt();
view类上,点击右键,增加消息处理
void CStyle1View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// 状态栏第一个面板上显示鼠标的位置
CString str;
str.Format("x=%d,y=%d",point.x,point.y);
// 获取框架类窗口
((CMainFrame*) GetParent())->m_wndStatusBar.SetWindowText(str);
CView::OnMouseMove(nFlags, point);
}
// CG: This file was added by the Splash Screen component.
#ifndef _SPLASH_SCRN_
#define _SPLASH_SCRN_
// Splash.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// Splash Screen class
class CSplashWnd : public CWnd
{
// Construction
protected:
CSplashWnd();
// Attributes:
public:
CBitmap m_bitmap;
// Operations
public:
static void EnableSplashScreen(BOOL bEnable = TRUE);
static void ShowSplashScreen(CWnd* pParentWnd = NULL);
static BOOL PreTranslateAppMessage(MSG* pMsg);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSplashWnd)
//}}AFX_VIRTUAL
// Implementation
public:
~CSplashWnd();
virtual void PostNcDestroy();
protected:
BOOL Create(CWnd* pParentWnd = NULL);
void HideSplashScreen();
static BOOL c_bShowSplashWnd;
static CSplashWnd* c_pSplashWnd;
// Generated message map functions
protected:
//{{AFX_MSG(CSplashWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
// CG: This file was added by the Splash Screen component.
// Splash.cpp : implementation file
//
#include "stdafx.h" // e. g. stdafx.h
#include "resource.h" // e.g. resource.h
#include "Splash.h" // e.g. splash.h
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Splash Screen class
BOOL CSplashWnd::c_bShowSplashWnd;
CSplashWnd* CSplashWnd::c_pSplashWnd;
CSplashWnd::CSplashWnd()
{
}
CSplashWnd::~CSplashWnd()
{
// Clear the static window pointer.
ASSERT(c_pSplashWnd == this);
c_pSplashWnd = NULL;
}
BEGIN_MESSAGE_MAP(CSplashWnd, CWnd)
//{{AFX_MSG_MAP(CSplashWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CSplashWnd::EnableSplashScreen(BOOL bEnable /*= TRUE*/)
{
c_bShowSplashWnd = bEnable;
}
void CSplashWnd::ShowSplashScreen(CWnd* pParentWnd /*= NULL*/)
{
if (!c_bShowSplashWnd || c_pSplashWnd != NULL)
return;
// Allocate a new splash screen, and create the window.
c_pSplashWnd = new CSplashWnd;
if (!c_pSplashWnd->Create(pParentWnd))
delete c_pSplashWnd;
else
c_pSplashWnd->UpdateWindow();
}
BOOL CSplashWnd::PreTranslateAppMessage(MSG* pMsg)
{
if (c_pSplashWnd == NULL)
return FALSE;
// If we get a keyboard or mouse message, hide the splash screen.
if (pMsg->message == WM_KEYDOWN ||
pMsg->message == WM_SYSKEYDOWN ||
pMsg->message == WM_LBUTTONDOWN ||
pMsg->message == WM_RBUTTONDOWN ||
pMsg->message == WM_MBUTTONDOWN ||
pMsg->message == WM_NCLBUTTONDOWN ||
pMsg->message == WM_NCRBUTTONDOWN ||
pMsg->message == WM_NCMBUTTONDOWN)
{
c_pSplashWnd->HideSplashScreen();
return TRUE; // message handled here
}
return FALSE; // message not handled
}
BOOL CSplashWnd::Create(CWnd* pParentWnd /*= NULL*/)
{
//if (!m_bitmap.LoadBitmap(IDB_SPLASH))
if (!m_bitmap.LoadBitmap(IDB_BITMAP1))
return FALSE;
BITMAP bm;
m_bitmap.GetBitmap(&bm);
return CreateEx(0,
AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
NULL, WS_POPUP | WS_VISIBLE, 0, 0, bm.bmWidth, bm.bmHeight, pParentWnd->GetSafeHwnd(), NULL);
}
void CSplashWnd::HideSplashScreen()
{
// Destroy the window, and update the mainframe.
DestroyWindow();
AfxGetMainWnd()->UpdateWindow();
}
void CSplashWnd::PostNcDestroy()
{
// Free the C++ class.
delete this;
}
int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// Center the window.
CenterWindow();
// Set a timer to destroy the splash screen.
SetTimer(1, 20000, NULL);
return 0;
}
void CSplashWnd::OnPaint()
{
CPaintDC dc(this);
CDC dcImage;
if (!dcImage.CreateCompatibleDC(&dc))
return;
BITMAP bm;
m_bitmap.GetBitmap(&bm);
// Paint the image.
CBitmap* pOldBitmap = dcImage.SelectObject(&m_bitmap);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
dcImage.SelectObject(pOldBitmap);
}
void CSplashWnd::OnTimer(UINT nIDEvent)
{
// Destroy the splash screen window.
HideSplashScreen();
}
// CG: The following block was added by the Splash Screen component.
\
{
\
CCommandLineInfo cmdInfo;
\
ParseCommandLine(cmdInfo);
\
\
CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
\
}
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
BOOL CStyle1App::PreTranslateMessage(MSG* pMsg)
{
// CG: The following lines were added by the Splash Screen component.
if (CSplashWnd::PreTranslateAppMessage(pMsg))
return TRUE;
return CWinApp::PreTranslateMessage(pMsg);
}
VC++6.0入门——第九讲 定制应用功能程序外观
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有