日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

用VC++制作变形窗体

發布時間:2025/3/15 c/c++ 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用VC++制作变形窗体 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
用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++制作变形窗体的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。