API入門系列之六 自己實現MessageBox

2021-05-21 14:07:19 字數 3413 閱讀 6710

api入門系列文章的第六篇之自己動手實現messagebox。

我在第四篇文章:乙個相當簡單的sdk程式 中講到了通過呼叫messageboxapi函式來彈出乙個對話方塊,那你有沒有想過,我們一句簡單的**背後所隱藏的細節是怎麼的呢,那時候讓你了解這些未免還早了些,不過現在時機到了,通過一些基本的api函式呼叫來實現乙個自己的對話方塊其實也不是很難,那麼這一篇文章就是這個目的。並順帶介紹一些基本api的應用,由於前面五篇文章的鋪墊,我相信你對sdk的程式的大致結構和相關字元處理都有所了解了,所以在這篇文章中的這些知識點,我就不再多說,以免有些人覺得我實在太過囉嗦。實在疑惑的,可以參看前面的文章。

首先我先大概的列出我們為完成這個任務所要用到的一些api函式他

setwindowtext    設定視窗的標題

getclientrect 得到視窗客戶區的大小資訊

getwindowlongptr 通過視窗控制代碼得到和視窗的相關聯資訊

createwindowex 建立視窗

beginpaint 得到視窗的裝置控制代碼

endpaint 釋放視窗的裝置控制代碼

drawtext 通過裝置控制代碼在視窗上畫出文字

好了,就這些函式,我們就能自己實現有乙個確定按鈕並在確定按鈕正上方顯示提示資訊的簡易的對話方塊了,不過這個對話方塊可是我們一句一句**自己實現的喲~~還是比較有成就感吧~

case wm_create:

rect rctclient; //用來存放主視窗客戶區大小資訊

const int buttonwidth = 80; //按鈕的寬

const int buttonheight = 25; /按鈕的高

getclientrect( hwnd, &rctclient ); //得到主視窗客戶區的大小資訊

hinstance hinst = (hinstance)getwindowlongptr( hwnd, gwlp_hinstance );

hwnd hbutton = createwindowex( 0l, _t("button"), _t("確定"), ws_visible |  ws_child , rctclient.right/2-buttonwidth/2, rctclient.bottom/2-buttonheight/2, buttonwidth,  buttonheight, hwnd, (hmenu)2, hinst, null );

setwindowtext( hwnd, _t("自定義對話方塊") );

break;

在wm_create訊息的處理中,我們就用到了getclientrect,它的第乙個引數是視窗的控制代碼,你想要獲取哪個視窗的客戶區大小,你就將傳遞哪個視窗的控制代碼,第二個引數是乙個rect結構的指標,我上面定義了乙個rctclient變數,然後這裡把這個變數的位址傳遞給getclientrect的第二個引數,讓它將所得到的視窗的大小資訊儲存到這個變數裡面。這個函式的具體用法,讀者朋友們還可以自己參考msdn,如果函式呼叫成功,那麼rctclient這個結構體變數中就存放了這個視窗的大小資訊了。

然後,我定義了兩個整形常量buttonwidth, buttonheight用來儲存我們需要建立的按鈕的寬和高。

建立完了按鈕子視窗,我們還需要將我們的主視窗的標題設定為我們想要的,可以通過setwindowtext這個api函式來完成,第乙個引數就是要設定的視窗的控制代碼,這裡為主視窗,所以是我們視窗訊息處理函式傳遞進來的第乙個引數hwnd, 第二個引數就是乙個字串指標,指向乙個以零結尾的字串。這裡我們就直接將乙個字串常量的首位址傳遞給它。就完成了主視窗的標題設定。

經過上面這些步驟,我們已經在主窗體的**顯示了乙個按鈕了,並且把主視窗的標題設定為我們自己需要的,但是還要乙個問題需要解決,那就是在按鈕的正上方顯示一串提示文字,怎麼來完成呢,這就是我們下面要講的。

要在主視窗的按鈕的正上方顯示提示文字資訊,就需要得到主視窗的裝置控制代碼,然後通過該裝置控制代碼呼叫gdi函式drawtext來完成。由於該提示文字需要在每次視窗進行更新的時候繪出,所以我們需要處理wm_paint訊息來達到這個目的。下面還是先看**:

case wm_paint:

const int buttonwidth = 80;

const int buttonheight = 25;

const int textheight = 25;

paintstruct ps;

hdc hdc = beginpaint( hwnd, &ps );

rect rctclient,rcttext;

getclientrect( hwnd, &rctclient );

rcttext.left = rctclient.left;

rcttext.right = rctclient.right;

rcttext.top = rctclient.bottom/2 - buttonheight -textheight;

rcttext.bottom = rctclient.bottom/2 - buttonheight;

drawtext( hdc, _t("beyondcode"), _tcslen( _t("beyondcode")), &rcttext, dt_center  | dt_singleline | dt_vcenter );

endpaint( hwnd, &ps );

break;

首先定義了三個整形常量 buttonwidth,buttonheight指示剛才建立的按鈕的大小,textheight指示要顯示在文字的矩形框的高度,矩形框的寬度和主視窗的寬度一直,所以就沒定義了,然後paintstruct 是beginpaint和endpaint這兩個函式會用到的乙個結構體型別,用它定義了乙個結構體變數ps,並在呼叫beginpaint和endpaint的時候將它的位址傳遞給他們的第二個引數。獲取一些相關和繪圖有關的資訊。不過我們這裡不會用到,所以就不做詳細解釋,可以檢視msdn。

注意,beginpatin這個函式會返回乙個裝置控制代碼,然後我們就可以通過這個裝置控制代碼進行繪圖,顯示文字也是一種繪圖,在繪圖完畢後,我們需要呼叫endpaint這個函式釋放剛才得到的哪個裝置控制代碼,也就是是剛才哪個裝置控制代碼無效。而所有的繪圖操作,都必須在beginpaint和endpatin這兩個函式之間完成。如上面,通過引數hdc呼叫drawtext這個函式,因為獲取的hdc是通過hwnd這個視窗控制代碼的,所以這裡所有的繪圖都會顯示在hwnd這個控制代碼所代表的視窗上,也就是主視窗。rcttext是顯示文字的矩形的資訊,它的大小和位置是通過按鈕的大小和當前主視窗的大小資訊計算出來的,具體的計算**中已經寫的很清楚了,如有疑惑的可以和我交流交流。 然後還要說的乙個就是dt_center 和dt_vcenter這兩個標誌表示在剛才那個矩形框中的水平**和垂直**顯示我們的文字,dt_singleline就是指示單行顯示。

最後留給大家乙個問題,以供大家思考,上面的程式中,當你改變視窗的大小的時候,就會出現問題,按鈕就不會再位於主視窗的**了,怎麼解決呢? 我提示一下吧,處理wm_size這個訊息。好了,留下這個任務給大家,試試吧~~讓按鈕隨時隨地位於主視窗的**。

6 oracle學習入門系列之六 模式

oracle學習入門系列之六 模式上篇咱們學習記錄了oracle資料庫中的資料庫結構 記憶體結構和程序等,篇幅 感覺偏多了。這次要休整下,每次筆記不宜太多,不然與書籍有何區別。我們要保證的是每次做記錄都能所有收穫所有提公升。上次中我們從總體上把握了下oracle系統結構,這次開始我們將涉及到orac...

C 3 0入門系列(六) 之OrderBy操作

本節講orderby操作 我突然在想這麼乙個問題,讀者會t sql嗎?要是不知道,那我寫的是不是太簡單了呢?做個調查哦,不知道的舉手 orderby操作 簡單的,按雇用日期排序,預設為公升序 var q from e indb.employees orderby e.hiredate select ...

Asp元件中級入門與精通系列之六

作為asp的內建物件,我們最後來學習server物件 server物件用的比較多的就是html編碼,url編碼和網頁的重定向,傳送。開啟vb6,新建activex dll工程。工程名修改為fcom,類名修改為fz6 引用 microsoft active server pages object 物件...