|
sprintf is King.
even CString::Format uses a flavor of it.
-c
As always, it's bread and circuses. And while bread is down right now, circuses are way up.
|
|
|
|
|
In the words of the prophets:
Thou shalt foreswear the vile printf and all his horrid brethren.
J
|
|
|
|
|
You can assemble a std::ostringstream using the stream-operator <<, which is overloaded for almost any type.
To access the std::string , you would use CMyOStringStream.str() , and if you need the LPCTSTR , you would add .c_str() to convert the std::string into a dumb char array.
|
|
|
|
|
Right, but I want the caller to simply pass in one set of parameters with no lead up.
I could do this...
void Trace(std::ostringstream &s);
...
std::ostringstream traceMessage;
...
Trace(traceMessage << "Wankity wank with the number " << 7);
I think. But I'd have to make sure the stream is empty before each trace call.
J
|
|
|
|
|
Use sprintf. That's what pretty much everyone else uses. Trace code is going to be removed in Release mode anyway right?
Todd Smith
|
|
|
|
|
Todd Smith wrote:
Trace code is going to be removed in Release mode anyway right?
Hmmm. Probably not. It's not retail software. It's a one-off that I'm going to want a detailed trace when the damn thing crashes in the field.
Performance isn't really the issue. Readability is.
J
|
|
|
|
|
You are always going to have some sort of format string. C has no mechansism to tell what the types of the parameters in the ... part are, so you need a format string (or some other type of list) to let the function know what to grab off the stack.
--Mike--
Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
I did
CTest myTest;
myTest.SetWindowText("abc"); <code>debug asserts here</code>
int nret = myTest.DoModal();
However if I do SetWindowText("abc"); in the InitDialog() of the CDialog class (CTest), it works fine.
Why cant we set the caption in the view class which spawns the dialog?
Thanks,
ns
Thanks,
ns
|
|
|
|
|
Your dialog doesn't exist as a window yet in the context you're trying to set its caption. There is no m_hwnd yet and so the call to SetWindowText kicks out. It's not until you call DoModal() that your window is created. If you want to set the caption prior to it even existing, throw in a string member variable in your CTest class and set it like you are with SetWindowText, except write some other cool function:
class CTest : public CDialog
{
private:
CString m_strCaption;
public:
....
SetCaption( const char *szCaption )
{
m_strCaption = szCaption;
}
};
DoStuff()
{
CTest myDlg;
myDlg.SetCaption( "Cool caption" );
myDlg.DoModal();
}
Then call SetWindowText in your OnInitDialog(), passing in your new m_strCaption variable.
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Thanks for the very detailed and informative solution. I was going to set some global flag to communicate between the view class and dialog, but definitely your way is the way to go! APpreciate it,
Thanks,
ns
|
|
|
|
|
So we are limited only to functions that dont have any cDialog controls in them.
We cant do
CTest myTest;
myTest.DoStuff();
myTest.DoModal();
where
CTest::DoStuff()
{
m_editInCTest.SetWindowText("a");
}
right?
So the functions we can call are only for setting variables in the CTest.
Just making sure,
Thanks,
ns
|
|
|
|
|
Yeah, this is the same as calling SetWindowText() directly. You can't do it either way because your window doesn't exist yet. You have to squirrel away the variable for use later on, once the window does exist.
You can always call other functions of CTest, just not any that deal with windows Which pretty much limits you to DoModal() and anything you've written yourself.
Here's what is really happening under the hood. SetWindowText() is an immediate action that needs to occur. This is also an MFC-specific function in CWnd. MFC handles this particular action by sending a low-level windows message, likely via the SendMessage() API call, named WM_SETTEXT. SendMessage() only works when you specify a valid handle to a pre-existing window. Your window doesn't exist yet, so this parameter would be NULL.
If you called SendMessage() yourself with a NULL parameter, the result is probably undefined. It likely just goes nowhere. MFC is protecting you from this unfortunate situation by kicking out an ASSERT and gently reminding you that you can't do this yet. SetWindowText and the many other MFC functions of CWnd are just protective wrappers around the Win32 API. If you didn't get this ASSERT, you'd never know that your caption wasn't being set properly, and you'd be looking all over the place trying to figure out why. God bless MFC
Hope this helps-
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
Hey thanks for that deeper insight! Yep - MFC is cool.
Thanks,
ns
|
|
|
|
|
no, that doesn't work either, because the Cdialog is not realized yet, it is realized when it is created.
You can set variables, do non-windows oriented processing, but you can't set the text to a control until the "WINDOW" is created.
You have to overwrite the OnInitDialog method to initialize dialog controls.
Max.
|
|
|
|
|
Thanks for that info! I didnt have time to test it....
Thanks,
ns
|
|
|
|
|
Hello world!!!
Why doesn't this compiled?
int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
volatile int pint[1] = {456};
int* p = pint;
return 0;
}
But this well:
int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
int pint[1] = {456};
int* p = pint;
return 0;
}
How to convert a volatile int* to a int* ???
Is this possible???
Thanks in advance...
|
|
|
|
|
Just add the volatile keyword to your pointer.
int main(int argc, TCHAR* argv[], TCHAR* envp[])
{
volatile int pint[1] = {456};
volatile int* p = pint;
return 0;
}
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
But the problem is that I can do that... Because the int* p = pint is (in fact) an argument of a function that I don't have any access...
This is why I try to "transtype" this variable!
Hello World!!!
from Raphaël
|
|
|
|
|
Well, you can do this:
int* p = const_cast<int*>(pint); however if the original is volatile, it means the compiler should never optimize access to the variable. Removing volatile from your pointer gets around that, which might lead to strange problems.
--Mike--
Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
This compile... thanks...
The "volatile" code is necessary because the variable pint could be changed by another thread at any time.
And why not use this syntax to "transtype" ???
int* p = (int*)(pint);
Hello World!!!
from Raphaël
|
|
|
|
|
I did the following which works fine. But then I changed (to see what happens ) the FALSE (in red in code) to TRUE and it still works
the way I want it. I am puzzled because I thought that returning TRUE in this function meant ignore the Enter. But it doesnt, and responds to Enter just like when it was FALSE.
BOOL CTest::PreTranslateMessage(MSG* pMsg)
{
if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
if (GetFocus() ==& m_Ctestedit && (m_Ctestedit.GetWindowTextLength()) )
{
m_Ctestedit.GetWindowText(m_text);
if(m_text=="a")
{
EndDialog(IDOK);
return <code>FALSE</code>;
}
else
{
m_Ctestedit.SetFocus();
}
}
else
{
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
Why does it do that? According to MSDN:
Return Value
Nonzero if the message was translated and should not be dispatched; zero if the message was not translated and should be dispatched.
Thanks,
ns
|
|
|
|
|
the EndDialog(IDOK) is throwing me off.. wouldn't the dialog your in? also you should trace to make sure that its working the way you think it is.
still a newb.. cut me some slack :P
-dz
|
|
|
|
|
what is the best way to check to make sure a person does not have read only access to a folder?
also this folder may get alot of files in it over a period of time, is there a way to make sure i dont go over the limit of files in a folder? or to check if they have more than 100 files and if so delete files older than a month or so?
just looking for directions, dont need exact code.. thanks for the help!
-dz
|
|
|
|
|
Every directory supports a nul file name. I think this is leftovers from the DOS days, and its strong imitation of *nix. So you can attempt to open a file for write access to Drive:\Directory\nul and see if that works. If it does, your user has the "write" right to the directory. No file will ever be created, because nul is a big black hole.
As for checking for old files, if you're using MFC you can use the CFileFind class to iterate through all of the current files in any given directory. There is a function of CFileFind called GetLastWriteTime() that will tell you the last time it was modified. Take the CTime that function gives you, a CTime::GetCurrentTime() and combine it with a CTimeSpan to compare them. It's not very intuitive, so here's some sample code
<code>
const int cNumDays = 30;
CFileFind fFinder;
CTime tCurrent = CTime::GetCurrentTime();
CTime tFile;
CTime tCompare;
BOOL bWorking = fFinder.FindFile( "c:\\mydirectory\\*.*" );
while( bWorking )
{
bWorking = fFinder.FindNextFile();
if( !fFinder.IsDirectory() && !fFinder.IsDots() )
{
fFinder.GetLastWriteTime( tFile );
tCompare = tFile + CTimeSpan( cNumDays, 0, 0, 0 );
if( tCompare <= tCurrent )
{
TRACE( "%s\n", fFinder.GetFilePath() );
}
}
}
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
thanks for the help!
still a newb.. cut me some slack :P
-dz
|
|
|
|