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;
}
Beispiel #2
0
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
}
Beispiel #3
0
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;
}