dwgs :: ~dwgs() { for(int k=0;k<4;k++) delete d[k]; for(int m=0;m<M;m++) destroy_filter(&(dispersion[m])); destroy_filter(&lowpass); destroy_filter(&fracdelay); destroy_filter(&bottomfilter); }
image_p image_scale(image_p src, int w, int h,int mode) { image_p dst; uint8 * temp; uint8 recover = 0; uint32 spitch, dpitch; filter_base* filter = create_filter(mode); dst = image_create(w,h,src->dtype); dst->dontswizzle = 1; if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } temp = malloc(dst->w*src->h*src->bpb); memset(temp,0,dst->w*src->h*src->bpb); spitch = src->texw; dpitch = dst->texw; horiz_scale(filter,src->data,src->w,src->h,temp,dst->w,src->h,spitch,src->dtype); vert_scale (filter,temp,dst->w,src->h,dst->data,dst->w,dst->h,dpitch,src->dtype); free(temp); destroy_filter(filter); if(recover) swizzle_swap(src); return dst; }
/** * @brief Main entry point for R * * @param bamfilenameR Filename of read container * @param aRgvals Vector containing the user arguments * @param filterList passed from R in the form list("chr1"=c(100,200,3000,3010...start,end...)) * @return R list in the form list("chr1"=c(1,2,1,2,1,1,...),"chr1_gind"=c(1100,1200...),"chr1_lind"=c(0,112,...),"chrX"=NA,...) and a Statistics vector * @details All chromosome of the filter or all chromosomes in the file header will be scanned and passed to an R list * @note * @todo high_cov not yet implemented. */ SEXP construct_dc(SEXP bamfilenameR, SEXP aRgvals, SEXP filterList) { double *statsp;//resulting statistics in the order "total reads" "coverage" "local coverage" "max score" uint32_t upcounter=0,i=0; time_t tstart,tstop; global_densities_t gd={0}; user_arguments_t user_args; filter_t ft; SEXP histogram,stats; int *argvalsp; signal(SIGINT,SIG_DFL);//make this thing stop on CTRL+C time(&tstart); /* Set user defined values */ PROTECT(aRgvals=AS_INTEGER(aRgvals));upcounter++; if(LENGTH(aRgvals)!=10)error("Invalid amount of arguments - arguments[%d] / should be %d!\n",LENGTH(aRgvals),9); argvalsp=INTEGER_POINTER(aRgvals); user_args.bamfilename = STRING_VALUE(bamfilenameR); user_args.READTHROUGH = argvalsp[0];//bool. read from start to end and 0 take whole read whithout CIGAR splice info user_args.PAIRED = argvalsp[1]; user_args.STRANDED = argvalsp[2];//Set to 1 / -1 it will use only forward / reverse reads respectively. 0 means all reads are processed user_args.TMAPQ = argvalsp[3];//Minimum MPAQ score. Lower scored reads will be skipped user_args.COLLAPSE = argvalsp[4]; user_args.EXTEND = argvalsp[5];//extend each read in its direction by this amount of BPs user_args.HWINDOW = argvalsp[6]; user_args.COMPRESSION = argvalsp[7];//minimum BPs needed between data blocks to collapse the gap and index it user_args.VERBOSE = argvalsp[8]; user_args.UNIQUE = argvalsp[9]; /* Try to open the file */ samfile_t *bam_file; bam_file=open_samtools(user_args.bamfilename); if(!bam_file){ warning("sam/bam file not found!\n"); UNPROTECT(upcounter); return(R_NilValue); } if(user_args.HWINDOW>user_args.COMPRESSION){ warning("HWINDOW has to be smaller than COMPRESSION! HWINDOW updated to %d\n",user_args.COMPRESSION); user_args.HWINDOW=user_args.COMPRESSION; } PROTECT(histogram = NEW_INTEGER(UINT16_MAX));upcounter++;//initialize compressed scores gd.histogramp = (uint32_t*) INTEGER_POINTER(histogram); for(i = 0; i < UINT16_MAX; i++) gd.histogramp[i] = 0; gd.total_elements=bam_file->header->n_targets;//one vector per chromosome needed /* #### CHECK IF THERE IS AN ACTIVE FILTER IN PLACE */ user_args.FILTER=isNewList(filterList) ? 1 : 0; if(user_args.FILTER){ upcounter+=set_filter(filterList,&ft); gd.total_elements=ft.seqn;//overwrite total elements if filter is passed, since one density is returned per slice } // Creating a list with vector elements as many as sequences plus a character string vector: PROTECT(gd.list = allocVector(VECSXP, (gd.total_elements*3)+2));upcounter++;//3x for the two indexes and scores per chromosome PROTECT(gd.list_names = allocVector(STRSXP,(gd.total_elements*3)+2));upcounter++;//+1 for statistics vector +1 for the histogram /* PASS EVERYTHING */ write_density(&gd,&user_args,bam_file,&ft); if(!gd.total_reads)goto NO_READS_FOUND; // 1 total_reads 2 gcoverage 3 lcoverage 4 maxscore 5 lmaxscore 6 lowqual 7 filtered 8 collapsed 9 paired 10 proper_pairs 11 pos 12 neg 13 fmapmass 14 lsize 15 gsize SET_STRING_ELT(gd.list_names,gd.total_elements*3,mkChar("Statistics")); PROTECT(stats = NEW_NUMERIC(15));upcounter++; statsp = NUMERIC_POINTER(stats); *statsp++=(double)gd.total_reads; *statsp++=(double)gd.mapmass/(double)gd.gsize; *statsp++=(double)gd.lmapmass/(double)gd.lsize; *statsp++=(double)gd.maxscore; *statsp++=(double)gd.lmaxScore; *statsp++=(double)gd.lowqual; *statsp++=(double)gd.filtered_reads; *statsp++=(double)gd.collapsed; *statsp++=(double)gd.paired; *statsp++=(double)gd.ppairs/2; *statsp++=(double)gd.pos_strand; *statsp++=(double)gd.neg_strand; *statsp=(double)gd.mapmass; *statsp++=(double)gd.lsize; *statsp++=(double)gd.gsize; if(gd.lmaxScore>=umaxof(usersize)-1){ warning("\nThe maximum pile up is exceeding the maximal value of UINT16_MAX=%d. Reads have been capped to that value.\nConsider to rerun using the maxDups option!\n",UINT16_MAX); } SET_VECTOR_ELT(gd.list,gd.total_elements*3, stats); SET_STRING_ELT(gd.list_names,(gd.total_elements*3)+1,mkChar("Histogram")); SET_VECTOR_ELT(gd.list,(gd.total_elements*3)+1,histogram); setAttrib(gd.list, R_NamesSymbol, gd.list_names); NO_READS_FOUND: time(&tstop); if(user_args.VERBOSE>0)printf("About %.0f seconds passed. %llu reads processed \n", difftime(tstop, tstart),gd.total_reads); close_bamfile(bam_file); if(user_args.FILTER)destroy_filter(&ft); UNPROTECT(upcounter+gd.upcounter); if(!gd.total_reads)return(R_NilValue); else return(gd.list); }
int main(int argc, char** argv) { if (argc != 2) { printf("Usage: %s <iterations>\n", argv[0]); return (EXIT_FAILURE); } int iterations = atoi(argv[1]); printf("main_cuda()\n"); printf("Iterations: %d\n", iterations); bool ok = true; /* Read input file into buffer. */ unsigned char (**image_buffer_h)[CHANNELS]; if (ok) ok = read_image((unsigned char ***) &image_buffer_h); /* Allocate memory for image data. */ float (**image_h)[CHANNELS]; if (ok) ok = alloc_float_array((float ***) &image_h, B + HEIGHT + B, B + WIDTH + B, CHANNELS); /* Convert input. */ unsigned int i, j, c; if (ok) { for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) for (c = 0; c < CHANNELS; c++) image_h[i + B][j + B][c] = (float) image_buffer_h[i][j][c]; } /* Device memory allocation. */ float (**prev_image_d)[CHANNELS]; float (**curr_image_d)[CHANNELS]; float *prev_image_p; float *curr_image_p; if (ok) ok = alloc_float_array_cuda((float ***) &prev_image_d, &prev_image_p, B + HEIGHT + B, B + WIDTH + B, CHANNELS); if (ok) ok = alloc_float_array_cuda((float ***) &curr_image_d, &curr_image_p, B + HEIGHT + B, B + WIDTH + B, CHANNELS); /* Initialize filter in device memory space. */ float (**filter_d)[1]; float *filter_p; if (ok) ok = init_filter(&filter_d, &filter_p, filter); /* Device parameters for nVidia 9600GT (G94), passed to main filter function. */ /* nVidia G94 supports 8 resident blocks per SMP, 768 resident threads per SMP. */ unsigned int block_size = 64; // maximum 512 threads per block for nVidia G94 printf("Block size: %u\n", block_size); /* nVidia G94 supports 2-dimensional grids with a maximum of 65535 for x,y dimension. */ unsigned int grid_dim = HEIGHT * WIDTH / block_size; double sqr = sqrt(grid_dim); grid_dim = sqr; grid_dim++; printf("Grid: %ux%u\n", grid_dim, grid_dim); /* Start timing. */ float memcopy, compute; timestamp t_start; t_start = getTimestamp(); /* Copy image data to device. */ if (ok) ok = (cudaSuccess == cudaMemcpy(curr_image_p, &(image_h[0][0][0]), (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float), cudaMemcpyHostToDevice)); memcopy = getElapsedtime(t_start); /* Clear host image data. */ memset(&(image_h[0][0][0]), 0, (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float)); /* Apply filter. */ t_start = getTimestamp(); unsigned int n; if (ok) { for (n = 0; iterations == 0 || n < iterations; n++) { /* Fill borders with edge image data. */ fill_borders(curr_image_d, HEIGHT, WIDTH); /* Apply filter. */ apply_filter_cuda(prev_image_d, curr_image_d, filter_d, block_size, grid_dim); /* Switch current / previous image buffers. */ float (**temp)[CHANNELS]; temp = prev_image_d; prev_image_d = curr_image_d; curr_image_d = temp; float *tmp; tmp = prev_image_p; prev_image_p = curr_image_p; curr_image_p = tmp; } } /* Stop time measurement, print time. */ cudaThreadSynchronize(); compute = getElapsedtime(t_start); t_start = getTimestamp(); /* Copy processed image data from device. */ if (ok) ok = (cudaSuccess == cudaMemcpy(&(image_h[0][0][0]), curr_image_p, (B + HEIGHT + B) * (B + WIDTH + B) * CHANNELS * sizeof (float), cudaMemcpyDeviceToHost)); memcopy += getElapsedtime(t_start); printf("Completed in %.3f sec\n", compute / 1000); printf("Memory copy in %.3f sec\n", memcopy / 1000); /* Convert output. */ if (ok) { for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) for (c = 0; c < CHANNELS; c++) image_buffer_h[i][j][c] = (unsigned char) image_h[i + B][j + B][c]; } /* Create output files, one for each channel. */ if (ok) ok = write_channels(image_buffer_h, HEIGHT, WIDTH); /* Free allocated memory. */ dealloc_uchar_array((unsigned char ***) &image_buffer_h); dealloc_float_array((float ***) &image_h); dealloc_float_array_cuda((float ***) &prev_image_d, &prev_image_p); dealloc_float_array_cuda((float ***) &curr_image_d, &curr_image_p); destroy_filter(&filter_d, &filter_p); return ok ? (EXIT_SUCCESS) : (EXIT_FAILURE); }
void obe_close( obe_t *h ) { void *ret_ptr; fprintf( stderr, "closing obe \n" ); /* Cancel input thread */ for( int i = 0; i < h->num_devices; i++ ) { pthread_cancel( h->devices[i]->device_thread ); pthread_join( h->devices[i]->device_thread, &ret_ptr ); } fprintf( stderr, "input cancelled \n" ); /* Cancel filter threads */ for( int i = 0; i < h->num_filters; i++ ) { pthread_mutex_lock( &h->filters[i]->queue.mutex ); h->filters[i]->cancel_thread = 1; pthread_cond_signal( &h->filters[i]->queue.in_cv ); pthread_mutex_unlock( &h->filters[i]->queue.mutex ); pthread_join( h->filters[i]->filter_thread, &ret_ptr ); } fprintf( stderr, "filters cancelled \n" ); /* Cancel encoder threads */ for( int i = 0; i < h->num_encoders; i++ ) { pthread_mutex_lock( &h->encoders[i]->queue.mutex ); h->encoders[i]->cancel_thread = 1; pthread_cond_signal( &h->encoders[i]->queue.in_cv ); pthread_mutex_unlock( &h->encoders[i]->queue.mutex ); pthread_join( h->encoders[i]->encoder_thread, &ret_ptr ); } fprintf( stderr, "encoders cancelled \n" ); /* Cancel encoder smoothing thread */ if ( h->obe_system == OBE_SYSTEM_TYPE_GENERIC ) { pthread_mutex_lock( &h->enc_smoothing_queue.mutex ); h->cancel_enc_smoothing_thread = 1; pthread_cond_signal( &h->enc_smoothing_queue.in_cv ); pthread_mutex_unlock( &h->enc_smoothing_queue.mutex ); /* send a clock tick in case smoothing is waiting for one */ pthread_mutex_lock( &h->obe_clock_mutex ); pthread_cond_broadcast( &h->obe_clock_cv ); pthread_mutex_unlock( &h->obe_clock_mutex ); pthread_join( h->enc_smoothing_thread, &ret_ptr ); } fprintf( stderr, "encoder smoothing cancelled \n" ); /* Cancel mux thread */ pthread_mutex_lock( &h->mux_queue.mutex ); h->cancel_mux_thread = 1; pthread_cond_signal( &h->mux_queue.in_cv ); pthread_mutex_unlock( &h->mux_queue.mutex ); pthread_join( h->mux_thread, &ret_ptr ); fprintf( stderr, "mux cancelled \n" ); /* Cancel mux smoothing thread */ pthread_mutex_lock( &h->mux_smoothing_queue.mutex ); h->cancel_mux_smoothing_thread = 1; pthread_cond_signal( &h->mux_smoothing_queue.in_cv ); pthread_mutex_unlock( &h->mux_smoothing_queue.mutex ); pthread_join( h->mux_smoothing_thread, &ret_ptr ); fprintf( stderr, "mux smoothing cancelled \n" ); /* Cancel output_thread */ pthread_mutex_lock( &h->output_queue.mutex ); h->cancel_output_thread = 1; pthread_cond_signal( &h->output_queue.in_cv ); pthread_mutex_unlock( &h->output_queue.mutex ); pthread_join( h->output_thread, &ret_ptr ); /* could be blocking on OS so have to cancel thread too */ pthread_cancel( h->output_thread ); pthread_join( h->output_thread, &ret_ptr ); fprintf( stderr, "output thread cancelled \n" ); /* Destroy devices */ for( int i = 0; i < h->num_devices; i++ ) destroy_device( h->devices[i] ); fprintf( stderr, "devices destroyed \n" ); /* Destroy filters */ for( int i = 0; i < h->num_filters; i++ ) destroy_filter( h->filters[i] ); fprintf( stderr, "filters destroyed \n" ); /* Destroy encoders */ for( int i = 0; i < h->num_encoders; i++ ) destroy_encoder( h->encoders[i] ); fprintf( stderr, "encoders destroyed \n" ); // FIXME destroy smoothing thread /* Destroy mux */ destroy_mux( h ); fprintf( stderr, "mux destroyed \n" ); /* Destroy output */ destroy_output( h ); fprintf( stderr, "output destroyed \n" ); free( h->output_streams ); /* TODO: free other things */ free( h ); h = NULL; }
LRESULT album_list_window::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg) { case WM_CREATE: { list_wnd.add_item(this); initialised = true; modeless_dialog_manager::g_add(wnd); create_tree(); create_filter(); if (cfg_populate) refresh_tree(); static_api_ptr_t<library_manager_v3>()->register_callback(this); } break; /*case WM_GETMINMAXINFO: { LPMINMAXINFO mmi = LPMINMAXINFO(lp); mmi->ptMinTrackSize.y = cfg_height; return 0; }*/ case WM_SIZE: on_size(LOWORD(lp), HIWORD(lp)); break; /* case DM_GETDEFID: return (DC_HASDEFID<<16|IDOK); case WM_GETDLGCODE: return DLGC_DEFPUSHBUTTON;*/ // break; case WM_TIMER: if (wp == EDIT_TIMER_ID) { refresh_tree(); KillTimer(wnd, wp); m_timer = false; } break; case WM_COMMAND: switch (wp) { case IDC_FILTER | (EN_CHANGE << 16) : if (m_timer) KillTimer(wnd_edit, 500); m_timer = SetTimer(wnd, EDIT_TIMER_ID, 500, NULL) != 0; return TRUE; case IDOK: if (GetKeyState(VK_SHIFT) & KF_UP) do_playlist(p_selection, false); else if (GetKeyState(VK_CONTROL) & KF_UP) do_playlist(p_selection, true, true); else do_playlist(p_selection, true); return 0; } break; case WM_CONTEXTMENU: { enum { ID_SEND = 1, ID_ADD, ID_NEW, ID_AUTOSEND, ID_REMOVE, ID_REMOVEDEAD, ID_REFRESH, ID_FILT, ID_CONF, ID_VIEW_BASE }; HMENU menu = CreatePopupMenu(); POINT pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) }; service_ptr_t<contextmenu_manager> p_menu_manager; unsigned IDM_MANAGER_BASE = 0; HWND list = wnd_tv; HTREEITEM treeitem = NULL; TVHITTESTINFO ti; memset(&ti, 0, sizeof(ti)); if (pt.x != -1 && pt.y != -1) { ti.pt = pt; ScreenToClient(list, &ti.pt); uSendMessage(list, TVM_HITTEST, 0, (long)&ti); if (ti.hItem && (ti.flags & TVHT_ONITEM)) { //FIX THIS AND AUTOSEND //TreeView_Select(list, ti.hItem, TVGN_DROPHILITE); //uSendMessage(list,TVM_SELECTITEM,TVGN_DROPHILITE,(long)ti.hItem); treeitem = ti.hItem; } } else { treeitem = TreeView_GetSelection(list); RECT rc; if (treeitem && TreeView_GetItemRect(wnd_tv, treeitem, &rc, TRUE)) { MapWindowPoints(wnd_tv, HWND_DESKTOP, (LPPOINT)&rc, 2); pt.x = rc.left; pt.y = rc.top + (rc.bottom - rc.top) / 2; } else { GetMessagePos(&pt); } } TreeView_Select(list, treeitem, TVGN_DROPHILITE); HMENU menu_view = CreatePopupMenu(); unsigned n, m = cfg_view_list.get_count(); string8_fastalloc temp; temp.prealloc(32); uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(directory_structure_view_name, view) ? MF_CHECKED : 0), ID_VIEW_BASE + 0, directory_structure_view_name); list_t<string_simple, pfc::alloc_fast> views; views.add_item(string_simple(directory_structure_view_name)); for (n = 0; n<m; n++) { temp = cfg_view_list.get_name(n); string_simple item(temp.get_ptr()); if (item) { uAppendMenu(menu_view, MF_STRING | (!stricmp_utf8(temp, view) ? MF_CHECKED : 0), ID_VIEW_BASE + views.add_item(item), temp); } } IDM_MANAGER_BASE = ID_VIEW_BASE + views.get_count(); uAppendMenu(menu, MF_STRING | MF_POPUP, (UINT)menu_view, "View"); if (!m_populated && !cfg_populate) uAppendMenu(menu, MF_STRING, ID_REFRESH, "Populate"); uAppendMenu(menu, MF_STRING | (m_filter ? MF_CHECKED : 0), ID_FILT, "Filter"); uAppendMenu(menu, MF_STRING, ID_CONF, "Settings"); bool show_shortcuts = standard_config_objects::query_show_keyboard_shortcuts_in_menus(); node * p_node = NULL; TVITEMEX tvi; memset(&tvi, 0, sizeof(tvi)); tvi.hItem = treeitem; tvi.mask = TVIF_HANDLE | TVIF_PARAM; TreeView_GetItem(list, &tvi); p_node = (node*)tvi.lParam; if (treeitem && p_node) { uAppendMenu(menu, MF_SEPARATOR, 0, ""); uAppendMenu(menu, MF_STRING, ID_SEND, (show_shortcuts ? "&Send to playlist\tEnter" : "&Send to playlist")); uAppendMenu(menu, MF_STRING, ID_ADD, show_shortcuts ? "&Add to playlist\tShift+Enter" : "&Add to playlist"); uAppendMenu(menu, MF_STRING, ID_NEW, show_shortcuts ? "Send to &new playlist\tCtrl+Enter" : "Send to &new playlist"); uAppendMenu(menu, MF_STRING, ID_AUTOSEND, "Send to &autosend playlist"); if (!static_api_ptr_t<core_version_info_v2>()->test_version(0, 9, 6, 0)) { uAppendMenu(menu, MF_STRING, ID_REMOVE, "&Remove from library"); uAppendMenu(menu, MF_STRING, ID_REMOVEDEAD, "Remove &dead entries (slow)"); } uAppendMenu(menu, MF_SEPARATOR, 0, ""); contextmenu_manager::g_create(p_menu_manager); p_node->sort_entries(); if (p_menu_manager.is_valid()) { p_menu_manager->init_context(p_node->get_entries(), 0); p_menu_manager->win32_build_menu(menu, IDM_MANAGER_BASE, -1); menu_helpers::win32_auto_mnemonics(menu); } } int cmd = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, pt.x, pt.y, 0, get_wnd(), 0); DestroyMenu(menu); TreeView_Select(list, NULL, TVGN_DROPHILITE); if (cmd) { if (p_menu_manager.is_valid() && (unsigned)cmd >= IDM_MANAGER_BASE) { p_menu_manager->execute_by_id(cmd - IDM_MANAGER_BASE); } else if (cmd >= ID_VIEW_BASE) { unsigned n = cmd - ID_VIEW_BASE; if (n<views.get_count()) { view = views[n].get_ptr(); refresh_tree(); } } else if (cmd<ID_VIEW_BASE) { unsigned cmd2 = 0; switch (cmd) { case ID_NEW: do_playlist(p_node, true, true); break; case ID_SEND: do_playlist(p_node, true); break; case ID_ADD: do_playlist(p_node, false); break; case ID_AUTOSEND: do_autosend_playlist(p_node, view, true); break; case ID_CONF: { static_api_ptr_t<ui_control>()->show_preferences(g_guid_preferences_album_list_panel); } break; case ID_FILT: { m_filter = !m_filter; create_or_destroy_filter(); } break; case ID_REMOVE: p_node->remove_from_db(); break; case ID_REMOVEDEAD: p_node->remove_dead(); break; case ID_REFRESH: if (!m_populated && !cfg_populate) refresh_tree(); break; } if (cmd2) uSendMessage(get_wnd(), WM_COMMAND, cmd2, 0); } } p_menu_manager.release(); /* if (treeitem_context && (treeitem_context != treeitem) && cfg_autosend) TreeView_SelectItem(wnd_tv,treeitem);*/ } return 0; case WM_NOTIFY: { LPNMHDR hdr = (LPNMHDR)lp; switch (hdr->idFrom) { case IDC_TREE: { if (hdr->code == TVN_ITEMEXPANDING) { LPNMTREEVIEW param = (LPNMTREEVIEW)hdr; if (cfg_picmixer && (param->action == TVE_EXPAND)) { TreeView_CollapseOtherNodes(param->hdr.hwndFrom, param->itemNew.hItem); } } else if (hdr->code == TVN_SELCHANGED) { LPNMTREEVIEW param = (LPNMTREEVIEW)hdr; p_selection = (node*)param->itemNew.lParam; if ((param->action == TVC_BYMOUSE || param->action == TVC_BYKEYBOARD)) { if (cfg_autosend) do_autosend_playlist(p_selection, view); } if (m_selection_holder.is_valid()) { m_selection_holder->set_selection(p_selection.is_valid() ? p_selection->get_entries() : metadb_handle_list()); } #if 0 if (cfg_picmixer) { HTREEITEM ti_parent_old = TreeView_GetParent(param->hdr.hwndFrom, param->itemOld.hItem); HTREEITEM ti_parent_new = TreeView_GetParent(param->hdr.hwndFrom, param->itemNew.hItem); if (/*ti_parent_old != param->itemNew.hItem && */!TreeView_IsChild(param->hdr.hwndFrom, param->itemNew.hItem, param->itemOld.hItem)) { HTREEITEM ti = //TreeView_GetLevel(param->hdr.hwndFrom, param->itemNew.hItem) < TreeView_GetLevel(param->hdr.hwndFrom, param->itemOld.hItem) ? TreeView_GetCommonParentChild(param->hdr.hwndFrom, param->itemOld.hItem, param->itemNew.hItem) //: param->itemOld.hItem ; if (ti && ti != TVI_ROOT) TreeView_Expand(param->hdr.hwndFrom, ti, TVE_COLLAPSE); } if (ti_parent_new) { HTREEITEM child = TreeView_GetChild(param->hdr.hwndFrom, ti_parent_new); while (child) { if (child != param->itemNew.hItem) { } } } } #endif } } break; } } break; case WM_DESTROY: static_api_ptr_t<library_manager_v3>()->unregister_callback(this); modeless_dialog_manager::g_remove(wnd); destroy_tree(); destroy_filter(); m_selection_holder.release(); m_root.release(); p_selection.release(); if (initialised) { list_wnd.remove_item(this); if (list_wnd.get_count() == 0) { DeleteFont(g_font); g_font = 0; } initialised = false; } break; } return DefWindowProc(wnd, msg, wp, lp); }