MFC逃跑按鈕的實現(兩種方式)
阿新 • • 發佈:2019-02-12
簡易版本的逃跑按鈕的實現,下面是兩個實現方法,一個是建立兩個一樣的按鈕,然後通過一個按鈕接觸滑鼠時,隱藏並顯示另一個按鈕來實現"逃跑"。另一個是通過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 顯示視窗。