C/C++ Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
 
Go Back   Dev Articles Community ForumsProgrammingC/C++ Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Dev Articles Community Forums Sponsor:
  #1  
Old March 10th, 2006, 08:53 AM
Chesso Chesso is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2006
Posts: 24 Chesso User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 57 m 33 sec
Reputation Power: 0
Problem with GetOpenFileName buffer too small.

I have written a DLL for a Delphi application I am making and decided to have the Open/Save dialog
functionality within an external DLL instead of inside the application.

The problem is I have to hard code the buffer which makes the DLL much larger then it should be.

I have read on MSDN about this problem but it really does not help as I am not too proficient with C++ in
general as I only use it when I need it. I have found plenty of article about this issue but they only explain
how to solve it using MFC with VS. I am however using Dev-CPP enviroment.

Here is the function source:

Code:
std::string OpenSaveDialog(int Open, char* InitDir)
{
 OPENFILENAME ofn;
 char szFileName[21000] = "";
 string FData("");
    
 ZeroMemory(&ofn, sizeof(OPENFILENAME));
 ofn.lStructSize = sizeof(OPENFILENAME);
 ofn.hwndOwner = NULL;
 ofn.lpstrFile = szFileName;
 ofn.nMaxFile = 21000;
 
 switch(Open)
 {
  case 0: break;
  case 1:
    ofn.lpstrFilter = "All Supported Files\0*.mp3;*.mp2;*.wav;*.wma;*.mid;*.ogg\0";
    ofn.lpstrInitialDir = InitDir;
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT;
    
    if (GetOpenFileName(&ofn))
    {
     int len = strlen(ofn.lpstrFile);
     
     if( ofn.lpstrFile[len + 1] == 0) { return ofn.lpstrFile; } // If single file was selected.
     else {
     // This is the directory.
      FData = ofn.lpstrFile;
     
      ofn.lpstrFile += len + 1;
      while(ofn.lpstrFile[0]) {
     
     // This will contain the current file name from multiple selection.
      FData = FData + "|" + ofn.lpstrFile;      
      
      // Find next name
      len = strlen(ofn.lpstrFile);
      ofn.lpstrFile += len + 1;
      } 
       return FData;                        
     }
    }
    else { return "CANCEL"; }
  break;
  case 2: 
    ofn.lpstrFilter = "All Supported Files\0*.sm3l;*.sm3;*.m3u;*.pls\0";
    ofn.lpstrInitialDir = InitDir;
    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
    ofn.lpstrDefExt = "sm3l";
    
    if (GetOpenFileName(&ofn)) { return ofn.lpstrFile; }
    else { return "CANCEL"; }
  break;  
  case 3:
    ofn.lpstrFilter = "SM3 format\0*.sm3\0M3U Format\0*.m3u\0PLS Format\0*.pls\0";
    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
    ofn.lpstrDefExt = "sm3l";
    
    if (GetSaveFileName(&ofn)) { return ofn.lpstrFile; }
    else { return "CANCEL"; }                                   
 }
}


Does anyone know how to solve this issue? From what I read on MSDN I need some sort of callback function to resize the buffer if necessary and read something about calling it twice.....

Reply With Quote
  #2  
Old March 11th, 2006, 01:26 AM
Cirus Cirus is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Mar 2005
Posts: 276 Cirus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 11 h 48 m 58 sec
Reputation Power: 4
Quote:
Originally Posted by Chesso

The problem is I have to hard code the buffer which makes the DLL much larger then it should be.




What do you mean by this?
Quote:

Here is the function source:

Code:
std::string OpenSaveDialog(int Open, char* InitDir)
{
 OPENFILENAME ofn;
 char szFileName[21000] = "";
 string FData("");
    
 ZeroMemory(&ofn, sizeof(OPENFILENAME));
 ofn.lStructSize = sizeof(OPENFILENAME);
 ofn.hwndOwner = NULL;
 ofn.lpstrFile = szFileName;
 ofn.nMaxFile = 21000;
 
 switch(Open)
 {
  case 0: break;
  case 1:
    ofn.lpstrFilter = "All Supported Files\0*.mp3;*.mp2;*.wav;*.wma;*.mid;*.ogg\0";
    ofn.lpstrInitialDir = InitDir;
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT;
    
    if (GetOpenFileName(&ofn))
    {
     int len = strlen(ofn.lpstrFile);
     
     if( ofn.lpstrFile[len + 1] == 0) { return ofn.lpstrFile; } // If single file was selected.
     else {
     // This is the directory.
      FData = ofn.lpstrFile;
     
      ofn.lpstrFile += len + 1;
      while(ofn.lpstrFile[0]) {
     
     // This will contain the current file name from multiple selection.
      FData = FData + "|" + ofn.lpstrFile;      
      
      // Find next name
      len = strlen(ofn.lpstrFile);
      ofn.lpstrFile += len + 1;
      } 
       return FData;                        
     }
    }
    else { return "CANCEL"; }
  break;
  case 2: 
    ofn.lpstrFilter = "All Supported Files\0*.sm3l;*.sm3;*.m3u;*.pls\0";
    ofn.lpstrInitialDir = InitDir;
    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
    ofn.lpstrDefExt = "sm3l";
    
    if (GetOpenFileName(&ofn)) { return ofn.lpstrFile; }
    else { return "CANCEL"; }
  break;  
  case 3:
    ofn.lpstrFilter = "SM3 format\0*.sm3\0M3U Format\0*.m3u\0PLS Format\0*.pls\0";
    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
    ofn.lpstrDefExt = "sm3l";
    
    if (GetSaveFileName(&ofn)) { return ofn.lpstrFile; }
    else { return "CANCEL"; }                                   
 }
}


Does anyone know how to solve this issue? From what I read on MSDN I need some sort of callback function to resize the buffer if necessary and read something about calling it twice.....



Are you facing trouble in case 1 that is when you are allowing for MULTISELECT?

If its so then i think it is becuase you areselecting too many files such that there combined string length size exceeds ofn.maxfileSize.

Moreover , is file name a TCHAR? or WCHAR becuse they use double space per character .Hence if you choose a few files or if your code runs in a loop without freeing buffer, memory limits is broken by your code.

I do not know the exact solution but one way is to reallocate buffer size using realloc.

It will help me if you give me a pointer of MSDN page from where you have read the solution.

Reply With Quote
  #3  
Old March 11th, 2006, 02:01 AM
Chesso Chesso is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2006
Posts: 24 Chesso User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 57 m 33 sec
Reputation Power: 0
Yes because of the multi selection, as you see the maxfile and the lpstrfile is hard codec at 21000 characters in length.

I'm sorry I couldn't find the MSDN article but here is one at CodeProject explaning the problem and how to solve it but using MFC:

http://www.codeproject.com/dialog/pja_multiselect.asp?df=100&forumid=13589&exp=0&select=904139

Reply With Quote
  #4  
Old March 11th, 2006, 02:16 AM
Cirus Cirus is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Mar 2005
Posts: 276 Cirus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 11 h 48 m 58 sec
Reputation Power: 4
Quote:
Originally Posted by Chesso
Yes because of the multi selection, as you see the maxfile and the lpstrfile is hard codec at 21000 characters in length.

I'm sorry I couldn't find the MSDN article but here is one at CodeProject explaning the problem and how to solve it but using MFC:

http://www.codeproject.com/dialog/pja_multiselect.asp?df=100&forumid=13589&exp=0&select=904139


From my experience, I once faced same problem when implementing list in MFC and updating it.
For this instead of hard coding I initially malloced ( allocated memory) .Then I put a check that if total string length size exceeds a limit, use realloc() such that a new limit is set.

then after the process is done, free memory from the buffer.

Reply With Quote
  #5  
Old March 11th, 2006, 03:18 AM
Chesso Chesso is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2006
Posts: 24 Chesso User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 57 m 33 sec
Reputation Power: 0
But the whole error checking thing doesn't happen until the OPEN button is pressed and it instead returns that CANCEL was pressed.

Which means it's a little too late as I would have to re open it again, I think.....

Reply With Quote
  #6  
Old March 11th, 2006, 05:57 PM
Cirus Cirus is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Mar 2005
Posts: 276 Cirus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 11 h 48 m 58 sec
Reputation Power: 4
Quote:
Originally Posted by Chesso
But the whole error checking thing doesn't happen until the OPEN button is pressed and it instead returns that CANCEL was pressed.

Which means it's a little too late as I would have to re open it again, I think.....


Okay.For that put a breakpoint at the statement where you are hard coding.When you press "Open" that is when you get a CommadDialogBox, select multiple files and then press ok. Your debugger will come to a point where your " ofn " structure gets filled. At that point check the size of the file size string( remember, the string contans comma seperated file names) .

I actally tried to give a solution where you dynamically allocate buffer and change according to the byte size of the string you get.

just check the sizes of string and hardcoded size.

Tell me the result.

Reply With Quote
  #7  
Old March 11th, 2006, 09:07 PM
Chesso Chesso is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2006
Posts: 24 Chesso User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 57 m 33 sec
Reputation Power: 0
But checking lpstrFile wouldn't make a difference, it's a set size and will already be filled. It's the dialog box's "FileName" field I need to check isn't it?

I don't mind hard coding it but both of those declarations set to 21000 characters makes my DLL larger for some reason... Even If say I set szFileName to 21000 and nMaxFile to szFileName I still get extra bloat as if I had set nMaxFile to 21000 as well.

Reply With Quote
  #8  
Old March 13th, 2006, 06:58 PM
Cirus Cirus is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Mar 2005
Posts: 276 Cirus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 11 h 48 m 58 sec
Reputation Power: 4
Quote:
Originally Posted by Chesso
But checking lpstrFile wouldn't make a difference, it's a set size and will already be filled. It's the dialog box's "FileName" field I need to check isn't it?

I don't mind hard coding it but both of those declarations set to 21000 characters makes my DLL larger for some reason... Even If say I set szFileName to 21000 and nMaxFile to szFileName I still get extra bloat as if I had set nMaxFile to 21000 as well.


Yes you have to check the Dialog's Box filename. i.e the string you get from the Dialog Box and then resize the lpstrFile ' s buffer accordingly.

Initially you have to mention some buffer length for ofn.lpstrFile in order to start filling it. Set a minumum size say assign 100 bytes or this , then after checking the size of string in bytes obtained from Dialog Box, resize the buffer accordingly.

This will reduce your DLL's size.

Reply With Quote
  #9  
Old March 13th, 2006, 07:21 PM
Chesso Chesso is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2006
Posts: 24 Chesso User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 57 m 33 sec
Reputation Power: 0
Ahh I see, thanks for your help.

Reply With Quote
  #10  
Old March 14th, 2006, 09:51 AM
Cirus Cirus is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Mar 2005
Posts: 276 Cirus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 11 h 48 m 58 sec
Reputation Power: 4
Welcome.

Reply With Quote
Reply

Viewing: Dev Articles Community ForumsProgrammingC/C++ Help > Problem with GetOpenFileName buffer too small.


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway
Stay green...Green IT