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