關於編輯控制件
編輯控制項是一個矩形控制元件視窗,通常用於對話框中,讓使用者能夠輸入和編輯文字。
編輯控件同時支援 Unicode 字元集,其中字元為兩個字節,以及其中字元為一個字節的 ANSI 字元集。 如需 Unicode 和 ANSI 字元集的詳細資訊,請參閱 Unicode 和字元集。
豐富的編輯控制項 支援系統編輯控制件中無法使用的許多功能。 如需詳細資訊,請參閱 Rich Edit Controls。
本概觀將討論下列主題。
編輯控制項功能
選取時,編輯控件會顯示指出插入點的閃爍插入號。 然後,使用者可以輸入文字、移動插入點,或使用鍵盤或滑鼠選取要編輯的文字。 編輯控制項會以WM_COMMAND訊息的形式,將通知碼傳送至其父視窗。 如需來自編輯控件之訊息的詳細資訊,請參閱 編輯控件通知訊息。 父視窗可以呼叫 SendDlgItemMessage 函式,將訊息傳送至對話框中的編輯控制件。 某些訊息也可以使用預先定義的宏來傳送。
系統同時提供單行編輯控制項和多行編輯控制項。 編輯控制件屬於 EDIT 視窗類別。
下拉式方塊是一個控件,結合了編輯控件和清單框的大部分功能。 在下拉式方塊中,編輯控件會顯示目前的選取範圍,而清單框會顯示使用者可以選取的選項。 如需下拉式方塊的詳細資訊,請參閱 下拉式方塊。
許多開發人員會使用通用對話框連結庫 (Comdlg32.dll) 中提供的對話框來執行工作,否則可能需要自定義的編輯控件。 如需通用對話框的相關信息,請參閱 通用對話框連結庫。
編輯控制項類型和樣式
個別編輯控制項可以同時有數個樣式。 大部分的開發人員都會使用工具來開發對話方塊,因此可能不需要明確指定編輯控件樣式。 不過,如果應用程式使用 CreateWindow 或 CreateWindowEx 函式建立編輯控件,則必須指定這些編輯控件樣式。 如需編輯控件樣式的表格,請參閱 編輯控件樣式。
每個編輯控制項都會指定一組樣式值,以定義編輯控制件的外觀和功能。 樣式值可以建立單行或多行編輯控件的外觀;對齊 控件中的文字;和會決定文字出現在編輯控件中的方式,即使如此。
多行樣式
編輯控制件有兩個線條樣式。 預設值為單行編輯控制件。 應用程式也可以使用ES_MULTILINE樣式來建立多行編輯控件。
捲動樣式
ES_AUTOHSCROLL樣式會告知編輯控件視需要水平卷動文字,因為使用者輸入文字。 如果未指定此樣式,編輯控件就無法水平捲動。 對於沒有 ES_AUTOHSCROLL的單行編輯控件,只會接受填滿控件可見區域的字元。 對於沒有 ES_AUTOHSCROLL的多行編輯控件,當使用者輸入的文字超過單行顯示時,文字會換行到下一行。 如果 為多行編輯控件指定了ES_AUTOHSCROLL ,當使用者輸入的文字超過可以在單行上顯示時,控件會水平捲動;文字不會換行。
ES_AUTOHSCROLL會自動套用至具有WS_HSCROLL樣式的靠左對齊多行編輯控件。 換句話說,任何靠左對齊的多行編輯控件,其水準滾動條會自動水平捲動。
多行編輯控件不會靠左對齊,則會忽略ES_AUTOHSCROLL 。 置中和靠右對齊的多行編輯控件無法水平捲動
ES_AUTOVSCROLL樣式會告訴編輯控件當使用者輸入的文字超過可在編輯控件中顯示的文字時,垂直捲動文字。 此樣式僅適用於多行編輯控制件。 如果未為多行編輯控件指定此樣式,編輯控件在輸入的文字超過可顯示時,將不會接受輸入。
對齊樣式
有三種樣式會導致系統對齊編輯控件中的文字。 ES_LEFT、ES_CENTER和ES_RIGHT樣式會決定文字是否分別靠左、置中或靠右對齊。 靠右對齊和置中多行編輯控件不能有 ES_AUTOHSCROLL 樣式;也就是說,它們無法水平捲動。
雖然無法動態變更編輯控制件的對齊樣式,但下列技術可用來解決這項限制:
- 建立多個編輯控件,針對應用程式所需的每個樣式建立一個,並視需要切換它們。
- 視需要建立具有所需樣式的新編輯控件,並切換至新的控件。
文字和輸入樣式
應用程式可以使用樣式來指定編輯控件顯示文字的方式。 ES_LOWERCASE樣式會使輸入編輯控件的所有大寫字元轉換成小寫。 同樣地, ES_UPPERCASE 樣式會導致所有小寫字元轉換成大寫。
如需字元集的詳細資訊,請參閱 Unicode 和字元集。
ES_PASSWORD樣式會將單行編輯控制項中的所有字元顯示為星號。 應用程式可以使用EM_SETPASSWORDCHAR訊息來定義要顯示的不同字元,如本主題稍後所述。
如果編輯控制項來自第 6 版Comctl32.dll,黑色圓圈是ES_PASSWORD樣式的預設字元。 在編輯舊版通用控件的控件中,預設字元為星號。
ES_OEMCONVERT樣式會使輸入編輯控件的文字從設定為 OEM 字元集的 Windows 字元轉換為 OEM 字元集,然後轉換回 Windows 字元集。 當應用程式呼叫 CharToOem 函式,將編輯控件中的 Windows 字串轉換為 OEM 字元時,這可確保適當的字元轉換。 ES_OEMCONVERT最適用於編輯控件,這些控制件包含將用於不支援 Unicode 之文件系統上的檔名。
對於對話框中的多行編輯控件, ES_WANTRETURN 樣式會在使用者輸入文字時按下 ENTER 鍵時插入歸位字元。 如果未指定此樣式,按下 ENTER 鍵的效果與在對話框中按下預設的按鈕相同。 如果沒有 ES_WANTRETURN,用戶必須按 CTRL+ENTER 以插入歸位字元。 如需 Wordwrap 和換行符的相關信息,請參閱 處理 Wordwrap 和換行符。
可視化樣式
當 編輯控件沒有焦點時,ES_NOHIDESEL 樣式會使選取的文字保持醒目提示。 如果沒有此樣式,當控件失去焦點時,選取的文字會失去醒目提示。
根據預設,編輯控件沒有框線。 若要給予它,應用程式可以使用 WS_BORDER 視窗樣式。
若要搭配編輯控件使用可視化樣式,應用程式必須包含指令清單,而且必須在程式開頭呼叫 InitCommonControls。 如需可視化樣式的資訊,請參閱 可視化樣式。 如需指令清單的資訊,請參閱 啟用可視化樣式。
文字緩衝區
系統會將編輯控件文字儲存在緩衝區中,並視需要將它複製到控件。
下列主題討論系統如何配置和初始化緩衝區,並變更其特性:
配置文字緩衝區
當系統建立編輯控件時,它會自動建立文字緩衝區、設定其初始大小,並視需要增加大小。 單行編輯控制元件的大小最多可以有大約 32 KB 的預先定義限制。 因為此限制可能會變更,所以稱為「軟限制」。 應用程式可以將EM_SETLIMITTEXT訊息傳送至編輯控件,來設定緩衝區大小的硬性限制。 如果緩衝區超過任一限制,系統會傳送 應用程式EN_ERRSPACE 通知碼。 應用程式可以藉由傳送 EM_GETLIMITTEXT 訊息來擷取目前的文字限制。
系統通常會使用應用程式數據區段外的記憶體,在對話框中建立編輯控件緩衝區。 當建立編輯控件時,應用程式可以使用DS_LOCALEDIT樣式來隱藏此預設配置行為,並從其本機堆積建立緩衝區(請參閱關於對話框的「對話框範本樣式」。 使用DS_LOCALEDIT樣式的應用程式負責所有緩衝區配置。 若要進行初始配置,應用程式可以呼叫 LocalAlloc 函式,並將傳回的緩衝區句柄傳送至編輯控件,方法是傳送EM_SETHANDLE訊息。 若要進行後續配置(例如,為了回應 EN_ERRSPACE 通知程式代碼),應用程式應該儲存目前的緩衝區內容(如有必要),並取得如下所示的新緩衝區。
若要儲存目前的緩衝區並取得新的緩衝區,請遵循此程式。
- 藉由傳送控件EM_GETHANDLE訊息,擷取目前為多行編輯控件中文字配置的記憶體句柄。
- 呼叫 LocalFree 函式來釋放緩衝區。
- 呼叫 LocalAlloc 以取得新的緩衝區(和緩衝區句柄)。
- 藉由傳送控件 EM_SETHANDLE 訊息,將緩衝區句柄提供給系統。
EM_SETHANDLE和EM_GETHANDLE訊息僅適用於多行編輯控件。
使用預設配置行為的應用程式(也就是不使用DS_LOCALEDIT樣式(請參閱關於對話方塊的「對話框範本樣式」)不得將EM_SETHANDLE和EM_GETHANDLE訊息傳送至編輯控件。
傳送EM_SETHANDLE訊息有數個副作用:它會清除復原旗標(使EM_CANUNDO訊息傳回零)、清除修改旗標(使EM_GETMODIFY訊息傳回零),並重新繪製編輯控件視窗。
初始化文字緩衝區
應用程式可以呼叫 SetDlgItemText 函式,初始化或重新初始化編輯控件的文字緩衝區。 應用程式可以藉由呼叫 GetDlgItemText 函式來擷取文字緩衝區的內容。
將文字緩衝區設定為唯讀
針對每個編輯控件,系統會維護唯讀旗標,指出控件的文字是可擦寫的(預設值)還是唯讀的。 應用程式可以藉由傳送 控件EM_SETREADONLY 訊息來設定文字的讀取/寫入旗標或只讀旗標。 若要判斷編輯控件是否為唯讀,應用程式可以使用GWL_STYLE常數呼叫 GetWindowLong 函式。 EM_SETREADONLY訊息同時套用至單行和多行編輯控件。
變更格式化矩形
編輯控件文字的可見性是由其視窗矩形及其格式矩形的維度所控管。 視窗矩形是包含編輯控制件之視窗的工作區。 格式化矩形是由系統維護的建構,用於格式化視窗矩形中顯示的文字。 第一次顯示編輯控件時,畫面上兩個矩形都相同。 應用程式可以將格式化矩形設為大於視窗矩形(藉此限制編輯控件文字的可見度)或小於視窗矩形(從而在文字周圍建立額外的空格符)。
應用程式可以藉由傳送 EM_SETRECT 訊息來設定編輯控件格式化矩形的座標。 EM_SETRECT訊息也會自動重新繪製編輯控件的文字。 若要建立格式化矩形的座標,而不重新繪製控件的文字,應用程式可以傳送 控件EM_SETRECTNP 訊息。 若要擷取格式化矩形的座標,應用程式可以傳送 控件EM_GETRECT 訊息。 這些訊息僅適用於多行編輯控制件。
編輯控制項通知訊息
用戶會使用鍵盤和滑鼠進行編輯要求。 系統會以WM_COMMAND訊息的形式,將每個要求傳送至編輯控件的父視窗。 此訊息包含 wParam 參數低序字組的編輯控件識別碼、lParam 參數中編輯控件的句柄,以及對應至 wParam 參數之高序文字中使用者動作的編輯控件通知程式代碼。
應用程式應該檢查每個通知訊息隨附的通知代碼,並適當地回應。 下表列出每個編輯控制項通知程式代碼,以及產生它的動作。
通知程序代碼 | 使用者動作 |
---|---|
EN_CHANGE | 使用者已修改編輯控制件中的文字。 系統會在傳送此通知碼之前更新顯示器(與EN_UPDATE不同)。 |
EN_ERRSPACE | 編輯控制項無法配置足夠的記憶體以符合特定要求。 |
EN_HSCROLL | 用戶已按下編輯控制件的水準滾動條。 系統會在更新畫面之前傳送此通知程序代碼。 |
EN_KILLFOCUS | 用戶已選取另一個控制件。 |
EN_MAXTEXT | 插入文字時,用戶已超過編輯控件的指定字元數。 插入已截斷。 當編輯控件沒有ES_AUTOHSCROLL樣式且要插入的字元數超過編輯控件的寬度,或編輯控件沒有ES_AUTOVSCROLL樣式,以及要插入的行總數超過編輯控件的高度時,也會傳送此通知程式代碼。 |
EN_SETFOCUS | 用戶已選取此編輯控制件。 |
EN_UPDATE | 用戶已變更編輯控制件中的文字,而且系統即將顯示新的文字。 系統會在格式化文字之後傳送此通知程式代碼,但在顯示文字之前,讓應用程式可以調整編輯控件視窗的大小。 |
EN_VSCROLL | 用戶已按下編輯控件的垂直滾動條,或已將滑鼠滾輪捲動到編輯控件上。 系統會在更新畫面之前傳送此通知程序代碼。 |
EN_SEARCHWEB | 用戶已按下 [搜尋 Web] 操作功能表項。 系統會在啟動瀏覽器之後傳送此通知。 |
此外,系統會在繪製編輯控制項之前,將WM_CTLCOLOREDIT訊息傳送至編輯控件的父視窗。 此訊息包含編輯控件的顯示內容句柄(DC)和子視窗的句柄。 父視窗可以使用這些句柄來變更編輯控件的文字和背景色彩。
編輯控制項預設訊息處理
預先定義編輯控制項視窗類別的視窗程式會針對編輯控制程式未處理的所有訊息執行預設處理。 當編輯控制程式傳回 任何訊息的 FALSE 時,預先定義的視窗程式會檢查訊息,並執行下列預設動作。
訊息 | 默認動作 |
---|---|
EM_CANUNDO | 如果可以復原編輯控件作業,則傳回 TRUE。 |
EM_CHARFROMPOS | 傳回最接近指定點之字元的字元索引和行索引。 |
EM_EMPTYUNDOBUFFER | 清空復原緩衝區,並將EM_CANUNDO訊息所擷取的復原旗標設定為 FALSE。 每當編輯控制件收到 WM_SETTEXT 或 EM_SETHANDLE 訊息時,系統就會自動清除復原旗標。 |
EM_FMTLINES | 在多行編輯控件中,將虛換行符(兩個歸位字元和換行字元)新增或移除至換行符的結尾。 它不會由單行編輯控制件處理。 |
EM_GETFIRSTVISIBLELINE | 傳回單行編輯控件中第一個可見字元之以零起始的索引,或多行編輯控件中最上層可見行的以零起始的索引。 |
EM_GETHANDLE | 傳回句柄,識別包含多行編輯控件文字的緩衝區。 它不會由單行編輯控制件處理。 |
EM_GETLIMITTEXT | 傳回目前的文字限制,以字元為單位。 |
EM_GETLINE | 將單行編輯控制件中的字元複製到緩衝區,並傳回復制的字元數。 在多行編輯控件中,從控件擷取一行文字,並傳回復制的字元數。 |
EM_GETLINECOUNT | 傳回編輯控制件中的行數。 |
EM_GETMARGINS | 傳回左右邊界的寬度。 |
EM_GETMODIFY | 傳回旗標,指出編輯控件的內容是否已修改。 |
EM_GETPASSWORDCHAR | 傳回編輯控制項搭配 ES_PASSWORD 樣式使用的字元。 |
EM_GETRECT | 傳回編輯控制件中格式化矩形的座標。 |
EM_GETSEL | 傳回編輯控制項中目前選取範圍的開始和結束字元位置。 |
EM_GETTHUMB | 傳回多行編輯控件中垂直滾動條中滾動盒的位置。 |
EM_GETWORDBREAKPROC | 傳回編輯控制項中目前 Wordwrap 函式的位址。 |
EM_LINEFROMCHAR | 傳回包含指定字元索引的多行編輯控制項中以零起始的行數。 此訊息是EM_LINEINDEX訊息的反向訊息。 它不會由單行編輯控制件處理。 |
EM_LINEINDEX | 傳回多行編輯控制件中行的字元。 此訊息是EM_LINEFROMCHAR訊息的反向訊息。 它不會由單行編輯控制件處理。 |
EM_LINELENGTH | 傳回單行編輯控件的長度,以字元為單位。 在多行編輯控件中,傳回指定行的長度,以字元為單位。 |
EM_LINESCROLL | 在單行編輯控件中垂直捲動文字,或在多行編輯控件中水平卷動文字(當控件具有 ES_LEFT 樣式時)。 lParam 參數會指定要從目前行開始垂直捲動的行數。 wParam 參數會指定要水平捲動的字元數,從目前的字元開始。 |
EM_POSFROMCHAR | 傳回指定字元的用戶端座標。 |
EM_REPLACESEL | 以應用程式提供的緩衝區中的文字取代目前的選取範圍、傳送父視窗 EN_UPDATE 和 EN_CHANGE 通知碼,並更新復原緩衝區。 |
EM_SCROLL | 在多行編輯控件中垂直捲動文字。 此訊息相當於將 WM_VSCROLL 訊息傳送至編輯控制件。 它不會由單行編輯控制件處理。 |
EM_SCROLLCARET | 將插入號捲動到編輯控件的檢視中。 |
EM_SETFONT | 不支援。 |
EM_SETHANDLE | 將句柄設定為做為文字緩衝區的記憶體、清空復原緩衝區、將捲動位置重設為零,以及重新繪製視窗。 |
EM_SETLIMITTEXT | 設定用戶可在編輯控制件中輸入的最大字元數。 對於單行編輯控件,此值會0x7FFFFFFE或 wParam 參數的值,無論哪一個較小。 對於多行編輯控件,這個值可以是1或 wParam 參數的值,無論哪一個較小。 |
EM_SETMARGINS | 設定左右邊界的寬度,並重新繪製編輯控制項以反映新的邊界。 |
EM_SETMODIFY | 設定或清除修改旗標,以指出編輯控件是否已修改。 |
EM_SETPASSWORDCHAR | 定義編輯控制項搭配 ES_PASSWORD 樣式使用的字元。 |
EM_SETREADONLY | 設定或移除編輯控制件中的唯讀樣式(ES_READONLY)。 |
EM_SETRECT | 設定多行編輯控件的格式矩形,並重新繪製視窗。 它不會由單行編輯控制件處理。 |
EM_SETRECTNP | 設定多行編輯控件的格式矩形,但不會重新繪製視窗。 它不會由單行編輯控制件處理。 |
EM_SETSEL | 藉由設定要選取的開始和結束位置,選取編輯控件中的字元範圍。 |
EM_SETTABSTOPS | 設定多行編輯控制件中的製表位位置。 它不會由單行編輯控制件處理。 |
EM_SETWORDBREAKPROC | 以應用程式定義的 Wordwrap 函式取代預設 Wordwrap 函式。 |
EM_UNDO | 拿掉剛插入或插入任何已刪除字元的任何文字,並將選取範圍設定為插入的文字。 如有必要,請將 EN_UPDATE 和 EN_CHANGE 通知碼傳送至父視窗。 |
WM_CHAR | 將字元寫入單行編輯控件,並將EN_UPDATE和EN_CHANGE通知碼傳送至父視窗。 將字元寫入多行編輯控制件。 處理標準函式的快速鍵,例如 CTRL+C 來複製,CTRL+V 用於貼上。 在多行編輯控件中,也會處理 TAB 和 CTRL+TAB 按鍵,以在對話框中的控件之間移動,並將索引標籤插入多行編輯控件。 針對不合法的字元使用 MessageBeep 函式。 |
WM_CLEAR | 在編輯控件中清除目前的選取範圍,如果有的話。 如果沒有目前的選取範圍,請刪除插入號右邊的字元。 如果使用者按下 SHIFT 鍵,這會剪下剪貼簿的選取範圍,或在沒有選取專案時刪除插入號左邊的字元。 如果使用者按下 CTRL 鍵,這會刪除選取範圍,或在沒有選取專案時刪除到行尾。 |
WM_COPY | 除非樣式 ES_PASSWORD,否則會將文字複製到剪貼簿,在此情況下,訊息會傳回零。 |
WM_CREATE | 建立編輯控制項,並通知父視窗成功或失敗 1。 |
WM_CUT | 將選取範圍剪下至剪貼簿,如果沒有選取專案,則刪除游標左邊的字元。 |
WM_ENABLE | 讓單行編輯控件以灰色重繪矩形。 傳回單行和多行編輯控件的啟用狀態。 |
WM_ERASEBKGND | 以編輯控制件的目前色彩填滿多行編輯控制元件視窗。 |
WM_GETDLGCODE | 傳回下列值:DLGC_WANTCHARS、DLGC_HASSETSEL和DLGC_WANTARROWS。 在多行編輯控件中,它也會傳回DLGC_WANTALLKEYS。 如果使用者按下 ALT+BACKSPACE,它也會傳回DLGC_WANTMESSAGE。 |
WM_GETFONT | 傳回控件所使用的字型句柄,如果 控件使用系統字型,則傳回 NULL 。 |
WM_GETTEXT | 將指定的字元數複製到緩衝區,並傳回復制的字元數。 |
WM_GETTEXTLENGTH | 傳回編輯控件中文字的長度,以字元為單位。 長度不包含 Null 終止字元。 |
WM_HSCROLL | 水平捲動多行編輯控件中的文字,並處理滾動盒移動。 |
WM_KEYDOWN | 執行虛擬金鑰代碼的標準處理。 |
WM_KILLFOCUS | 拿掉編輯控制元件視窗的鍵盤焦點、終結插入號、隱藏目前的選取範圍,並通知父視窗編輯控制件已失去焦點。 |
WM_LBUTTONDBLCLK | 清除目前的選取範圍,並選取游標下的單字。 如果 SHIFT 鍵為壓低,請將選取範圍延伸至游標下的單字。 |
WM_LBUTTONDOWN | 變更目前的插入點。 如果 SHIFT 鍵為壓低,請將選取範圍延伸至游標的位置。 在多行編輯控件中,當使用者按住多行編輯控件視窗外的滑鼠按鈕時,也會設定定時器自動捲動。 |
WM_LBUTTONUP | 釋放滑鼠擷取,並在單行編輯控件中設定文字插入點。 在多行編輯控件中,也會終止WM_LBUTTONDOWN訊息中設定的定時器。 |
WM_MOUSEMOVE | 如果滑鼠按鈕關閉,則變更單行編輯控件中的目前選取範圍。 在多行編輯控件中,如果使用者按住多行編輯控件視窗外的滑鼠按鈕,也會設定定時器自動捲動。 |
WM_NCCREATE | 視窗的 CREATESTRUCT 結構的指標。 第一次建立視窗時,此訊息會傳送至 WM_CREATE 訊息。 |
WM_NCDESTROY | 釋放與編輯控制視窗相關聯的所有記憶體,包括文字緩衝區、復原緩衝區、製表位緩衝區,以及反白顯示筆刷。 |
WM_PAINT | 清除背景、以編輯控件視窗的目前色彩填滿視窗、繪製框線(如果有)、設定字型並繪製任何文字,並顯示文字插入插入號。 |
WM_PASTE | 將剪貼簿中的文字貼到插入號位置的編輯控件視窗中。 |
WM_SETFOCUS | 設定編輯控制件視窗的鍵盤焦點(如果隱藏目前選取範圍,則會建立插入點)。 |
WM_SETFONT | 設定字型,並選擇性地重新繪製編輯控制件。 |
WM_SETTEXT | 將文字複製到單行編輯控件,在記憶體不足時通知父視窗、清空復原緩衝區,並將EN_UPDATE和EN_CHANGE通知碼傳送至父視窗。 在多行編輯控件中,也會重新包裝行(如有必要),並設定滾動位置。 |
WM_SIZE | 設定編輯控制元件視窗的大小,確保大小符合字元的高度和寬度。 |
WM_SYSCHAR | 如果使用者按下 ALT+BACKSPACE,則傳回 TRUE;否則不會採取任何動作。 |
WM_SYSKEYDOWN | 如果使用者按下 ALT+BACKSPACE,請復原最後一個動作;否則不會採取任何動作。 |
WM_TIMER | 如果使用者按住多行編輯控件視窗外的滑鼠按鈕,就會捲動編輯控件視窗中的文字。 |
WM_UNDO | 拿掉剛插入或插入任何已刪除字元的任何文字,並將選取範圍設定為插入的文字。 如有必要,請將 EN_UPDATE 和 EN_CHANGE 通知碼傳送至父視窗。 |
WM_VSCROLL | 垂直捲動多行編輯控件,並處理滾動盒移動。 它不會由單行編輯控制件處理。 |
預先定義的編輯控制視窗程式會將所有其他訊息傳遞至 DefWindowProc 函式,以進行默認處理。