程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB.NET >> API入門系列之六 -自己實現MessageBox

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

編輯:VB.NET

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

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

SetWindowText    設置窗口的標題

GetClientRect 得到窗口客戶區的大小信息

GetWindowLongPtr 通過窗口句柄得到和窗口的相關聯信息

CreateWindowEx 創建窗口

BeginPaint 得到窗口的設備句柄

EndPaint 釋放窗口的設備句柄

DrawText 通過設備句柄在窗口上畫出文字

好了,就這些函數,我們就能自己實現有一個確定按鈕並在確定按鈕正上方顯示提示信息的簡易的對 話框了,不過這個對話框可是我們一句一句代碼自己實現的喲~~還是比較有成就感吧~

程序的大體框架呢還是我們上一篇文章中的框架,注冊窗口類,創建一個主窗口,消息循環,窗口消 息處理函數。不過要我們需要在窗口消息處理函數中添加一些代碼來完成我們需要的功能。在什麼地方 添加呢?  上個程序,我們只處理WM_DESTROY這個消息。對於這個消息我不再做講解,不懂的或者忘記 了的可以自己MSDN或者看上一篇文章,這裡我們要添加對兩個消息的處理代碼,首先是WM_CREATE,這個 消息會在一個窗口被創建的時候被發送到窗口消息處理函數,如果一些事情需要在一個窗口剛被創建的 時候執行,那麼通過處理WM_CREATE最合適不過啦,代碼如下:

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用來保存我們需要創建的按鈕的寬和高。

再然後我調用GetWindowLongPtr這個函數獲取和窗口有關的信息,這裡獲取的是窗口所屬的應用程序 實例的句柄,也就是WinMain函數所傳遞進來的第一個參數。在得到這些需要的信息之後,我們就開始著 手子窗體的創建了,這裡我們要創建的是一個按鈕,按鈕也是一個窗體,所以也需要窗口類,我們並沒 有寫按鈕的窗口類進行注冊,那麼這個窗口類由誰來注冊呢? 其實是有系統創建並注冊了按鈕的窗口類 ,窗口類的名字是button,所以我們這裡只管用這個窗口類來創建窗口就是了,我們創建主窗口是用的 WS_OVERLAPPEDWINDOW這個窗口樣式,如果是創建一個子窗口,那麼我們需要指定WS_CHILD ,如果我們 需要創建的窗口能顯示出來,那麼需要指定WS_VISIBLE這個窗口樣式,並且還需要指定創建的窗口所屬 的父窗口的句柄,如上代碼所示。其中第五個參數到第八個參數是該按鈕的坐標位置和寬度高度的信息 ,因為我們需要將該按鈕創建在主窗口的中央,所以有一系列的計算,具體是怎麼計算的,就請各位自 己仔細根據上面的代碼進行思考了,如果還是有些疑惑,請與我討論或者加入SDK編程(81543028)群進 行討論交流。

創建完了按鈕子窗口,我們還需要將我們的主窗口的標題設置為我們想要的,可以通過 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 );

首先定義了三個整形常 量 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這個消息。好了,留下 這個任務給大家,試試吧~~讓按鈕隨時隨地位於主窗口的中央。

出處:http://blog.csdn.net/beyondcode

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved