|
I made a few futile attempts to get CMap working ... Basically, I need:
Key CString
Value CString
What I did... after readingthis articlewas:
1. Declaration:
CMap<cstring, lpctstr,="" cstring,="" lpctstr=""> m_Result;
2. Adding elements/association:
CString sKey;
CString sVal;
m_Result.SetAt((LPCTSTR) &sKey, (LPCTSTR) &sVal);
3. *trying to* access elements
CString csVal;
I tried:
csVal = m_Result[(LPCTSTR) &csKey];
I also tried:
bSuccess = m_Result.Lookup(csKey, csVal);
The problem is, csVal always returns "nothing" (i.e. an empty/blank string)...
4. I've already implemented HashKey
<br />
inline UINT AFXAPI HashKey(const CString& str)<br />
{<br />
...<br />
<br />
return nHash;
}<br />
<br />
<br />
inline UINT AFXAPI HashKey(CString& str)<br />
{<br />
...<br />
<br />
return nHash;
}<br />
MSDN
REF 1 CMap Lookup[^] REF 2 CMap[^]
REF 3 Sample download MFC Collection classes[^]
Code Project
humm... [^]
-- modified at 20:52 Friday 29th December, 2006
Norman Fung
|
|
|
|
|
I would declare a data stucture to hold the two CStrings if you can.
struct MyStrMapStruct {
CString String1;
CString String2;
};
Use the CMapStringToPtr to map the 'key' STRING to a pointer to this data structure.
Then use returned pointer to get the secondary 'value' string.
If you want to hash the first string, watch out for collisions on any add, but then you could use
CMapWordToPtr and then just double check that your source string matches String1 and if so, then use contents of String2.
If not, then have the data structure store pointers to the two CString objects.
|
|
|
|
|
Does anyone have specific code examples of how to detect and retrieve a Users CD Rom drive?
I am writting an "Install" program using VS 6.0 and MFC and I need to be able to locate which drive pathway the User has the "Install" CD in - automatically; without User response.
Code examples please!
A C++ programming language novice, but striving to learn
|
|
|
|
|
You can figure out which drive(s) are CDROM drives using the GetDriveType function:
for (char d='C';d<'Z';d++)
{
CString drive = CString(d)+":\\";
UINT driveType = GetDriveType(drive.GetBuffer(0));
if (driveType == DRIVE_CDROM)
{
//If we make it to here, then drive is a CD-ROM drive.
//Just in case the user has more than one CD-ROM drive,
//You may want to test to see if a specific file (unique to your CD) exists
//on this drive.
}
}
Just curious, why bother writing a home brew installation program when there are a lot of good freeware installation building tools such as InnoSetup or Advanced Installer? You can google to find either of these tools.
|
|
|
|
|
The simplest way to find out 'where' an application is running from is to use the GetModuleFileName [^] function as follows:
char EXE[_MAX_PATH];
GetModuleFileName(NULL,EXE,_MAX_PATH);
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
char path[_MAX_PATH];
_splitpath(EXE,drive,dir,fname,ext);
_makepath(path,drive,dir,"",""); The path string now contains the directory path from which the current program was started.
Software Zen: delete this;
|
|
|
|
|
Is there a way to tell which process last wrote to a file? I can't see anything in the .NET File class or the FileAttributes enum which you get back from the File.GetAttributes call or the Win32 API either.
My program is reading a log file which gets written to by multiple processes. Each process opens the log file, writes to it and closes it. I would like to know which process last wrote to it.
Any ideas?
Thanks,
-Darryl
|
|
|
|
|
I would have thought it was easier for each process to tag the entry/entries in the log file with a moniker unique to that process - I guess it depends on the lifetime of the process as to what you're doing with the information
I dont think there's an 'easy' way of looking at a file and saying 'who last wrote to it' from an o/s point of view
- I think you can :-
enumerate active processes
for each process, see what file(s) its using
or maybe use a hook and detect when a particular file (the log file) is opened, then raise an event
or use a filesystem watcher to raise an event when the log file is modified, but Im not sure if that gives you the process details
but thats a lot of overhead isnt it ?
if anyone else knows how to solve this I'd love to see the answer myself
'g'
|
|
|
|
|
Garth J Lancaster wrote: I would have thought it was easier for each process to tag the entry/entries in the log file with a moniker unique to that process - I guess it depends on the lifetime of the process as to what you're doing with the information
Unfortunatley I don't think this can be done in my case.
Garth J Lancaster wrote:
or use a filesystem watcher to raise an event when the log file is modified, but Im not sure if that gives you the process details
FileSystemWatcher is what I am using now. In the Changed event handler I don't seem to have access to any process information. I get only the change type (Changed, Created, Deleted, or Renamed) and the file name and directory name.
Since the file is opened only a very brief time while 1 line is written to it I'm not sure if I will be able to hook off of processes opening files but that may be a possibility.
Thanks for your advice and maybe someone else has other insights as well?
Darryl
|
|
|
|
|
Identify the writer process in log file with an additional field.
The file attributes alone do not keep track of the last process, only timestamps. Neither ReadDirectoryChangesW and FILE_NOTIFY_INFORMATION can offer a PID, at least (even if PIDs are reusable so you can't "make a guess" based on a PID value alone).
The closest thing could be the USN_RECORD structure, but that implies you are on a filesystem with journaling of some sort, although I can't see process-related data either in journaling structures.
So, AFAIK, the process should write additional info themselves in the log file.
|
|
|
|
|
Thanks for your help Cristian. This is pretty much what I expected but I hoped I was missing something. Unfortunatly the code writing to the file is out of my control but maybe I can get them to make changes for the next version.
Darryl
|
|
|
|
|
|
Filemonitor does not offer process identification, just file events (but not source).
|
|
|
|
|
|
Do you want to show a dialog that you created(Create) if yes use of ShowWindow
|
|
|
|
|
If you want it modal you can always use DoModal(); .
If you want it to be non modal, then you must create that dialog and then show it using ShowWindow();
Hope this helps.
|
|
|
|
|
How can be tested - in VC++6 that a driver is installed or not? We know the driver name.
36. When you surround an army, leave an outlet free.
...
Do not press a desperate foe too hard.
SUN-TZU - Art of War
|
|
|
|
|
How about starting with:
EnumDeviceDrivers(aDrivers, sizeof(aDrivers), &cbNeeded)
(SDK)
and test if the driver is in the list?
You could get additional infos with
GetDeviceDriverBaseName(aDrivers[i], szBaseName,sizeof(szBaseName))
and
GetDeviceDriverFileName(aDrivers[i], szDriverFileName,sizeof(szDriverFileName))
greetings,
ralf.
|
|
|
|
|
Thanks!
=======================================================================
36. When you surround an army, leave an outlet free.
...
Do not press a desperate foe too hard.
SUN-TZU - Art of War
|
|
|
|
|
Sorry, I've not been able to place here a better title...
Hello all,
A strange thing that deserves a code sample and somebody that know what could happen... (this is not me).
BOOL CTCC::InitInstance()
{
m_pLogAE = new A;
m_pXmlAEInternal = new B;
m_pXmlConfig = new C;
if (!FunctionX() ||
!m_pControl->FunctionY() ||
!m_pXmlFile->LoadFile(csPath, csReason))
{
DoSomething();
}
else
{
CTCCDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
m_pControl->RestoreSettings();
if(m_pLogAE) delete m_pLogAE;
if(m_pXmlAEInternal) delete m_pXmlAEInternal;
if(m_pXmlConfig) delete m_pXmlConfig;
}
if(m_pLogAE) delete m_pLogAE;
if(m_pXmlAEInternal) delete m_pXmlAEInternal;
if(m_pXmlConfig) delete m_pXmlConfig;
return FALSE;
As you can see there is a terrible design: I've repeated some code: after the POINT 1 there are three lines that should be only after the POINT 2 as they are intended to clear some memory that has been filled before the first if clause.
It surprises me a lot, but if I place a breakpoint in the line where POINT 1 is, I can see how the application continues until the bracket that is before POINT 2 "}". If I remove the code that is before that bracket and after POINT 1, and execute again the code I can see how if the code reach that bracket it gets stopped again and don't go further the POINT 2.
Any idea?
Thank you in advance.
PS: I've made a "Clean" and a "Rebuild All".
|
|
|
|
|
The 3 if/delete statements below POINT 1 are not necessary. Other than that, I'm not sure what you are asking.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
this is exactly what I mean, the code cannot reach those three second if/delete statements, and I cannot get any idea about what is happening here.
Of course I didn't had the first ones there, in that way that was general and was being used independent from the previous condition, but I've been forced to do that, it is impossible to reach that code.
|
|
|
|
|
Try this as a test:
BOOL CTCC::InitInstance()
{
m_pLogAE = new A;
m_pXmlAEInternal = new B;
m_pXmlConfig = new C;
CTCCDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
if(m_pLogAE) delete m_pLogAE;
if(m_pXmlAEInternal) delete m_pXmlAEInternal;
if(m_pXmlConfig) delete m_pXmlConfig;
return FALSE;
} If this works, put the call to RestoreSettings() back in.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Ok, done, but it continues making the same.
In fact, when I press F10 in order to continue executing the next instruction, everything is correct but when I reach the bracket "}" and then I press F10 again then I get the application finished suddenly. (Even if I try to use F11)...
|
|
|
|
|
Joan Murt wrote: ...when I reach the bracket "}" and then I press F10 again then I get the application finished suddenly.
This makes no sense, other than this is what should be happening. In the code snippet I provided, there is only one closing curly brace. Once code execution reaches that point, your program is effectively done.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
yes in your code snippet, but not in mine, there you can see how there is a previous condition (if) that must not be accomlpished in order to be able to make that main dialog appear. Once this has been reached, I had the if/delete clauses general (outside that condition) in order to clear all the memory in the two situations.
so:
InitInstance
{
if (A)
{
}
else
{
dlg.DoModal();
<code><big> }</big></code>
if/delete clauses
return FALSE;
}
If I place the if/delete clauses before the bold closing curly brace then I can see how the program goes through it.
If I place that code after that bold closing curly brace it cannot be reached.
I know that this is very strange... but it happens to me.
|
|
|
|