第十篇:模式對話框和通用控件(下)
大家好,雷神由於出差在外,所以筆記今天才寫出抱歉。不知道大家有沒有做上篇提到的計算器,計算器對雷神來說可是經典的程序,學VB先搞了計算器,學VC也搞了個計算器,前不久在學擴展CBUTTON類時也是用計算器程序,為什麼?按鈕多呗,雷神最終做出了一個圓形按鈕,液晶顯示的計算器,感覺真的不錯。學編程就是要編寫代碼,代碼寫的多少和編程水平是成正比的。
由對話框編輯器和Class Wizard生成的對話框可以很輕松的不需編寫很多的代碼而獲得很多的功能,但如果我們想對對話框進一步的改進則需要手工編程了。
我們以上一篇的電腦體育彩票選號小程序為例進行一系列的改進工作。
改進一:截獲退出控制權
當我們的光標不在選號按鈕上時(例如在文本框內),當按下回車(Enter)鍵則回退出程序的運行,還有當你按下ESC鍵時也會退出。為什麼?因為當用戶按下回車鍵時Windows就會自動查找“輸入焦點”在哪個按鈕上,如果所有的按鈕都沒有獲得輸入焦點,Windows會自動的尋找程序資源指定的默認按鈕,如果對話框沒有默認按鈕,系統會調用OnOK函數。ESC鍵也會觸發對OnCancel函數的調用,從而導致控制從對話框中退出。如果我們想截獲退出控制權該如何做呢?用啞函數,就是將按下Enter和ESC後的處理函數寫成空函數。
步驟1、由於我們的對話框沒有OK和CANCEL按鈕,我們只能手工添加代碼。在guessDlg.h文件的類聲名重載:virtual void
OnOK()和virtual void OnCancel();兩個虛函數。
class CGuessDlg : public CDialog
{
.......
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGuessDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void OnOK();
virtual void OnCancel();
//}}AFX_VIRTUAL
.......
};
步驟2、在guessDlg.cpp文件加入兩個啞函數OnOK和OnCancel。
void CGuessDlg::OnOK ()
{
}
void CGuessDlg::OnCancel()
{
}
好了在編譯運行,按ESC和在文本框內點一下鼠標,按下回車(Enter)鍵,上一篇的問題不存在了,程序不會退出,徹底退不出了,只能通過任務管理器退了,這可不行,我們還需要繼續改進。
步驟3、添加一個按鈕,叫退出。加入這個按鈕的消息控制函數如下:
void CGuessDlg::OnButton2()
{
CDialog::OnOK();
}
這回可以了,我們已經掌握了對話框退出控制權。
改進二:改變對話框的外觀
我們可以改變對話框的背景顏色,或對話框中的控件顏色以使得程序界面不至於千篇一律,如何做呢?每個控件和對話框在顯示之前回發送WM_CTLCOLOR消息,如果派生對話框類對WM_CTLCOLOR消息進行了映射,就可以設定文本的前景色和背景色。同時還可以為控件或對話框的非文本區域選擇一個刷子。
WM_CTLCOLOR消息對應的函數為OnCtlColor,OnCtlColor函數的原型為:afx_msg HBRUSH OnCtlColor(
CDC* pDC, CWnd* pWnd, UINT nCtlColor );其中參數pDC是:一個指向設備環境的指針。pWnd:指定特定的控件。nCtlColor:指明控件類型。
可以有以下類型:
CTLCOLOR_BTN button control
CTLCOLOR_DLG dialog box
CTLCOLOR_EDIT edit control
CTLCOLOR_LISTBOX list box
CTLCOLOR_MSGBOX message box
CTLCOLOR_SCROLLBAR scroll bar
CTLCOLOR_STATIC static text, frame, or rectangle
現在為了突出顯示文本框的顯示號碼,我們將文本框的文字背景設為黃色。
步驟1、添加一個成員變量 HBRUSH m_hBrush;
步驟2、用Class Wizard為CGuessDlg加入WM_CTLCOLOR消息,並編輯OnCtlColor函數:
HBRUSH CGuessDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if(nCtlColor==CTLCOLOR_EDIT){
pDC->SetBkColor (RGB(255,255,0));//EDIT控件文字背景為黃色
return m_hBrush;
}
return CDialog::OnCtlColor (pDC,pWnd,nCtlColor);
}
編譯運行,怎麼樣,文本框內的文字均變為黃底了。關於對話框的外觀我們將在以後再說。
改進三、增加進度條。
程序在隨機產生號碼時沒有任何提示,我們不知道程序是否在運行,怎麼辦?我們增加一個進度條控件,用來觀察程序的運行狀況。
步驟1、在對話框編輯器中增加一個進度條控件(Progress),並在CGuessDlg為進度條增加一個成員變量。int m_nProgress;
步驟2、將CGuessDlg::OnButton1()用下面代碼替換。
void CGuessDlg::OnButton1()
{
m_nProgress=0;//初始進度條為0
CProgressCtrl *pProg=(CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
pProg->SetRange (0,70);//設定進度條范圍為0-70
int temp,pnum[35],num[7]; //臨時變量,臨時數組
for(int i=0;i<35;i++) //賦值,以作選號用
pnum[i]=i+1;
//***選號過程:***//
for(i=0;i<7;i++)
{
srand( (unsigned)time( NULL ) );
//srand(3);
temp=rand(); //取隨機種子數
temp=temp%36+1; //取小於35的數組元素
while(pnum[temp]==0)//如果是已被選過的元素,重選
{
srand( (unsigned)time( NULL ) );
temp=rand();
temp=temp%36+1;
}
m_nProgress+=10;//進度加10
num[i]=temp; //選定一個號碼
pnum[temp]=0; //給該元素置0,表示已被選過
UpdateData(TRUE);//刷新
pProg->SetPos (m_nProgress);
}
/*** 在選完號碼後,應該為它們排一下序:***/
//排序部分無變化省略。
}
編譯運行它,好了,有了進度顯示我們可以知道程序的運行情況了。
在這篇筆記中我們通過對上一篇所寫的小程序的改進,掌握了一些改進對話框的方法,不用書上的例子是想給大家多個例子參考,不過書上的例子一定要掌握。好了關於模式對話框我們已經掌握,下一篇我們將繼續學習無模式對話框。
未完待續