第8課 逃跑按鈕的巧妙實現

來源:互聯網
上載者:User
文章目錄
  • Return Value (of OnWizardNext)
  • Return Value

1.如何改變按紐的字型?在對話方塊的屬性中改變字型的屬性即可
2.逃跑按紐的實現
  1.從CButton派生一個類,CWeixinBtn
  2.將IDC_EDIT1關聯成員變數m_btn1,類型為CWeixinBtn,注意要包含標頭檔。
  3.在CWeixinBtn中加一個指標成員變數CWeixinBtn *pWeixinBtn,然後將其地址初始化。
  4.在新類中增加滑鼠移動的訊息處理。
3.屬性工作表單
  1.插入屬性頁面資源。Insert->new Resource->Dialog
  2.當選擇Classwizard菜單時,系統提示是否為建立新的類,我們將其從CPropertyPage派生!這樣可以為

方便為其增加訊息響應函數。
  3.插入新的從CPropertySheet派生的類,在類中增加3個CPropertyPage的執行個體。
  4.在view中增加功能表項目,當點擊時顯示內容表單,出現中文亂碼,修改CPropertyPage屬性為中文,另外將

其字型設為宋體。
  5.在CPropertyPage中設定SetWizardButtons可將其屬性改為上一步、完成!
  6.為IDC_RADIO1關聯成員變數,需要先設定Group屬性才行。另外別忘記調用UpdateData().
  7.為CPropertyPage增加虛函數,OnWizardNext,如果使用者點擊下一步時,不想讓他進入下一步,剛返回-1!
  8.將使用者的選擇輸出到螢幕上,此時可以在View中增加幾個成員變數,用來接收使用者選擇的資料。

4.memset()的用法! memset(m_bLike,0,sizeof(m_bLike));

 

一、 簡單的逃跑按鈕

//開始: 架構對話方塊屬性裡面有Font字型改變的選項,但在其上放置的按鈕沒有

//上面的情況,可以通過前者改變後者

//注意下列方法,定義一個類為了捕獲滑鼠移動點的方便

1,建立一個基於對話方塊的MFC AppWizard工程

2,在View視窗點右鍵,添加一個自訂的類(或者用Classwizard工具添加),基類為CButton

class CWeiXinBtn : public CButton

3,給CWeiXinBtn類新增成員變數CWeiXinBtn* m_pBtn;

4,給對話方塊添加倆按鈕,每個按鈕都關聯一個CWeiXinBtn的變數

5,在OnInitDialog添加

       m_btn1.m_pBtn=&m_btn2;

       m_btn2.m_pBtn=&m_btn1;

6,CWeiXinBtn::OnMouseMove中添加切換顯示器的語句

       ShowWindow(SW_HIDE);

       m_pBtn->ShowWindow(SW_SHOW); //將對方顯示出來...

大功告成!

當然可以SetWindowPos函數實現更客觀

//由此可見,我們見到的程式----一切都是虛幻!(超哥等人的名言...)

二、 屬性頁面的編輯

//插入三個IDD_PROPPAGE_LARGE型屬性頁面資源

ID: IDD_PROP 1/2/3 Caption:Prop1/2/3

我們插入的對話方塊: 屬性頁面----More Styles: Disabled

//調整控制項儲存位置:按住Ctrl鍵選擇以後在左下角

Radio

Check

Combox (注意要拉得大一點,否則可能顯示不出來,但是又不能調整大小;所以我們只有在擺放的同時將它拉得大一些)

三種類型: Dropdown: 可以輸入,且有一個列表框;

Simple: 列表框和輸入框一同顯示(果然相當地simple)

DropList: 編輯框不能輸入

CProp1的基類要選擇為: CPropertyPage

添加類時VC++本身的問題看不到Prop1,刪掉.clw,再產生之;還是用原來的Prop.clw這個名字

1,CPropertyPage類

As with standard dialog boxes, you derive a class from CPropertyPage for each page in your property sheet. To use CPropertyPage-derived objects, first create a CPropertySheet object, and then create an object for each page that goes in the property sheet. Call CPropertySheet::AddPage for each page in the sheet, and then display the property sheet by calling CPropertySheet::DoModal for a modal property sheet, or CPropertySheet::Create for a modeless property sheet.

//增加一個CPropSheet類,基類為CPropertySheet;

在CPropSheet中增加成員變數

#include "Prop1.h"
#include "Prop2.h"
#include "Prop3.h"

CProp1 m_prop1;
CProp2 m_prop2;
CProp3 m_prop3;

在sheet的建構函式中添加propertyPage

在CPropSheet兩個建構函式(只是第一個參數UINT nIDCaption和LPCTSTR pszCaption不一樣)中,都增加如下:

AddPage(&m_prop1);
AddPage(&m_prop2);
AddPage(&m_prop3);

//預設是第一個最先出現

prop1sheet::AddPage 把頁面添加到sheet

//在View類出增加OnPropertysheet函數並編輯如下代碼:

CPropSheet propSheet("維新屬性工作表單程式");

prop1sheet.DoModal();

//出現亂碼

解決: 將新增加的IDD_PROP1/2/3語言一欄修改為Chinese(P.R.C),同時修改字型

屬性-->嚮導:

在DoModal之前調用SetWizardMode()即可變為嚮導

但上一步,下一步有問題

CPropertySheet classmembers SetWizardButtons

Enables or disables the Back, Next, or Finish button in a wizard property sheet.

void SetWizardButtons( DWORD dwFlags ); 
dwFlags

A set of flags that customize the function and appearance of the wizard buttons. This parameter can be a combination of the following values:

  • PSWIZB_BACK   Back button

  • PSWIZB_NEXT   Next button

  • PSWIZB_FINISH   Finish button

  • PSWIZB_DISABLEDFINISH   Disabled Finish button

Call SetWizardButtons only after the dialog is open; you can't call SetWizardButtons before you call DoModal. Typically, you should call SetWizardButtons from CPropertyPage::OnSetActive.

於是我們進入OnSetActive (虛函數)

在Prop1右鍵-->增加虛函數

2,屬性頁面變嚮導類型

prop1sheep.SetWindowMode();//嚮導模式語句

prop1sheet.DoModal();

3,第一頁的"上一步",最後一頁的"下一步"取消方法

在第一個/最後一頁屬性頁面類添加虛函數PnSetActive,並在其中添加

((CPropertySheet *)GetParent())->SetWizardButtons(PSWIZB_NEXT);//第一頁 因為AddPage了,故是父視窗? 要注意強制轉換

((CPropertySheet *)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_NEXT);//中間的頁

((CPropertySheet *)GetParent())->SetWizardButtons(PSWIZB_BACK|PSWIZB_FINISH);//最後一頁

4,"下一步"之前,檢查是否已完成“選擇”等

在PropertyPage的OnWizardNext函數中檢查

//Radio1 屬性勾選中Group (後面的選項按鈕與它是一組了, Radio1關聯的成員變數為0, Radio2關聯的成員變數值為1,依次類推)

//組到什麼時候結束?直到遇到下一個具有組這個屬性的選項按鈕

CProp1中增加m_occupation 選Value,變數類型只能選int了

初始化為-1;這樣如果它為-1則表明使用者沒有選擇

在DoDataExchange中

DDX_Radio(pDX, IDC_RADIO1, m_occupation)關聯起來了;

 

在哪一步判斷使用者選擇沒有呢?

在CProp1中增加虛函數 OnWizardNext!!

下面解釋: Called when the Next button is clicked while using wizard-type property sheet.

即:點擊"下一步"按鈕時調用;

LRESULT CProp1::OnWizardNext()
{
    // TODO: Add your specialized code here and/or call the base class
    UpdateData();//不要忘了這個東東
    if(m_occupation==-1)
    {
        MessageBox("請選擇你的職業!");
        return -1;
    }
    if(m_workAddr=="")//CListBox類,

AddString函數:增加字串到列表框,傳回值為基於0的索引
    {
        MessageBox("請選擇你的工作地點!");
        return -1;
    }
    return CPropertyPage::OnWizardNext();
}

Return Value (of OnWizardNext)

0 to automatically advance to the next page; –1 to prevent the page from changing. To jump to a page other than the next one, return the identifier of the dialog to be displayed.

//判斷工作地點:

CProp1::OnInitDialog()中

BOOL CProp1::OnInitDialog()
{
    CPropertyPage::OnInitDialog();
    // TODO: Add extra initialization here
    ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("北京");
    ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("天津");
    ((CListBox*)GetDlgItem(IDC_LIST1))->AddString("上海");

//偶認為將其存在一個字元數組裡,然後利用迴圈加AddString更好...
    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}

自動進行的初始化

CProp1::CProp1() : CPropertyPage(CProp1::IDD)
{
    //{{AFX_DATA_INIT(CProp1)
    m_occupation = -1;
    m_workAddr = _T("");
    //}}AFX_DATA_INIT
}

分別為四個check框添加BOOL型成員變數

LRESULT CProp2::OnWizardNext()
{
    // TODO: Add your specialized code here and/or call the base class
    UpdateData();//不要忘了加這個東東哦謔謔
    if(m_football || m_basketball || m_volleyball || m_swim)
    {
        return CPropertyPage::OnWizardNext();
    }
    else
    {
        MessageBox("請選擇你的興趣愛好!");
        return -1;
    }
}

//老孫說: 要靈活編程----把系統自己加的放到前面去

5,編輯對話方塊/屬性頁面上的ComBox控制項

((CComoBox *)GetDlgItmem(IDC_ComBOX1))->AddString(" ");//增加選項

把列表框的 Sort屬性取消勾選,則按我們原始AddString的順序顯示

int SetCurSel( int nSelect ); 
Return Value

The zero-based index of the item selected if the message is successful. The return value is CB_ERR if nSelect is greater than the number of items in the list or if nSelect is set to –1, which clears the selection.

((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0);//預設選項

6,擷取List(ComBox)控制項,並進行編輯

int sel=((CComoBox *)GetDlgItmem(IDC_ComBOX1))->GetCurSel();

CString m_str;

((CComoBox *)GetDlgItmem(IDC_ComBOX1))->GetLBText(sel,&m_str);//取出使用者的選擇

BOOL CProp3::OnWizardFinish()
{
    // TODO: Add your specialized code here and/or call the base class
    int index;
    index=((CComboBox*)GetDlgItem(IDC_COMBO2))->GetCurSel(); //返回的index是一個基於零的索引
    ((CComboBox*)GetDlgItem(IDC_COMBO2))->GetLBText(index,m_strSalary);

//GetLBText: Gets a string from the list box of a combo box.
    return CPropertyPage::OnWizardFinish();
}

7,視窗IDOK==xxx.DoModal()後,其上面的控制項生命期仍有效,所以可以用變數接受其值

//在View類中重新定義: int m_iOccupation, CString m_strWorkAddr; BOOL m_bLike[4]來接收

//在建構函式中進行初始化-1;"";

memset(m_bLike,0,sizeof(m_bLike));

三個參數分別為:數組, 字元, 個數;

當DoModal()返回之後,接收資料,視窗消失了,但對象沒有析構,還可以接收;

void CPropView::OnPropertysheet()
{
    // TODO: Add your command handler code here
    CPropSheet propSheet("維新屬性工作表單程式");
    propSheet.SetWizardMode();
    if(ID_WIZFINISH==propSheet.DoModal()) //在這裡改動了

IDOK or IDCANCEL if the function was successful; otherwise 0 or -1. If the property sheet has been established as a wizard (see SetWizardMode), DoModal returns either ID_WIZFINISH or IDCANCEL.
    {
        m_iOccupation=propSheet.m_prop1.m_occupation;
        m_strWorkAddr=propSheet.m_prop1.m_workAddr;
        m_bLike[0]=propSheet.m_prop2.m_football;
        m_bLike[1]=propSheet.m_prop2.m_basketball;
        m_bLike[2]=propSheet.m_prop2.m_volleyball;
        m_bLike[3]=propSheet.m_prop2.m_swim;
        m_strSalary=propSheet.m_prop3.m_strSalary;
        Invalidate();
    }
}

8,List控制項的sort屬性選中/不選中,表示是否自動排序,注意有時不需要自己排序

//OnDraw裡面添加: (字型改變)

void CPropView::OnDraw(CDC* pDC)
{
    CPropDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    CFont font;
    font.CreatePointFont(300,"華文行楷");

    CFont *pOldFont;
    pOldFont=pDC->SelectObject(&font);

    CString strTemp;
    strTemp="你的職業:";

    switch(m_iOccupation)
    {
    case 0:
        strTemp+="程式員";
        break;
    case 1:
        strTemp+="系統工程師";
        break;
    case 2:
        strTemp+="專案經理";
        break;
    default:
        break;
    }
    pDC->TextOut(0,0,strTemp);

    strTemp="你的工作地點:";
    strTemp+=m_strWorkAddr;

    TEXTMETRIC tm;
    pDC->GetTextMetrics(&tm);

    pDC->TextOut(0,tm.tmHeight,strTemp);

    strTemp="你的興趣愛好:";
    if(m_bLike[0])
    {
        strTemp+="足球 ";
    }
    if(m_bLike[1])
    {
        strTemp+="籃球 ";
    }
    if(m_bLike[2])
    {
        strTemp+="排球 ";
    }
    if(m_bLike[3])
    {
        strTemp+="遊泳 ";
    }
    pDC->TextOut(0,tm.tmHeight*2,strTemp);

    strTemp="你的薪資水平:";
    strTemp+=m_strSalary;
    pDC->TextOut(0,tm.tmHeight*3,strTemp);

    pDC->SelectObject(pOldFont);
}

下面講述一個屬性頁面對話方塊的使用常式。

1,VC++經常問題。

不能為已建好的類開啟檔案

在VC中為資源(對話方塊、屬性頁面等)添加類時,開啟classwizard=>添加類,輸入類名,選擇baseclass,點OK之後,彈出不能開啟檔案的錯誤"Unable to open the file(XXX.h,XXX.cpp) for class xxx"

解決辦法:刪除類資訊檔XXX.clw;再次調用classwizard,重新產生一個xxx.clw即可

2,屬性頁面資源的增加

在Resource View裡Dialog處點擊右鍵InsertèDialogèIDD_PROPPAGE_LARGE(English(U.S.))

注意看屬性頁面資源的屬性:類型-Child,Border-Thin,System menu不複選,More style中複選了Disabled

也可以通過修改普通對話方塊,而成為屬性頁面。

3,建立類

給屬性頁面對話方塊添加類的時候,基類選為CPropertyPage,而不是CDialog

4,建立屬性工作表單

利用Classwizard插入一個新的類,基類選為CPropertySheet

5,給屬性工作表單添加三個public變數

CProp1 m_prop1;

CProp2 m_prop2;

CProp3 m_prop3;

6,在屬性工作表單的兩個建構函式增加表單

AddPage(&m_prop1);

AddPage(&m_prop2);

AddPage(&m_prop3);

7,在View類添加一個功能表項目,添加響應函數,添加下列語句

CPropSheet propSheet("維新屬性工作表單程式");

       //propSheet.SetWizardMode();//嚮導類時增加這一句

if(ID_WIZFINISH==propSheet.DoModal())

       {

              //擷取各個表單項的選項,僅作為例子

m_iOccupation=propSheet.m_prop1.m_occupation;

m_strWorkAddr=propSheet.m_prop1.m_workAddr;

m_bLike[0]=propSheet.m_prop2.m_football;

m_strSalary=propSheet.m_prop3.m_strSalary;

Invalidate();

       }

屬性工作表單建立完畢。屬性頁面具體內容的編輯和內容的顯示過程省略

三. 嚮導類的建立

step1: Excel和Word就是多文檔程式;

支援文檔--視類架構? 如果取消,則沒有Doc類了

step2: 是否要包含對資料庫的支援

step3: 是否要包含對複合文檔姝支援

step4: 去掉列印和預覽列印

Docking toolbar

Initial status bar

Printing and print preview

Context-sensitive help

3D controls

MAPI[Message API]

Windows Sockets

How do you want your toolbars to look?

Normal / Internet Explorer ReBars

進階選項: Windows Styles...等等

文件範本字串:一般不需要修改

使用分隔視窗; 邊框;最小/已最大化的視窗, 系統功能表, 最小/最大化顯示

step5: 工程類型: MFC標準,還是Windows Explorer 資源管理員類型?

注釋

MFC 庫: as a shared dll (多數WINDOWS平台已經隨著系統的安裝安裝了,故多選此項); or as a statically linked library

step6:

修改視類的基類: CEditView或CRichEditView

1,在Domodal之前添加

propSheet.SetWizardMode();

2,設定最初/末頁的“上一步”和“下一步”

在CProp1類處右鍵,載入虛函數OnSetActive,並在CProp1::OnSetActive中添加

((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_NEXT);

在CProp4::OnSetActive中添加

((CPropertySheet*)GetParent())->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH);

為每一頁添加限制條件:只有在當頁進行必要操作後,才能“下一步”

1, 為每個屬性頁面添加虛函數DoDataExchange,其中不添加代碼

2,為最後一頁添加虛函數OnWizardFinish,其他頁添加OnWizardNext函數,並在其中添加“下一步”的判斷條件

資料交換

UpdateData(TRUE);//從控制項中取回值

UpdateData(FALSE);//將變數值賦給控制項

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.