>_<" 小工具和對話框的區別:
- 小工具可以創建並獨立使用,因為它們本質上就是窗口。但是,通常需要使用對話框,它是包含一個或多個小工具的窗口。
- 對話框通常是一個窗口,它在出現時會要求用戶輸入信息。它可能包含多個小工具,要求用戶根據各種選擇來提供信息,或者以消息框的形式,僅提供信息 (比如向用戶提供注意事項或警告)和一個“確定”按鈕。
>_<" 對話框的基本原理:
輸入焦點
窗口管理器能記住用戶使用觸摸屏、鼠標、鍵盤或用其他方式最終所選擇的窗口或窗口對象。該窗口會收到鍵盤輸入消息,即具有輸入焦點。追蹤輸入焦點的主要原因是為了確定鍵盤命令的發送目的地。具有輸入焦點的窗口會接收由鍵盤所生成的事件。如果要將對話框內的輸入焦點移至下一個焦點對話框項目,可以使用GUI_KEY_TAB鍵。如果要向后移動,則可以使用GUI_KEY_BACKTAB。
阻塞式和非阻塞式對話框
對話框窗口可以分為阻塞式和非阻塞式。阻塞式對話框會阻塞執行的線程。默認情況下,它有輸入焦點,用戶必須先關閉它,線程才能繼續執行。阻塞式對話框不會同時禁用所顯示的其他對話框。換言之,阻塞式對話框並非模式對話框。如果對話框為阻塞式,則表示只有在對話框關閉后,所使用的函數 (GUI_ExecDialogBox()或GUI_ExecCreatedDialog())才會返回值。而非阻塞式對話框則不會阻塞調用的線程--在它為可見時,可允許任務繼續運行。創建對話框后,函數會立即返回值。需要注意的是,切勿從回調函數中調用阻塞式函數。否則,可能會導致應用程序故障。
對話框過程函數
對話框就是一個窗口,它接收消息的方式與系統中其他所有窗口一樣。大多數消息由對話框的窗口回調程序自動處理,而其他消息則傳遞到建立對話框時所指定的回調程序,這便稱為對話框過程函數。
對話框消息
發送到對話框過程函數的兩種附加消息為:WM_INIT_DIALOG和WM_NOTIFY_PARENT。在顯示對話框前,WM_INIT_DIALOG消息會立即發送到對話框過程函數。對話框過程函數通常使用該消息來初始化小工具,並執行其他任何會影響對話框外觀的初始化任務。 WM_NOTIFY_PARENT消息則通過對話框的子窗口發送到對話框,通知任何事件的父窗口以確保同步化。通過子窗口發送的事件取決於其類型,並針對每個類型的小工具單獨記錄。
>_<" 創建對話框需要兩個基本要素:
資源表和對話框過程;前者定義所要包括的小工具,后者定義小工具的初始值及其行為。一旦具備這兩個要素,則只需進行單個函數調用(GUI_CreateDialogBox()或GUI_ExecDialogBox())就能創建對話框。
1 /********************************************************************* 2 * 3 對話框可以基於阻塞(使用GUI_ExecDialogBox())或非阻塞(使用GUI_CreateDialogBox()) 4 方式創建。必須首先定義一個資源表,以指定在對話框中所要包括的所有小工具。下面的示例說明了創 5 建資源表的方法: 6 對話框中所要包括的任何小工具都必須使用<WIDGET>_CreateIndirect()函數來間接創建。 7 */ 8 static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { 9 { FRAMEWIN_CreateIndirect, "Dialog", 0, 10, 10, 180, 230, FRAMEWIN_CF_MOVEABLE, 0 }, 10 { BUTTON_CreateIndirect, "OK", GUI_ID_OK, 100, 5, 60, 20 }, 11 { BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 100, 30, 60, 20 }, 12 { TEXT_CreateIndirect, "LText", 0, 10, 55, 48, 15, TEXT_CF_LEFT }, 13 { TEXT_CreateIndirect, "RText", 0, 10, 80, 48, 15, TEXT_CF_RIGHT }, 14 { EDIT_CreateIndirect, NULL, GUI_ID_EDIT0, 60, 55, 100, 15, 0, 50 }, 15 { EDIT_CreateIndirect, NULL, GUI_ID_EDIT1, 60, 80, 100, 15, 0, 50 }, 16 { TEXT_CreateIndirect, "Hex", 0, 10, 100, 48, 15, TEXT_CF_RIGHT }, 17 { EDIT_CreateIndirect, NULL, GUI_ID_EDIT2, 60, 100, 100, 15, 0, 6 }, 18 { TEXT_CreateIndirect, "Bin", 0, 10, 120, 48, 15, TEXT_CF_RIGHT }, 19 { EDIT_CreateIndirect, NULL, GUI_ID_EDIT3, 60, 120, 100, 15 }, 20 { LISTBOX_CreateIndirect, NULL, GUI_ID_LISTBOX0,10, 10, 48, 40 }, 21 { CHECKBOX_CreateIndirect, NULL, GUI_ID_CHECK0, 10, 140, 0, 0 }, 22 { CHECKBOX_CreateIndirect, NULL, GUI_ID_CHECK1, 30, 140, 0, 0 }, 23 { SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER0, 60, 140, 100, 20 }, 24 { SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER1, 10, 170, 150, 30 } 25 }; 26 /********************************************************************* 27 * 28 對話框過程函數 29 上述示例使用如下所示的空白對話框過程函數創建。在創建任何對話框過程函數時,該基本模板都將 30 作為起始點: 31 */ 32 static void _cbCallback(WM_MESSAGE * pMsg) { 33 switch (pMsg->MsgId) { 34 default: 35 WM_DefaultProc(pMsg); 36 } 37 } 38 /********************************************************************* 39 * 40 * MainTask 41 */ 42 void Fun(void) { 43 //對於該示例,對話框顯示時會有下列代碼行: 44 GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate),&_cbCallback, 0, 0, 0); 45 } 46 /* 47 創建對話框后,所有資源表中的小工具都將可見。盡管這些小工具在上面的屏幕截圖中可見,但它們 48 是以 “空”的形式出現的。這是因為對話框過程函數尚未包含初始化單個元素的代碼。小工具的初始 49 值、由它們所引起的行為以及它們之間的交互作用都需要在對話框過程中進行定義。 50 */