Silverfrost Forums

Welcome to our forums

Windows 7 Problems with GET_FILTERED_FILE@

22 Jun 2012 9:15 #10394

Hi John,

I'm fairly sure the problem exists with both dialogues under W7. I had noticed the problem in my main complex app and that was using the old dialogue (not via get_filtered_file@ but via a 3rd-party 'MFC' DLL) - I can't easily prove that in my 'noddy' prog though!

K

edit: I've just run my 'noddy' prog on my old XP-32 machine and get some memory loss, but not as much:

With or without /3Gb:

Don't open file browser: 1400Mb Open file browser: 1080Mb

K

2nd edit:

On a Vista-32 machine:

Don't open file browser: 1320Mb Open file browser: 920Mb

K

23 Jun 2012 11:42 #10406

Kenny, Here is some sample code based on what is in the library.

#include <string.h>
#include <ctype.h>
#include <dir.h>
#include <stdio.h>
#include <windows.h>
#include <commdlg.h>

enum logical {false, true};
  
static logical get_file_name(HWND parent,char* title,char* ufileName,
                  int bufLen,char* filter,char* defPath,logical must_exist,logical saving)
{
  logical l;
  const int file_length = 500;
  int mlen;
  static char szDialogDirName[300];
  char fileName[file_length];
  OPENFILENAME ofn;
  char szDirName[300];
  char szFilter[]=
    'All files (*.*)\\0*.*\\0'
    '\\0';

  if (fileName==NULL || bufLen<1) return false;

  if(bufLen > file_length) mlen = file_length;
  else                     mlen=bufLen;

  strncpy(fileName,ufileName,mlen);
  *(fileName+mlen-1)=0;

  getcwd(szDirName,300);

  strcpy(szDialogDirName,defPath);

  if (filter==NULL) filter=szFilter;

  ofn.lStructSize = sizeof(OPENFILENAME);
  ofn.hwndOwner = parent;
  ofn.hInstance = windows_instance();
  ofn.lpstrFilter = filter;
  ofn.lpstrCustomFilter = NULL;
  ofn.nMaxCustFilter = 0L;
  ofn.nFilterIndex = 1L;
  ofn.lpstrFile = fileName;
  ofn.nMaxFile = mlen;
  ofn.lpstrInitialDir = szDialogDirName;
  ofn.lpstrFileTitle = NULL;
  ofn.lpstrTitle = title;
  
  if(title)  ofn.nMaxFileTitle=strlen(title)+1;
  else       ofn.nMaxFileTitle=0;

  if(must_exist) ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  else           ofn.Flags=OFN_HIDEREADONLY;

  ofn.nFileOffset = 0;
  ofn.nFileExtension = 0;
  ofn.lpstrDefExt = NULL;
  ofn.lCustData = NULL;
  ofn.lpfnHook = NULL;
  ofn.lpTemplateName = NULL;
  if(saving) l = logical(GetSaveFileName(&ofn));
  else       l = logical(GetOpenFileName(&ofn));

  if(l) strncpy(ufileName,fileName,mlen);

  return l;
}

extern 'C' void __get_filtered_file(char* z_title,char* file,char* z_path, char** filter_names, char** filter_specs, int must_exist)
{
  char z_file[MAX_PATH+1];
  char file_filter[512];
  HWND parent=NULL;
  char* p=file_filter;
  int i=0;
  while(filter_names && filter_names[i])
  {
    strcpy(p,filter_names[i]);
    strcat(p,' (');
    strcat(p,filter_specs[i]);
    strcat(p,')');
    p=strend(p)+1;
    p=stpcpy(p,filter_specs[i])+1;
    i++;
  }
  *p=0;
  strcpy(z_file,file);
  logical found=get_file_name(parent, z_title, z_file, MAX_PATH+1, file_filter, z_path, logical(must_exist), logical(!must_exist));
  if(found) strcpy(file,z_file);
  else      file[0]=0;
}

int main()
{
  char file[MAX_PATH];
  char* filter_names[] = {'Bitmap files', 'All files', NULL};
  char* filter_specs[] = {'*.bmp','*.*',NULL};
  *file = 0;
  __get_filtered_file('Open File', file, 'C:\\techsupport', filter_names, filter_specs, TRUE);
  printf('%s\\n', file);
  return 0;
}
23 Jun 2012 1:51 #10408

Thanks, Paul, have you built and tested it to see if it also limits memory grabbing under w7?

K

23 Jun 2012 2:08 #10409

No I have not tested this for memory usage.

23 Jun 2012 3:57 #10410

Well, I don't really speak 'C' but I tried compiling the source using the MS 'free' express C++ builder but I can't get past these errors:

memtest1.cpp(39): error C3861: 'windows_instance': identifier not found
memtest1.cpp(40): error C2440: '=' : cannot convert from 'char *' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
memtest1.cpp(44): error C2440: '=' : cannot convert from 'char [500]' to 'LPWSTR'
1>          Types pointed to are unrelated; conversion requires memtest1.cpp(46): error C2440: '=' : cannot convert from 'char [300]' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
memtest1.cpp(48): error C2440: '=' : cannot convert from 'char *' to 'LPCWSTR'
1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
memtest1.cpp(81): error C3861: 'strend': identifier not found
memtest1.cpp(82): error C3861: 'stpcpy': identifier not found

Help!

K

23 Jun 2012 5:15 #10411

You can run the program from Plato or from a command line using the Salford compiler....

scc prog.cpp /lgo

23 Jun 2012 5:39 #10412

OK, that works, thanks. Now I need it to prompt for whether to call the file open dialogue or not, then to loop doing 'mallocs' until it fails before reporting how much allocation had succeeded? Any takers?

K

edit: with a bit of googling, I've done it, tks.

K

25 Jun 2012 6:23 #10420

Hi Paul, nearly there. I've passed on the source to an 'MS' programmer but he needs some help on two functions that he can't find:

This is the project I tried to created according to your code.

But I have some places are not clear:

windows_instance()

and

strend(p)

I'm not sure if my this demo can reproduce this issue, can you help us finished the demo and test if it can repro the same issue?

Thanks!

Mike Zhang[MSFT] MSDN Community Support

http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/a543ecf0-fe4a-4476-be7e-296989c79acb/

Can you advise, please?

K

edit: it's OK, I've managed to distill the problem down to a simple direct call to GetOpenFileName...

I'll let you know what results come up.

K

25 Jun 2012 3:26 #10424

OK, the simple C routine exhibits the same issues but with an interesting twist. The amount of malloc-able memory changes dramatically depending on the size of block being 'malloc-ed':

Blocks of 40Mb: 400MB 'lost' Blocks of 4Mb: 200Mb 'lost' Blocks of 4Kb: 100Mb 'lost'

So it looks as though using getopenfilename doesn't just put a ceiling, it must fragment memory pretty thoroughly!

Here's the simple example, with 4Kb blocks:

#include <windows.h>

#include <string.h>
#include <ctype.h>
#include <direct.h>
#include <stdio.h>
#include <stdlib.h>

#include <commdlg.h>

int main()
{
  char file[MAX_PATH], prompt[3];
  int k=0;
  OPENFILENAME ofn ;
  char* buffer;
  printf('%s\\n','Open file browser? [y/n]');
  fscanf(stdin, '%1s', prompt);
  if (!strncmp(prompt,'y',1))
  {
 	ZeroMemory( &ofn , sizeof( ofn));
	ofn.lStructSize = sizeof ( ofn );
	ofn.hwndOwner = NULL ;
	ofn.lpstrFile = file ;
	ofn.lpstrFile[0] = '\\0';
	ofn.nMaxFile = sizeof( file );
	ofn.lpstrFilter = 'All(*.*)\\0*.*\\0Text(*.txt)\\0*.TXT\\0';
	ofn.nFilterIndex =1;
	ofn.lpstrFileTitle = NULL ;
	ofn.nMaxFileTitle = 0 ;
	ofn.lpstrInitialDir=NULL ;
	ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
	GetOpenFileName( &ofn );
    printf('%s\\n', file);
  }
  do 
  {
    buffer = (char*) malloc (4*1024);
    if (buffer==NULL) break;
    k=k+1;
  }  while (k>=0) ;
  printf('%6ld MB allocated\\n',k*4/1024);
//  fscanf(stdin, '%1s', prompt);
  return k*4/1024;
} 

K

25 Jun 2012 10:57 #10433

I have got this problem with get_filterd_file first time many years ago with some new version of OS or FTN95 or processor or motherboard (do not remember exactly), may be 10-12 years ago. It totally failed, just not opening anything and freezing the program. But there was a lot of other problems with the code and FTN95 so i probably reported and ignored it, this was obvious bug but not important to me.

Then it started to work kind of OK around 5 years later. Generally i get 3-10 times file openings OK, then get i start to open file with 5 failed attempts where dialog is not showing anything, but i retry and retry several times in a row and eventually i get the dialog showing folders and files. Or if it starts to fail the opening, i just wait 10-20-30 seconds and dialog eventually appears... I am not using it due to that very often. This kind of bugs is very hard to hunt, we just need much more FTN95 users for that. Or time.

Conclusion - advertise FTN95 everywhere you can and get flurry of new features and all your bugs quickly fixed or suffer early adopters syndrome forever and your compiler eventually dead no matter how good it is.

Please login to reply.