Windows API入门系列之七 -完善MessageBox
原創(chuàng)文章,轉(zhuǎn)載請注明作者和出處
?
http://www.cnblogs.com/beyond-code
SDK編程群號:81543028 歡迎加入
各位不好意思,前幾天有些事很忙,昨天才稍稍有時(shí)間空閑下來,所以我將我的API入門系列文章繼續(xù)下去,上一篇《自己實(shí)現(xiàn)MessageBox》中我們基本已經(jīng)實(shí)現(xiàn)了一個(gè)對話框了,可以在中央顯示自己的文字,并且顯示一個(gè)確定按鈕,可是,上一篇完的時(shí)候我留下了一個(gè)問題,那就是那個(gè)確定按鈕并不會根據(jù)窗口的大小的改變而改變。那么我們怎么來解決這個(gè)問題呢?
我給出了提示可以通過處理WM_SIZE來完成這個(gè)目的。那么今天我們就來完成這一遺留的問題。所要使用到的新的API函數(shù)也不多,就兩個(gè),要處理的消息也就兩個(gè)WM_SIZE和WM_COMMAND
GetDlgItem
MoveWindow
這么兩個(gè),至于其他的API函數(shù),都是我們以前接觸過的,如果你忘記了,可以自己復(fù)習(xí)一下使用方法。
首先,我們先看WM_SIZE消息處理函數(shù)是怎么寫的
case?WM_SIZE:
{
const?int?buttonWidth?=?80;
const?int?buttonHeight?=?25;
int?buttonx,?buttony;
RECT?rctClient;
GetClientRect(?hwnd,?&rctClient?);
buttonx?=?rctClient.right/2?-?buttonWidth/2;
buttony?=?rctClient.bottom/2?-?buttonHeight/2;
HWND?hButton?=?GetDlgItem(?hwnd,?2?);
MoveWindow(?hButton,?buttonx,?buttony,?buttonWidth,?buttonHeight,?TRUE?);
}
break;
由于這篇文章內(nèi)容比較少,那么我就可以詳細(xì)的介紹一下WM_SIZE這個(gè)消息處理函數(shù)中實(shí)現(xiàn)按鈕始終保持居中的代碼。WM_SIZE這個(gè)消息是當(dāng)一個(gè)窗口的size也就是大小被改變后而被發(fā)送到該窗口的消息處理函數(shù)的。我們在這里通過截獲WM_SIZE就可以在每次窗口大小被改變的時(shí)候進(jìn)行一些處理,我們這里的處理就是將該窗口上的一個(gè)子窗口,也就是那個(gè)確定按鈕移動到中央。
首先,我們還是老規(guī)矩,定義buttonWidth,和buttonHeight兩個(gè)常整形來存放確定按鈕的長和高。然后定義了兩個(gè)整形變量buttonx,和buttony用來存放后面通過計(jì)算得到的確定按鈕的左上角的坐標(biāo)位置。
然后定義了一個(gè)RECT結(jié)構(gòu)體用來保存后面通過GetClientRect?API函數(shù)獲取的窗口的長寬,其中rctClient中right就保存了窗口的長,bottom就保存了窗口的高。我們?yōu)榱俗尠粹o保持在主窗口的中央,那么我們就需要讓按鈕的左上角的x坐標(biāo)位置在主窗口的長的一半再減去按鈕的長的一半的位置。高也是一樣的原理。所以?buttonx?=?rctClient.right/2?-?buttonWidth/2;?buttony?=?rctClient.bottom/2?-?buttonHeight/2;?這兩句就是根據(jù)當(dāng)前主窗口的長和高計(jì)算按鈕應(yīng)該在的位置。
計(jì)算完成后,我們就只需要移動按鈕就可以了??墒且苿影粹o之前,我們需要獲得按鈕的句柄,這個(gè)句柄怎么獲得呢,有很多中方法,這里我就用GeDlgItem這個(gè)API函數(shù)來獲取,它需要兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)主窗口的句柄,這里我們就傳遞按鈕的主窗口的句柄hwnd,第二個(gè)參數(shù)是按鈕的一個(gè)標(biāo)識符,因?yàn)槲覀冊谇耙黄恼轮杏肅reateWindowEx創(chuàng)建子窗口的時(shí)候給按鈕指定的標(biāo)識符是2,所以這里我們就傳遞2,那么這樣GetDlgItem返回的就是這個(gè)按鈕的句柄了。
得到了句柄后,我們就需要用MoveWindow來移動這個(gè)子窗口按鈕,到我們需要的位置了。第一個(gè)參數(shù)是這個(gè)字窗口的句柄,也就是我們上面獲得的句柄,第二個(gè)參數(shù)和第三個(gè)參數(shù)是移動到的x,y坐標(biāo)。這里我們傳遞buttonx和buttony,第四個(gè)和第五個(gè)是移動的窗口的長和高,如果同時(shí)還需要改變窗口的長和高,那么這里也可以傳遞改變后的長和高的值,我們這里只移動位置,不改變大小,所以就傳遞buttonWidth和buttonHeight。最后一個(gè)參數(shù)是一個(gè)BOOL型的,指示是否需要重繪,這里傳遞TRUE,也就是讓它在移動后進(jìn)行重繪。
好了,現(xiàn)在,當(dāng)你改變主窗口的大小的時(shí)候,里面的確定按鈕也會跟著改變位置而達(dá)到始終保持在主窗體的中央。
可是還有一個(gè)問題就是,當(dāng)我們點(diǎn)擊按鈕的時(shí)候,程序沒有任何的反映,MessageBox的確定按鈕被點(diǎn)擊的時(shí)候一般都會關(guān)閉當(dāng)前對話框,所以我們這里也需要實(shí)現(xiàn)當(dāng)用戶點(diǎn)擊確定按鈕的時(shí)候,將我們的主窗體關(guān)閉。那么怎么來實(shí)現(xiàn)呢。
在實(shí)現(xiàn)之前,我首先要講一講,子窗體是怎么通知他們的父窗體的,比如說按鈕被點(diǎn)擊的時(shí)候是怎么通知他們的父窗體的。其實(shí)一般就是通過WM_COMMAND來通知的,例如我點(diǎn)擊這個(gè)確定按鈕,那么在這個(gè)確定按鈕的窗口消息處理函數(shù)中就會向它的父窗體的窗口消息處理函數(shù)發(fā)送一條WM_COMMAND消息,并且WM_COMMAND消息的wParam參數(shù)的低16包含的就是一個(gè)標(biāo)識符,指示是哪個(gè)子窗體發(fā)送的這條消息。至于wParam的高16和lParam包含的是些什么信息,就請各位自己查閱MSDN了,這里我們不會用到,也就不做講解了。
所以我們要處理在子窗體上發(fā)生的事情,就需要在父窗體的消息處理函數(shù)中截獲WM_COMMAND消息,并進(jìn)行處理。那么這里的WM_COMMAND消息處理也很簡單,如下
case?WM_COMMAND:
{
if(?LOWORD(wParam)==2?)
{
DestroyWindow(?hwnd?);
}
}
break;
就是用LOWORD這個(gè)宏來取出wParam的低16位,并且判斷是不是2,也就是判斷是不是確定按鈕的標(biāo)識符,如果是,就表示確定按鈕上發(fā)生了事件,具體的事件我們就沒做過細(xì)的判斷了,一般來說都是指被點(diǎn)擊。所以我們就進(jìn)行處理,調(diào)用DestroyWindow這個(gè)API來銷毀主窗體。就達(dá)到了我們的目的了。
怎么樣,比較簡單吧~
經(jīng)過7篇API入門系列文章的介紹,我想你對WIN32?API編程的一般流程還是有了一個(gè)大概的了解了吧。以及對于windows的數(shù)據(jù)類型,字符編碼方面。API的使用方面,消息的處理方面,因?yàn)槎疾粫吧税伞?/span>
所以我后面的文章,對于細(xì)節(jié)就不會這么細(xì)了,對于一個(gè)API函數(shù),如果參數(shù)不是很復(fù)雜,我也不會做過多的解釋了。而只是說明一下它的作用。至于細(xì)節(jié),各位就應(yīng)該養(yǎng)成MSDN的習(xí)慣了。
好了,今天的文章就到這里了。如果有興趣,請加入WIN32?SDK編程群進(jìn)行討論與交流和訪問我的csdn博客http://blog.csdn.net/beyondcode
我的一些其他文章也會發(fā)布到csdn的博客上面~
總結(jié)
以上是生活随笔為你收集整理的Windows API入门系列之七 -完善MessageBox的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java string类的方法_Java
- 下一篇: Windows编程一日一练(1)