Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >VC++6.0入门——第九讲 定制应用功能程序外观

VC++6.0入门——第九讲 定制应用功能程序外观

原创
作者头像
Arya
发布于 2024-12-03 02:34:13
发布于 2024-12-03 02:34:13
1060
举报
文章被收录于专栏:后端开发专栏后端开发专栏

在文章开始之前,推荐一篇值得阅读的好文章!感兴趣的也可以去看一下,并关注作者!

题目: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,用来设定窗口的类型、光标、背景和图标。该函数的原型声明如下所示:

代码语言:java
AI代码解释
复制
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 0,0,
		LoadIcon(NULL,IDI_WARNING));
代码语言:java
AI代码解释
复制
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
		LoadCursor(NULL,IDC_HELP),
		(HBRUSH) GetStockObject(BLACK_BRUSH),
		0);

在窗口创建后修改

代码语言:java
AI代码解释
复制
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));

对于CStyleView类来说, AppWizard并没有自动为它创建OnCreate函数,因此,我们需要为该类添加WM_CREATE消息的响应函数,然后在这个响应函数(OnCreate函数)中,调用SetClassLong函数修改视类窗口的光标和背景

代码语言:java
AI代码解释
复制
	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数据成员。

代码语言:java
AI代码解释
复制
	// 加载图标
	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取模。实际上,取模运算就是取余。

代码语言:java
AI代码解释
复制
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按钮向右拖动一点距离后再松开鼠标,此时可以看到,在帮助按钮和工按钮之间就有了一点空隙。

删除的方式

创建工具栏

插入工具栏的两种方式

显示和隐藏实现

代码语言:java
AI代码解释
复制
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);

}
代码语言:java
AI代码解释
复制
ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);

对号标记的实现

代码语言:java
AI代码解释
复制
void CMainFrame::OnUpdateNewTool(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());
}

状态栏编程

代码语言:java
AI代码解释
复制
	// 获得一下时间, 设置为窗格显示内容
	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);

进度条

代码语言:java
AI代码解释
复制
	CProgressCtrl m_progress; // 进度条	


	// 创建进度栏
	m_progress.Create(WS_CHILD | WS_VISIBLE,CRect(100,100,200,120),this,1234);
	m_progress.SetPos(50);
代码语言:java
AI代码解释
复制
	m_progressv.Create(WS_CHILD | WS_VISIBLE | PBS_VERTICAL,CRect(100,150,120,300),this,12345);
	m_progressv.SetPos(70);
【插曲】程序调试
代码语言:java
AI代码解释
复制
// 定义一个消息
#define UM_PROGRESS WM_USER+1
代码语言:java
AI代码解释
复制
	// 声明消息响应函数
	afx_msg void OnProgress();
代码语言:java
AI代码解释
复制
	// 建立消息和消息响应函数的映射关系
	ON_MESSAGE(UM_PROGRESS,OnProgress)
代码语言:java
AI代码解释
复制
	// 发送一个消息
	PostMessage(UM_PROGRESS);
代码语言:java
AI代码解释
复制
// 实现消息响应函数
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);

}
代码语言:java
AI代码解释
复制
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
}
代码语言:java
AI代码解释
复制
	// 进度栏每间隔1s前进
	m_progressm.StepIt();

显示鼠标当前位置

view类上,点击右键,增加消息处理

代码语言:java
AI代码解释
复制
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);
}

启动画面

从其他项目复制代码

代码语言:java
AI代码解释
复制
// 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
代码语言:java
AI代码解释
复制
// 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();
}

app中加入代码

代码语言:java
AI代码解释
复制
		// CG: The following block was added by the Splash Screen component.
\
	{
\
		CCommandLineInfo cmdInfo;
\
		ParseCommandLine(cmdInfo);
\

\
		CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
\
	}
代码语言:java
AI代码解释
复制
public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
代码语言:java
AI代码解释
复制
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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C/C++ 如何来自动优雅的涮别银家的贴子
  被涮屏涮烦了,就分享一下如何用低调的c/c++来涮别人家的屏吧! 此处埋下三颗雷! 这不是啥新知识,也不是什么浅显的代码。下面,来淘淘这份经验,呼呼 我们要了解Web browser 这个控件,因为到目前为止,很少有浏览器能够被调用内核API,而Web browser 提供了IE的内核内容,就是我们可以用Ie提供的内核来自己设计一个简单的浏览器  当然,我们这儿并不是扯这个蛋。 但是为了后面说起来比较合理些 ,就只能翻山越岭的开始介绍了! 首先创建一个dlg,然后点击Acx control ,如果看见了
Gxjun
2018/03/26
1.3K0
C/C++ 如何来自动优雅的涮别银家的贴子
MFC编程入门之五(MFC消息映射机制概述)
在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作。 比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应。
acoolgiser
2019/06/14
1.8K0
简单的TCP客户端发包工具[通俗易懂]
链接:https://pan.baidu.com/s/1MzNUzwd7WwBat6vNMcu6Ow 密码:ibuv
全栈程序员站长
2022/10/04
3.8K0
简单的TCP客户端发包工具[通俗易懂]
MFC原理第六讲.消息传递
    通过上一讲我们的消息映射表.我们得知. 消息映射表 会保存父类的MessageMap 以及自己当前的消息结构体数组.
IBinary
2019/05/25
1K0
VC++6.0入门——第六讲 菜单编程
题目:Text to image论文精读Adma-GAN:用于文本到图像生成的属性驱动内存增强型GAN Attribute-Driven Memory Augment
Arya
2024/11/20
1580
VC++6.0入门——第六讲 菜单编程
MFC学习笔记3引用资源
#include <afxwin.h> #include "resource.h"//引用是必须的,不然菜单不会出现 class MyFrameWindow:public CFrameWnd { public: afx_msg void OnPaint() { CPaintDC paintDC(this); paintDC.TextOut(0,0,"这是我的第一个窗口程序"); } afx_msg void OnFileExit()
liulun
2022/05/09
2130
MFC学习笔记3引用资源
MFC进度条同步问题
大家好,又见面了,我是你们的朋友全栈君。 读者朋友们可能天天使用Visual C++这个强大的工具来开发应用程序,不知道注意到没有,Visual C++每次装载一个项目的时候,为了使项目加载过程不至于太单调,会在状态栏的左半部分会出现一个装载进度条,用来即时显示Visual C++装载项目的进度,当项目装载完毕后,进度条隐藏。那么这个功能是如何实现的呢?为了说明该功能的实现原理,本例提供了一个范例程序prgsbar,它演示了在编辑视图里显示文本文件,在加载文本文件时,在界面的状态条中的进度指示器仿真显示文件的加载过程,当文本装载完毕后,进度条隐藏。由于该程序在装载文件显示的进度条时无法进行拷屏操作,所以这里没有给出状态条中显示进度条的界面效果图,读者可以运行本书所带光盘中的程序代码观看相应的效果。   一、实现方法   虽然Visual C++中的MFC类提供了标准的进度指示器控件(progress control),但是我们不能在状态栏里直接使用这个控件,要解决这个问题,可以创建一个可重用C++类CProgStatusBar,这个类从CStatusBar派生,用来来实现状态条中的进度指示。整个实现过程不是很难,思路是在状态栏创建一个进度指示器控制,把它作为子窗口来对待,然后根据不同的状态来显示或者隐藏进度指示器。   在具体实现CProgStatusBar类的过程中,首先在CProgStatusBar派生类中加了一个CProgressCtrl类型的数据成员–m_wndProgBar,然后重载CstatusBar类的二个重要成员函数:OnCreate()、OnSize(),最后还要在该类中添加一个自定义成员函数OnProgress()。在上述三个函数中, OnCreate()负责在状态栏第一次被创建时接收控制,继而创建进度指示器并将它初始化为一个子窗口,它的实现代码如下: int CProgStatusBar::OnCreate(LPCREATESTRUCT lpcs) {  lpcs->style |= WS_CLIPCHILDREN;  VERIFY(CStatusBar::OnCreate(lpcs)==0);  VERIFY(m_wndProgBar.Create(WS_CHILD, CRect(), this, 1));  m_wndProgBar.SetRange(0,100);  return 0; }   OnCreate()函数在状态栏的式样中加了一个WS_CLIPCHILDREN,它告诉Windows不要绘制子窗口以下的状态栏区域,这样可以减少屏幕闪烁。接着OnCreate()函数创建进度指示器控件并将它的范围设置成[0,100]。注意在这里创建进度指示器控件时没有用WS_VISIBLE,因为我们要实现的目标是仅仅当装载文件时进度条才显现,其余时间内应用程序都隐藏它。   熟悉Windows编程的人都清楚,无论何时,只要在某个窗口里添加子窗口,那么一定要负责管理它的大小尺寸,也就是说,当父窗口大小改变后,子窗口的大小也要跟着作相应的改变。一般来说,这个工作由父窗口的WM_SIZE消息处理函数OnSize()来作,所以我们也要处理该类的OnSize()函数。 void CProgStatusBar::OnSize(…) {  CStatusBar::OnSize(…);  CRect rc;  GetItemRect(0, &rc);//获取状态条的第一个窗口的尺寸;  m_wndProgBar.MoveWindow(&rc,FALSE);//移动进度条到状态条的第一个窗口; }   从上述代码可以看出,CProgStatusBar::OnSize()将进度指示器放在了状态栏的第一个窗格,这个窗格通常用来显示程序的”就绪”信息和命令提示信息。注意这里不论进度指示器是处于可见状态还是隐藏状态,MoveWindow都照样起作用–所以即便是进度指示器处于隐藏状态,其窗口大小同样是可调的。   调整好进度指示器的窗口大小后,下面要作的就是进度指示器的显示,进度指示器当前进度状态的显示在CProgStatusBar::OnProgress中完成。它有一个类型为UINT的入口参数:参数值的范围从0到100,表示进度百分比,0表示进度没开始,100表示全部完成。如果这个参数的值大于0,则OnProgress显示进度控制并设置指示器的位置;如果参数值等于0,则 OnProgress隐藏进度控制。   虽然子窗口控件通常都是放在父窗口能绘制的区域的最上面,但这样做在绘制方面是有一定风险的。在隐藏/显示进度控制时尤其如此,这时候会出现两个问题:第一,因为进度指示器显示在状态栏的第一个窗格位置,所以如果进度条指示器
全栈程序员站长
2022/09/18
1.2K0
MFC应用程序——标签控件_IP控件_时间控件_List Control控件_Tree Control控件_命令按钮_列表框_组合框_图片_滚动控件「建议收藏」
【Tab Control 标签控件】 标签控件也比较常见。它可以把多个页面集成到一个窗口中, 每个页面对应一个标签,用户点击某个标签时,它对应的页 面就会显示。 使用标签控件我们可以同时加载多个有关联的页面,用 户只需点击标签即可实现页面切换,方便灵活的进行操作。 每个标签除了可以显示标签文本,还可以显示图标。 标签控件相当于是一个页面的容器,可以容纳多个对话 框,而且一般也只容纳对话框,所以我们不能直接在标签控 件上添加其他控件,必须先将其他控件放到对话框中,再将 对话框添加到标签控件中。最终我们点击标签切换页面时, 切换的不是控件的组合,而是对话框。
全栈程序员站长
2022/09/23
2.7K0
MFC应用程序——标签控件_IP控件_时间控件_List Control控件_Tree Control控件_命令按钮_列表框_组合框_图片_滚动控件「建议收藏」
directshow摄像头录像_open camera 使用方法
工程下载: http://download.csdn.net/detail/yulinxx/9263639
全栈程序员站长
2022/11/08
1.7K0
directshow摄像头录像_open camera 使用方法
窗口分割
我们在使用OutLook或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割。 那么我们自己如何创建类似的界面,也实现窗口的任意的分割呢?要解决这个问题,在Visual C++6.0编程中就需要使用到MFC提供的CSplitterWnd类。CSplitterWnd看上去像是一种特殊的框架窗口,每个窗口都被相同的或者不同的视图所填充。当窗口被切分后用户可以使用鼠标移动切分条来调整窗口的相对尺寸。虽然VC6.0支持从AppWizard中创建分割窗口,但是自动加入的分割条总是不能让我们满意,因此我们还是通过手工增加代码来熟悉这个类。本实例采用多模板模式,即实现了窗口的任意分割,又介绍了各个视图如何相互通信。程序编译运行后的界面效果如图一所示:
全栈程序员站长
2022/07/18
7980
opencv:image->imageData+image->widthStep*i)[j]表达式含义
image->imageData+image->widthStep*i)[j] 就是得到image图像中第i行第j列的像素值。
全栈程序员站长
2022/08/31
2740
opencv:image->imageData+image->widthStep*i)[j]表达式含义
【大三操作系统实验】 请求页式管理中的置换算法
(1)FIFO算法总是选择在内存驻留时间最长的一页将其淘汰。FIFO算法认为调入内存的页不再被可能性要比其他页大,因而选择最先调入内存的页换出。
用户7886150
2020/12/29
5520
基于消息的事件驱动机制(Message Based, Event Driven)
基于消息的事件驱动机制是一个通用模型,广泛应用于桌面软件开发、网络应用程序开发、前端开发等技术方向中。本文主要描述基本模型、基本框架,用于说明不同技术的共性知识。可以理解为外部操作事件,被转化为消息存放于队列中;而每种类型的消息都有对应的处理;通过消息循环,完成读消息、调用消息处理这个过程。这个过程,只要应用不退出,会一直进行下去。下图的模型从Windows应用程序而来,但是具有一定的通用性。
河边一枝柳
2021/08/06
2.7K0
基于消息的事件驱动机制(Message Based, Event Driven)
VC++6.0入门——第三讲 认识MFC框架
今日推荐:【机器学习】机器学习回归模型全解析:线性回归、多项式回归、过拟合与泛化、向量相关性与岭回归的理论与实践
Arya
2024/11/15
4290
VC++6.0入门——第三讲 认识MFC框架
VC++6.0 转 VS2005以上版本(1)
AutoPDMS8.0源码使用高版本ObjectARX(2004/2007)编译的总结
用户3519280
2023/07/06
3170
VC++6.0入门——案例 电话本的案例
题目:Text to image论文精读Adma-GAN:用于文本到图像生成的属性驱动内存增强型GAN Attribute-Driven Memory Augment
Arya
2024/11/22
730
VC++6.0入门——案例 电话本的案例
VC++ MFC 常用技巧 (一)
VC++ MFC 常用技巧(一)  <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 我现在学习
ternturing
2018/09/12
1.4K0
VC++6.0入门——第四讲 简单绘图
文章链接:https://cloud.tencent.com/developer/article/2465870
Arya
2024/11/18
1230
VC++6.0入门——第四讲 简单绘图
VC编程常见问题解答收集贴
1.使用ModifyStyleEx改变了控件风格无效 答:修改之后,重绘一次,如果还不行的话,再试试看调用SetWindowPos(0,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME);
全栈程序员站长
2022/09/09
1.7K0
VC++6.0入门——第7讲 对话框编程(一)
好事文章地址:https://cloud.tencent.com/developer/article/2470499
Arya
2024/11/25
2400
VC++6.0入门——第7讲 对话框编程(一)
相关推荐
C/C++ 如何来自动优雅的涮别银家的贴子
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档