static si_t handle_window_cancel (union message * msg) { struct widget* w; w = application_widgets_for_each_increament(do_find_window, msg); if(w->callback != NULL) w->callback(w, msg); /* 如果要关闭主窗口 */ if(global_application.main_window == WINDOW_POINTER(w)) { application_del_window(WINDOW_POINTER(w)); } else { cancel_window(WINDOW_POINTER(w)->descriptor); application_del_window(WINDOW_POINTER(w)); /* 没有顶层窗口了 */ /* 退出程序 */ /* 这是为了处理没有设置主窗口的情况 */ if(vector_size(&(global_application.window_vector)) == 0) { application_exit(); } /* 还有顶层窗口 */ else { application_widgets_for_each_increament(do_dispatch_repaint_event_to_all, NULL); } } return 0; }
/* 如果 window 有左子节点 那么这个左子节点并不是 window 子对象 所以在析构以 window 为根的树之前一定要要将 window->lchild 成员清空 如果 window 在对象树中 那么完成删除工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员 这是为了保证遍历的正确 */ si_t application_del_window(struct window * window) { si_t is_top_window = 0; /* 删除主窗口 */ /* 退出程序 */ if(window == global_application.main_window) { application_exit(); return 0; } if(window->parent->parent == OBJECT_POINTER(window)) { is_top_window = 1; } cancel_window(window->descriptor); object_delete(OBJECT_POINTER(window), __widget_destructor); if(is_top_window) { si_t i = 0, n = 0; /* 有多少个窗口 */ n = vector_size(&(global_application.window_vector)); /* 找到这个窗口在向量中的索引 */ for(i = 0; i < n; ++ i) { struct object* tree = vector_at(&(global_application.window_vector), i); if(tree->parent == OBJECT_POINTER(window)) { /* 从窗口向量中删除这个节点 */ vector_erase(&(global_application.window_vector), i); break; } } } return 0; }