(注:本文轉載自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_VSCROLL和WM_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 互斥搜索