|
you can't pass a char * as a CString - they ain't the same thing.
try it.
-c
Cheap Oil. It's worth it!
|
|
|
|
|
*slaps self*
Sorry, didn't read the question correctly. Thought he was passing a CString as the parameter
--------
Hey you Whitehouse, ha ha, charade you are
You house proud town mouse, ha ha, charade you are -- Pink Floyd, Pigs (Three Different Ones)
|
|
|
|
|
I use number one exept no unicode support and i don't use LPTSTR, i don't like it.
const char *stringArgument
LPCTSTR = A 32-bit pointer to a constant character string that is portable for Unicode and DBCS.
|
|
|
|
|
I never use LPTSTR. I may have a TCHAR array here and there if I need to pass a non-const string to a system API. But I never use functions that take LPTSTR - I'd use a non-const reference to a CString in that case.
For clarification, what I meant about a parameter creating a temporary CString object is in this scenario. I guess it would only matter, as Chris Losinger said, if you pass in great big strings or are in a loop or something like that.
void SomeFunc(const CString & )
{
...
}
...
// This will create a temporary CString to pass into
// SomeFunc.
SomeFunc("This is not a C-String!");
// But this won't.
CString = "This one is.";
SomeFunc( );
Yes, I know it is against C++ standards to use an icon as a variable name.
No generalization is 100% true.
Not even this one.
|
|
|
|
|
You have to look at what you are doing with your string. What is coming in and how it will be used inside the routine.
Outside routine: CString
Inside routine: CString (for example, storing into a local str var)
Argument: const CString &
In this case, you are able to take advantage of the reference counting used by CString. No duplicate strings will be created. (GOOD)
Outside routine: CString
Inside routine: CString (for example, storing into a local str var)
Argument: LPCTSTR
In this case, the CString will just pass the pointer to the internal string. However, once that string is used as a CString inside of the routine, a duplicate will have to be made. (BAD)
Outside routine: LPCTSTR
Inside routine: CString (for example, storing into a local str var)
Argument: const CString &
In this case, a CString will have to be created prior to the routine being invoked. However, since the routine will actually be using the CString internally, it would have had to have been created anyway. No performance loss. (GOOD)
Outside routine: LPCTSTR
Inside routine: CString (for example, storing into a local str var)
Argument: LPCTSTR
In this case, the string is being passed directly into the routine. Then internally a CString is being created. However, the same would have been true if the argument was CString. (GOOD)
Outside routine: CString
Inside routine: LPCTSTR (maybe a call to _tcscmp)
Argument: const CString &
In this case, the string is passed directly in and the routine just uses the (LPCTSTR) operator in CString to access the contents. No performance loss. (GOOD)
Outside routine: CString
Inside routine: LPCTSTR (maybe a call to _tcscmp)
Argument: LPCTSTR
In this case, the CString will just pass the pointer to the internal string. The routine will use the pointer as is. (GOOD)
Outside routine: LPCTSTR
Inside routine: LPCTSTR (maybe a call to _tcscmp)
Argument: const CString &
In this case, a copy of the string will get created to be passed as a CString. Then the CString is just dereferneced. Needless creation of temp string. (BAD)
Outside routine: LPCTSTR
Inside routine: LPCTSTR (maybe a call to _tcscmp)
Argument: LPCTSTR
In this case, the string is being used as is. No temp objects. (GOOD)
SOOOOOOO
If you total it all up:
Case 1:
If inside the routine you are using the string as a CString:
Argument as CString: 2 good cases, no bad.
Argument as LPCTSTR: 1 good case, 1 bad case.
So, when the routine will be using the string as a CString, there is no reason to not use "const CString &" for the argument.
Case 2:
If inside the routine you are using the string as a LPCTSTR:
Argument as CString: 1 good case, 1 bad case.
Arguemnt as LPCTSTR: 2 good cases, no bad cases.
So, when the routine will be using the string as a LPCTSTR, there is no reason to not use "LPCTSTR".
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
I have a program Visual C++ which is connecting to SQL 2000. Because the SQL 2000 set to WindowsNT authorization I can't use the 'sa'. How do I deal with this problem??
|
|
|
|
|
You need to make sure that your SQL database tables has the NT users assigned to it via the users in SQL Server enterprise manager.
Michael
"Eureka" is Greek for "This bath is too hot"
|
|
|
|
|
This code is from the mttty sample in MSDN but I'm not sure how ReadFile works. It says it does not return until it encounters an error or the actual amount of bytes read equals what was specified as a parameter. I'm wondering how this code works because it can only write the data to disk in the else block or after the WaitForMultipleObjects call. I've modified some of the code so that OutputABuffer() should now be OutputABufferToFile(). I'm a little confused how threading works here. If ReadFile doesn't return until 512 bytes are read then how does the WaitForMultipleObjects apply? It looks like the code in the WaitForMultipleObjects section does the same thing...write to a file, as the code after the else block of the ReadFile call.
#define AMOUNT_TO_READ 512
while ( !fThreadDone )
{
//
// If no reading is allowed, then set flag to
// make it look like a read is already outstanding.
//
if (NOREADING( TTYInfo ))
fWaitingOnRead = TRUE;
//
// if no read is outstanding, then issue another one
//
if (!fWaitingOnRead)
{
if (!ReadFile(COMDEV(TTYInfo), lpBuf, AMOUNT_TO_READ, &dwRead, &osReader))
{
if (GetLastError() != ERROR_IO_PENDING) // read not delayed?
ErrorInComm("ReadFile in ReaderAndStatusProc");
fWaitingOnRead = TRUE;
}
else
{ // read completed immediately
if ((dwRead != MAX_READ_BUFFER) && SHOWTIMEOUTS(TTYInfo))
UpdateStatus("Read timed out immediately.\r\n");
// modify section here to assemble 20 byte messages before writing to disk
if (dwRead)
{
if(gdwReceiveState == RECEIVE_CAPTURED)
{
OutputABufferToFile(ghFileCapture, lpBuf, dwRead);
}
}
}
}
.
.
.
//
// wait for pending operations to complete
//
if ( fWaitingOnStat && fWaitingOnRead )
{
dwRes = WaitForMultipleObjects(NUM_READSTAT_HANDLES, hArray, FALSE, STATUS_CHECK_TIMEOUT);
switch(dwRes)
{
//
// read completed
//
case WAIT_OBJECT_0:
if (!GetOverlappedResult(COMDEV(TTYInfo), &osReader, &dwRead, FALSE)) {
if (GetLastError() == ERROR_OPERATION_ABORTED)
UpdateStatus("Read aborted\r\n");
else
ErrorInComm("GetOverlappedResult (in Reader)");
}
else { // read completed successfully
if ((dwRead != MAX_READ_BUFFER) && SHOWTIMEOUTS(TTYInfo))
UpdateStatus("Read timed out overlapped.\r\n");
if (dwRead)
OutputABufferToFile(ghFileCapture, lpBuf, dwRead);
// OutputABuffer(hTTY, lpBuf, dwRead);
}
fWaitingOnRead = FALSE;
break;
.
.
.
case WAIT_TIMEOUT:
.
.
} // END WHILE LOOP
|
|
|
|
|
I sort of figured it out. The operation is overlapped so it would return from ReadFile() immediately. So, it looks like I'll have to make a function that will package my data into 20 byte messages - I append time and port number to each 8 or 14 byte messages. And, this function will have to be called from the else block and in the WaitForMultipleObjects switch statement. Sound good?
|
|
|
|
|
Allright, I have some major questions that maybe some one can help me with.
First I am writing a Windows GUI that interfaces to an embedded system via RS232 messages. In order to transmit these messages, I was asked to create a three level OSI protocol stack (transport, network, and datalink.) This stack then communicates back to the application via windows messages (WM_COMM_SENT, WM_COMM_RETRY, and so on...) This uses two threads (send and recieve for each layer) but only the transport thread sends messages.
I have a simple callback system where the transport talks only to the CMainFrame class. The mainframe class handles the messages, queries a messages manager, and then the message manager sends out a WM_COMM_CALLBACK message to each window that needs the data.
The problem is, I am currently trying to interact with the box via the new GUI. The GUI handles a button press, issues the send command in the transport just fine and recieves the data back immediately. However I must release or terminate the current windows message before the messages that come back from the communications stack are processed. This works fine because most of the GUI message handlers are short..., but finally to my question?
Is there a case where during a button press that sends out say 128 messages to handle some of the return messages before the button press message returns back to the message pump? Or is there better system for returning information from the transport... I guess after working 16 hours a day for three weeks to get a demo ready for a trade show and being the only one in a small company that can handle this, I am a little fried and need help walking through the Windows messaging world and threads...
My only other ideas are to release control and wait for the callback before sending the next message, but that limits the functionality of placing a multi-message buffer in the comm stack... or to write a thread that GUI message starts up and then lets it ride until all the messages are sent, however I am already handling so many threads... In other words how many threads are too many threads .
Any help is appreciated...
Thanks,
Brian
Stop the hatred, free the Mallocs.
|
|
|
|
|
Any process which is syncronchous inside the GUI, should be seperated by implementing within a thread.
I guess from your description.
I would have a thread to process requests from the GUI.
Eg.
CProcessTread
{
AddRequest(...)
ProcessQueue(...)
etc.
AddFeedBackDelegate(...)
}
This frees the GUI to get on with it's own business. "AddFeedBackDelegate" would take call back function to your GUI so that you can be notified of message receipt/delivery. Alternatively you could Send requests back to the GUI via custom WM_APP + 0x??? messages.
I hope I make since, feel free to contact me with a more descriptive email.
Normski. - Professional Windows Programmer
|
|
|
|
|
Hi,
I am begineer in VC++ and C++ programming. I need to write a "Callback function" for performing certain operations in my application.
I need some guidance or article where I can learn about writing callback functions. (Do's and Dont's). I will be greatful to get some information.
Thanks and Regrads,
Arthi
|
|
|
|
|
a callback function is really just a plain C function (not a C++ member function). you give its address (ie. the adress of your function) to another function which will then call your function when it needs to do something (like compare two items in qsort, store info about a font in EnumFonts, etc.) . but there's nothing special about them in general.
here's how you get font info:
BOOL CALLBACK EnumFontCallBack(LPLOGFONT lplf, LPTEXTMETRIC lptm, DWORD dwType, LPARAM lpData)
{
TRACE("Get font: %s\n", lplf->lfFaceName);
return TRUE;
}
void CMyDialog::DumpFonts()
{
CClientDC dc(this);
EnumFonts (dc, 0,(FONTENUMPROC) EnumFontCallBack, 0);
}
-c
shh! the audience (and the NSA) is listening
|
|
|
|
|
I would like to know also if the word CALLBACK is significant. Can it be ignored? Do functions declared with the CALLBACK identifier are decorated differntly than other C functions? Can it be replaced with a static C++ method of some class?
Thanks!
Best regards,
Alexandru Savescu
|
|
|
|
|
depending on your build settings and MFC version, CALLBACK is defined as "__stdcall" or as nothing. so, it depends.
-c
Beware the leader who bangs the drums of war to whip the public into patriotic fervor, for patriotism is a double-edged sword. It emboldens the blood and narrows the mind. When the drums of war have reached a fever pitch, the blood boils and the mind closed, the leader will not need to seize the rights of citizens. Rather, infused with fear and blinded by patriotism, they will gladly offer up their rights. How do I know? For this is what I have done. And I am Caesar.
|
|
|
|
|
Hey guys. I'm using Installshield 6 for VC++ and I was wondering how I could get the installer to run a seperate executable during the install. I need to run an app that has a driver bundled in it. It's a pain, I know, but I have no other recourse. Speaking of drivers, does InstallShield provide a way to install device drivers?
Thanks,
-Mike Zinni
Software Engineer
email: mzinni@rimail.com
AIM: zin9999
|
|
|
|
|
InstallShield installing device drivers? Good luck! We have to do what you are trying to do - call a custom DLL from within InstallShield. We're going to a full custom installer becuase of this (and other issues.)
I know it is possible to run an executable or call a DLL from inside InstallShield - try going to the InstallShield website and searching their newsgroups. You may want to write a DLL and launch your EXE from there.
No generalization is 100% true.
Not even this one.
|
|
|
|
|
I need "graph line printing". my app collects some data in a long period, and using GDI API to draw a curve, now i have to wait until having more enough data to draw a curve in a full paper and then print it. i want to print the curve on time and not when having a full paper.
Anyone have any suggestion ? Thanks!
Hello! World!
|
|
|
|
|
I want to initialize a vector or a list with data that is stored in a file. I have not seen any example on how to read this data into the vector or list. All I have seen is an array that is initialized and that data is then placed in the vector. I want to open the file and insert the data directly into the vector. Thanks for the help.
Josh
|
|
|
|
|
unfortunately, vectors are not file parsers. you'll have to read the data yourself and then insert it into the vector (as you describe).
-c
30% of your base are belong to the IRS!
|
|
|
|
|
This example opens a file filled with int s separated by whitespace and feed them into a vector:
std::vector<int> v;
std::ifstream ifs("test.in");
std::copy(std::istream_iterator<int>(ifs),std::istream_iterator<int>(),
std::back_inserter(v)); Of course you can do it the non-STL way, opening the file, reading the data one at a time and pushing into the vector with push_back .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
A vector is an array. This is an old WG issue, and will be corrected. You can assume that the following gives you a pointer to 2048 bytes of contigous memory:
std::vector<char> foo;
foo.reserve(2048);
char* p = &foo[0];
|
|
|
|
|
I'm trying to pass a file path with spaces in the cmdInfo.m_strfile. It only excepts the first letters before the space. ie c:\documents and settings. Only c:\documents copyied into cmdInfo.m_strfile. Any ideas.
Thanks
|
|
|
|
|
Put quotes around the file name, maybe?
cmdInfo.m_strFile = _T("\"C:\\documents and settings\"");
This could be worth a try.
Michel
It is a lovely language, but it takes a very long time to say anything in it, because we do not say anything in it, unless it is worth taking a very long time to say, and to listen to.
- TreeBeard
|
|
|
|
|
What Michel says should work. You can also get at the command line another way - simply access the app's m_lpCmdLine member variable and avoid ParseCommandLine completely. I guess it depends on what you want to do. If you are ever going to have more than one parameter, you'll have no other choice than to surround the file by quotes.
No generalization is 100% true.
Not even this one.
|
|
|
|
|