|
I'm having a really hard time getting this function to properly find a file. I know I'm supposed to use the registry for app initialization info, but I've got an old app and DLL that use an INI file and I need to continue supporting it.
I'm just trying to read from a file called "api.ini" in the same directory as the application. Of course, that directory is not known at compile time. I determine the directory using GetModuleFileName() and append api.ini to the full path. Then I convert all '\' chars to '\\' since that is how the func needs it. This never works!
If I put the api.ini file in the WINNT directory, and only pass "api.ini" as the last param to GetPrivateProfileString(), it properly finds the file. If I hard code the full path ("c:\\program files\\test\\api.ini"), the function finds the file IF the application is run from a different directory (the VS 6.0 dev environment.) However, if I place the app in the c:\program files\test\ directory, then it fails and can't find the file.
Does anybody know why this is not working for me? It seems so simple...I assume I'm missing something really easy. I should be able to just pass the full path to the file and have it read properly. By the way, I have verified that the path I pass to GetPrivateProfileString() is the correct, full path.
Any help would be greatly appreciated.
|
|
|
|
|
Justin Cooke wrote:
Then I convert all '\' chars to '\\' since that is how the func needs it.
You don't need to convert \ to \\, it's only for hardcoded strings you do that.
Try ´not to, and see if it don't help...
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
Thanks for the suggestion, but it didn't seem to help. It's very odd, now that I'm not modifying the string at all (leaving the single slashes alone), I'm passing the same file path string to GetPrivateProfileString() that I pass to CStdioFIle::Open(). The file opens properly, but GetPrivateProfileString() can't find it (it returns the default value.)
Does anyone have any other ideas? Could it have something to do with the fact that this is MFC?
Thanks.
|
|
|
|
|
Have you debugged the app to see what GetModuleFileName() is returning? It should retrun a fully qualified path (i.e., the filename is included). You have to remove the filename before appending another filename.
char szBuffer[MAX_PATH] = {0};
GetModuleFileName(hInstance, szBuffer, sizeof(szBuffer)); Something like the above will give you C:\My Path\myfile.exe . You'll have to drop myfile.exe before you add the other filename or else you'll get C:\My Path\myfile.exe\api.ini .
Oh, and like it was stated, you don't need to escape the backslash unless it's a string literal (i.e., you're typing it in the code directly).
Jeremy Falcon
"so be it, threaten no more, to secure peace is to prepare for war" - Metallica
|
|
|
|
|
I think the two suggetions mentioned will work for you. That being said, I feel it is my duty to point out one thing: GetPrivateProfileString is EVIL. If you ever run on a 9X box and your INI file gets to be bigger than 64K, it will mysteriously fail, and you will spend a lot of time tracking it down.
I'd personally recommend using an INI clas (I'm sure there's one here on CP - or you can write your own), or write some simple routines to parse a text file and get the info you need.
Yes, it IS more work to do it that way, but you have more control, and aren't subject to 64K limitations.
"When a man sits with a pretty girl for an hour, it seems like a minute. But let him sit on a hot stove for a minute and it's longer than any hour. That's relativity." - Albert Einstein
|
|
|
|
|
I have an MFC app that links several libs and DLLs. Does it matter how my libs and DLLs were built, whether it is Multithreaded or Multithreaded DLL, as long as they link? I'm just not sure whether everything is totally working yet.
If my app is compiled as "multithreaded DLL", must all my DLLs and libs be compiled the same way to work properly?
In one case, UNZDLL.dll (a dll for unzipping files) doesn't seem to work right when called from a DLL at all, however it is built (I don't know how this one was built). I'm just trying to eliminate some possibilities.
Thanks!
-Aaron
|
|
|
|
|
mixing DLL and libraries compiled with different crt implementations, produces most colorful and difficult errors to diagnose. Typical error is when you create an object in one DLL and try to destroy in the other.
|
|
|
|
|
Uggghhh. Thanks for the foreboding warning. I'll find "multithreaded DLL" versions of those DLLs.
One more question: Do the CRT libs only matter for DLLs and libs that use MFC? I have several DLLs and libs that are not MFC. Do I need to find new versions of those too?
Thanks again.
-Aaron
|
|
|
|
|
It applies to all executables (or almost all). The way windows API avoid the problem is they use some other mechanism to allocate memory (like HeapAlloc, CoTaskMemAlloc) and they do not use global/static variables. You can use a dll with different crt if you absolutely sure there is no memory "exchange" and no global variables (that is why MFC dlls are especially unsafe).
P.S. c++ export dll's, by definition must be used in the same CRT environment they are compiled for.
|
|
|
|
|
How can I know when the app gets minimized?
There is no WM_ for that, or...
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
|
Try WM_SYSCOMMAND with WPARAM SC_MINIMIZE .
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Thank you both!
I never looked at WM_SIZE that well...
Rickard Andersson@Suza Computing
C# and C++ programmer from SWEDEN!
UIN: 50302279
E-Mail: nikado@pc.nu
Speciality: I love C#, ASP.NET and C++!
|
|
|
|
|
Hey, how can you make dc draw commands (like FillRect) in a dialog box? The Dialog is a child of the CDialog class. Thanks
Bob
|
|
|
|
|
Provide a handler for the WM_PAINT message.
Regards,
Alvaro
When birds fly in the right formation, they need only exert half the effort. Even in nature, teamwork results in collective laziness. -- despair.com
|
|
|
|
|
If you are just wanting to fill in the background, then you should handle the WM_ERASEBKGND message, as this still allows default handling of WM_PAINT, meaning that dialog controls will paint themselves properly.
Dave
http://www.cloudsofheaven.org
|
|
|
|
|
Hi!,
I use ODBC in a database MFC project. In My project, I already have the CClinicView, CClinicDoc and CClinicSet that represent my clinic table. I would like to add another table into my project. How can I do this?
Thanks!
Everything's beautiful if you look at it long enough...
|
|
|
|
|
You mean Multiple recordsets in an app?
To get multiple recordsets, you must create the CDatabase object first. Then you can construct as many recordsets as you want, passing a CDatabase pointer as a parameter to the CRecordset constructor. You start by embedding a CDatabase object in the document in place of the CRecordset object. You also include a pointer to the primary recordset. Here are the document data members:
CClinicSet* m_pClinicSet;
CDatabase m_database;
In your overridden CDocument::OnNewDocument function, you construct the primary recordset on the heap, passing the address of the CDatabase object to the recordset constructor. Here's the code you insert:
if (m_pClinicSet == NULL) {
m_pClinicSet = new CClinicSet(&m_database);
CString strConnect = m_pClinicSet->GetDefaultConnect();
m_database.Open(NULL, FALSE, FALSE, strConnect, FALSE);
}
In the CRecordView::OnInitialUpdate add:
m_pSet = GetDocument()->m_pClinicSet;
if(m_pSet->IsOpen())
{
m_pSet->Close();
}
m_pSet->Open();
Now you create another Class derived from CRecordset and link it with the table you want. and in the View, suppose you will load a list with this table.
in this case called CSectionSet.
void CClinicView::LoadListbox()
{
CClinicDoc* pDoc = GetDocument();
CListBox* pLB = (CListBox*) GetDlgItem(IDC_SECTIONS);
CSectionSet sect(&pDoc->m_database); // db passed via constructor
sect.m_strFilter.Format(....whatever filter you want);
sect.Open();
pLB->ResetContent();
while (!sect.IsEOF()) {
////load the ListBox
}
// sect closed by CRecordset destructor
}
I hope it works for you..
regards from Argentina!!
Daniel Cespedes Daza
"Santa Cruz de la Sierra Paraiso Terrenal!"
daniel.cespedes@ieee.org
|
|
|
|
|
Thank you so much!!!
That will help a lot...
Regards
Everything's beautiful if you look at it long enough...
|
|
|
|
|
Is there any way to purge the pending messages for a Window?
Davy
Blog for Software Testing, Bugs, Quality, Security and Stability - www.latedecember.com
News From Angus, Scotland - The Angus Blog My Personal Blog - Homepage.
|
|
|
|
|
you could call PeekMessage in a loop, passing PM_REMOVE to actuallyr remove them. This will, however, not supress WM_TIMER or WM_PAINT messages.
I don't know if "hiding away" window messages is such a good idea, though.
Italian is a beautiful language. amare means to love, and amara bitter.
sighist | Agile Programming | doxygen
|
|
|
|
|
Thanks might try it. A video window is getting some extra (user defined) stop messages for some reason. I've tried stopping them been sent but that breaks loads of things. Still the guy who knows the code should be back tomorrow
Davy
Blog for Software Testing, Bugs, Quality, Security and Stability - www.latedecember.com
News From Angus, Scotland - The Angus Blog My Personal Blog - Homepage.
|
|
|
|
|
In this case it would be better (if anything else fails) to inject your own WindowProc, and pass on only those message that are "sutable" to the original proc.
Italian is a beautiful language. amare means to love, and amara bitter.
sighist | Agile Programming | doxygen
|
|
|
|
|
I put in a handler for both functions. IF I step in, on hitting enter in my textbox, I find that if the pretranslate code is there (returning true after handling VK_RETURN and KDOWN ) the OnCommand doesnt get triggered. I am trying to figure out why but not getting the reason from MSDN. Is this behavior to be expected and if so why? I cant quite figure out what translate msg does that makes onCommnad not run.. In the onCommand I look at the wParam,lParam and IDOK)
Appreciate your help,
ns
|
|
|
|
|
>IF I step in, on hitting enter in my textbox
Are you sure that OnCommand had to be generated on this event? For examlpe, OnComand will be generate if you
click some button, but not if the button set focus
or lost using Tab key.
Pretranslate massege gets ALL messages. And
if you do all right WM_COMMAND will be prosecute or
not, how you want.
================================
Useful links
|
|
|
|