一、窗口的繪制
繪制窗體實際上可以看作是繪制輪廓和繪制組件兩個部分。
我們先看這么一個文件 CustCoordinates.c
這個文件主要是定義了這么一個宏 g_categories_controls_map:
或者類似于這樣的定義,這個數組就具體的將窗體的輪廓以及窗體的各個組件的位置作出了定義
下面我們以一個具體的例子作為說明:
const U8 category5[] =
{
5, // 這個代表組件的個數;
DM_BASE_LAYER_START, // 開始層;
DM_SCR_BG, // 背景;
DM_BASE_CONTROL_SET1, //表示窗體的基本組成——狀態欄、標題和軟按鍵
DM_MULTILINE_INPUTBOX1, //多行輸入框
DM_CATEGORY_CONTROLLED_AREA // 輸入法的部分;
};
這些組件被定義在枚舉結構mmi_dm_control_ids_enum中。
const S16 coordinate_set5[] =
{
DM_FULL_SCREEN_COORDINATE_FLAG,
DM_CONTENT_COORDINATE_FLAG,
DM_FULL_SCREEN_COORDINATE_FLAG
};
這個數組是這些組件的屬性;這個屬性主要是指各個組件的坐標,高度,寬度;
這些數組里面定義的內容通過dm_get_coordinates() 這個函數映射到 具體的繪制過程中;
在dm_get_coordinates 這個函數中我們可以看到,這些 DM_FULL_SCREEN_COORDINATE_FLAG常量實際上都被轉化為坐標。
現在我們回到剛才的那個函數 ShowCategory..Screen() 中來。下圖是個典型的窗口圖:
以下為例子:
void ShowCategory353Screen(
U8 *title,
U16 title_icon,
U16 left_softkey,
U16 left_softkey_icon,
U16 right_softkey,
U16 right_softkey_icon,
S32 number_of_items,
U8 **list_of_items,
U16 *list_of_icons,
U8 **list_of_descriptions,
S32 flags,
S32 highlighted_item,
U8 *history_buffer)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
dm_data_struct dm_data;
S32 i;
U8 h_flag;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
gdi_layer_lock_frame_buffer(); // 鎖定當前層的buffer;
// 創建一個列表式的窗口
create_fixed_icontext_menuitems();
associate_fixed_icontext_list();
// 并將窗口下的內容,包括標題欄,左右軟件,以及各個子菜單的圖標 顯示出來;
ShowListCategoryScreen(
(UI_string_type) title,
get_image(title_icon),
get_string(left_softkey),
get_image(left_softkey_icon),
get_string(right_softkey),
get_image(right_softkey_icon),
number_of_items);
if (list_of_descriptions == NULL)
{
for (i = 0; i < number_of_items; i++)
{
add_fixed_icontext_item((UI_string_type) list_of_items[i], wgui_get_list_menu_icon(i, list_of_icons[i]));
wgui_pop_up_description_strings[i].text_strings[0] = NULL;
}
}
else
{
for (i = 0; i < number_of_items; i++)
{
add_fixed_icontext_item((UI_string_type) list_of_items[i], wgui_get_list_menu_icon(i, list_of_icons[i]));
wgui_pop_up_description_strings[i].text_strings[0] = (UI_string_type) list_of_descriptions[i];
}
}
h_flag = set_list_menu_category_history(MMI_CATEGORY52_ID, history_buffer);
// 高亮當前選中的ITEM
if (h_flag)
{
fixed_list_goto_item_no_redraw(MMI_fixed_list_menu.highlighted_item);
}
else
{
fixed_list_goto_item_no_redraw(highlighted_item);
}
MMI_title_string = (UI_string_type) title;
MMI_title_icon = (PU8) get_image(title_icon);
set_pop_up_descriptions(1, number_of_items, MMI_fixed_list_menu.highlighted_item);
gdi_layer_unlock_frame_buffer();
// 前面這整個一段是用來繪制一個列表窗口,這部分的內容基本上根據自己的選擇有什么畫什么;
// 而下面的內容是每個窗體都共有的部分;
ExitCategoryFunction = ExitListCategoryScreen;
dm_setup_category_functions(dm_redraw_category_screen,dm_get_category_history, dm_get_category_history_size);
dm_data.s32ScrId = (S32) GetActiveScreenId();
dm_data.s32CatId = MMI_CATEGORY52_ID;
dm_data.s32flags = 0;
dm_setup_data(&dm_data);
dm_redraw_category_screen();
} /* end of ShowCategory353Screen */
因為MTK后面的代碼的gui 部分是用 draw_manager 這個來控制的,因此所有的窗口的控件的實際繪制過程都是通過 dm_redraw_category_screen(); 這個函數來實現的;這個函數可以幫助我們繪制一些比較特殊的自己需要的組件,當然如果我們使用的組件已經包含在這個函數里面,那么直接使用。
可以分析一下這個函數的流程:
獲取窗體模版的ID; // 這個在showcategory里面實現,dm_data.s32CatId = MMI_CATEGORY52_ID;
↓
根據模版的ID得到組件的集合和個數;
// control_set_ptr = dm_search_control_set((U16) g_dm_data.s32CatId, &DeafultCoordinateSet_p);
↓
根據模版ID得到組件屬性標識的集合;
// UICtrlAccessPtr_p = dm_search_coordinate_set(g_dm_data.s32ScrId);
↓
鎖定當前的frame,各個組件繪制前的任務準備就緒;// gdi_layer_lock_frame_buffer();
↓
繪制窗體之前,還可以改變窗體的大?。?/p>
// UICtrlAccessPtr_p = dm_get_cat_scr_coordinates(UICtrlAccessPtr_p, &dm_cat_scr_info);
↓
獲取不同組件的不同屬性,并根據不同的屬性繪制出自己需要的窗口;
// for (u8CtrlCt = 1; u8CtrlCt <= u8NoOfUICtrls; u8CtrlCt++) 這個語句包含的內容
↓
全部繪制完畢,整合GDI layer,將當前frame 解鎖;
上面已經說明了一個窗體的繪制過程。另外與窗體相關的函數還有:
Redrawcategory**screen(); 這個是窗體的刷新函數;
Exitcategory**screen() ; 這個是窗體的退出函數
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/xzl04/archive/2009/04/14/4068447.aspx