Windows編程中的子窗口控件設計

(注:本文轉載自http://www.cnblogs.com/duzouzhe/archive/2010/03/12/1683922.html

取父窗口的窗口句柄:
hwndParent = GetParent (hwnd) ;

發送消息:
SendMessage (hwndParent, message, wParam, lParam) ;

預定義的控件有:
按鈕、複選框、編輯方塊、清單方塊、下拉式清單方塊、靜態字符串標籤和滾動條。

當使用預定義的控件時,不必爲其註冊窗口類,窗口類已經存在於Windows中,並有一個預先定義的名字。
您只需在CreateWindow()的參數中指出窗口類名字。CreateWindow()的窗口樣式參數準確地定義了子窗口
控件的外形和功能。Windows內建了這些控件的窗口消息處理程序。

========================================
按鈕控件

創建子窗口時指定窗口類爲"button".

顯示窗口的CreateWindow參數如下:
Class name(類別名稱)  TEXT ("button")
Window text(窗口文字)  一個c字符串szText
Window style(窗口樣式)  WS_CHILD | WS_VISIBLE | 按鈕樣式(下邊有說明)
x position(x位置)
y position(y位置)
Width(寬度)
Height(高度)
Parent window(父窗口)
Child window ID(子窗口ID) 要轉換爲HMENU類型.如(HMENU) i  
Instance handle(執行實體句柄) 執行實例句柄
Extra parameters(附加參數)   NULL


其中的按鈕樣式爲:
BS_PUSHBUTTON
BS_DEFPUSHBUTTON
BS_CHECKBOX   (帶有複選框.複選框的狀態要手動發送BM_SETCHECK消息設置)
BS_AUTOCHECKBOX  (帶有複選框.複選框的狀態自動設置)
BS_RADIOBUTTON  (帶單選按鈕.其狀態要手動發送BM_SETCHECK消息設置)
BS_3STATE
BS_AUTO3STATE
BS_GROUPBOX  (分組方塊. 它只是一個標題框. 不處理輸入.)
BS_AUTORADIOBUTTON
BS_OWNERDRAW

按鈕會向父窗口發送WM_COMMAND消息.參數:
LOWORD(wParam)  爲子窗口ID.
HIWORD(wParam)   爲通知碼.
lParam   爲子窗口句柄.

通知碼HIWORD(wParam)有:
BN_CLICKED
BN_PAINT
BN_HILITE or BN_PUSHED
BN_UNHILITE or BN_UNPUSHED
BN_DISABLE
BN_DOUBLECLICKED or BN_DBLCLK
BN_SETFOCUS
BN_KILLFOCUS

父窗口也可以向按鈕發送消息.
BM_GETCHECK (複選框的選定標記)
BM_SETCHECK
BM_GETSTATE ("正常狀態" 還是"按下狀態" )
BM_SETSTATE
BM_SETSTYLE (改變按鈕樣式)
BM_CLICK
BM_GETIMAGE
BM_SETIMAGE


要得到控件ID
GetDlgCtrlId(hwndChild);
要得到控件的子窗口句柄
GetDlgItem(hwndParent, id);
 

改變按鈕的文字
SetWindowText (hwnd, pszString) ;
取按鈕的當前文字
iLength = GetWindowText (hwnd, pszBuffer, iMaxLength) ;

======================================
顯示/隱藏子窗口

如果子窗口的窗口類的樣式中沒有WS_VISIBLE. 則在沒有呼叫ShowWindow之前不會顯示窗口.
顯示子窗口用:
ShowWindow (hwndChild, SW_SHOWNORMAL) ;
隱藏子窗口用:
ShowWindow (hwndChild, SW_HIDE) ;
查看子窗口是否可見用:
IsWindowVisible (hwndChild) ;

不可用/啓用 子窗口

要使按鈕不可用(文字變爲灰色).用:
EnableWindow (hwndChild, FALSE) ;
恢復爲可用:
EnableWindow (hwndChild, TRUE) ;
判斷是否被啓用:
IsWindowEnabled (hwndChild) ;


輸入焦點

用戶使用按鈕時.按鈕獲得輸入焦點而其父窗口失去輸入焦點.這時父窗口先收到WM_KILLFOCUS
息(wParam參數爲獲得輸入焦點的窗口的句柄).然後獲得輸入焦點的窗口(按鈕子窗口)收到一個WM
_SETFOCUS
消息(wParam參數爲失去輸入焦點的窗口的句柄).


控件與顏色

系統顏色
Windows保留了29種系統顏色以供各種顯示使用(例如:菜單顏色.菜單文字顏色.窗口顏色等等)。您可
以使用GetSysColor和SetSysColors來獲得和設定這些顏色。設定的系統顏色只在目前Windows對
話過程中有效。

在按鈕中顯示圖標或位圖,您可以用BS_ICON或BS_BITMAP樣式,並用BM_SETIMAGE消息設定位圖。
對於BS_OWNERDRAW樣式的按鈕,它允許完全自由地繪製按鈕

====================================
靜態控件

創建子窗口時指定窗口類爲"static".它既不接收鼠標或鍵盤輸入,也不向父窗口發送WM_COMMAND消息。
設置靜態控件的文字SetWindowText.


================================
滾動條控件

創建子窗口時指定窗口類爲"scrollbar".
它不向父窗口發送WM_COMMAND消息而是像窗口滾動條那樣發送WM_VSCROLLWM_HSCROLL消息
可以通過lParam參數來區分窗口滾動條與滾動條控件對子窗口滾動條其值爲0對於滾動條控件其值爲滾動
子窗口的句柄。wParam對窗口滾動條和滾動條控件來說含義相同。

設置滾動條控件用的函數和設置窗口滾動條一樣:
SetScrollRange (hwndScroll, SB_CTL, iMin, iMax, bRedraw) ;
SetScrollPos (hwndScroll, SB_CTL, iPos, bRedraw) ;
SetScrollInfo (hwndScroll, SB_CTL, &si, bRedraw) ;
區別是設置滾動條控件時.第一個參數是控件子窗口句柄而不是父窗口句柄.第二個參數是SB_CTL而不是
SB_VERT或SB_HORZ.


===========================
爲控件指定窗口函數

控件的窗口函數是windows內部的. 但可以用GWL_WNDPROC做參數通過GetWindowLong函數得到它
的函數地址. 而且可以用SetWindowLong給它重新指定一個新的窗口函數(新的函數也要是callback函數).如:
OldScroll = (WNDPROC) SetWindowLong (hwndScroll,GWL_WNDPROC,
         (LONG) ScrollProc)) ;
//返回值是原來的窗口函數的地址.

在需要用Tab鍵在控件之間切換輸入焦點時. 由於控件獲得輸入焦點後所有的鍵盤消息都發送給控件的窗口
函數了.而控件原來的窗口函數並不處理Tab鍵按下的消息.這時就可以用上邊的方法給控件重新設定一個窗
口消息處理函數並在其中處理Tab鍵.最後再在新的窗口函數中呼叫原來的窗口函數處理其它消息:
return CallWindowProc (OldScroll, hwnd, message, wParam,lParam) ;
這樣就可以處理Tab鍵了.

就像可以通過SetWindowLong給窗口重新設置窗口函數一樣.可以用SetClassLong來設置某個窗口的窗
口類的一些東西
.例如下邊重新設置窗口類的畫刷:
 SetClassLong (hwnd, GCL_HBRBACKGROUND,
      (LONG)CreateSolidBrush (RGB (color[0], color[1], color[2])));


===============================
編輯控件

創建子窗口時用"edit".如:
hwndEdit = CreateWindow (TEXT ("edit"), NULL,       
               WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |       
               WS_BORDER | ES_LEFT | ES_MULTILINE |       
               ES_AUTOHSCROLL | ES_AUTOVSCROLL,       
               0, 0, 0, 0, hwnd, (HMENU) ID_EDIT,       
              ((LPCREATESTRUCT) lParam) -> hInstance, NULL) ;

編輯控件的樣式:
文字對齊: ES_LEFT、ES_RIGHT和ES_CENTER
多行: ES_MULTILINE (缺省爲單行)
在單行樣式中.要文字水平捲動: ES_AUTOHSCROLL
在多行樣式中.要文字水平捲動(不是出現滾動條)(這阻止了自動換行): ES_AUTOHSCROLL
在多行樣式中.要文字垂直捲動(不是出現滾動條): ES_AUTOVSCROLL
在多行樣式中.要顯示滾動條用WS_HSCROLL和WS_VSCROLL
編輯控件缺省時沒有邊框.要顯示邊框用 WS_BORDER
選擇編輯控件的文字時.文字反白顯示.但編輯控件失去焦點後文字將不再加亮顯示.要使失去焦點後
選擇的文字仍然加亮顯示用: ES_NOHIDESEL

編輯控件給父窗口消息處理程序發送WM_COMMAND消息.消息參數爲
LOWORD (wParam)     子窗口ID
HIWORD (wParam)      通知碼
lParam              子窗口句柄

其中通知碼爲:
EN_SETFOCUS        編輯控件已經獲得輸入焦點
EN_KILLFOCUS       編輯控件已經失去輸入焦點
EN_CHANGE          編輯控件的內容將改變
EN_UPDATE          編輯控件的內容已經改變
EN_ERRSPACE        編輯控件執行已經超出中間
EN_MAXTEXT         編輯控件在插入時執行超出空間
EN_HSCROLL         編輯控件的水平滾動條已經被按下
EN_VSCROLL         編輯控件的垂直滾動條已經被按下

要處理tab鍵切換輸入焦點或處理Enter鍵. 可以給它重新指定一個窗口函數並在其中攔截.

在編輯區插入文字用:
GetWindowTextLength
GetWindowText
SetWindowText

給編輯控件發送消息:
SendMessage (hwndEdit, WM_CUT, 0, 0) ;   //剪貼     
SendMessage (hwndEdit, WM_COPY, 0, 0) ;  //複製 
SendMessage (hwndEdit, WM_CLEAR, 0, 0) ; //刪除選擇文字
SendMessage (hwndEdit, WM_PASTE, 0, 0) ; //粘貼

SendMessage (hwndEdit, EM_GETSEL, (WPARAM) &iStart,(LPARAM) &iEnd) ;
//取得目前選擇的起始位置和末尾位置.(末尾位置是選擇的最後一個文字的位置加1)

SendMessage (hwndEdit, EM_SETSEL, iStart, iEnd) ;  //選擇文字

SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) szString) ;
//用其他文字替換目前選擇的文字

iCount = SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0) ;
//取得多行編輯控件的行數

iOffset = SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0) ;
//對任何特定的行(從0行開始),您可以取得距離編輯緩衝區文字開頭的偏移量.
//iLine爲-1時返回光標所在行的偏移量.

iLength = SendMessage (hwndEdit, EM_LINELENGTH, iLine, 0) ;
//取得第iLine行的長度

iLength = SendMessage (hwndEdit, EM_GETLINE, iLine, (LPARAM) szBuffer) ;
//將第iLine行復制到緩衝區szBuffer中


==========================
列表控件

創建列表子窗口時,用"listbox"作爲窗口類.

列表樣式:
LBS_NOTIFY   允許父窗口接收列表的WM_COMMAND消息(缺省時不向父窗口發送WM_COMMAND消息)
LBS_SORT    對列表中的項目排序
LBS_MULTIPLESEL   列表是多選的(缺省時爲單選)
LBS_NOREDRAW    防止在向列表增加項目時自動重畫列表
樣式LBS_STANDARD包含了最常用的樣式:(LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)

將字符串放入列表:
SendMessage (hwndList, LB_INSERTSTRING, i, (LPARAM) szString) ;
第一個參數是列表控件的窗口句柄.
第二個參數LB_INSERTSTRING表示要插入一個項目.
第三個參數表示要插入的位置.(位置值從0開始.0表示最上邊第一個位置.-1表示插入最後)
第四個參數是要插入的字符串(字符串以0結尾).
函數返回0表示正常完成.

如果列表控件包含LBS_SORT樣式.則插入一個字符串時可以將第2個參數設置爲LB_ADDSTRING.這樣
字符串就會被自動插入到一個位置.如:
SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM) szString) ;

在列表控件中刪除一個字符串.只要指定第2個參數爲LB_DELETESTRING. 例如:
SendMessage (hwndList, LB_DELETESTRING, iIndex, 0) ;

刪除所有列表中的內容.則指定第2個參數爲LB_RESETCONTENT. 如:
SendMessage (hwndList, LB_RESETCONTENT, 0, 0) ;


在向列表增加或刪除字符串時.列表控件會自動被它的窗口函數重畫.如果你有許多字符串需要增加.
你可能希望在所有字符串增加完成前暫時阻止列表的自動重畫.這要:
SendMessage (hwndList, WM_SETREDRAW, FALSE, 0) ;
在增加完成後再恢復列表控件的自動重畫就可以了:
SendMessage (hwndList, WM_SETREDRAW, TRUE, 0) ;


要取得現在列表控件中的項目數用:
iCount = SendMessage (hwndList, LB_GETCOUNT, 0, 0) ;

單選列表控件中.要選擇一個項目(它會被加亮顯示)用:
SendMessage (hwndList, LB_SETCURSEL, iIndex, 0) ;
//iIndex參數爲要選擇第幾個項目.指定爲-1表示取消所有選擇.

單選列表控件中.也可以根據一個字符串的第一個字母來選擇一個項目.如:
iIndex = SendMessage (hwndList, LB_SELECTSTRING, iIndex,
                     (LPARAM) szSearchString) ;
表示從第iIndex位置開始搜索.如果哪個項目的開始字母與 szSearchString相同.則選擇該項目.並
返回該項目的位置. 沒有匹配的項目時返回-1.

單選列表控件中.要取得當前選擇項目的索引.用:
iIndex = SendMessage (hwndList, LB_GETCURSEL, 0, 0) ;
如果沒有被選項目.函數返回LB_ERR(值爲-1).

單選列表控件中.將某個項目複製到一個字符緩衝區.用:
iLength = SendMessage (hwndList, LB_GETTEXT, iIndex, (LPARAM) szBuffer) ;
則將列表控件中索引爲iIndex的項目複製到szBuffer. 並返回字符串的長度iLength.
(爲了使szBuffer緩衝區足夠大.你可以用LB_GETTEXTLEN做參數先取得該項目的字符串長度.)


對於多選列表控件:

可以使用LB_SETSEL來設定某特定項目的選擇狀態(不會影響其他項目的選擇狀態):
SendMessage (hwndList, LB_SETSEL, wParam, iIndex) ;
參數wParam爲0時.取消選擇. 爲-1時.選擇/取消所有項目. 爲其它值時. 選擇第iIndex個項目.

查看某項目的選擇狀態
iSelect = SendMessage (hwndList, LB_GETSEL, iIndex, 0) ;
//項目被選擇時返回非0. 否則返回0.

 

要使清單控件獲得輸入焦點用:
SetFocus (hwndList) ;

清單控件發送給父窗口的消息是WM_COMMAND. 參數如下:
LOWORD (wParam) 子窗口ID
HIWORD (wParam) 通知碼
lParam 子窗口句柄
 
其中通知碼的值如下:
LBN_ERRSPACE -2  表示已經超出執行空間
LBN_SELCHANGE 1  表示目前選擇已經被改變
LBN_DBLCLK 2     說明某項目已經被鼠標雙擊
LBN_SELCANCEL 3
LBN_SETFOCUS 4
LBN_KILLFOCUS 5
 
只有清單窗口樣式包括LBS_NOTIFY時,清單控件纔會向父窗口發送LBN_SELCHANGE和LBN_DBLCLK。


文件列表
將文件目錄列表填入清單列表.用:
SendMessage (hwndList, LB_DIR, iAttr, (LPARAM) szFileSpec) ;
//iAttr參數是文件屬性代碼,其低字節是文件屬性代碼:
iAttr    值 屬性
DDL_READWRITE  0x0000  普通文件
DDL_READONLY  0x0001 只讀文件 
DDL_HIDDEN  0x0002 隱藏文件 
DDL_SYSTEM  0x0004 系統文件 
DDL_DIRECTORY  0x0010 子目錄 
DDL_ARCHIVE  0x0020 歸檔位設立的檔案
//高字節提供了一些對所要求項目的附加控制:
iAttr  值 屬性 
DDL_DRIVES 0x4000 包括磁盤驅動器句柄 
DDL_EXCLUSIVE 0x8000 互斥搜索
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章