HCURSOR SWELL_LoadCursor(const char *_idx) { #ifdef SWELL_TARGET_GDK GdkCursorType def = GDK_LEFT_PTR; if (_idx == IDC_NO) def = GDK_PIRATE; else if (_idx == IDC_SIZENWSE) def = GDK_BOTTOM_LEFT_CORNER; else if (_idx == IDC_SIZENESW) def = GDK_BOTTOM_RIGHT_CORNER; else if (_idx == IDC_SIZEALL) def = GDK_FLEUR; else if (_idx == IDC_SIZEWE) def = GDK_RIGHT_SIDE; else if (_idx == IDC_SIZENS) def = GDK_TOP_SIDE; else if (_idx == IDC_ARROW) def = GDK_LEFT_PTR; else if (_idx == IDC_HAND) def = GDK_HAND1; else if (_idx == IDC_UPARROW) def = GDK_CENTER_PTR; else if (_idx == IDC_IBEAM) def = GDK_XTERM; else { SWELL_CursorResourceIndex *p = SWELL_curmodule_cursorresource_head; while (p) { if (p->resid == _idx) { if (p->cachedCursor) return p->cachedCursor; // todo: load from p->resname, into p->cachedCursor, p->hotspot char buf[1024]; GetModuleFileName(NULL,buf,sizeof(buf)); WDL_remove_filepart(buf); snprintf_append(buf,sizeof(buf),"/Resources/%s.cur",p->resname); GdkPixbuf *pb = gdk_pixbuf_new_from_file(buf,NULL); if (pb) { getHotSpotForFile(buf,&p->hotspot); GdkCursor *curs = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),pb,p->hotspot.x,p->hotspot.y); return (p->cachedCursor = (HCURSOR) curs); } } p=p->_next; } } HCURSOR hc= (HCURSOR)gdk_cursor_new_for_display(gdk_display_get_default(),def); return hc; #endif return NULL; }
char *WDL_ChooseFileForOpen(HWND parent, const char *text, const char *initialdir, const char *initialfile, const char *extlist, const char *defext, bool preservecwd, bool allowmul, const char *dlgid, void *dlgProc, #ifdef _WIN32 HINSTANCE hInstance #else struct SWELL_DialogResourceIndex *reshead #endif ) { char olddir[2048]; GetCurrentDirectory(sizeof(olddir),olddir); #ifdef _WIN32 #ifdef WDL_FILEBROWSE_WIN7VISTAMODE if (!allowmul) // todo : check impl of multiple select, too? { Win7FileDialog fd(text); if(fd.inited()) { //vista+ file open dialog fd.addOptions(FOS_FILEMUSTEXIST); fd.setFilterList(extlist); if (defext) { fd.setDefaultExtension(defext); int i = 0; const char *p = extlist; while(*p) { if(*p) p+=strlen(p)+1; if(!*p) break; if(stristr(p, defext)) { fd.setFileTypeIndex(i+1); break; } i++; p+=strlen(p)+1; } } fd.setFolder(initialdir?initialdir:olddir, 0); fd.setTemplate(hInstance, dlgid, (LPOFNHOOKPROC)dlgProc); if(initialfile) { char temp[4096]; lstrcpyn_safe(temp,initialfile,sizeof(temp)); //check for folder name if (WDL_remove_filepart(temp)) { //folder found fd.setFolder(temp, 0); fd.setFilename(temp + strlen(temp) + 1); } else fd.setFilename(temp); } if(fd.show(parent)) { char temp[4096]; temp[0]=0; //ifileopendialog saves the last folder automatically fd.getResult(temp, sizeof(temp)-1); if (preservecwd) SetCurrentDirectory(olddir); return temp[0] ? strdup(temp) : NULL; } if (preservecwd) SetCurrentDirectory(olddir); return NULL; } } #endif int temp_size = allowmul ? 256*1024-1 : 4096-1; char *temp = (char *)calloc(temp_size+1,1); OPENFILENAME l={sizeof(l), parent, hInstance, extlist, NULL, 0, 0, temp, temp_size, NULL, 0, initialdir, text, OFN_HIDEREADONLY|OFN_EXPLORER|OFN_FILEMUSTEXIST,0,0, (char *)(defext ? defext : ""), 0, (LPOFNHOOKPROC)dlgProc, dlgid}; if (hInstance&&dlgProc&&dlgid) l.Flags |= OFN_ENABLEHOOK|OFN_ENABLETEMPLATE|OFN_ENABLESIZING; if (allowmul) l.Flags|=OFN_ALLOWMULTISELECT; if (preservecwd) l.Flags|=OFN_NOCHANGEDIR; if (initialfile) lstrcpyn_safe(temp,initialfile,temp_size); WDL_fixfnforopenfn(temp); if (!l.lpstrInitialDir||!l.lpstrInitialDir[0]) l.lpstrInitialDir=olddir; int r = GetOpenFileName(&l); if (preservecwd) SetCurrentDirectory(olddir); if (!r) free(temp); return r?temp:NULL; #else char if_temp[4096]; if (initialfile) { lstrcpyn_safe(if_temp,initialfile,sizeof(if_temp)); WDL_fixfnforopenfn(if_temp); initialfile = if_temp; } // defext support? BrowseFile_SetTemplate(dlgid,(DLGPROC)dlgProc,reshead); char *ret = BrowseForFiles(text,initialdir,initialfile,allowmul,extlist); if (preservecwd) SetCurrentDirectory(olddir); return ret; #endif }
bool WDL_ChooseFileForSave(HWND parent, const char *text, const char *initialdir, const char *initialfile, const char *extlist, const char *defext, bool preservecwd, char *fn, int fnsize, const char *dlgid, void *dlgProc, #ifdef _WIN32 HINSTANCE hInstance #else struct SWELL_DialogResourceIndex *reshead #endif ) { char cwd[2048]; GetCurrentDirectory(sizeof(cwd),cwd); #ifdef _WIN32 char temp[4096]; memset(temp,0,sizeof(temp)); if (initialfile) lstrcpyn_safe(temp,initialfile,sizeof(temp)); WDL_fixfnforopenfn(temp); #ifdef WDL_FILEBROWSE_WIN7VISTAMODE { Win7FileDialog fd(text, 1); if(fd.inited()) { fd.addOptions(FOS_DONTADDTORECENT); //vista+ file open dialog char olddir[2048]; GetCurrentDirectory(sizeof(olddir),olddir); fd.setFilterList(extlist); if (defext) { fd.setDefaultExtension(defext); int i = 0; const char *p = extlist; while(*p) { if(*p) p+=strlen(p)+1; if(!*p) break; if(stristr(p, defext)) { fd.setFileTypeIndex(i+1); break; } i++; p+=strlen(p)+1; } } fd.setFolder(initialdir?initialdir:olddir, 0); if(initialfile) { //check for folder name if (WDL_remove_filepart(temp)) { //folder found fd.setFolder(temp, 0); fd.setFilename(temp + strlen(temp) + 1); } else fd.setFilename(temp); } fd.setTemplate(hInstance, dlgid, (LPOFNHOOKPROC)dlgProc); if(fd.show(parent)) { //ifilesavedialog saves the last folder automatically fd.getResult(fn, fnsize); if (preservecwd) SetCurrentDirectory(olddir); return true; } if (preservecwd) SetCurrentDirectory(olddir); return NULL; } } #endif OPENFILENAME l={sizeof(l),parent, hInstance, extlist, NULL,0, 0, temp, sizeof(temp)-1, NULL, 0, initialdir&&initialdir[0] ? initialdir : cwd, text, OFN_HIDEREADONLY|OFN_EXPLORER|OFN_OVERWRITEPROMPT,0,0,defext, 0, (LPOFNHOOKPROC)dlgProc, dlgid}; if (hInstance&&dlgProc&&dlgid) l.Flags |= OFN_ENABLEHOOK|OFN_ENABLETEMPLATE|OFN_ENABLESIZING; if (preservecwd) l.Flags |= OFN_NOCHANGEDIR; if (!GetSaveFileName(&l)||!temp[0]) { if (preservecwd) SetCurrentDirectory(cwd); return false; } if (preservecwd) SetCurrentDirectory(cwd); lstrcpyn_safe(fn,temp,fnsize); return true; #else BrowseFile_SetTemplate(dlgid,(DLGPROC)dlgProc,reshead); char if_temp[4096]; if (initialfile) { lstrcpyn_safe(if_temp,initialfile,sizeof(if_temp)); WDL_fixfnforopenfn(if_temp); initialfile = if_temp; } bool r = BrowseForSaveFile(text,initialdir,initialfile,extlist,fn,fnsize); if (preservecwd) SetCurrentDirectory(cwd); return r; #endif }
static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { const int maxPathLen = 2048; const char *multiple_files = "(multiple files)"; switch (uMsg) { case WM_CREATE: if (lParam) // swell-specific { SetWindowLong(hwnd,GWL_WNDPROC,(LPARAM)SwellDialogDefaultWindowProc); SetWindowLong(hwnd,DWL_DLGPROC,(LPARAM)swellFileSelectProc); SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); BrowseFile_State *parms = (BrowseFile_State *)lParam; if (parms->caption) SetWindowText(hwnd,parms->caption); SWELL_MakeSetCurParms(1,1,0,0,hwnd,false,false); SWELL_MakeButton(0, parms->mode == BrowseFile_State::OPENDIR ? "Choose directory" : parms->mode == BrowseFile_State::SAVE ? "Save" : "Open", IDOK,0,0,0,0, 0); SWELL_MakeButton(0, "Cancel", IDCANCEL,0,0,0,0, 0); HWND edit = SWELL_MakeEditField(0x100, 0,0,0,0, 0); HWND dir = SWELL_MakeCombo(0x103, 0,0,0,0, CBS_DROPDOWNLIST); HWND list = SWELL_MakeControl("",0x104,"SysListView32",LVS_REPORT|LVS_SHOWSELALWAYS| (parms->mode == BrowseFile_State::OPENMULTI ? 0 : LVS_SINGLESEL)| LVS_OWNERDATA|WS_BORDER|WS_TABSTOP,0,0,0,0,0); if (list) { LVCOLUMN c={LVCF_TEXT|LVCF_WIDTH, 0, 280, (char*)"Filename" }; ListView_InsertColumn(list,0,&c); c.cx = 120; c.pszText = (char*) "Size"; ListView_InsertColumn(list,1,&c); c.cx = 140; c.pszText = (char*) "Date"; ListView_InsertColumn(list,2,&c); } HWND extlist = (parms->extlist && *parms->extlist) ? SWELL_MakeCombo(0x105, 0,0,0,0, CBS_DROPDOWNLIST) : NULL; if (extlist) { const char *p = parms->extlist; while (*p) { const char *rd=p; p += strlen(p)+1; if (!*p) break; int a = SendMessage(extlist,CB_ADDSTRING,0,(LPARAM)rd); SendMessage(extlist,CB_SETITEMDATA,a,(LPARAM)p); p += strlen(p)+1; } SendMessage(extlist,CB_SETCURSEL,0,0); } SWELL_MakeLabel(-1,parms->mode == BrowseFile_State::OPENDIR ? "Directory: " : "File:",0x101, 0,0,0,0, 0); if (BFSF_Templ_dlgid && BFSF_Templ_dlgproc) { HWND dlg = SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, hwnd, BFSF_Templ_dlgproc, 0); if (dlg) SetWindowLong(dlg,GWL_ID,0x102); BFSF_Templ_dlgproc=0; BFSF_Templ_dlgid=0; } SWELL_MakeSetCurParms(1,1,0,0,NULL,false,false); if (edit && dir) { char buf[maxPathLen]; const char *filepart = ""; if (parms->initialfile && *parms->initialfile && *parms->initialfile != '.') { lstrcpyn_safe(buf,parms->initialfile,sizeof(buf)); char *p = (char *)WDL_get_filepart(buf); if (p > buf) { p[-1]=0; filepart = p; } } else if (parms->initialdir && *parms->initialdir) { lstrcpyn_safe(buf,parms->initialdir,sizeof(buf)); } else getcwd(buf,sizeof(buf)); SetWindowText(edit,filepart); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); } SetWindowPos(hwnd,NULL,0,0,600, 400, SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE); SendMessage(hwnd,WM_USER+100,1,0); // refresh list } break; case WM_USER+100: switch (wParam) { case 0x103: // update directory combo box -- destroys buffer pointed to by lParam if (lParam) { char *path = (char*)lParam; HWND combo=GetDlgItem(hwnd,0x103); SendMessage(combo,CB_RESETCONTENT,0,0); WDL_remove_trailing_dirchars(path); while (path[0]) { SendMessage(combo,CB_ADDSTRING,0,(LPARAM)path); WDL_remove_filepart(path); WDL_remove_trailing_dirchars(path); } SendMessage(combo,CB_ADDSTRING,0,(LPARAM)"/"); SendMessage(combo,CB_SETCURSEL,0,0); } break; case 1: { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (parms) { char buf[maxPathLen]; const char *filt = NULL; buf[0]=0; int a = (int) SendDlgItemMessage(hwnd,0x105,CB_GETCURSEL,0,0); if (a>=0) filt = (const char *)SendDlgItemMessage(hwnd,0x105,CB_GETITEMDATA,a,0); a = (int) SendDlgItemMessage(hwnd,0x103,CB_GETCURSEL,0,0); if (a>=0) SendDlgItemMessage(hwnd,0x103,CB_GETLBTEXT,a,(LPARAM)buf); if (buf[0]) parms->scan_path(buf, filt, parms->mode == BrowseFile_State::OPENDIR); else parms->viewlist.DeleteAll(); HWND list = GetDlgItem(hwnd,0x104); ListView_SetItemCount(list, 0); // clear selection ListView_SetItemCount(list, parms->viewlist.GetSize()); ListView_RedrawItems(list,0, parms->viewlist.GetSize()); } } break; } break; case WM_GETMINMAXINFO: { LPMINMAXINFO p=(LPMINMAXINFO)lParam; p->ptMinTrackSize.x = 300; p->ptMinTrackSize.y = 300; } break; case WM_SIZE: { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); // reposition controls RECT r; GetClientRect(hwnd,&r); const int buth = 24, cancelbutw = 50, okbutw = parms->mode == BrowseFile_State::OPENDIR ? 120 : 50; const int xborder = 4, yborder=8; const int fnh = 20, fnlblw = parms->mode == BrowseFile_State::OPENDIR ? 70 : 50; int ypos = r.bottom - 4 - buth; int xpos = r.right; SetWindowPos(GetDlgItem(hwnd,IDCANCEL), NULL, xpos -= cancelbutw + xborder, ypos, cancelbutw,buth, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,IDOK), NULL, xpos -= okbutw + xborder, ypos, okbutw,buth, SWP_NOZORDER|SWP_NOACTIVATE); HWND emb = GetDlgItem(hwnd,0x102); if (emb) { RECT sr; GetClientRect(emb,&sr); if (ypos > r.bottom-4-sr.bottom) ypos = r.bottom-4-sr.bottom; SetWindowPos(emb,NULL, xborder,ypos, xpos - xborder*2, sr.bottom, SWP_NOZORDER|SWP_NOACTIVATE); ShowWindow(emb,SW_SHOWNA); } HWND filt = GetDlgItem(hwnd,0x105); if (filt) { SetWindowPos(filt, NULL, xborder*2 + fnlblw, ypos -= fnh + yborder, r.right-fnlblw-xborder*3, fnh, SWP_NOZORDER|SWP_NOACTIVATE); } SetWindowPos(GetDlgItem(hwnd,0x100), NULL, xborder*2 + fnlblw, ypos -= fnh + yborder, r.right-fnlblw-xborder*3, fnh, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,0x101), NULL, xborder, ypos, fnlblw, fnh, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,0x103), NULL, xborder, 0, r.right-xborder*2, fnh, SWP_NOZORDER|SWP_NOACTIVATE); SetWindowPos(GetDlgItem(hwnd,0x104), NULL, xborder, fnh+yborder, r.right-xborder*2, ypos - (fnh+yborder) - yborder, SWP_NOZORDER|SWP_NOACTIVATE); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case 0x105: if (HIWORD(wParam) == CBN_SELCHANGE) { SendMessage(hwnd,WM_USER+100,1,0); // refresh list } return 0; case 0x103: if (HIWORD(wParam) == CBN_SELCHANGE) { SendMessage(hwnd,WM_USER+100,1,0); // refresh list } return 0; case IDCANCEL: EndDialog(hwnd,0); return 0; case IDOK: { char buf[maxPathLen], msg[2048]; buf[0]=0; int a = (int) SendDlgItemMessage(hwnd,0x103,CB_GETCURSEL,0,0); if (a>=0) { SendDlgItemMessage(hwnd,0x103,CB_GETLBTEXT,a,(LPARAM)buf); size_t buflen = strlen(buf); if (!buflen) strcpy(buf,"/"); else { if (buflen > sizeof(buf)-2) buflen = sizeof(buf)-2; if (buf[buflen-1]!='/') { buf[buflen++] = '/'; buf[buflen]=0; } } } GetDlgItemText(hwnd,0x100,msg,sizeof(msg)); BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); int cnt; if (parms->mode == BrowseFile_State::OPENMULTI && (cnt=ListView_GetSelectedCount(GetDlgItem(hwnd,0x104)))>1 && (!*msg || !strcmp(msg,multiple_files))) { HWND list = GetDlgItem(hwnd,0x104); WDL_TypedBuf<char> fs; fs.Set(buf,strlen(buf)+1); int a = ListView_GetNextItem(list,-1,LVNI_SELECTED); while (a != -1 && fs.GetSize() < 4096*4096 && cnt--) { const char *fn = NULL; struct BrowseFile_State::rec *rec = parms->viewlist.EnumeratePtr(a,&fn); if (!rec) break; if (*fn) fn++; // skip type ident fs.Add(fn,strlen(fn)+1); a = ListView_GetNextItem(list,a,LVNI_SELECTED); } fs.Add("",1); parms->fnout = (char*)malloc(fs.GetSize()); if (parms->fnout) memcpy(parms->fnout,fs.Get(),fs.GetSize()); EndDialog(hwnd,1); return 0; } else { if (msg[0] == '.' && (msg[1] == '.' || msg[1] == 0)) { if (msg[1] == '.') SendDlgItemMessage(hwnd,0x103,CB_SETCURSEL,a+1,0); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } else if (msg[0] == '/') lstrcpyn_safe(buf,msg,sizeof(buf)); else lstrcatn(buf,msg,sizeof(buf)); } switch (parms->mode) { case BrowseFile_State::OPENDIR: if (!buf[0]) return 0; else if (msg[0]) { // navigate to directory if filepart set DIR *dir = opendir(buf); if (!dir) { snprintf(msg,sizeof(msg),"Error opening directory:\r\n\r\n%s\r\n\r\nCreate?",buf); if (MessageBox(hwnd,msg,"Create directory?",MB_OKCANCEL)==IDCANCEL) return 0; CreateDirectory(buf,NULL); dir=opendir(buf); } if (!dir) { MessageBox(hwnd,"Error creating directory","Error",MB_OK); return 0; } closedir(dir); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } else { DIR *dir = opendir(buf); if (!dir) return 0; closedir(dir); } break; case BrowseFile_State::SAVE: if (!buf[0]) return 0; else { struct stat st={0,}; DIR *dir = opendir(buf); if (dir) { closedir(dir); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } if (!stat(buf,&st)) { snprintf(msg,sizeof(msg),"File exists:\r\n\r\n%s\r\n\r\nOverwrite?",buf); if (MessageBox(hwnd,msg,"Overwrite file?",MB_OKCANCEL)==IDCANCEL) return 0; } } break; default: if (!buf[0]) return 0; else { struct stat st={0,}; DIR *dir = opendir(buf); if (dir) { closedir(dir); SendMessage(hwnd, WM_USER+100, 0x103, (LPARAM)buf); SetDlgItemText(hwnd,0x100,""); SendMessage(hwnd,WM_USER+100,1,0); // refresh list return 0; } if (stat(buf,&st)) { snprintf(msg,sizeof(msg),"File does not exist:\r\n\r\n%s",buf); MessageBox(hwnd,msg,"File not found",MB_OK); return 0; } } break; } if (parms->fnout) { lstrcpyn_safe(parms->fnout,buf,parms->fnout_sz); } else { size_t l = strlen(buf); parms->fnout = (char*)calloc(l+2,1); memcpy(parms->fnout,buf,l); } } EndDialog(hwnd,1); return 0; } break; case WM_NOTIFY: { LPNMHDR l=(LPNMHDR)lParam; if (l->code == LVN_GETDISPINFO) { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); NMLVDISPINFO *lpdi = (NMLVDISPINFO*) lParam; const int idx=lpdi->item.iItem; if (l->idFrom == 0x104 && parms && idx >=0 && idx < parms->viewlist.GetSize()) { const char *fn = NULL; struct BrowseFile_State::rec *rec = parms->viewlist.EnumeratePtr(idx,&fn); if (rec && fn) { if (lpdi->item.mask&LVIF_TEXT) { switch (lpdi->item.iSubItem) { case 0: if (fn[0]) lstrcpyn_safe(lpdi->item.pszText,fn+1,lpdi->item.cchTextMax); break; case 1: if (fn[0] == 1) { lstrcpyn_safe(lpdi->item.pszText,"<DIR>",lpdi->item.cchTextMax); } else { static const char *tab[]={ "bytes","KB","MB","GB" }; int lf=0; WDL_INT64 s=rec->size; if (s<1024) { snprintf(lpdi->item.pszText,lpdi->item.cchTextMax,"%d %s ",(int)s,tab[0]); break; } int w = 1; do { w++; lf = (int)(s&1023); s/=1024; } while (s >= 1024 && w<4); snprintf(lpdi->item.pszText,lpdi->item.cchTextMax,"%d.%d %s ",(int)s,(int)((lf*10.0)/1024.0+0.5),tab[w-1]); } break; case 2: if (rec->date > 0 && rec->date < WDL_INT64_CONST(0x793406fff)) { struct tm *a=localtime(&rec->date); if (a) { char str[512]; strftime(str,sizeof(str),"%c",a); lstrcpyn(lpdi->item.pszText, str,lpdi->item.cchTextMax); } } break; } } } } } else if (l->code == LVN_ODFINDITEM) { } else if (l->code == LVN_ITEMCHANGED) { const int selidx = ListView_GetNextItem(l->hwndFrom, -1, LVNI_SELECTED); if (selidx>=0) { BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); if (parms && parms->mode == BrowseFile_State::OPENMULTI && ListView_GetSelectedCount(l->hwndFrom)>1) { SetDlgItemText(hwnd,0x100,multiple_files); } else { const char *fn = NULL; struct BrowseFile_State::rec *rec = parms ? parms->viewlist.EnumeratePtr(selidx,&fn) : NULL; if (rec) { if (fn && fn[0]) SetDlgItemText(hwnd,0x100,fn+1); } } } } else if (l->code == NM_DBLCLK) { SendMessage(hwnd,WM_COMMAND,IDOK,0); } } break; } return 0; }