|
Hi David,
You are right. Incorporating C code in my plugin is a big leap for me. But in this case it must be done. I've already learned alot in the process.
Many if not most of the c files have a main(argc, argv) function.
|
|
|
|
|
C and C++ have different naming schemes for function names in object code, so if you try to call a C function "normally" from C++, you'll get an unresolved-external linker error.
So to call a C function from C++, add the 'extern "C"' attribute to its declaration:
extern "C" int myCFunction (int par);
This tells C++ to use the C naming scheme for this function (underscore before the name) rather than the C++ naming scheme (decorated/mangled name).
|
|
|
|
|
|
You can only have one main function. If you need functions in the other files, comment out the extra main methods.
|
|
|
|
|
Hi Alan Thank you for your reply. I was wondering about that. Why would the other c files have a main function? I think the answer lies in the comments of a file with a main function. The coder writes:
I think each c file is a separate little program perhaps?
Tim
modified on Tuesday, April 7, 2009 5:09 PM
|
|
|
|
|
That's what the multiple main () functions would suggest. The important question is whether they have the other functions you need for your application.
|
|
|
|
|
Hi Alan,
Yes, all the basic functions are there. It is up to me to make them work in sequence.
Tim
|
|
|
|
|
In my program I write files out to the disk. When I had the files at this location ("c:\\Wells") I had no problems. Now that the files are located here: ("C:\\Program Files\\WellDB\\Wells") I get this error: "Access Denied"!
Does anyone know why?, and how to solve it?
A C++ programming language novice, but striving to learn
|
|
|
|
|
Probably just because you don't have the privileges to write a file at this location. which platform and which rights are you using ?
|
|
|
|
|
Since I am the owner and only user I would think I could. But what I need to fix is this. When the program installs it does so in the "Program Files" directory, and everything with the program is installed there also. I need to somehow be able to copy directories(a "tree") back to "c:\\" and apparantly MFC VS2008 does not have that kind of ability. I can't tell a customer,"Okay, now use exployer and copy the well directory to "C:\\"" so how do I solve this problem?
A C++ programming language novice, but striving to learn
|
|
|
|
|
I know that in Vista applications that aren't running as an administrator (default) need to be elevated before they can do anything in the C:\Program Files\ directory.. I'm not sure about XP or earlier if you're using that though. Try building a release of your app and running it as administrator and see if it works.
Hope this helps,
--Perspx
"Nowadays, security guys break the Mac every single day. Every single day, they come out with a total exploit, your machine can be taken over totally. I dare anybody to do that once a month on the Windows machine." - Bill Gates
BSoD during a Win98 presentation
|
|
|
|
|
Larry Mills Sr wrote: apparantly MFC VS2008 does not have that kind of ability.
No Larry, that is incorrect. I remember you recently explained your background to me, that this is all new stuff for you and I do not desire to insult you but that is just a ridiculous assumption. You can't expect everything to just work for you because you spent the last 10 years developing drivers or whatever it was. The reality is, you do not have that kind of ability. The only question is are you going to do the work required to learn this new environment that you appear to be working in, to gain the ability, or are you going to just expect everything to be easy and work for you and come ask someone in these forums every time something doesn't work the way you assumed it would.
Larry Mills Sr wrote: so how do I solve this problem?
That depends on information you have not provided. Windows implements special folders like "Documents and Settings" where each user can have their files maintained. That is only one of many solutions that might be appropriate if this is a desktop application which we don't know. These special folders can be accessed and used by applications using the Windows Shell API[^].
led mike
|
|
|
|
|
Sorry, but I don't see anything in the Shell API that allows me to place a directory "tree" at "c:\\".
Maybe it's there and since you presented it then I'm sure it's there, I just don't recognise it for what it is. I looked at the functions, structures, etc. and don't see a revelance to my problem. I don't realy think I should be, in some way, changing someones "settings" or even interupting them on purpose, Do you?
A C++ programming language novice, but striving to learn
|
|
|
|
|
This is why elevated privileges are required by installers.
Writing to the program files folder after installation is not
recommended.
There are special folders available - per user and common, for
storing application runtime data. An installer should create the
app's special folders with the appropriate access rights so a standard
user running the app can write to them.
As for copying a directory tree, maybe SHFileOperation()?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: There are special folders available - per user and common, for
storing application runtime data.
Yeah, I already attempted to tell him that.
led mike
|
|
|
|
|
Mark, again thanks. I'll look up the SHFileOperation() and see. the reason I need to place the root tree at "c:\\" is because my program only knows that location and it contains the complete database for the program. I tried to change the paths to Program Files\\WellDB and placed the root tree there, but the operating system wouldn't let me write to the database saying Access Denied.
I suppose I could just write a function to re-create those database directories in the root tree after the program is installed. A little sloopy, but it would work! Can you think of a better way? I have to have the databases at "c:\\"?
A C++ programming language novice, but striving to learn
|
|
|
|
|
You'll have the same problem writing to the root.
Larry Mills Sr wrote: the reason I need to place the root tree at "c:\\" is because my program only knows that location
That's why the proper method is to use the known system folders, which vary by OS.
There's API's to get these folders. The installer should create subfolders with
the appropriate permissions and that's where your app should write app data.
Installers should know about these folders just like they know about the Program Files folder.
For example, on Vista you can use SHGetKnownFolderPath() to get the following paths at runtime:
FOLDERID_RoamingAppData - per user roaming application data
FOLDERID_LocalAppData - per user local application data
FOLDERID_ProgramData - common application data
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
While I was waiting for some answers I did this. Remember you showed me about this:
if(!myFile.Open(m_csFileName, CFile::modeNoTruncate | CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyWrite | CFile::typeText, &ex))
{
TCHAR szError[1024];
ex.GetErrorMessage(szError, 1024);
AfxMessageBox(szError, MB_OK, 0);
return;
}
I have a function that creates all the directories the program uses called SetDir(); I did this:
======================================================================================================================================
CString s;
if(!myFile.Open(m_csFileName, CFile::modeNoTruncate | CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyWrite | CFile::typeText, &ex))
{
TCHAR szError[1024];
ex.GetErrorMessage(szError, 1024);
//AfxMessageBox(szError, MB_OK, 0);
// I know I'll get the PATH_NOT_FOUND error
SetDir();
s = _T("Done");
FileSaveDir(s); // s will be written to the already known filename
return;
}
=====================================================================================================================================
It creates all the directories and also creates the file. I placed this in The programs application function InitInstance() right after the call for ShowWindow(). everything works fine. Your approach is probally best, but I don't know what all that stuff is. I'll find out though!
A C++ programming language novice, but striving to learn
|
|
|
|
|
led mike wrote: Windows implements special folders like "Documents and Settings" where each user can have their files maintained. That is only one of many solutions that might be appropriate if this is a desktop application which we don't know. These special folders can be accessed and used by applications using the Windows Shell API.
I don't see anywhere in my reply where I said you can use Shell API to write to the root folder of the C drive, do you?
led mike
|
|
|
|
|
okay working with a dialog app. I have a little worker thread doing stuff and then I want to update the dialog. So here is what I am doing...
#define UWM_UPDATEGRAPH (WM_APP + 1)
//{{AFX_MSG_MAP(CVC_ExampleDlg)
...
ON_MESSAGE(UWM_UPDATEGRAPH, OnUpdateGraph)
...
//}}AFX_MSG_MAP
// I ignore both params
LRESULT CVC_ExampleDlg::OnUpdateGraph(WPARAM, LPARAM)
{...}
now to post this message I thought I wanted to write
PostMessage(UWM_UPDATEGRAPH, 0, 0);
however it is asking for an additional parameter of the HWND.
So here is my question, did I define my message wrong or do how is the best way to get the HWND
|
|
|
|
|
The first argument to PostMessage should be the handle of the window to which you want to post the message. You can retrieve it from the CDialog by calling GetSafeHwnd() on it.
|
|
|
|
|
Cedric Moonen wrote: The first argument to PostMessage should be the handle of the window to which you want to post the message. You can retrieve it from the CDialog by calling GetSafeHwnd() on it.
CDialog is derived from CWnd which has a PostMessage method with the following signature:
BOOL CWnd::PostMessage(UINT message, WPARAM wParam, LPARAM lParam)
Depending on the specifics calling Win32's ::PostMessage function may not be the best way to go about things.
Steve
|
|
|
|
|
Stephen Hewitt wrote: Depending on the specifics calling Win32's ::PostMessage function may not be the best way to go about things.
What do you mean ? If the thread runs outside the dialog class, you have to use ::PostMessage to deliver the message to the correct window. I don't see what you mean in fact, could you elaborate ?
|
|
|
|
|
He’s using MFC and wants to post a message to a CDialog derived class. If the worker thread has access to this class then he can use CDialog::PostMessage. An example:
CDialog theDialog;
void CalledFromOtherThread()
{
theDialog.PostMessage(WM_APP, 0, 0);
}
Steve
|
|
|
|
|
PostMessage function [^] takes four parameters, indeed.
I.e. did you realize the thread procedure is NOT a method (a instance one) of your dialog class?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|