久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7043|回復: 4
打印 上一主題 下一主題
收起左側(cè)

從零開始學VC系列教程 二. 對話框及常用控件實驗

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:6404 發(fā)表于 2008-11-6 19:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
從零開始學VC系列教程 二. 對話框及常用控件實驗
    恭喜你,進入VC學習的第二節(jié)了.這一節(jié)是人機交互的基礎.所謂人機交互,說通俗點就是與機器對話.然而我們現(xiàn)在的技術還不能像科幻片里一樣與機器人直接說話就行了.所以,我們的操作意圖還得通過文本輸入,命令按鈕等等來實現(xiàn).
本節(jié)內(nèi)容:學會對話框調(diào)用及一些常用控件的使用方法.
    學習目的:學習人機交互,為軟件開發(fā)提供界面基礎.
1.新建工程.參考第一節(jié)的方法新建一個工程,名字為Eg02完成后如下圖

細心的朋友一定會發(fā)現(xiàn).新建的工程里還有一個對話框,ID名是IDD_ABOUTBOX這個是做什么用的呢?我們用到的軟件都會有一個版權(quán)聲明.通過第一章的學習,大家應該知道怎么觀看這個IDD_ABOUTBOX對話框了吧.沒錯!雙擊IDD_ABOUTBOX就可以了.我們會看到如下的一個對話框

這就是我們這個程序的關于對話框,一般用于版權(quán)聲明及版本號標識.大家看到的這個對話框里有兩個靜態(tài)文本框和一個圖像框(Picture),靜態(tài)文本框我們在前一節(jié)已經(jīng)介紹過了.大家可以修改一下版權(quán)所有這一行,填什么都可以,簽個大名也行.完成以后你一定想看看效果,這個對話框怎么打開呢?其實VC已經(jīng)為我們做好了.先按F7編譯,然后按F5運行.大家可以看到程序運行了.


單擊應用程序圖標,就會出現(xiàn)一個菜單,選最后一個[關于Eg02],關于對話框就彈出來了.
當然,這是系統(tǒng)為我們做好的.自己怎么在程序中調(diào)用這個對話框呢?為了演示,首先參考第一節(jié)的內(nèi)容添加一個按鈕,然后把按鈕的ID改為IDC_BTN_ABOUTME,把標題,也就是Caption改為[關于].最終效果如下


下面我們?yōu)榘粹o添加代碼.相信大家一定還記得怎么進入代碼吧..對了,雙擊[關于]按鈕,在彈出的對話框中點[確定]就可以了.為了讓大家更好的理解下面的操作,我們先要解釋一下關于對話框的類.VC向?qū)䴙殛P于對話框建立一個類,大家看看下面的圖


單擊標簽ClassView(這里顯示的是[Class…])就可以看到Eg02這個應用程序的類.第一個CAboutDlg就是關于對話框的類.CEg02Dlg對應IDD_EG02_DIALOG.中間的Ceg02App是應用程序的基礎類.所以,如果要對關于對話框進行操作,就要用到類CAboutDlg,因為與此有關的函數(shù)及變量都封裝在CAboutDlg中.看到這里大家可能又糊涂了,沒關系,在以后的教程中,通過一些練習大家就會慢慢領會到的.這里還是先為[關于]按鈕添加代碼.
void CEg02Dlg::OnBtnAboutme()  
{
        // TODO: Add your control notification handler code here
         
}
上面是VC為[關于]按鈕添加的響應函數(shù).我們添加代碼成以下所示
void CEg02Dlg::OnBtnAboutme()  
{
        // TODO: Add your control notification handler code here
        CAboutDlg ADlg;
        ADlg.DoModal();
}
一共有兩句,第一句是CAboutDlg ADlg;作用是定義一個變量Adlg.第二句是ADlg.DoModal();功能是調(diào)用類CAboutDlg里的一個函數(shù)DoModal();這個函數(shù)在MSDN里的解釋是Call this member function to invoke the modal dialog box and return the dialog-box result when done. This member function handles all interaction with the user while the dialog box is active. This is what makes the dialog box modal; that is, the user cannot interact with other windows until the dialog box is closed.一般我們用于顯示一個對話框.其實大家看看CAboutDlg這個類下面,只有兩個函數(shù)



  
DoModal()這個函數(shù)并不在這個里面.第一章我們提到過類的派生和繼承.其實CAboutDlg這個類是派生于CDialog類,DoModal()這個函數(shù)是CDialog的成員函數(shù),由于CAboutDlg是繼承父類CDialog的,所以CDialog里的函數(shù)在CAboutDlg中也可以使用.
下面我們來說說幾個常用控件的使用.
首先在IDD_EG02_DIALOG對話框中加入一個Edit(編輯框)控件.Edit一般用于輸入輸出數(shù)據(jù)文本.相當于VB里的TextBox.加入Edit控件后,編輯其屬性為


然后,我們再加一個按鈕(PushButton),并編輯其屬性為


接下來,我們先說一下要實現(xiàn)的效果.很簡單,在編輯框里輸入一個文本,然后按顯示,就把文本顯示在靜態(tài)文本框中.所以,這里要把靜態(tài)文本編輯框的ID改為IDC_DISPLABEL
下面我們?yōu)閇顯示]按鈕添加代碼
void CEg02Dlg::OnBtnShow()  
{
        // TODO: Add your control notification handler code here
        CString a;
        GetDlgItemText(IDC_EDIT_INPUT,a);
        SetDlgItemText(IDC_DISPLABEL,a);
}
其實不復雜,也只有三句,第一句定義一個CString類變量a 我們來說說GetDlgItemText這個函數(shù)吧.查查MSDN就知道函數(shù)原型了.
int GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;
int GetDlgItemText( int nID, CString& rString ) const;
大家看看就覺得奇怪了,怎么有兩個原型啊?并且一個是傳兩個參數(shù),另一個是傳三個參數(shù).在VC里面,同一個類下是可以存在多個同名函數(shù)的,具體調(diào)用哪個函數(shù)要看參數(shù)的不同.在這里我們傳入了兩個參數(shù),所以VC會調(diào)用int GetDlgItemText( int nID, CString& rString ) const;這個函數(shù).第一個函數(shù)是控件的ID號,第二個是字串.第二個傳了地址,所以我們在下一句中用的a已經(jīng)是獲得IDC_EDIT_INPUT的文本了.運行效果如下

下面介紹一下進度條的使用以及定時器的使用.
我們要實現(xiàn)的效果是進度從0到滿格,然后再從0到滿格,依次循環(huán).每跳一格間隔500ms,這個時間我們用定時器來實現(xiàn).
首先從控件條里拖出一個進程條到對話框,修改屬性如下


然后我們要介紹一下VC的定時器.VC里面使用定時器有多種方式,我們先介紹一種作為拋磚引玉
首先添加一個Windows消息處理器.消息這個詞語可能很陌生,我們會在后面很多次說明.這里先照圖做

在類管理器里選中Ceg02Dlg這個類,然后點右鍵,就會彈出一個菜單,選擇[Add Windows Message Handler…],接下來會彈出另一個菜單


雙擊WM_TIMER然后按[確定]就可以了.大家會看到,CEg02Dlg類中多了一個函數(shù)


這個就是VC中的定時器響應函數(shù).然后雙擊這個函數(shù)就進入代碼了


然后我們?yōu)門imer事件添加代碼.
void CEg02Dlg::OnTimer(UINT nIDEvent)  
{
        // TODO: Add your message handler code here and/or call default IDC_PROGRESS
        static int nPos=0;
        ((CProgressCtrl*)(GetDlgItem(IDC_PROGRESS)))->SetPos(nPos);
        if(nPos<100) nPos+=10;
        else nPos=0;
        CDialog::OnTimer(nIDEvent);
}
首先定義一個整型的變量nPos用于記錄進度條的進度值.默認時,進度條0為空,100為滿格.從后的程序大家可以看到,這個變量自加到100就變?yōu)?.最難理解的就是
((CProgressCtrl*)(GetDlgItem(IDC_PROGRESS)))->SetPos(nPos);
首先, GetDlgItem(IDC_PROGRESS)這個函數(shù)用來獲取IDC_PROGRESS的句柄,在VC里面引入了句柄這個詞語,我們將在下一章中對消息和句柄進行詳細的說明, 句柄是WINDOWS用來標識被應用程序所建立或使用的對象的唯一整數(shù),WINDOWS使用各種各樣的句柄標識諸如應用程序?qū)嵗翱冢刂疲粓D,GDI對象等等。WINDOWS句柄有點象C語言中的文件句柄。在這里,GetDlgItem獲取了窗體句柄,大家應該還記得,在VC里面,控制就看成窗體。(CProgressCtrl*)這個地方是將返回的句柄強制轉(zhuǎn)換為CProgressCtrl類型,與C語言的中的強制轉(zhuǎn)換是一樣的.進度條的控制類是CprogressCtrl.而前面返回的是一個窗體類型,所以先要強制轉(zhuǎn)換.在第一章中,我們提到過,VC中的控件都認為是窗體,在這里就體現(xiàn)出來了. SetPos(nPos);這個函數(shù)是類CprogressCtrl的成員函數(shù),用來指定當前進度條的進度.最后還有一步,就是激活這個定時器.像我們的C51或AVR一樣,要初始化定時器. 而void CEg02Dlg::OnTimer(UINT nIDEvent)這個函數(shù)就像我們單片機的定時器中斷服務函數(shù)一樣.時間到了就會自動執(zhí)行.
參考上面的圖,雙擊OnInitDialog(),就可以進入對話框初始化函數(shù),只要添加一句就可以了.完成后如下
BOOL CEg02Dlg::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
        SetTimer(0,500,NULL); //這里是添加的,別的都是自動生成的

        return TRUE;  // return TRUE  unless you set the focus to a control
}
在這里我們只添加SetTimer(0,500,NULL);其中,參數(shù)0代表定時器的ID號為0,.第二個參數(shù)500是定時器的時間,單位為ms,后面的NULL是指不要回調(diào)函數(shù).
按F7編譯后運行就可以看到運行效果了.

或許大家有個問題,為什么開始時是添加了一個WM_TIMER的消息處理器呢?我們使用SetTimer開始定時器后,如果沒有回調(diào)函數(shù),系統(tǒng)會在每次定時時間到后發(fā)送一個WM_TIMER消息到窗體.窗體收到這個信息后,調(diào)用OnTimer()函數(shù)進行處理.系統(tǒng)定義這個函數(shù)為afx_msg void OnTimer(UINT nIDEvent);可以看到是以afx_msg修飾的,這種函數(shù)會與其中一個信息關聯(lián),或者說是消息影射到這個函數(shù).每當有消息發(fā)過來,都會執(zhí)行這個函數(shù).大家只要好好想想單片機的定時器中斷就會明白的,原理一樣,只是傳輸機制不同.
如果上面的內(nèi)容你制作成功了,那么恭喜你,第二節(jié)就基本學完了.
下面我們也來說說多任務和消息機制吧.
Windows是基于消息機制的,它是一個多任務的操作系統(tǒng),也就是說,同一時間內(nèi),系統(tǒng)會掛起多個任務.為了說明多任務,我們先來看一段單片機程序.
Void main(void)
{
        While(1)
{
        TaskA();
}
}
這個程序很簡單,單片機工作后就進入while()循環(huán)了,單片機這個時候就干一件事,那就是執(zhí)行任務TaskA.這樣的工作總是在一個主循環(huán)內(nèi)實施,一次只執(zhí)行一個任務的我們稱為單任務系統(tǒng).單片機程序只要不引入操作系統(tǒng)并且由一個主循環(huán)一直執(zhí)行完畢的基本都是單任務的.有些程序也是這樣寫的.
Void main(void)
{
        While(1)
{
        TaskA();
        TaskB();
TaskC();
}
}
這樣的程序看起來似乎是有三個任務了.這三個任務是順序執(zhí)行的,也就是說,必須讓A完成后,才能到B,B完成后才能到C.如果A有一個長時間的延時,系統(tǒng)就會在A中空等,然而B與A本來是無關的,這樣空等的時間就算是浪費了.如果我們的windows也是順序執(zhí)行的就麻煩了,那時我們不僅僅會說Windows有點慢,而是說Windows像蝸牛一樣在爬.如果我們讓這些任務更合理的安排一下,在執(zhí)行A的時候,有空就去執(zhí)行B,而在B的空閑時間去執(zhí)行C或者A,那么時間就節(jié)省下來了.如果時間切換夠快,那么我們可以認為A,B,C三個任務在同時進行.所以,如果我們把單片機的執(zhí)行時間分成若干等份,每份1ms或者更小,這種時間等份我們稱為時間片,每次時間到了就換一個任務.也就是說,第一毫秒執(zhí)行A,這時我們并不等A全部執(zhí)行完,并記住這個斷點,到了第二毫秒執(zhí)行B,第三毫秒執(zhí)行C,第四毫秒又執(zhí)行A并從原來的斷點開始執(zhí)行,依次直至三個任務都完成.大家可以看到,任務A每三毫秒執(zhí)行了一次.這就是多任務的模型了.
Windows其實就是這么干的.只是每次任務時間不一定是我們上面說的3ms,因為系統(tǒng)同一時間內(nèi)可能會有很多待執(zhí)行的任務,這些任務就被系統(tǒng)按優(yōu)先級排成隊,一個個取出來執(zhí)行.比如我們現(xiàn)在打開VC,系統(tǒng)在加載VC,同時我們還可以移動鼠標,這些好像都是在同時進行,其實它們也是按時間片分時執(zhí)行的.
現(xiàn)在分析一下這個工作過程吧.現(xiàn)在我們要打開VC,系統(tǒng)開始加載VC了,可以看到VC的LOGO界面,但這個時候我們還可以動一下鼠標,硬件首先會響應,并給軟件發(fā)個通知,而軟件這個時候可能還沒有輪到鼠標程序的執(zhí)行,怎么辦呢?系統(tǒng)會先把這個鼠標操作保存起來,輪到鼠標時間片時再來處理鼠標操作.大家可能覺得,這樣鼠標操作不是滯后了嗎?確實是這樣的,但這個滯后時間是很短的,我們基本不會察覺出來.
我們來看看消息的定義.
消息系統(tǒng)對于一個win32程序來說十分重要,它是一個程序運行的動力源泉。一個消息,是系統(tǒng)定義的一個32位的值,他唯一的定義了一個事件,向Windows發(fā)出一個通知,告訴應用程序某個事情發(fā)生了。例如,單擊鼠標、改變窗口尺寸、按下鍵盤上的一個鍵都會使Windows發(fā)送一個消息給應用程序。
消息本身是作為一個記錄傳遞給應用程序的,這個記錄中包含了消息的類型以及其他信息。例如,對于單擊鼠標所產(chǎn)生的消息來說,這個記錄中包含了單擊鼠標時的坐標。
綜合前面的分析,消息就好理解了,鼠標動一下會產(chǎn)生一個事件,這個事件必須要告訴系統(tǒng)啊,怎么告訴系統(tǒng)呢?Windows把這個定義為Message也就是消息,所以,消息可以認為是一個操作記號,記錄上一步所發(fā)生的或者說是下一步所要處理的事件.系統(tǒng)為消息安排了一個隊列,里面可以存放很多個消息,我們稱為消息隊列.有鍵盤操作時,把鍵盤操作放到消息隊列里面,相當于做一個記號,我們動了鍵盤,有鼠標操作時,把鼠標操作放到消息隊列,也便記住我們在鍵盤后還動了鼠標,系統(tǒng)就把這些東西一個個按時間取出來執(zhí)行.在Windows里面,鼠標消息可以有幾種,例如單擊落了左鍵,系統(tǒng)會產(chǎn)生一個消息為WM_LBUTTONDOWN如果我們移動了鼠標,就像產(chǎn)生一個消息為WM_MOUSEMOVE消息入隊后,系統(tǒng)會依次處理.當然,我們這樣的解釋雖然容易懂,但不是非常專業(yè),并且Windows內(nèi)部處理消息也比這復雜多了,但基本原理就是這樣的了,并且,我們在進行操作時,并不用關心Windows的底層是怎么處理這些事件的,除非我們的操作真的讓Windows生氣了,就必須去查查出什么問題了.
說了這么多,消息可能還是一個十分飄渺的概念,倒底要怎么用呢?我們來舉個例子說明一下.給系統(tǒng)發(fā)消息一般會用到兩個函數(shù),一個是SendMessage,另一個是PostMessage,這兩個是有點區(qū)別的,具體區(qū)別作為這次的作品,大家去網(wǎng)上查查.例如我們要退出當前的應用程序,最簡單的方法當然是按一下關閉的那個紅X,如果我們要自己讓程序退出,可以給系統(tǒng)發(fā)一個消息,其實那個關閉程序的紅X也是這么干的.為了演示,首先在上次的對話框中加一個按鈕,修改標題也就是Caption為”關閉程序”,ID號改為IDC_QUIT_ME雙擊為按鈕添加以下代碼.
PostMessage(WM_CLOSE);
編譯運行試試,如果沒有寫錯代碼就可以用那個按鈕退出程序了.
這一節(jié)也就寫到這里了,可以大家還是有點糊涂,慢慢體會一下就好了.還是不明白可以來這里提問.
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:6404 發(fā)表于 2008-11-6 19:46 | 只看該作者
我的貼,有人看,沒人回!
沒信心發(fā)了。
回復

使用道具 舉報

板凳
ID:6585 發(fā)表于 2008-11-6 22:27 | 只看該作者

沙發(fā),外菜來頂一下!!!!

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美激情一区二区三级高清视频 | 亚洲视频在线播放 | 99精品国产一区二区三区 | 亚洲人在线观看视频 | 亚洲人成网亚洲欧洲无码 | 亚洲高清一区二区三区 | 亚洲永久精品国产 | 亚洲精品日韩综合观看成人91 | 欧美一级视频在线观看 | 欧美中文 | 国产在线一区观看 | 中文字幕一区二区三区四区不卡 | 欧美精品欧美精品系列 | 每日更新av | 亚洲成人精品国产 | 日日综合 | 特级丰满少妇一级aaaa爱毛片 | 亚洲国产欧美日韩 | 亚洲成人av | 亚洲欧美在线观看 | 视频国产一区 | 欧美日韩一区二区在线观看 | 色综合天天天天做夜夜夜夜做 | 午夜三级在线观看 | 久久精品视频网站 | 日韩欧美一区二区三区免费看 | 自拍偷拍亚洲视频 | 极品一区 | 337p日本欧洲亚洲大胆鲁鲁 | av在线免费观看网址 | 国产日韩欧美一区二区 | 精品国产一区二区在线 | 中文字幕一区二区三区精彩视频 | 亚洲成人精选 | 国产精品123区 | 国产一区二区三区高清 | 久草精品在线 | 四虎永久免费影院 | 亚洲国产精品久久久久婷婷老年 | 国产精品毛片一区二区在线看 | 亚洲网站在线观看 |