|
Version II:
CString CLUPort::BuildStartCommand()
{
LUMessage msg;
CString strConnect;
LPTSTR pBuffer = strConnect.GetBuffer(1);
memset(&msg, 0, sizeof(LUMessage));
msg.start.cmd = START;
msg.start.crc16 = crc16_checksum((byte_t *)&msg, sizeof(msg.start) - 2);
msg.start.crc16 = TO_buint16(msg.start.crc16);
memcpy(pBuffer, &msg, sizeof(msg.start));
strConnect.ReleaseBuffer();
return strConnect;
}
This seems to only copy msg.start.cmd into strConnect, but I need the whole msg.start struct...
|
|
|
|
|
Hi,
Replace this;
strConnect.GetBuffer(1);
with;
strConnect.GetBuffer(sizeof(msg.start));
Hope that helps.
> Andrew.
|
|
|
|
|
Been there, done that. Whether I put 1, 100, or sizeof(msg.start) I get the same result each time. pBuffer seems to get the value of only msg.start.cmd instead of all of msg.start.
|
|
|
|
|
Without information about the data types of LUMessage struct nobody here will be able to help you.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
There may be a zero byte after msg.start.cmd, this will cause ReleaseBuffer() to cut the string at that point.
|
|
|
|
|
One suggestion:
Instead of returning a CString, I would suggest passing one as a parameter by reference and manipulating it. Also, memcpy doesn't work well with CString (too much detail involved in explaining why -- basically, the memory structure is different than a normail C-style character arrary).
Zac Howland
|
|
|
|
|
> One suggestion: Instead of returning a CString, I would
> suggest passing one as a parameter by reference and manipulating it
Why? CString uses copy-on-write - the cost of copy constructor call is very low (no memory allocations are performed).
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
I disagree, we had a serious performance problem that was caused by
passing CStrings into a method by value rather than by reference.
Pass by value implies use of the copy constructor. Performance was increased dramatically by using pass by reference. I didn't do the work, but it
made such a difference the entire department was told about it.
Stephen Kellett
--
C++/Java/Win NT/Unix variants
Memory leaks/corruptions/performance/system problems. UK based.
Problems with RSI/WRULD? Contact me for advice.
|
|
|
|
|
> I disagree, we had a serious performance problem that was
> caused by passing CStrings into a method by value rather than
> by reference.
> Pass by value implies use of the copy constructor.
CString's copy c'tor only increments a counter using InterlockedIncrement. No memory allocations are made. Unless the function was called in very tight loop millions of times, there should be no noticeable difference.
Or maybe it was before MFC 4.0? I believe they've implemented copy-on-write in this version.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
TRY THE FOLLOWING:
CString CLUPort::BuildStartCommand()
{
LUMessage msg;
CString strConnect;
int nSize = sizeof(msg.start) + sizeof(TCHAR) ; //<-------------
LPTSTR pBuffer = strConnect.GetBuffer(nSize);
memset(&msg, 0, sizeof(LUMessage));
msg.start.cmd = START;
msg.start.crc16 = crc16_checksum((byte_t *)&msg, sizeof(msg.start) - 2);
msg.start.crc16 = TO_buint16(msg.start.crc16);
memcpy(pBuffer, &msg, sizeof(msg.start));
strConnect.ReleaseBuffer(nSize); //<---------------
return strConnect;
}
Mh2!
|
|
|
|
|
MDI applications begin with a blank window by default. What code creates this, and how can I prevent it from opening immediately? There are certainly programs that open up without a blank window, such as Photoshop. thanks-
Jake
|
|
|
|
|
Change your application's InitInstance:
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (CCommandLineInfo::FileNew == cmdInfo.m_nShellCommand)
{
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
}
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Hello Jake,
I suppose you've created a MDI application using the VC++ Wizard.
In this case, the creation of the first initial document is performed by
ProcessShellCommand(cmdInfo) in the main of your program.
If you check the docs, you will find that next code:
----
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
---
will handle the passed arguments when you execute the application. You can override these by writing your own command-line parsing stuff.
The default behaviour of ProcessShellCommand is when not passing parameters with your application: "Start appl. and open new document".
Hopes this helps,
EiSl
|
|
|
|
|
I have developed a base class to assist with multi-threaded database access that I would like to make use of in a huge (50+) number of dialogs. The way that makes the most sense is to have my class inherit from CWnd and to then have a number of different control class's, such as CListCtrl, CComboBox, CListBox, etc inherit from my class. The only way I can think of doing this is to rebuild the MFC DLL's after modifying the source. This sounds like to daunting a task, even for the likes of me . Does anyone else have a tip or suggestion to try instead. Thanks and I can elaborate more if you have questions.
Chris
|
|
|
|
|
Multiple inheritance is out of question? You could put DB-related functionality in separate class and create CEditDB, CListCtrlDB, CComboBoxDB etc.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
Thanks Tomasz. I think going the multiple inheritance route is probably the best. My only knock against it is that I end up having to duplicate a number of methods in the controls that are really window specific. For example, I want to handle the OnDestroy() and cleanup the base class. Each control will need to handle the message and run the same code. If I could get my class into the hierarchy between the CWnd class and CWhateverControl class, then I only have to write the OnDestroy handler once. That's really what I was trying to avoid. Thanks for the suggestion, it will probably be the way that I end up going.
Chris
|
|
|
|
|
> If I could get my class into the hierarchy between the CWnd
> class and CWhateverControl class, then I only have to write
> the OnDestroy handler once.
You can check Paul DiLascia's CMsgHook class, described in March 1997 issue of MSJ ("More Fun With MFC: DIBs, Palettes, Subclassing and a Gamut of Goodies, Part II"). This class isn't derived from CWnd and makes Windows message processing possible outside of CWnd hierarchy. Even if it doesn't solve your problem, it's very good reading - DiLascia has its own unique, funny style.
The article should be in the 'Periodicals' section of MSDN installed on your HD --and-- it's available at msdn.microsoft.com.
Tomasz Sowinski -- http://www.shooltz.com.pl
|
|
|
|
|
I enjoy his articles too. They have that "I've been through the wars" kinda feel to them
Thanks again.
Chris
|
|
|
|
|
What does your base class represent?
If you want the controls to inherit from your class, then Why do you need Multithreaded-database access per control??
Your classes should represent entities like record and recordset. And then you need RFX mechanism for the controls!
|
|
|
|
|
It represents a window that when created or subclassed, will start a thread that performs the database access. When properly implemented, the dialog and controls can be created much faster, providing an application that is responsive. Put together a dialog with 4 listboxes, 8 comboboxes, 1 list control and if you try to populate the data in these controls during OnInitDialog(), all it takes is for just one of the controls to have to load a large number of records, eg. a couple of thousand, and your user has to sit and wait. But if the OnCreate or PreSubclass method is used to start a thread that populates the data, then the dialog appears much quicker and is more responsive.
Chris
|
|
|
|
|
Sounds Cool! But why don't you create base classes like CSQLQuery, CRecordset
and then derive CDialogRecordset from that. You can make your CDialogRecordset class so that it would create a second thread and does the work there... and it uploads the controls automatically!
You also need to define some MACROS to MAP dialog controls to certain fields!
Does this work?
|
|
|
|
|
I maybe totally off the mark here, but have you considered making your class a template class?
<br />
template <typename T><br />
class CMTDBWnd : public T<br />
{<br />
};<br />
and then use it like so...
CMTDBWnd<CListCtrl> m_listCtrl;
HTH
Jignesh
|
|
|
|
|
You've probably given me a pretty good reason to dig up a tutorial on building templates
I've only used templates minimally in the past, but this seems like an idea to persue.
Thanks for the suggestion.
Chris
|
|
|
|
|
I am getting the following linkage problem to occur when building. MSDN says they have a solution but
I can't seem to make the solution work.
mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in CreateCharacterCls.obj
mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in CreateCharacterCls.obj
What I try is placing mfcs42d.lib in the Object/library module box under links under project settings, which looked to be what microsoft was trying to tell me. (I also tried placing in under libraries to ignore since that was also mentioned. Perhaps I using the wrong libraries.)
Does anyone know the real solution around this. Either I'm reading the microsoft solution wrong, or it's not descriptive enough on the solution.
Thanks!
|
|
|
|
|
It looks like the simpler solution (from MSDN) would be:
"When using MFC libraries, you must make sure they are linked before the CRT library. This can be done by ensuring every file in your project includes ..\Msdev\Mfc\Include\Afx.h first, either directly [#include <afx.h>] or indirectly [#include <Stdafx.h>]. The Afx.h include file forces the correct order of the libraries, by using the #pragma comment [lib,"<libname>"] directive. [from PRB: LNK2005 Errors When Link C Run-Time Libs Before MFC Libs ]
Just making sure all your .cpp files include stdafx.h might do it.
|
|
|
|