15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Changing App's INI filename in MFC 4.2

Marion Nalepa -- mnalepa@rust.net
Sunday, December 08, 1996

Environment: VC++ 4.2b, Win 95

I am converting a 16-bit system to 32-bit. The existing system contains
several MFC modules that all share a system-wide INI file. In order to
do this, the apps change their CWinApp's m_pszProfileName by doing a:

   m_pszProfileName = "GLOBALNAME.INI" ;

in the CWinApp constructor. Then all references are to this global INI
file when the application does a CWinApp::ReadProfileString.

The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
variable is changed so that re-assigning it causes a free to fail in 
the MFC Code.

So, my question is -- if this is not the way to do this (obviously) then
how does one go about using a name other than APPNAME.INI?

Oh, and yes, I know that this should all be using Registry entries in the
32-bit world, but the system has numerous modules and not all are being
converted to 32-bit yet. So the INI files have to stick around a while
longer. There are also some that like the ease of editing that having
ASCII files gives you.

Thanks for any help...

Marion Nalepa
mnalepa@rust.net



sja@gte.net
Tuesday, December 10, 1996

[Mini-digest: 10 responses]

Environment: VC++ 4.2b, Win 95

>I am converting a 16-bit system to 32-bit. The existing system contains
>several MFC modules that all share a system-wide INI file. In order to
>do this, the apps change their CWinApp's m_pszProfileName by doing a:
>
>   m_pszProfileName = "GLOBALNAME.INI" ;
>
>in the CWinApp constructor. Then all references are to this global INI
>file when the application does a CWinApp::ReadProfileString.
>
>The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
>variable is changed so that re-assigning it causes a free to fail in 
>the MFC Code.
>
>So, my question is -- if this is not the way to do this (obviously) then
>how does one go about using a name other than APPNAME.INI?
>

	Here's one way. I use this code to establish a local .INI profile. Note 
the ExitInstance code that restores the saved value of m_pszProfileName:

BOOL CMyApp::InitInstance()
{
	// set-up profile path to point to local .ini file...
	TCHAR szBuff[_MAX_PATH];
	TCHAR drive[_MAX_DRIVE];
	TCHAR dir[_MAX_DIR];
	TCHAR fname[_MAX_FNAME];
	TCHAR ext[_MAX_EXT];
	VERIFY(::GetModuleFileName(AfxGetInstanceHandle(), szBuff, _MAX_PATH));
	_splitpath(szBuff, drive, dir, fname, ext);
	strcpy(ext, "ini");
	_makepath(m_pszProfile, drive, dir, fname, ext);

	// save pointer to profile name str for exiting...
	m_pszSaveProfileName = (TCHAR *)m_pszProfileName;

	m_pszProfileName = m_pszProfile;

snip.. snip.. deleted other code for clarity

	return TRUE;
}

int CMyApp::ExitInstance() 
{
	// restore pointer to profile name string so wincore.cpp can free it!
	m_pszProfileName = m_pszSaveProfileName;
	
	return CWinApp::ExitInstance();
}

Steven J. Ackerman, Consultant
ACS, Sarasota, FL
sja@gte.net
http://www.acscontrol.com

-----From: "Dean Wiles" 

This seems to have changed a few times in different versions of MFC, but
the last thing I used that seemed to work correctly was to free any
existing profile name and alloc a new one:

	if (m_pszProfileName != NULL)
		free((void*)m_pszProfileName);
	m_pszProfileName = _tcsdup(_T("GLOBALNAME.INI"));

--------------------------------------------------------------------------
Dean Wiles (deanw@mail.isc-br.com)          Olivetti North America
Phone:  (509)927-7037                       22425 East Appleway Ave
Fax:    (509)927-2499                       Liberty Lake, WA 99019-9534
If the Son sets you free, you will be free indeed.  (John 8:36)


----------
> From: Marion Nalepa 
> To: mfc-l@netcom.com
> Subject: Changing App's INI filename in MFC 4.2
> Date: Sunday, December 08, 1996 8:28 PM
> 
> Environment: VC++ 4.2b, Win 95
> 
> I am converting a 16-bit system to 32-bit. The existing system contains
> several MFC modules that all share a system-wide INI file. In order to
> do this, the apps change their CWinApp's m_pszProfileName by doing a:
> 
>    m_pszProfileName = "GLOBALNAME.INI" ;
> 
> in the CWinApp constructor. Then all references are to this global INI
> file when the application does a CWinApp::ReadProfileString.
> 
> The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
> variable is changed so that re-assigning it causes a free to fail in 
> the MFC Code.
> 
> So, my question is -- if this is not the way to do this (obviously)
then
> how does one go about using a name other than APPNAME.INI?
> 
> Oh, and yes, I know that this should all be using Registry entries in the
> 32-bit world, but the system has numerous modules and not all are being
> converted to 32-bit yet. So the INI files have to stick around a while
> longer. There are also some that like the ease of editing that having
> ASCII files gives you.
> 
> Thanks for any help...
> 
> Marion Nalepa
> mnalepa@rust.net
-----From: "Smith, Brad P. (Exchange)" 

Thing is, m_pszProfileName is not a CString anymore, but an LPSTR. So
you can't just go assigning contents to it. I'm guessing the change was
made for performance (CString has overhead), or maybe it's some
multi-threaded thing. :-)

The trick in a situation like this is to scan through the MFC source and
see what *they* do. If you do that, you'll find code like 
	m_pszProfileName = _tcsdup(szExeName);
in APPINIT.CPP (CWinApp::SetCurrentHandles()). _tcsdup() takes an
existing string, allocates a memory block to hold a copy of the
contents, and then assigns the pointer.

In *your* code, you'd do something like:
	if( NULL != m_pszProfileName )
		free((void*)m_pszProfileName)
	m_pszProfileName = _tcsdup( szNewName );
in your CWinApp-derived InitInstance.

Hope this helps;
Brad.
-----From: "Frank Clark" 


Environment: VC++ 4.2b, Win 95

I am converting a 16-bit system to 32-bit. The existing system contains
several MFC modules that all share a system-wide INI file. In order to
do this, the apps change their CWinApp's m_pszProfileName by doing a:

   m_pszProfileName = "GLOBALNAME.INI" ;

in the CWinApp constructor. Then all references are to this global INI
file when the application does a CWinApp::ReadProfileString.

The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
variable is changed so that re-assigning it causes a free to fail in 
the MFC Code.

So, my question is -- if this is not the way to do this (obviously) then
how does one go about using a name other than APPNAME.INI?

Yes, this broke in our code when we went from 4.1 to 4.2.  The following 
works:

	if(m_pszAppName) free((void *)m_pszAppName);
	m_pszAppName = new char[strlen(szSpecialAppName)+1];
	strcpy((char *)m_pszAppName, szSpecialAppName);  

Frank Clark
-----From: Mike Blaszczak 

At 23:28 12/8/96 -0500, Marion Nalepa wrote:
>Environment: VC++ 4.2b, Win 95

>The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
>variable is changed so that re-assigning it causes a free to fail in 
>the MFC Code.
>
>So, my question is -- if this is not the way to do this (obviously) then
>how does one go about using a name other than APPNAME.INI?

m_pszProfileName = strdup("GLOBALNAME.INI");

.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.

-----From: "Kenneth A. Argo" 

If you look into the source code for MFC you will find your answers.  VC =
4.2 uses a different method for allocating the memory space for storing =
the variables managed in CWinApp, as you now know.  There are 2 ways to =
force an app to use a particular INI file.  The 1st is to set the app =
name, which is now a parameter to the CWinApp constructor.   The second =
is to set the m_pszProfileName.  To take a code snippit from the CWinApp =
source:

	free((void*)m_pszProfileName);
	m_pszProfileName =3D _tcsdup(m_pszAppName);

Free the old, and assign the new.  _ tcsdup duplicates a string, =
allocating new space.  All you need to do is give it the string, in this =
case your INI file.


Ken

=20

----------
From:  Marion Nalepa[SMTP:mnalepa@rust.net]
Sent:  Sunday, December 08, 1996 11:28 PM
To:  mfc-l@netcom.com
Subject:  Changing App's INI filename in MFC 4.2

Environment: VC++ 4.2b, Win 95

I am converting a 16-bit system to 32-bit. The existing system contains
several MFC modules that all share a system-wide INI file. In order to
do this, the apps change their CWinApp's m_pszProfileName by doing a:

   m_pszProfileName =3D "GLOBALNAME.INI" ;

in the CWinApp constructor. Then all references are to this global INI
file when the application does a CWinApp::ReadProfileString.

The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
variable is changed so that re-assigning it causes a free to fail in=20
the MFC Code.

So, my question is -- if this is not the way to do this (obviously) =
then
how does one go about using a name other than APPNAME.INI?

Oh, and yes, I know that this should all be using Registry entries in =
the
32-bit world, but the system has numerous modules and not all are being
converted to 32-bit yet. So the INI files have to stick around a while
longer. There are also some that like the ease of editing that having
ASCII files gives you.

Thanks for any help...

Marion Nalepa
mnalepa@rust.net

-----From: "Daniel Munoz" 

Environment: VC++ 4.2, Win 95, NT 3.51, NT 4.00

Hi Marion, 

in your InitInstance(), after the SetRegistryKey ("...") call, add:

free((void*)m_pszProfileName);
m_pszProfileName = _tcsdup("MyNewName");

Maybe there's a cleanest way...!?
But this one work !

Daniel Munoz
dmunoz@socabim.fr

-----From: "Doug Brubacher" 

     Marion,
     
     There is nothing stopping you from using the API calls
     GetPrivateProfileInt, GetPrivateProfileString, and 
     WritePrivateProfileString.  These calls take a few additional 
     parameters including the INI file name. They are probably the easiest 
     way to accomplish your goal.
     
     Regards
     
     Doug Brubacher
     DouglasB@msn.com

-----From: bliu@campbellsoft.com

     This is a bug in MFC 4.2.
     
     The same thing happens to other strings memeber in CWinApp.
     See docuement about CWinApp::m_pszHelpFilePath. You can assign a 
     constant string to this member, and CWinApp::~CWinApp() will free it 
     no matter what. In CWinApp::SetCurrentHandles(), it will check to see 
     if those pointers are NULL, if they are , it will allocate space for 
     them.
     
     In your case, when you set m_pszProfileName = "GLOBALNAME.INI",
     there is no space allocate cause the fail at the CWinApp::~CWinApp().
     
     You can do m_pszProfileName = _tcsdup("GLOBALNAME.INI"), then you will 
     be OK.


______________________________ Reply Separator _________________________________
Subject: Changing App's INI filename in MFC 4.2
Author:  mfc-l@netcom.com at Internet
Date:    12/08/1996 11:28 PM


Environment: VC++ 4.2b, Win 95
     
I am converting a 16-bit system to 32-bit. The existing system contains 
several MFC modules that all share a system-wide INI file. In order to 
do this, the apps change their CWinApp's m_pszProfileName by doing a:
     
   m_pszProfileName = "GLOBALNAME.INI" ;
     
in the CWinApp constructor. Then all references are to this global INI 
file when the application does a CWinApp::ReadProfileString.
     
The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName 
variable is changed so that re-assigning it causes a free to fail in 
the MFC Code.
     
So, my question is -- if this is not the way to do this (obviously) then 
how does one go about using a name other than APPNAME.INI?
     
Oh, and yes, I know that this should all be using Registry entries in the 
32-bit world, but the system has numerous modules and not all are being 
converted to 32-bit yet. So the INI files have to stick around a while 
longer. There are also some that like the ease of editing that having 
ASCII files gives you.
     
Thanks for any help...
     
Marion Nalepa
mnalepa@rust.net
-----From: "Brad Wilson" 

> The problem is that in MSVC++ 4.2, the handling of the m_pszProfileName
> variable is changed so that re-assigning it causes a free to fail in 
> the MFC Code.

Memory is auto-cleaned up on exit ... in your ExitInstance(), set
m_pszProfileName to NULL and let the memory system catch the dangling
memory block (from the original copy) on exit.

--
Brad Wilson                       Custom software development & solutions
crucial@pobox.com               Internet and intranet consulting services
The Brads' Consulting          Windows NT/Windows 95 software development
http://www.thebrads.com    Web site planning, development and maintenance
   Content (C) 1996 Brad Wilson; no reproduction without authorization




Mike Blaszczak -- mikeblas@nwlink.com
Friday, December 13, 1996

[Moderator's note: Let's let this be the last word on this subject.]

At 16:23 12/10/96 -0600, sja@gte.net wrote:

>Environment: VC++ 4.2b, Win 95
>>I am converting a 16-bit system to 32-bit. The existing system contains
>>several MFC modules that all share a system-wide INI file. In order to
>>do this, the apps change their CWinApp's m_pszProfileName by doing a:
>>
>>   m_pszProfileName = "GLOBALNAME.INI" ;
>>
>>in the CWinApp constructor. Then all references are to this global INI
>>file when the application does a CWinApp::ReadProfileString.

>-----From: bliu@campbellsoft.com
>
>     This is a bug in MFC 4.2.

No, it isn't.  It's completely by-design.  It won't be "fixed": it's
not a bug.

>-----From: "Brad Wilson" 

>Memory is auto-cleaned up on exit ... 

That depends on what operating system you're using.  In Win32s, it isn't.
Your suggestion will cause irrecoverable memory leaks under Win32s, and
shouldn't be followed by anyone using that platform.



.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.





| Вернуться в корень Архива |