分享
 
 
 

用VC++制作变形窗体

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

用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++ 高级编程》)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有