MTK的控件和窗体绘制机制及其事件响应机制(二)
一、窗口的绘制 绘制窗体实际上可以看作是绘制轮廓和绘制组件两个部分。 我们先看这么一个文件 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(); ↓ 绘制窗体之前,还可以改变窗体的大小; // 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() ; 这个是窗体的退出函数; |