1. 程式人生 > >MFC逃跑按鈕的實現(兩種方式)

MFC逃跑按鈕的實現(兩種方式)

簡易版本的逃跑按鈕的實現,下面是兩個實現方法,一個是建立兩個一樣的按鈕,然後通過一個按鈕接觸滑鼠時,隱藏並顯示另一個按鈕來實現"逃跑"。另一個是通過SetWindowPos函式來隨機地讓按鈕在新位置出現 下面是主要的程式碼 先是第一個版本 然後是第二個版本

// NewButton.cpp : implementation file
//

#include "stdafx.h"
#include "Test.h"
#include "NewButton.h"

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

/////////////////////////////////////////////////////////////////////////////
// CNewButton

CNewButton::CNewButton()
{
	m_pBtn=NULL;
}

CNewButton::~CNewButton()
{
}


BEGIN_MESSAGE_MAP(CNewButton, CButton)
	//{{AFX_MSG_MAP(CNewButton)
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNewButton message handlers

void CNewButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	ShowWindow(SW_HIDE);
	m_pBtn->ShowWindow(SW_SHOW);

	CButton::OnMouseMove(nFlags, point);
}

上面是派生於CButton類的一個按鍵類,用來關聯按鈕視窗,定義了一個指標變數,用來儲存另外一個按鈕的地址

BOOL CTestDlg::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

	m_btn1.m_pBtn=&m_btn2;
	m_btn2.m_pBtn=&m_btn1;
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

在程式執行時,當對話方塊及其上面的子控制元件建立完成,在顯示之前會發送一個訊息:WM_INITDLALOG,他的響應函式就是上面的OnInitDialog,所以將指標m_pBtn的賦值放在這個函式的後面,當然在return 之前。在執行之前要先把其中一個按鈕的屬性中的visible選項不選,才不會一開始的時候兩個按鈕都顯示在對話方塊中。

第二個版本:

// NewButton.cpp : implementation file
//

#include "stdafx.h"
#include "taopao2.h"
#include "NewButton.h"

#include <time.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CNewButton

CNewButton::CNewButton()
{
	i=0;
	j=0;
}

CNewButton::~CNewButton()
{
}


BEGIN_MESSAGE_MAP(CNewButton, CButton)
	//{{AFX_MSG_MAP(CNewButton)
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNewButton message handlers

void CNewButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CRect rectLarge;
	CRect rectbutton;
	GetParent()->GetWindowRect(&rectLarge);
	GetWindowRect(&rectLarge);
	
	i=point.y+rand()%(rectLarge.Width()*3);
	j=point.x+rand()%(rectLarge.Height()*3);
	SetWindowPos(NULL,i,j,0,0,SWP_NOSIZE);
	
	CButton::OnMouseMove(nFlags, point);
}

新類CNewButton派生於CButton類

這次用到的主要函式有:

void GetWindowRect( LPRECT lpRect ) const;

Parameters

lpRect

Points to a CRect object or a RECT structure that will receive the screen coordinates of the upper-left and lower-right corners
BOOL SetWindowPos( const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );

Return Value

Nonzero if the function is successful; otherwise 0.

下面是關於SetWindowPos的一個介紹 網上找到的

  引數pWndInsertAfter  
  標識了在Z軸次序上位於這個CWnd物件之前的CWnd物件。這個引數可以是指向CWnd物件的指標,也可以是指向下列值的指標:  
  wndBottom     將視窗放在Z軸次序的底部。如果這個CWnd是一個頂層視窗,則視窗將失去它的頂層狀態;系統將這個視窗放在其它所有視窗的底部。  
  wndTop     將視窗放在Z軸次序的頂部。  
  wndTopMost     將視窗放在所有非頂層視窗的上面。這個視窗將保持它的頂層位置,即使它失去了活動狀態。  
  wndNoTopMost     將視窗重新定位到所有非頂層視窗的頂部(這意味著在所有的頂層視窗之下)。這個標誌對那些已經是非頂層視窗的視窗沒有作用。有關這個函式以及這些引數的使用規則參見說明部分。  
   
  x指定了視窗左邊的新位置。  
  y指定了視窗頂部的新位置。  
  cx指定了視窗的新寬度。  
  cy指定了視窗的新高度。  
   
  nFlags指定了大小和位置選項。這個引數可以是下列值的組合:  
  SWP_DRAWFRAME     圍繞視窗畫出邊框(在建立視窗的時候定義)。  
  SWP_FRAMECHANGED     向視窗傳送一條WM_NCCALCSIZE訊息,即使視窗的大小不會改變。如果沒有指定這個標誌,則僅當視窗的大小發生變化時才傳送WM_NCCALCSIZE訊息。  
  SWP_HIDEWINDOW     隱藏視窗。  
  SWP_NOACTIVATE     不啟用視窗。如果沒有設定這個標誌,則視窗將被啟用並移動到頂層或非頂層視窗組(依賴於pWndInsertAfter引數的設定)的頂部。  
  SWP_NOCOPYBITS     廢棄這個客戶區的內容。如果沒有指定這個引數,則客戶區的有效內容將被儲存,並在視窗的大小或位置改變以後被拷貝回客戶區。  
  SWP_NOMOVE     保持當前的位置(忽略x和y引數)。  
  SWP_NOOWNERZORDER     不改變擁有者視窗在Z軸次序上的位置。  
  SWP_NOREDRAW     不重畫變化。如果設定了這個標誌,則不發生任何種類的變化。這適用於客戶區、非客戶區(包括標題和滾動條)以及被移動視窗覆蓋的父視窗的任何部分。當這個標誌被設定的時候,應用程式必須明確地無效或重畫要重畫的視窗和父視窗的任何部分。  
  SWP_NOREPOSITION     與SWP_NOOWNERZORDER相同。  
  SWP_NOSENDCHANGING     防止視窗接收WM_WINDOWPOSCHANGING訊息。  
  SWP_NOSIZE     保持當前的大小(忽略cx和cy引數)。  
  SWP_NOZORDER     保持當前的次序(忽略pWndInsertAfter)。  
  SWP_SHOWWINDOW     顯示視窗。