|
how about using _splitpath
cheers
kannan
|
|
|
|
|
"GetCurrentDirectory" will return you the directory that the current process is running in (fairly obvious from the name, really!!). If you create a desktop shortcut this is the "Start In" entry (at least, that's what it's called under 2000 - I can't remember if NT/95/etc use the exact same terminology).
"GetModuleFileName" will return you the path of the file that the specified module (such as a DLL) was loaded into memeory from. If you pass NULL as the first parameter you get the path of the current process module. You may need to process the returned value from "GetModuleFileName" to extract exactly what you want (path only, filename only, etc) - it's been a while since I did anything like this, so I'm not sure!
|
|
|
|
|
But if you call to GetCurrentDirectory when the application start you can get the directory. But dependes the application. If the App is runing like NT service the currentdirectory will be System32
Cheers!!!
Carlos Antollini.
|
|
|
|
|
Here's a crap-load of filename code I use a lot. The function you're interested in is at the bottom, and it relies on one or two of the other functions. You didn't specify, but I assume you're using VC++ and MFC.
Here's the header file (FILENAME.H) :
#ifndef __FILENAME_H
#define __FILENAME_H
CString justFileName(LPCSTR);
CString justName(LPCSTR);
CString justExtention(LPCSTR);
CString justPath(LPCSTR);
CString justDrive(LPCSTR);
CString forceExtention(CString fn, CString newext);
CString forceFileName(CString fn, CString newname);
CString forcePath(CString fn, CString newpath);
BOOL FileExists(CString fn);
int DeleteFile(CString fname);
int RenameFile(CString oldname, CString newname);
void AddBackSlash(CString& path);
CString RemoveBackSlash(CString path);
CString GetProgramPath(BOOL bAndExeName=FALSE);
#endif
And here's the CPP file (FILENAME.CPP) :
#include "stdafx.h"
#include "filename.h"
#include <io.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString justFileName(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f, drive, dir, file, ext);
st = file;
st += ext;
return st;
}
CString justName(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f, drive, dir, file, ext);
st = file;
return st;
}
CString justPath(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f, drive, dir, file, ext);
st = drive;
st += dir;
return st;
}
CString justExtention(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f,drive,dir,file,ext);
st = ext;
return st;
}
CString forceExtention(CString fn, CString newext)
{
CString st = justPath(fn);
st += justName(fn);
st += newext;
return st;
}
CString forceFileName(CString fn, CString newname)
{
CString st = justPath(fn);
st += newname;
st += justExtention(fn);
return st;
}
CString forcePath(CString fn, CString newpath)
{
CString st = newpath;
AddBackSlash(st);
st += justFileName(fn);
return st;
}
BOOL FileExists(CString fn)
{
BOOL exists = FALSE;
if (!fn.IsEmpty())
{
int status = _access(fn,0);
if (status == 0)
exists = TRUE;
}
return exists;
}
int RenameFile(CString oldname, CString newname)
{
int status = 0;
BOOL oldexists = FileExists(oldname);
BOOL newexists = FileExists(newname);
if (oldexists && !newexists)
CFile::Rename(oldname, newname);
else
status = -1;
return status;
}
int DeleteFile(CString fname)
{
int status = 0;
if (FileExists(fname))
CFile::Remove(fname);
else
status = -1;
return status;
}
void AddBackSlash(CString& path)
{
int length = path.GetLength();
if (length > 1)
{
if (path.GetAt(length - 1) != '\\')
{
path += "\\";
}
}
else if (1 == length)
{
CString temp = path;
temp.MakeUpper();
TCHAR ch = temp.GetAt(0);
if (ch >= 'A' && ch <= 'Z')
{
path += ":\\";
}
else if (ch != '\\')
{
path += "\\";
}
}
else
{
path += "\\";
}
}
CString RemoveBackSlash(CString path)
{
if (path.Find('\\') == 0)
return path;
int len = path.GetLength();
path = path.Left(len - 1);
return path;
}
CString GetProgramPath(BOOL bAndExeName)
{
TCHAR szFullPath[MAX_PATH];
::GetModuleFileName(NULL, szFullPath, MAX_PATH);
CString path = szFullPath;
if (!bAndExeName)
{
path = justPath(path);
AddBackSlash(path);
}
return path;
}
|
|
|
|
|
Thanks for all the input. Just to let you all know, GetCurrentDirectory() doesn't cut it, your current working directory seems to have nothing to do with your exe path. Anyway, the easiest way I found is shown below.
CString File;
GetModuleFileName(NULL, File.GetBuffer(MAX_PATH), MAX_PATH);
File.ReleaseBuffer(File.ReverseFind('\\') + 1);
If the exe path was say... "c:\my documents\code\program\app.exe", the File CString is "c:\my documents\code\program\"
RE: John Simmons / outlaw programmer (or anyone else who knows how to...)
How do you get your code to show up like that on a message? (With the yellow background, and formatting in-tact)
THANKS!
John
|
|
|
|
|
Is it possible to simulate a carriage return in VC++? Basically I’m trying to have my application "push the enter key" on a specified event.
Thanks in advance for your help!
Rob
|
|
|
|
|
Do you want to add a carriage return to a text box, push OK, or what ?
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
Try
this->PostMessage(WM_OK);
Or if you want to SEE the click, your going to have get Spy++ out
and capture all the WM_COMMAND message & parameters and figure out
which one(s) to Post/Send to the window.
Julien.
|
|
|
|
|
To simulate a carriage return all you need to do is called CWnd::GetWindowText() giving the CString obj you want to fill. Next you append the "\n" (Newline Character in C/C++) to the end of the CString obj using the "+=" operator. Lastly, you use CWnd::SetWindowText().
This is for MFC only.
Check MSDN on how to use CWnd::GetWindowText(), the "+=" operator, and CWnd::SetWindowText().
|
|
|
|
|
Can anyone tell me how to convert a:
BYTE *btArray ==> CStringArray
I would really appreciate it.
Thanks in advance,
Dan
|
|
|
|
|
Hmm. I believe you need to convert it to a CString, not to a CStringArray.
CString is a string class (like the STL 'string'), while CStringArray is an array of strings (like an STL 'vector<string>').
I guess btArray is a pointer to an array of characters (a 'C' string).
To convert it to a CString, this should be enough:
CString s = btArray;
CStringArray can hold many CStrings, and it resizes dynamically.
You can, for example: CStringArray sa; sa.Add(s); sa.Add("Hello");
After this, sa[0] is a CString and you can do:
sa[0] = "SomeString";
printf("My String is: %s\n", (LPCTSTR)sa[0]);
Hope this helps,
Pavlos
|
|
|
|
|
Doesn't work...I get:
const CString& CString::operator=(LPCTSTR lpsz)
{
ASSERT(lpsz == NULL || AfxIsValidString(lpsz)); <=========== Error is here!
AssignCopy(SafeStrlen(lpsz), lpsz);
return *this;
}
HERE is an example of the code:
//BYTE btArr[3] = {67,245,67}; <========= I can see this!
BYTE *btArr = lpVal[3].Value.bin.lpb;
CString s = _T("");
s = btArr; <=========================== Error!
s = lpVal[3].Value.bin.lpb[0]; <======== Error!
MessageBox(0,s,"",0);
Thanks in advance,
Dan
|
|
|
|
|
>> AfxIsValidString(lpsz)
This function checks if the address you have passed in points to memory that your program has 'read' access to. This routine looks for a terminating NULL char, since all valid 'C' and windows strings must have terminating NULL. All characters between the starting address and the terminating NULL must be in valid 'read' access memory.
Looking at your samp,e code, you appear to be passing the address of an array that has no terminating NULL, so this is why the attempt to load the CString from this memory is failing.
The bigger question is why you want to load and array 'byte' data, which does not appear to be a valid string value, into a CString ??
|
|
|
|
|
I have written a program that processes mails from Outlook into a Database. I noticed that the Messages are being cut off after 255 characters. When reading the message text I am using:
"CString csBody = lpVal[3].Value.lpszA;" which gives be only 255. another value is:
"lpVal[3].Value.bin.lpb;" which returns a LPBYTE...see below (from MSDN). I have also looked at "lpVal[3].Value.bin.cb;" which returns "8792808"?? I am basically really confused!
typedef struct _SBinary
{
ULONG cb;
LPBYTE lpb;
} SBinary, FAR *LPSBinary;
Members
cb
Count of bytes in the lpb member.
lpb
Pointer to the PT_BINARY property value.
Thanks in advance,
Dan
|
|
|
|
|
Ok. You will need to rethink this, or approach things fromn another angle. The "lpVal[3].Value.bin.lpb" variable is NOT a suitable pointer to initialize a CString with. By definition, a CString is useful for holding NULL terminated plain text. It IS possible to make a CString hold binary info, but that's a topic for another day (and a much longer discussion!)
What you need to do first is find out why you only get 255 chars from the "lpVal[3].Value.lpszA" pointer. I don't knowe the Outlook format at all, but this sounds like the data you want - yet it's being truncated. Chase that down first.
If you find that you really do need to process the binary data in order to get the full body of text (sounds strange, but might be true), then I'd suggest the STL vector (or perhaps stringstream) as a better container for working with the binary data you want to process.
|
|
|
|
|
Thanks for you help...because I took a look from a far, I can now read the entire body of the message. The way I did this was first of all, I "Read the ____ing Manual". MAPI says that if you have a large message to read, you should do the following (I felt you deserved how I got it to work!:
hr = pmsgRoute->OpenProperty(PR_BODY, STGM_READ, (LPUNKNOWN FAR *) &lpstreamBody);
if(S_OK != GetScode(hr))
{
DebugTraceResult(OpenProperty, hr);
goto err;
}
hr = lpstreamBody->Stat(&statstg, STATFLAG_NONAME);
if(S_OK != GetScode(hr))
{
DebugTrace("IStream::Stat failed");
goto err;
}
Assert(statstg.cbSize.HighPart == 0);
if(MAPIAllocateBuffer(statstg.cbSize.LowPart + 1, (LPVOID FAR *) &lpszNoteText))
{
goto err;
}
hr = lpstreamBody->Read(lpszNoteText, statstg.cbSize.LowPart, &cb);
if(S_OK != GetScode(hr))
{
DebugTrace("IStream::Read failed");
goto err;
}
lpszNoteText[statstg.cbSize.LowPart] = '\0';
SetDlgItemText(hDlg, IDC_RTNOTE, lpszNoteText);
MAPIFreeBuffer(lpszNoteText);
lpszNoteText = NULL;
lpstreamBody->Release();
lpstreamBody = NULL;
Thanks in advance,
Dan
|
|
|
|
|
I have declared a pointer to a function like this :
double (*pF)(double);
I have a function in a class CTest declared like this : double CTest::Compute(double);
the following code : pF =&Compute, doesn't work ????
The message error is :
"& : illegal operation on bound member function expression"
for compiler the function nammed Compute is Virtual...
So, How can I point a class member function ???
Leon
|
|
|
|
|
in general, you can't use member functions with function pointers unless the function is declared "static".
-c
------------------------------
Smaller Animals Software, Inc.
http://www.smalleranimals.com
|
|
|
|
|
There is no need of assigning the address like pF = &Compute;
The right way is pF = Compute;
|
|
|
|
|
Because the type of the Compute function is double (CTest::*)(double) .
--Mike--
http://home.inreach.com/mdunn/
"Holding the away team at bay with a non-functioning phaser was an act of unmitigated gall. I admire gall."
-- Lt. Cmdr. Worf
|
|
|
|
|
Hi,
You need to write pF = Compute, and not pF =&Compute.
Lose the & .
I hope that helps
|
|
|
|
|
Member function are different from global / static functions because they have an implicit this pointer as argument.
You have to declare a pointer to a class member function like this:
double (CTest::*pF)(double);
Read pF is a ptr to a member of CTest with takes double and returns double.
To assign the member function to the pointer do this:
pF = CTest::Compute;
To call the member function you need an instance of the class (because of the needed this pointer):
CTest test;
CTest* pTest = &test;
The call looks like this:
(pTest->*pF)(42);
Oliver
|
|
|
|
|
I use a CStringList to store all my outputs and everytime I finish an operation, I save the output to this list and print the whole CStringList out to the screen. and I have a scrollbar to let user to scroll back to see some previous outputs.
I have a touchscreen and I use WindowProc in view.cpp to wait for the "touch" and extract the window message and get the touch coordinate. These coordinates will store in a CList and also save to the CStringList for output.
OK.....when I touch the screen, and my program keeps displaying the touch coordinate. But after awhile, something strange......sometimes...the screen scroll backward!!!!! sometimes, it cannot display any more touch(just hear the beep sound...but no more output...) Another example, I display some values from the touchscreen and using a loop to do it.....that means i can do it forever until I stop it. Sometimes.....after awhile, the output will "overlap"....and strange characters....
This situation is more worse and happen faster in Win9x...... WinNT is more stable...but this situation did happen too in WinNT.....
What's going on ?????
|
|
|
|
|
I am using a third-party product and I pass a device context to their function to print a bar code. The return value is the size of the bar code (height and width). There is no way for me to know the height and width of the bar code prior to this call. Is there some way to call this function to get the height and width and NOT actually draw the bar code? My current solution is to use CreateCompatibleDC, pass that handle to the function, and delete the DC once I have obtained the height and width. I would appreciate any better ideas.
|
|
|
|
|
That sounds like the right approach to me.
The only other thing you might try, and this might not work depending on what the function does, would be to set the clip region of the DC to something silly, so that the rendering would not be apparent - some thing like:
CRgn rgn;
rgn.CreateRectRgn(0,0,1,1);
DC.SelectObject(&rgn);
DC.SelectClipRgn(&rgn, RGN_COPY);
...
Thats the MFC version, assuming a CDC. Will be similar for straight GDI.
Your solution is safer, I think, but this might let you get by without creating another DC if the third party function doesn't mess with the clipping region.
|
|
|
|
|