|
Read Jeffrey Righter's work:
http://ganz2006.chat.ru/pamw4ejr.rar1
http://ganz2006.chat.ru/pamw4ejr.r00
(this is two volume of RAR archive).
|
|
|
|
|
Thanks for the tip. Now a more specific question:
Suppose I have a struct of the following type:
struct BBG_SECURITIES {
long nRecords; // Number of Entries
CString *sName; // Security Name
CString *sTicker; // Security Ticker
CString *sMarket; // Security Market
CString *sIssuer; // Issuer
CString *sCoupon; // Coupon
CString *sFrequency; // Frequency
CString *sMaturity; // Maturity Date
CString *sCurrency; // Currency
CString *sCountry; // Country
CString *sDBRS; // DBRS Bond Rating
CString *sSP; // S&P Bond Rating
CString *sMoody; // Moody's Bond Rating
CString *sBloomberg; // Bloomberg Composite Bond Rating
};
As you can see it has a combinantion of heap and stack variables inside. Is it a good practice first of all?
I expect to have no more than 1000 records. When creating a new struct of BBG_SECURITIES type, am I better off declaring it on heap or on stack? I have read somewhere that all structs are extually declared on stack (is this true?). I expect to use the struct created quite often in the program, and I will need speed but I do not want to put a drain on memory (cause I will need a lot of it for something else as well).
Thanks.
|
|
|
|
|
Here's the problem with what you are doing. You should declare this structure with all stack variables like so:
struct BBG_SECURITIES {
long nRecords;
CString sName;
CString sTicker;
CString sMarket;
CString sIssuer;
CString sCoupon;
CString sFrequency;
CString sMaturity;
CString sCurrency;
CString sCountry;
CString sDBRS;
CString sSP;
CString sMoody;
CString sBloomberg;
};
In general, you probably don't want to use pointers in a struct because you will have to allocate memory for each of those variables individually outside the struct like so:
struct BBG_SECURITIES bbgs;
bbgs.sName = new CString("Bob");
bbgs.sTicker = new CString("MOT");
This also means that you will have to deallocate each of these later using delete. CString is a wrapper class that abstracts string manipulation. Using the structure as the way I've declared it above, you would simply do this:
struct BBG_SECURITIES bbgs;
bbgs.sName = "Bob";
bbgs.sTicker = "MOT";
This may sound contrary to my last post, but it's really not. Here you are talking about a structure declaration. I would personally use all stack (e.g. no pointers) variables for the structure declaration, however, when I go to use the structure itself, it becomes a different matter altogether. Here's an example. Say I want to create and populate these data structures in a function and then return a pointer to the one I've created. In this case, I would have to use new (e.g. the heap). Here's what I mean (by the way, the struct keyword is not required when using your structure in C++. In C it is, but not C++):
BBG_SECURITIES* pBbgs = GetNewStruct();
cout << pBbgs->sName << "," << pBbgs->sTicker << endl;
<br><br>
BBG_SECURITIES* GetNewStruct()
{
BBG_SECURITIES* pBbgs = new BBG_SECURITIES;
pBbgs->sName = "Bob";
pBbgs->sTicker = "MOT";
.
.
return pBbgs;
}
Again, this would be more efficient than passing back a copy. Not to mention that that copy would probably be invalid, but that has to do with a shallow versus deep copy. I can explain more about this if you're interested.
Now, for a little more on using the CString. In the days of C, you had to do all of the string manipulation yourself with char arrays, strcat, strcpy, strlen, etc. In that case you would either use pointers and allocate them with malloc, or (more commonly) you would create fixed length character arrays. It would have looked something like this.
struct BBG_SECURITIES {
long nRecords;
char sName[100];
char sTicker[100];
char sMarket[100];
char sIssuer[100];
char sCoupon[100];
char sFrequency[100];
char sMaturity[100];
char sCurrency[100];
char sCountry[100];
char sDBRS[100];
char sSP[100];
char sMoody[100];
char sBloomberg[100];
};
There is a problem with this method, though. You never know what length the data you might get is going to be. If someone should, by accident or on purpoase, fill up sName, for instance, with 101 chars instead of the allocated 100 (including null terminator), you'd have a buffer overflow on your hands.
CString makes all this a thing of the past. If you want to concatenate a string to another string, you simple do this:
CString sStr1 = "Hello ";
sStr1 += "World!\n";
CString handles all of the necessary memory allocation for you. This is the same way with the STL string too.
Now here's a little tidbit to think about. Say you created one of your structures as I've defined it above (e.g. everything on the stack) and you want to hand that structure off to a function. and you want that function to populate the structure's data. You would do something like this:
BBG_SECURITIES bbgs;
PopulateStruct( &bbgs );
void PopulateStruct( BBG_SECURITIES* pBbgs )
{
pBbgs->sName = "Bob";
pBbgs->sTicker = "MOT";
.
.
.
}
You see, we created the variable on the stack and then passed its address to our function. So we have still been pretty efficient here even though we used the stack. If we had passed by value we:
1. Would have needlessly made a copy
2. And more importantly, wouldn't have gotten the result we expected. If you pass it by value, it is a copy and so you are, therefore, populating a copy of the structure rather than the original structure.
See here:
BBG_SECURITIES bbgs;
PopulateStruct( bbgs );
void PopulateStruct( BBG_SECURITIES bbgs )
{
bbgs.sName = "Bob";
bbgs.sTicker = "MOT";
.
.
.
}
See when we got into the PopulateStruct, bbgs is not the original one we declared above it. It is now a copy because we passed by value. You have to understand the distinction between objects having the same contents and being the same object. If it is not the same object--which it is not when we send a copy--then the original object will not be affected.
If the object is the same object, that means it has the same memory location. If however, they have different memory locations but the same contents, they are not the same object--just two copies of the same contents. So if you make a change to the copied object and not the original object, you won't get the results you expect.
I hope this helps a litle bit. I'm not sure what all the gaps are that need filled in for you, but it seemed like this was a good path to go down. Feel free to ask more questions if this is not clear.
Good luck.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
first off, thanks so much for the help today, i've been coding all day today (now that i got my 80gb drive replaced), so i've been full of questions, thank you all so much!
I have a print function in my CMainFrame which loops through a set of documents.. it populates a cformview, calls its OnFilePrint(), then populates the formview with a different document, calls its OnFilePrint(), etc. etc.
I only want to make the user select their printer one time, after this i just want it to print print print..
i figure it should be possible to overload CFormView::OnFilePrint() and just make it store the 'strOutput' that it gets from calling CFileDialog() (where you choose the printer).
the problem is that OnFilePrint() looks pretty complex right off the bat.. it would be much cooler if there was an easier way to store the settings chosen once, and then not ask them again.. or just print to the default printer?
thanks ya'll!
-dz
|
|
|
|
|
Ok, How did u get the print information from CFileDialog ??,
Any way what you want is to not ask the user abt the print information
You could save the 'PRINTDLG' as a part of the App and then reuse the
same object every time, you could infact initialize the CPrintDialog's m_pd
to this struct.
Any way I since you are using CFormView, try to show the PrintDialog
yourself and not let the FrameWork do (You could override OnFilePrint)
This way you can control the whole process.
|
|
|
|
|
This is a little bit hard do explain, but I'll try:
When I write an e-mail, writing in Word or just in a text box in some other app..
I want to open my app and then click a button and some text will be pasted into the focused text box in Word or any app that I write in.
Like WOrdFinder (if you know it)
It can paste a translated word from WordFinder its selft to another app, such Word or Outlook (when writing an e-mail).
How to do that, if you understand what I mean!
Rickard Andersson@Suza Computing
ICQ#: 50302279 (Add me!)
E-mail: nikado@pc.nu
I'm from the winter country SWEDEN!
|
|
|
|
|
Ok,
I know you must have thought abt it a lot,
i think i have a small perfect solution,
In your app when you click a button(you could copy text
from your app here)and go to the application(or an edit box in it)
you want to paste and click on it.
At this point you could find out the Process from it and Post a message
using PostThreadMessage
(ID_EDIT_COPY with a WM_COMMAND)
Let me know if it works...
|
|
|
|
|
I dot't understand to 100 % what you mean...
but do have to paste it to the clipboard and then post a message to Word or something to paste it??
Rickard Andersson@Suza Computing
ICQ#: 50302279 (Add me!)
E-mail: nikado@pc.nu
I'm from the winter country SWEDEN!
|
|
|
|
|
Yes, I mean you copy it to the clipboard and then
imitate the user action of Ctrl+V.
|
|
|
|
|
And if I send it to the window that has an edit or rich text box that is focused... will the clipboard text be pasted there then?
Rickard Andersson@Suza Computing
ICQ#: 50302279 (Add me!)
E-mail: nikado@pc.nu
I'm from the winter country SWEDEN!
|
|
|
|
|
I think it should, but as i told you
i have not tried it out, but you could imitate the
message sending.
|
|
|
|
|
Hey, I've been trying to make a function that replaces certain strings with other strings. I found an article on this site about it, and this is what I've been trying to us:
// instr is the string to search in
// oldstr is the string to search for
// newstr is the string to replace with
CString CMFC2Dlg::Replace(LPCTSTR instr, LPCTSTR oldstr, LPCTSTR newstr)
{
CString output(instr);
CString input_lower(instr);
CString oldone_lower(oldstr);
input_lower.MakeLower();
oldone_lower.MakeLower();
int pos=0;
while ( (pos=input_lower.Find(oldone_lower,pos))!=-1 )
{
input_lower.Delete( pos, lstrlen(oldstr) );
input_lower.Insert( pos, newstr );
output.Delete( pos, lstrlen(oldstr) );
output.Insert( pos, newstr );
}
return output;
}
The only problem is that when I use it, it gets stuck in an endless loop. Any ideas?
Thanks alot,
Emearg
|
|
|
|
|
At first sight, seems like you'd need to add lstrlen(newstr) to pos at the end of your while loop.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
|
This will definitely loop if oldstr is a subset of newstr. The suggestion of adding lstrlen(newstr) to pos should eliminate the problem. This prevents the .Find method from scanning the newstr text.
I ran this. It doesn't loop if newstr and oldstr are disjoint sets.
BTW: This kind of problem is extremely easy to solve if you step though the code. You will be a much more productive coder if you learn basic debugging techniques.
Good Luck,
Bill
|
|
|
|
|
I think it's case sensitive. Would've been nice if there was a CString::ReplaceNoCase() analog of CString::CompareNoCase() .
/ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
|
Insert a #define WINVER 0x500 prior to the inclusion of shlwapi.h . If this does not work, you might need to download a newer version of the platform SDK.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Thanks. Where can i download the newest version of Platform SDK?
|
|
|
|
|
Follow the links from here.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I keep getting an "Automation server can't create obect." errors, and then no links appear...
|
|
|
|
|
Don't know. It worked OK for me. Keep trying, or use another machine (if you have it available.)
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
|
See the VC forum FAQ (Link at the top of the page)
--Mike--
Just released - RightClick-Encrypt - Adds fast & easy file encryption to Explorer
Like the Google toolbar? Then check out UltraBar, with more features & customizable search engines!
My really out-of-date homepage
Sonork - 100.10414 AcidHelm
|
|
|
|
|
i have a split window that i put a CFormView derived view into. How can I call this view's OnFilePrint function? I have a message map in this view:
BEGIN_MESSAGE_MAP(CDisplayPrintTemplate, CFormView)
ON_WM_ERASEBKGND()
ON_COMMAND(ID_PRINT_SELECTED,CFormView::OnFilePrint)
END_MESSAGE_MAP()
how can i send a message from CMainFrame to this view to print? I have tried the following, but nothing occurs. In the class itself i have a button that i press which has the ID_PRINT_SELECTED id, and it works fine..
CDisplayPrintTemplate* pForm = (CDisplayPrintTemplate*)m_wndSplitter.GetPane(1,0);
pForm->SendMessage(ID_PRINT_SELECTED);
i will continue to look for examples, if someone notices something small could you please help me out? thanks!
-dz
|
|
|
|
|