用VC++制作变形窗体

首先,我们要建立一个基于对话框的工程distort,这样生成了三个类,即CAboutDlg , CDistort , CDistortDlg ,我们将要进行大改动的是CDistortDlg类,因此我们给出此文件的原代码,有改动的地方 我们用粉色字表出,并加人注释。

// distortDlg.h : header file
//

#if !defined(AFX_DISTORTDLG_H__B21CDC69_5A48_11D7_A464_00055DE445C1__INCLUDED_)
#define AFX_DISTORTDLG_H__B21CDC69_5A48_11D7_A464_00055DE445C1__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// CDistortDlg dialog

class CDistortDlg : public CDialog
{
// Construction
public:
CDistortDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
{{AFX_DATA(CDistortDlg)
enum { IDD = IDD_DISTORT_DIALOG };
// NOTE: the ClassWizard will add data members here
}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDistortDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CDistortDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
}}AFX_MSG

//重载 WM_NCTHITEST 消息,单激对话框任何部位都可移动对话框
afx_msg UINT OnNcHitTest(CPoint point);
//定时器,使窗体可以变形
afx_msg void OnTimer(UINT nIDEEvent);
//在撤销对话框时关闭定时器
afx_msg void OnDestroy();
DECLARE_MESSAGE_MAP()

private:

//窗体初始的矩形对象
CRect m_rectWnd;
//设置窗体所在区域
CRgn m_rgn;

};

{{AFX_INSERT_LOCATION}}

#endif // !defined(AFX_DISTORTDLG_H__B21CDC69_5A48_11D7_A464_00055DE445C1
__INCLUDED_)

下一步,我们先将对话框的属性中的stype设为popup ,而Border设为none,如图:

在此类的实现文件中,我们就将系统自动生成的函数略去了,只写出有改动的地方

// distortDlg.cpp : implementation file
//

#include "stdafx.h"
#include "distort.h"
#include "distortDlg.h"

#if def _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
//略去系统自动生成的类成员
......
//此处为消息宏映射
BEGIN_MESSAGE_MAP(CDistortDlg, CDialog)
{{AFX_MSG_MAP(CDistortDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()

ON_WM_NCHITTEST()
ON_WM_TIMER()
}}AFX_MSG_MAP
END_MESSAGE_MAP()
//下面我们将要加入对话框程序一般都要重载的虚函数 OnInitDiolog(),它是消息响应函数,处理 //WM_INITDIALOG 消息

#define EVENT_REDRAW 0

BOOL CDistortDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
//获得对话框客户区的尺寸
GetClientRect(m_rectWnd);
//创建窗体对话框客户区的尺寸
m_rgn.CreateEllipticRgn(0,0,m_rectWnd.right,m_rectWnd.bottom);
//设置重画窗口定时器,每0.1秒重绘一次 SetWindowRgn((HRGN)m_rgn,TRUE);
this->SetTimer(EVENT_REDRAW,100,NULL);

//-------------------------set time----------------------------
return TRUE;
// return TRUE unless you set the focus to a control

其中椭圆效果是通过 int SetWindowRgn(HRGN hRgn,BOOL bRedraw);
而参数 hRgn 是窗体区的句柄, 参数 bRedraw 是决定是否要重画窗体,在本例中Windows 向窗体发送 WM_PAINT消息,从而调用 OnPaint()函数,
下面我们来修改此函数

void CDistortDlg::OnPaint()
{
CPaintDC dc(this);
if (IsIconic())
{
// device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
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;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
//add by myself---------------------------------------------------
dc.SelectStockObject(NULL_PEN);//绘制不带边的椭圆

//获得客户区的尺寸
CRect rect;
GetClientRect(rect);

CBrush *pBrushOld;
CBrush brushNew;

//定义画刷,在此你可以更改颜色
brushNew.CreateSolidBrush(RGB(204,255,66));
//选取画刷作为画图设备
pBrushOld=dc.SelectObject(&brushNew);
//绘制椭圆
dc.Ellipse(rect);
//还原画刷,并释放
dc.SelectObject(pBrushOld);
brushNew.DeleteObject();
}
}

//下面编写实现窗体任意托动的函数

HCURSOR CDistortDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

UINT CDistortDlg::OnNcHitTest(CPoint point)
{
UINT nHitTest=CDialog::OnNcHitTest(point);
return(nHitTest==HTCLIENT)?HTCAPTION:nHitTest;
}

//下面编写定时器实数

//若想结果n次变化后正好便为圆形,则设此值为 1.035
#define MULTI 1.1

void CDistortDlg::OnTimer(UINT nIDEvent)
{
static nCount=0;//窗体变化次数,每次增1
static bOrder=1;//表示变大或变小
static double dMulti=1;//窗体的变化倍数

CRect rectWnd;
CPoint ptMiddle,ptTopLeft,ptBtmRight;

//确定窗体区域中心
ptMiddle=m_rectWnd.CenterPoint();

//分情况处理各种定时事件
switch(nIDEvent)
{
case EVENT_REDRAW:
nCount++;
if(bOrder==1)
{//表示变大
dMulti*=MULTI;
}
else
{//表示变小
dMulti/=MULTI;
}

//确定窗体的矩形大小
ptTopLeft.x=(long)(ptMiddle.x-m_rectWnd.Width()/(2*dMulti));
ptTopLeft.y=(long)(ptMiddle.y-m_rectWnd.Height()/2);
ptBtmRight.x=(long)(ptMiddle.x+m_rectWnd.Width()/(2*dMulti));
ptBtmRight.y=(long)(ptMiddle.y+m_rectWnd.Height()/2);
rectWnd.SetRect(ptTopLeft,ptBtmRight);

//释放对象
m_rgn.Detach();

//创建椭圆区域
m_rgn.CreateEllipticRgn(ptTopLeft.x,ptTopLeft.y,ptBtmRight.x,ptBtmRight.y);

SetWindowRgn((HRGN)m_rgn,TRUE);

if(nCount==10)//设置变化次数,此为10次
{
nCount=0;
bOrder=(bOrder==1)?-1:1;//10次之后反向变化
}
break;
}
CDialog::OnTimer(nIDEvent);
}

最后的效果如图:

希望大家通过对本例的实践,初步了解 MFC 的对话框机制 (细节请参见《Vicual c++ 高级编程》)

用VC++制作变形窗体相关推荐

  1. C#WinForm制作异形窗体/控件

    制作异形窗体或控件的思路一般都是想办法生成一个region,然后设置给指定的窗口或控件.生成region的方法有很多,最常用的就是从一幅图片生成,把该图片中的透明色部分"抠"掉,剩 ...

  2. C# 制作不规则窗体的两种解决方案

    我的广告单元,有空点一下哦,谢谢! 冒着被拍砖的危险,投放到首页.C#制作不规则窗体应该又是一个老生常谈的问题了,可能很多老鸟会带BS的眼神,那么请老鸟们视该文章如浮云吧. 制作不规则窗体,本例采用图 ...

  3. java 窗体 源码_Java制作MDI窗体源代码

    由于实际需要做一个MDI窗体,百度里面找到一个不错的源代码给大家分享一下. import javax.swing.*; import java.awt.event.*; import java.awt ...

  4. 用VC++制作MSN、QQ 的消息提示窗口

    用VC++制作MSN.QQ 的消息提示窗口 用过QQ和MSN聊天工具的人都知道,只要好友上线,就会在托盘的位置处显示一个提示窗口,以是拉帘式的,或者是淡入淡出的形式出现:想想何不为自己的程式也加一个漂 ...

  5. VC制作类似于IE4的酷工具条

    用VC制作工具条的方法很多,本文提供一种制作类似于IE4.0的工具条.能实现鼠标移上图标时,图标变为彩色,在工具条的位置,能停摆几种工具条.具体原理解释见步骤过程. 步骤如下: 1.    运行App ...

  6. 电子脑PHP动画制作,用Flash制作变形动画效果

    Flash中的变形动画是动画的一种类型,它和运动动画相反,只对图形起作用而对元件不能产生动画效果.应用变形动画可以产生一些奇妙的变形效果,能使课件更富有吸引力,下面小编就为大家介绍用Flash制作变形 ...

  7. 使用C#制作Windows窗体应用,实现一个微端下载器功能(多线程/断点续传/微端/下载器)

    文章目录 一.前言 二.最终运行效果 三.Demo工程下载 四.工程类型 五.工程结构 六.多线程下载核心代码 一.前言 在PC端的QQ游戏大厅下载游戏的时候,我们会发现很多游戏都自己做了微端下载器, ...

  8. 【181114】VC++制作木质相框源代码

    源码下载简介 VC++制作木质相框,呵呵,相当基础的例子,不要感觉神秘哦,新手参考吧. 源码下载地址:点击下载 备用下载地址:点击下载

  9. VC 获取控制台窗体的句柄(hWnd)

    在Windows中,句柄是外国话,理解为编号的意思,只要你知道了这个窗口的句柄,就可以对这个窗体进行操作--移动窗体.改变窗体大小.把窗体极小化为图标等.Windows API函数中的句柄代表一些特殊 ...

最新文章

  1. Java_中快速获取系统时间
  2. python代码转换为pytorch_Pytorch中Tensor与各种图像格式的相互转化详解
  3. docker build 没有网络 执行dockerfile中yum报错 curl#6 - “Could not resolve host: mirrorlist.centos.org 解决方法
  4. 【小题目】输入三个数字,获取三个数字中的最小值
  5. ASP.NET Core - 基于IHttpContextAccessor实现系统级别身份标识
  6. [oracle原]访问局域网内出现“ORA-12541:TNS:无监听程序”
  7. HTML网页设计综合题,网页设计(Html5)试题C卷
  8. C#编程(二十五)----------接口
  9. webstorm 高效开发 (html)
  10. 老码识途——1.1反汇编机器码入门
  11. CSDN会员服务协议
  12. ThinkPHP在前台模板格式化输出时间
  13. 解决以太网IPv4无网络访问权限
  14. “黑暗潜伏者” -- 手机病毒新型攻击方式
  15. 胡阳pyhton作业题--20150801
  16. 没有软件开发人员,可以办理CMMI3级吗?
  17. 【转】定员108的车厢号码分布图
  18. Python绘制地图神器,上手直接开大!
  19. Linux 解压tar.bz2格式文件
  20. 免杀veil的简单使用

热门文章

  1. 产品人如何在小企业中夹缝生存?
  2. 能力清单:2020年SAAS的思考框架
  3. mysql begin end 用法_超实用的Mysql动态更新数据库脚本的示例讲解(推荐)
  4. java 对象的交互_Java中什么是对象的交互?解释一下交互怎么操作?
  5. 生态系统长期观测数据产品体系
  6. 作者:孔新川,杭州迈宁数据科技有限公司创始人、CEO。
  7. 【Java】《面向对象程序设计——Java语言》Castle代码修改整理
  8. 大量Input还是要靠scanf(洛谷P5082题题解,弃坑Java拥抱C++)
  9. 质因数分解(洛谷P1075题题解,Java语言描述)
  10. 【Python】Python列表基本操作