bool idaapi show_citem_custom_view(void *ud, qstring ctree_item, qstring item_name)
{
	HWND hwnd = NULL;
	qstring form_name = "Ctree Item View: ";
	form_name.append(item_name);
	TForm *form = create_tform(form_name.c_str(), &hwnd);
	func_ctree_info_t *si = new func_ctree_info_t(form);

	istringstream s_citem_str(ctree_item.c_str());
	string tmp_str;
	while (getline(s_citem_str, tmp_str, ';'))
	{
		qstring tmp_qstr = tmp_str.c_str();
		si->sv.push_back(simpleline_t(tmp_qstr));
	}

	simpleline_place_t s1;
	simpleline_place_t s2(ctree_item.size());
	si->cv = create_custom_viewer("Ctree Item View: ", NULL, &s1, &s2, &s1, 0, &si->sv);
	si->codeview = create_code_viewer(form, si->cv, CDVF_NOLINES);
	set_custom_viewer_handlers(si->cv, NULL, NULL, NULL, NULL, NULL, NULL, si);
	open_tform(form, FORM_ONTOP | FORM_RESTORE);

	return false;
}
static bool idaapi show_vtbl_xrefs_window_cb(void *ud)
{
	get_xrefs_to_vtbl();
	if (!xref_list.empty())
	{
		HWND hwnd = NULL;
		TForm *form = create_tform(vtbl_t_list[current_line_pos].vtbl_name.c_str(), &hwnd);

		object_explorer_info_t *si = new object_explorer_info_t(form);

		qvector <qstring>::iterator xref_iter;
		for (xref_iter = xref_list.begin(); xref_iter != xref_list.end(); xref_iter++)
			si->sv.push_back(simpleline_t(*xref_iter));

		simpleline_place_t s1;
		simpleline_place_t s2(si->sv.size() - 1);
		si->cv = create_custom_viewer("", NULL, &s1, &s2, &s1, 0, &si->sv);
		si->codeview = create_code_viewer(form, si->cv, CDVF_STATUSBAR);
		set_custom_viewer_handlers(si->cv, NULL, NULL, ct_vtbl_xrefs_window_click, NULL, NULL, si);
		open_tform(form, FORM_ONTOP | FORM_RESTORE);

		return true;
	}

	warning("ObjectExplorer not found any xrefs here ...");

	return false;
}
void object_explorer_form_init()
{
	if (!vtbl_list.empty() && !vtbl_t_list.empty())
	{
		HWND hwnd = NULL;
		TForm *form = create_tform("Object Explorer", &hwnd);
		if (hwnd == NULL)
		{
			warning("Object Explorer window already open. Switching to it.");
			form = find_tform("Object Explorer");
			if (form != NULL)
				switchto_tform(form, true);
			return;
		}

		object_explorer_info_t *si = new object_explorer_info_t(form);

		qvector <qstring>::iterator vtbl_iter;
		for (vtbl_iter = vtbl_list.begin(); vtbl_iter != vtbl_list.end(); vtbl_iter++)
			si->sv.push_back(simpleline_t(*vtbl_iter));

		simpleline_place_t s1;
		simpleline_place_t s2(si->sv.size() - 1);
		si->cv = create_custom_viewer("", NULL, &s1, &s2, &s1, 0, &si->sv);
		si->codeview = create_code_viewer(form, si->cv, CDVF_STATUSBAR);
		set_custom_viewer_handlers(si->cv, ct_object_explorer_keyboard, ct_object_explorer_popup, ct_object_explorer_click, NULL, NULL, si);
		hook_to_notification_point(HT_UI, ui_object_explorer_callback, si);
		open_tform(form, FORM_TAB | FORM_MENU | FORM_RESTORE);
	}
	else
		warning("ObjectExplorer not found any virtual tables here ...");
}
static bool idaapi show_rtti_window_cb(void *ud)
{
	if (!rtti_list.empty() && !rtti_addr.empty())
	{
		HWND hwnd = NULL;
		TForm *form = create_tform("RTTI Objects List", &hwnd);

		object_explorer_info_t *si = new object_explorer_info_t(form);

		qvector <qstring>::iterator rtti_iter;
		for (rtti_iter = rtti_list.begin(); rtti_iter != rtti_list.end(); rtti_iter++)
			si->sv.push_back(simpleline_t(*rtti_iter));

		simpleline_place_t s1;
		simpleline_place_t s2(si->sv.size() - 1);
		si->cv = create_custom_viewer("", NULL, &s1, &s2, &s1, 0, &si->sv);
		si->codeview = create_code_viewer(form, si->cv, CDVF_STATUSBAR);
		set_custom_viewer_handlers(si->cv, NULL, NULL, ct_rtti_window_click, NULL, NULL, si);
		open_tform(form, FORM_ONTOP | FORM_RESTORE);

		return true;
	}

	warning("ObjectExplorer not found any RTTI objects ...");

	return false;
}