HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags, const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL; HRESULT hres = S_OK; TRACE("navigating to %s\n", debugstr_w(url)); if((Flags && V_VT(Flags) != VT_EMPTY) || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY)) FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n", Flags, Flags ? V_VT(Flags) : -1, TargetFrameName, TargetFrameName ? V_VT(TargetFrameName) : -1); if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) { SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data); post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements; } if(Headers && V_VT(Headers) == VT_BSTR) { headers = V_BSTR(Headers); TRACE("Headers: %s\n", debugstr_w(headers)); } set_doc_state(This, READYSTATE_LOADING); This->ready_state = READYSTATE_LOADING; if(This->doc_navigate) { WCHAR new_url[INTERNET_MAX_URL_LENGTH]; if(PathIsURLW(url)) { new_url[0] = 0; }else { DWORD size; size = sizeof(new_url)/sizeof(WCHAR); hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME); if(FAILED(hres)) { WARN("UrlApplyScheme failed: %08x\n", hres); new_url[0] = 0; } } hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data, post_data_len, TRUE); }else { task_navigate_bsc_t *task; task = heap_alloc(sizeof(*task)); task->bsc = create_callback(This, url, post_data, post_data_len, headers); push_dochost_task(This, &task->header, navigate_bsc_proc, This->url == NULL); } if(post_data) SafeArrayUnaccessData(V_ARRAY(PostData)); return hres; }
static void gtk2perl_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkCellLayoutDataFunc func, gpointer func_data, GDestroyNotify destroy) { GET_METHOD_OR_DIE (cell_layout, "SET_CELL_DATA_FUNC"); { SV *code_sv, *data_sv; PREP (cell_layout); XPUSHs (sv_2mortal (newSVGtkCellRenderer (cell))); if (func) { create_callback (func, func_data, destroy, &code_sv, &data_sv); XPUSHs (sv_2mortal (code_sv)); XPUSHs (sv_2mortal (data_sv)); } CALL; FINISH; } }
/* * Class: org_java_gtk_gtk_Widget * Method: gtk_widget_add_configure_event_handler * Signature: (JLorg/java_gtk/gtk/Widget/ConfigureEventHandler;Lorg/java_gtk/gtk/Widget;)V */ JNIEXPORT void JNICALL Java_org_java_1gtk_gtk_Widget_gtk_1widget_1add_1configure_1event_1handler (JNIEnv *env, jclass cls, jlong instance, jobject handler, jclass receiver) { callback *c; long handle_id; c = create_callback(env, handler, receiver, "configureEventReceiver", "(Lorg/java_gtk/gtk/Widget$ConfigureEventHandler;JJ)Z"); handle_id = connect_callback((gpointer)instance, "configure-event", G_CALLBACK(widget_event_handler), c); update_handle(env, handler, "setHandleId", "(J)V", handle_id); }
/* * Class: org_java_gtk_gtk_Widget * Method: gtk_widget_add_destroy_handler * Signature: (JLorg/java_gtk/gtk/Widget/DestroyHandler;Lorg/java_gtk/gtk/Widget;)V */ JNIEXPORT void JNICALL Java_org_java_1gtk_gtk_Widget_gtk_1widget_1add_1destroy_1handler (JNIEnv *env, jclass cls, jlong instance, jobject handler, jclass receiver) { callback *c; long handle_id; c = create_callback(env, handler, receiver, "destroyReceiver", "(Lorg/java_gtk/gtk/Widget$DestroyHandler;J)V"); handle_id = connect_callback((gpointer)instance, "destroy", G_CALLBACK(widget_destroy_handler), c); update_handle(env, handler, "setHandleId", "(J)V", handle_id); }
/* * Class: org_java_gtk_gtk_ComboBox * Method: gtk_combo_box_add_changed_event_handler * Signature: (JLorg/java_gtk/gtk/ComboBox/ChangedEventHandler;Ljava/lang/Class;)V */ JNIEXPORT void JNICALL Java_org_java_1gtk_gtk_ComboBox_gtk_1combo_1box_1add_1changed_1event_1handler (JNIEnv *env, jclass cls, jlong instance, jobject handler, jclass receiver) { callback *c; long handle_id; c = create_callback(env, handler, receiver, "changedEventReceiver", "(Lorg/java_gtk/gtk/ComboBox$ChangedEventHandler;J)V"); handle_id = (long)connect_callback((gpointer)instance, "changed", G_CALLBACK(combo_box_changed_event_handler), c); update_handle(env, handler, "setHandleId", "(J)V", handle_id); }
static HRESULT navigate_hlink(DocHost *This, IMoniker *mon, IBindCtx *bindctx, IBindStatusCallback *callback) { IHttpNegotiate *http_negotiate; BindStatusCallback *bsc; PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL, url; BINDINFO bindinfo; DWORD bindf = 0; HRESULT hres; TRACE("\n"); hres = IMoniker_GetDisplayName(mon, 0, NULL, &url); if(FAILED(hres)) FIXME("GetDisplayName failed: %08x\n", hres); hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate, (void**)&http_negotiate); if(SUCCEEDED(hres)) { static const WCHAR null_string[] = {0}; IHttpNegotiate_BeginningTransaction(http_negotiate, null_string, null_string, 0, &headers); IHttpNegotiate_Release(http_negotiate); } memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(bindinfo); hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo); dump_BINDINFO(&bindinfo); if(bindinfo.dwBindVerb == BINDVERB_POST) { post_data_len = bindinfo.cbstgmedData; if(post_data_len) post_data = bindinfo.stgmedData.u.hGlobal; } if(This->doc_navigate) { hres = async_doc_navigate(This, url, headers, post_data, post_data_len, FALSE); }else { bsc = create_callback(This, url, post_data, post_data_len, headers); hres = navigate_bsc(This, bsc, mon); IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface); } CoTaskMemFree(url); CoTaskMemFree(headers); ReleaseBindInfo(&bindinfo); return hres; }
HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags, const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { task_navigate_bsc_t *task; PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL; TRACE("navigating to %s\n", debugstr_w(url)); if((Flags && V_VT(Flags) != VT_EMPTY) || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY)) FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n", Flags, Flags ? V_VT(Flags) : -1, TargetFrameName, TargetFrameName ? V_VT(TargetFrameName) : -1); if(PostData) { TRACE("PostData vt=%d\n", V_VT(PostData)); if(V_VT(PostData) == (VT_ARRAY | VT_UI1)) { SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data); post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements; } } if(Headers && V_VT(Headers) != VT_EMPTY && V_VT(Headers) != VT_ERROR) { if(V_VT(Headers) != VT_BSTR) return E_INVALIDARG; headers = V_BSTR(Headers); TRACE("Headers: %s\n", debugstr_w(headers)); } task = heap_alloc(sizeof(*task)); task->bsc = create_callback(This, url, post_data, post_data_len, headers); if(post_data) SafeArrayUnaccessData(V_ARRAY(PostData)); push_dochost_task(This, &task->header, navigate_bsc_proc, This->url == NULL); return S_OK; }
HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags, const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) { SAFEARRAY *post_array = NULL; PBYTE post_data = NULL; ULONG post_data_len = 0; LPWSTR headers = NULL; HRESULT hres = S_OK; TRACE("navigating to %s\n", debugstr_w(url)); if((Flags && V_VT(Flags) != VT_EMPTY && V_VT(Flags) != VT_ERROR) || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY && V_VT(TargetFrameName) != VT_ERROR)) FIXME("Unsupported args (Flags %s; TargetFrameName %s)\n", debugstr_variant(Flags), debugstr_variant(TargetFrameName)); if(PostData) { if(V_VT(PostData) & VT_ARRAY) post_array = V_ISBYREF(PostData) ? *V_ARRAYREF(PostData) : V_ARRAY(PostData); else WARN("Invalid post data %s\n", debugstr_variant(PostData)); } if(post_array) { LONG elem_max; SafeArrayAccessData(post_array, (void**)&post_data); SafeArrayGetUBound(post_array, 1, &elem_max); post_data_len = (elem_max+1) * SafeArrayGetElemsize(post_array); } if(Headers && V_VT(Headers) == VT_BSTR) { headers = V_BSTR(Headers); TRACE("Headers: %s\n", debugstr_w(headers)); } set_doc_state(This, READYSTATE_LOADING); This->ready_state = READYSTATE_LOADING; if(This->doc_navigate) { WCHAR new_url[INTERNET_MAX_URL_LENGTH]; if(PathIsURLW(url)) { new_url[0] = 0; }else { DWORD size; size = sizeof(new_url)/sizeof(WCHAR); hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT); if(FAILED(hres)) { WARN("UrlApplyScheme failed: %08x\n", hres); new_url[0] = 0; } } hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data, post_data_len, TRUE); }else { task_navigate_bsc_t *task; task = heap_alloc(sizeof(*task)); task->bsc = create_callback(This, url, post_data, post_data_len, headers); push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL); } if(post_data) SafeArrayUnaccessData(post_array); return hres; }
/* Extract all the files from a 7-zip archive to the specified location, with * callbacks. "file" is the path to the file to unpack, "base" is the location * to extract to, "before_entry_callback" is a function to call right before * each entry is unpacked, and "create_callback" is a function to call right * after each entry has been unpacked. Both callback functions' arguments are as * follows: the path (relative to base) of the entry, and an int that is nonzero * if the entry is a directory. */ int un7z (const char* file, const char* base, int (*before_entry_callback)(const char*, int), void (*create_callback)(const char*, int)) { // Create and fill out our reader object FileInStream instream; instream.sz_stream.Read = SzFileReadImp; instream.sz_stream.Seek = SzFileSeekImp; instream.filep = fopen(file, "rb"); if (!instream.filep) { archive_seterror("failed to open file '%s' for reading", file); return -1; } // Close the FILE* when we leave this scope RefType< FILE >::Ref fcloser(instream.filep, fclose); CrcGenerateTable(); CArchiveDatabaseEx db; SzArDbExInit(&db); // Free up the database when we leave this scope RefType< CArchiveDatabaseEx >::Ref db_deleter(&db, SzArDbExDeleter); // Set up 7-zip's memory allocation scheme (uses the default allocators) ISzAlloc allocImp, allocTempImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; // Open the archive if (SzArchiveOpen(&instream.sz_stream, &db, &allocImp, &allocTempImp) != SZ_OK) { archive_seterror("7zlib couldn't open '%s' as a 7z archive", file); return -1; } // Update progress total num_files_in_cur_op = db.Database.NumFiles; // Set up 7-zip's "cache" variables UInt32 blockIndex = 0xFFFFFFFF; Byte *outBuffer = 0; size_t outBufferSize = 0; // Delete the buffer when we leave this scope RefType< Byte >::Ref outbuf_deleter(outBuffer, OutBufferDeleter); // Iterate and extract entries for (unsigned i = 0; i < db.Database.NumFiles; i++) { // Update progress cur_file_in_op_index = i; CFileItem* cur_file = &db.Database.Files[i]; // Call before-extraction callback if (before_entry_callback) { int cbres = before_entry_callback(cur_file->Name, cur_file->IsDirectory); if (cbres != 0) { archive_seterror("7zlib failed to unzip '%s': cancelled from " "callback", cur_file->Name); return cbres; } } // Get the full path to output std::string out_path = std::string(base) + "/" + cur_file->Name; // If entry is a directory, merely create the directory if (cur_file->IsDirectory) { if (!makedir(base, cur_file->Name)) { archive_seterror("couldn't create directory '%s'", out_path.c_str()); return -1; } } // If entry is a file, extract it else { size_t offset, outSizeProcessed; // 7-zip seems to encourage getting the whole file in one blow SZ_RESULT res = SzExtract(&instream.sz_stream, &db, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res == SZE_CRC_ERROR) { archive_seterror("bad CRC for file '%s' in '%s'", cur_file->Name, file); return -1; } else if (res != SZ_OK) { archive_seterror("7zlib failed to unpack file '%s' in '%s'", cur_file->Name, file); return -1; } bool was_created = false; // If the output file already exists, make sure we can write over it if (chmod(out_path.c_str(), _S_IREAD|_S_IWRITE) != 0) was_created = true; // Open the output file for writing FILE* outfile = fopen(out_path.c_str(), "wb"); if (!outfile) { // Couldn't open it -- make sure its parent directory exists size_t p = std::string(cur_file->Name).find_last_of("/\\", std::string::npos); if (p != std::string::npos) { makedir(base, std::string(cur_file->Name).substr(0, p).c_str()); outfile = fopen(out_path.c_str(), "wb"); } } if (!outfile) { // Still couldn't open it; error out archive_seterror("couldn't open '%s' for writing", out_path.c_str()); return -1; } // Write out the whole file and then close it int written = fwrite(outBuffer + offset, 1, outSizeProcessed, outfile); fclose(outfile); if (written <= 0 || static_cast< size_t >(written) != outSizeProcessed) { // At this point we have an empty output file; remove it remove(out_path.c_str()); archive_seterror("failed to write %d bytes to '%s'", outSizeProcessed, out_path.c_str()); return -1; } } // Set stored attributes if (cur_file->AreAttributesDefined) SetFileAttributes(out_path.c_str(), cur_file->Attributes); // Call after-creation callback create_callback(cur_file->Name, cur_file->IsDirectory ? 1 : 0); } return 0; }
/** * Creates a control from the given XMLNode as a child of the given * parent. * * @param form the SubForm object * @param LookUpTable The parent CallBackTable * @param node The XMLNode that represents the control */ static Window * LoadChild(SubForm &form, ContainerWindow &parent, const CallBackTableEntry *lookup_table, XMLNode node, int bottom_most, WindowStyle style) { Window *window = NULL; // Determine name, coordinates, width, height // and caption of the control const TCHAR* name = GetName(node); const TCHAR* caption = GetCaption(node); PixelRect rc = parent.get_client_rect(); ControlPosition pos = GetPosition(node, rc, bottom_most); if (!pos.no_scaling) pos.x = ScaleWidth(pos.x); ControlSize size = GetSize(node, rc, pos); if (!size.no_scaling) size.cx = ScaleWidth(size.cx); if (!StringToIntDflt(node.getAttribute(_T("Visible")), 1)) style.Hide(); if (StringToIntDflt(node.getAttribute(_T("Border")), 0)) style.Border(); rc.left = pos.x; rc.top = pos.y; rc.right = rc.left + size.cx; rc.bottom = rc.top + size.cy; bool expert = (StringToIntDflt(node.getAttribute(_T("Expert")), 0) == 1); // PropertyControl (WndProperty) if (StringIsEqual(node.getName(), _T("Edit"))) { // Determine the width of the caption field int caption_width = StringToIntDflt(node.getAttribute(_T("CaptionWidth")), 0); if (Layout::ScaleSupported()) caption_width = Layout::Scale(caption_width); caption_width = ScaleWidth(caption_width); // Determine whether the control is multiline or readonly bool multi_line = StringToIntDflt(node.getAttribute(_T("MultiLine")), 0); bool read_only = StringToIntDflt(node.getAttribute(_T("ReadOnly")), 0); // Load the event callback properties WndProperty::DataChangeCallback_t data_notify_callback = (WndProperty::DataChangeCallback_t) GetCallBack(lookup_table, node, _T("OnDataNotify")); WindowControl::HelpCallback help_callback = (WindowControl::HelpCallback) GetCallBack(lookup_table, node, _T("OnHelp")); // Create the Property Control style.ControlParent(); EditWindowStyle edit_style; edit_style.vertical_center(); if (read_only) edit_style.read_only(); else edit_style.TabStop(); if (IsEmbedded() || Layout::scale_1024 < 2048) /* sunken edge doesn't fit well on the tiny screen of an embedded device */ edit_style.Border(); else edit_style.SunkenEdge(); if (multi_line) { edit_style.multiline(); edit_style.VerticalScroll(); } WndProperty *property; window = property = new WndProperty(parent, *xml_dialog_look, caption, rc, caption_width, style, edit_style, data_notify_callback); // Set the help function event callback property->SetOnHelpCallback(help_callback); // Load the help text property->SetHelpText(StringToStringDflt(node.getAttribute(_T("Help")), NULL)); // If the control has (at least) one DataField child control const XMLNode *data_field_node = node.getChildNode(_T("DataField")); if (data_field_node != NULL) { // -> Load the first DataField control DataField *data_field = LoadDataField(*data_field_node, lookup_table); if (data_field != NULL) // Tell the Property control about the DataField control property->SetDataField(data_field); } } else if (StringIsEqual(node.getName(), _T("TextEdit"))) { // Determine whether the control is multiline or readonly bool multi_line = StringToIntDflt(node.getAttribute(_T("MultiLine")), 0); bool read_only = StringToIntDflt(node.getAttribute(_T("ReadOnly")), 0); EditWindowStyle edit_style(style); if (read_only) edit_style.read_only(); else edit_style.TabStop(); if (IsEmbedded() || Layout::scale_1024 < 2048) /* sunken edge doesn't fit well on the tiny screen of an embedded device */ edit_style.Border(); else edit_style.SunkenEdge(); if (multi_line) { edit_style.multiline(); edit_style.VerticalScroll(); } EditWindow *edit; window = edit = new EditWindow(); edit->set(parent, pos.x, pos.y, size.cx, size.cy, edit_style); edit->InstallWndProc(); edit->set_font(*xml_dialog_look->text_font); // ButtonControl (WndButton) } else if (StringIsEqual(node.getName(), _T("Button"))) { // Determine ClickCallback function WndButton::ClickNotifyCallback click_callback = (WndButton::ClickNotifyCallback) GetCallBack(lookup_table, node, _T("OnClick")); // Create the ButtonControl ButtonWindowStyle button_style(style); button_style.TabStop(); button_style.multiline(); window = new WndButton(parent, *xml_dialog_look, caption, rc, button_style, click_callback); } else if (StringIsEqual(node.getName(), _T("CheckBox"))) { // Determine click_callback function CheckBoxControl::ClickNotifyCallback click_callback = (CheckBoxControl::ClickNotifyCallback) GetCallBack(lookup_table, node, _T("OnClick")); // Create the CheckBoxControl style.TabStop(); window = new CheckBoxControl(parent, *xml_dialog_look, caption, rc, style, click_callback); // SymbolButtonControl (WndSymbolButton) not used yet } else if (StringIsEqual(node.getName(), _T("SymbolButton"))) { // Determine ClickCallback function WndButton::ClickNotifyCallback click_callback = (WndButton::ClickNotifyCallback) GetCallBack(lookup_table, node, _T("OnClick")); // Create the SymbolButtonControl style.TabStop(); window = new WndSymbolButton(parent, *xml_dialog_look, caption, rc, style, click_callback); // PanelControl (WndPanel) } else if (StringIsEqual(node.getName(), _T("Panel"))) { // Create the PanelControl style.ControlParent(); PanelControl *frame = new PanelControl(parent, *xml_dialog_look, rc, style); window = frame; // Load children controls from the XMLNode LoadChildrenFromXML(form, *frame, lookup_table, &node); // KeyboardControl } else if (StringIsEqual(node.getName(), _T("Keyboard"))) { KeyboardControl::OnCharacterCallback_t character_callback = (KeyboardControl::OnCharacterCallback_t) GetCallBack(lookup_table, node, _T("OnCharacter")); // Create the KeyboardControl KeyboardControl *kb = new KeyboardControl(parent, *xml_dialog_look, pos.x, pos.y, size.cx, size.cy, character_callback, style); window = kb; // DrawControl (WndOwnerDrawFrame) } else if (StringIsEqual(node.getName(), _T("Canvas"))) { // Determine DrawCallback function WndOwnerDrawFrame::OnPaintCallback_t paint_callback = (WndOwnerDrawFrame::OnPaintCallback_t) GetCallBack(lookup_table, node, _T("OnPaint")); // Create the DrawControl WndOwnerDrawFrame* canvas = new WndOwnerDrawFrame(parent, pos.x, pos.y, size.cx, size.cy, style, paint_callback); window = canvas; // FrameControl (WndFrame) } else if (StringIsEqual(node.getName(), _T("Label"))){ // Create the FrameControl WndFrame* frame = new WndFrame(parent, *xml_dialog_look, pos.x, pos.y, size.cx, size.cy, style); // Set the caption frame->SetCaption(caption); // Set caption color Color color; if (StringToColor(node.getAttribute(_T("CaptionColor")), color)) frame->SetCaptionColor(color); window = frame; // ListBoxControl (WndListFrame) } else if (StringIsEqual(node.getName(), _T("List"))){ // Determine ItemHeight of the list items UPixelScalar item_height = Layout::Scale(StringToIntDflt(node.getAttribute(_T("ItemHeight")), 18)); // Create the ListBoxControl style.TabStop(); if (IsEmbedded() || Layout::scale_1024 < 2048) /* sunken edge doesn't fit well on the tiny screen of an embedded device */ style.Border(); else style.SunkenEdge(); window = new WndListFrame(parent, *xml_dialog_look, pos.x, pos.y, size.cx, size.cy, style, item_height); // TabControl (Tabbed) } else if (StringIsEqual(node.getName(), _T("Tabbed"))) { // Create the TabControl style.ControlParent(); TabbedControl *tabbed = new TabbedControl(parent, pos.x, pos.y, size.cx, size.cy, style); window = tabbed; for (auto i = node.begin(), end = node.end(); i != end; ++i) { // Load each child control from the child nodes Window *child = LoadChild(form, *tabbed, lookup_table, *i); if (child != NULL) tabbed->AddClient(child); } // TabBarControl (TabBar) } else if (StringIsEqual(node.getName(), _T("TabBar"))) { // Create the TabBarControl bool flip_orientation = false; if ( (Layout::landscape && StringToIntDflt(node.getAttribute(_T("Horizontal")), 0)) || (!Layout::landscape && StringToIntDflt(node.getAttribute(_T("Vertical")), 0) ) ) flip_orientation = true; style.ControlParent(); TabBarControl *tabbar = new TabBarControl(parent, *xml_dialog_look, pos.x, pos.y, size.cx, size.cy, style, flip_orientation); window = tabbar; // TabMenuControl (TabMenu) } else if (StringIsEqual(node.getName(), _T("TabMenu"))) { // Create the TabMenuControl style.ControlParent(); TabMenuControl *tabmenu = new TabMenuControl(parent, /* XXX this cast is an ugly hack! Please rewrite: */ (WndForm &)form, *xml_dialog_look, caption, pos.x, pos.y, size.cx, size.cy, style); window = tabmenu; } else if (StringIsEqual(node.getName(), _T("Custom"))) { // Create a custom Window object with a callback CreateWindowCallback_t create_callback = (CreateWindowCallback_t)GetCallBack(lookup_table, node, _T("OnCreate")); if (create_callback == NULL) return NULL; window = create_callback(parent, pos.x, pos.y, size.cx, size.cy, style); } else if (StringIsEqual(node.getName(), _T("Widget"))) { style.ControlParent(); DockWindow *dock = new DockWindow(); dock->set(parent, rc, style); window = dock; } if (window != NULL) { if (!StringIsEmpty(name)) form.AddNamed(name, window); if (expert) form.AddExpert(window); form.AddDestruct(window); } return window; }