用VC++制作变形窗体
2004-12-03 08:18
585 查看
用VC++制作变形窗体
首先,我们要建立一个基于对话框的工程distort,这样生成了三个类,即CAboutDlg , CDistort , CDistortDlg ,我们将要进行大改动的是CDistortDlg类,因此我们给出此文件的原代码,有改动的地方 我们用粉色字表出,并加人注释。
下一步,我们先将对话框的属性中的stype设为popup ,而Border设为none,如图:
在此类的实现文件中,我们就将系统自动生成的函数略去了,只写出有改动的地方
其中椭圆效果是通过 int SetWindowRgn(HRGN hRgn,BOOL bRedraw);
而参数 hRgn 是窗体区的句柄, 参数 bRedraw 是决定是否要重画窗体,在本例中Windows 向窗体发送 WM_PAINT消息,从而调用 OnPaint()函数,
下面我们来修改此函数
最后的效果如图:
希望大家通过对本例的实践,初步了解 MFC 的对话框机制 (细节请参见《Vicual c++ 高级编程》)
首先,我们要建立一个基于对话框的工程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_) |
在此类的实现文件中,我们就将系统自动生成的函数略去了,只写出有改动的地方
// 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 |
而参数 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++ 高级编程》)
相关文章推荐
- 哪个高手帮帮忙啊,谢谢了
- 参加特色教育网站评比
- 教育软件评审
- 帮帮我好不好!!!!
- 一个画图类,类似ms_chart的线图,适用于科学仿真数据分析(二)
- 使用C#开发COM+组件
- 看到一篇好文章与大家分享!!!!!
- thinkng in c++卷2
- servlet生命周期
- 如何通过动态生成Html灵活实现DataGrid分类统计的界面显示功能
- 一般网站用户注册流程:(适用初学者)
- 组件制作之二(一个简单组件的制作过程)
- 组件制作之四(定制外观)
- 在C#中编写多线程应用程序,简单!
- 关于C语言中的变量
- 权限管理的设计和实现
- 完全用 VB 6.0 自身功能实现对 Windows 消息的拦截!
- 序之学习C++
- 天天英语之04——11_11
- 一个投票程序