|
Hi.
I have an interesting problem. I am working on a program with with a CEditView window. I use GetEditCtrl().SetWindowsText to update the view with new text. Whenever I call SetWIndowsText, the CEditView repaint the entire view, but it always resets the scroll position. For example, let say I am view line 200. (line 200 is at top of view). Whenever I update the view, CEditView resets the current view to line 0.
Is there a way to set what line should CEditView beginning?
Thanks,
Kuphryn
|
|
|
|
|
Use
CEdit& edit = GetEditCtrl() ;
edit.LineScroll(200,0) ;
|
|
|
|
|
Thanks.
A special thanks to Scott McPhillips of MSDN newsgroup also for the solution (he posted it yesterday).
Kuphryn
|
|
|
|
|
Hi,
CStringArray& MyArrayFunction()
{
CStringArray aArray;
aArray.SetSize(...
aArray.SetAt(...
...
return aArray;
}
Question1: is the return line OK?
Question2: how can I fill another array in my code with the returned stringarray?
I tried
CStringArray aMyArray = MyArrayFunction();
but
error C2440: 'initializing' : cannot convert from 'class CStringArray' to 'class CStringArray'
is the answer.
Could you please help me?
Thanks a lot
Ricardo
|
|
|
|
|
change to:
CStringArray* MyArrayFunction()
{
CStringArray *paArray = new CStringArray();
paArray->SetSize(...);
return paArray;
}
getting the array
CStringArray *paMyArray = MyArrayFunction();
do not foget to delete paMyArray;
soptest
|
|
|
|
|
|
I have the following problem. I have included this header file many times in my code with no problems. Then I "included" it into a new file which now produces errors in my typedef statement. I really dont know if it is a problem with namespace as I have no idea how to use that correctly anyway.
Code for "entity.h"
<br />
#include <list.h><br />
<br />
using namespace std ;<br />
<br />
typedef struct<br />
{<br />
int ref;<br />
std::string name;<br />
<br />
}EntityData;<br />
typedef list<EntityData> ENTITYLIST;<br />
How can I include this file with out errors??
Code for "NewFile.cpp"
<br />
#include "stdafx.h"<br />
#include "NewFile.h"<br />
#include <list.h><br />
#include "entity.h"
using namespace std;
Pease help!!
---
|
|
|
|
|
Ooops, Rather than delete this message I will just post my solution.
Use <list> instead of <List.h>
---
|
|
|
|
|
what is the error?
soptest
|
|
|
|
|
It didnt understand the list definition in my header file. This is now fixed due to the way I included the list.h file. I.E #include <list> without a .h
Thanks anyway.
---
|
|
|
|
|
The list.h is the old header file from the old C++ standard and is included to prevent old code from breaking. That is why if you are developing new code you should use the plain <list> header.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
Also to make sure your header is included only once you must do the #ifdef stuff
#if !defined __ENTITIY_H
#define __ENTITIY_H
....
#endif
Best regards,
Alexandru Savescu
|
|
|
|
|
This is kind of trivial, but I have an ATL DCOM server project, and when I monitor it in the task manager, the .exe's name gets mangled. So, instead of the process entry reading DCOMServer.exe, I see DCOMS~1. Sometimes the problem doesn't show up. I just wondered if anyone knew why this happens.
|
|
|
|
|
If you look at how its registered, either in the registry or in OLEView, its probably using short file names. Its probably not a big deal unless you need it to be in long name format.
Like it or not, I'm right.
|
|
|
|
|
#include <string>
#include <iostream.h>
using namespace std;
string pres[5];
void loadPrescriptions(){
//this will read from a file later
pres[0] = "David Seruyange";
pres[1] = "Laura Bush";
pres[2] = "Jamie Myers";
pres[3] = "Pamela Anderson Lee";
pres[4] = "Grace Lozano";
}
int main(){
int select;
char quit;
loadPrescriptions();
while(1){ //forever
cout << "Enter a prescription ID\n";
cin >> select;
cout << "You are looking for:\n";
cout << pres[select].c_str() << endl;
cout << "Do again?\n";
cin >> quit;
if(quit=='q'||quit=='Q'){
break;
}
}
return(0);
}
It compiles perfectly but when I try to 'build' I get:
Linking...
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/string.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
*->>Always working on my game, teach me
*->>something new.
cout << "dav1d\n";
|
|
|
|
|
Go to Linker settings, In the command line text box type the following
/ENTRY:_mainCRTStartup /SUBSYSTEM:CONSOLE
|
|
|
|
|
Is his problem that the project is not a console project, so it's looking for winmain instead of main ? I thought of that after I posted, although my advice ( create a new console app and paste the code in ) would still solve it, and to be honest, I had no idea it could be set in this manner.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
And you don't spend much time with the opposite sex working day and night, unless the pizza delivery person happens to be young, cute, single and female. I can assure you, I've consumed more than a programmer's allotment of pizza, and these conditions have never aligned. - Christopher Duncan - 18/04/2002
|
|
|
|
|
Exactly
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?
|
|
|
|
|
1/ Do NOT include iostream.h, include iostream.
2/ Do using statements for the parts of std you need only.
3/ FYI if you allow HTML in a post, you can do & lt and & gt (without the space) to get < >. You can also wrap code in <pre> tags to get this:
This is my code
4/ I just pasted this code into a console app, and it runs fine, which again makes me think the problem is that your code is not included in a project. BTW, as you're using the std library anyhow, did you consider making your list a vector ? I have an article on CP if you don't know how to use one. It means your array can dynamically grow.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
And you don't spend much time with the opposite sex working day and night, unless the pizza delivery person happens to be young, cute, single and female. I can assure you, I've consumed more than a programmer's allotment of pizza, and these conditions have never aligned. - Christopher Duncan - 18/04/2002
|
|
|
|
|
I agree with Christian. Your problem is that you have setup a Win32 appliction and not a "Win32 Console Application". For Win32 applications, the linker expects to find a WinMain() function to use as the entry point for the application. But as you are well aware, you don't have a WinMain() function; you have a main() function. To use main(), you must create a "Win32 Console Application" and then the linker will look for main().
severehammer@yahoo.com
|
|
|
|
|
Hi:
Can anyone recommend a good read on memory management in C++.
Particularly I am interested in things like when to use stack vs. heap; tips on how to make program run faster and use memory efficiently, etc.
Thanks
|
|
|
|
|
I don't really know of any web sites the would lay out what you want exactly, but most beginning C books go into memory management in reasonable depth. Here's a few things to think about:
1. If you use a container class (e.g. CArray, std::vector, etc.), keep in mind that any TYPE that you use in that template class, must either be a pointer to that type, or the type must be a class that has a copy constructor defined. For instance:
<br>
CArray<MyClass, MyClass> m_myClassArray;
<br>
for( int x = 0; x < 2000; ++x )
{
MyClass myClass;
m_myClassArray.Add( myClass );
}
This example works, but keep in mind that a copy was made with every call to add. Since this call was made several thousand times, you'd have a real bottleneck on your hands. Instead, you should define the container such that it takes pointers in the add statement. Like this:
CArray<MyClass, MyClass*> m_myClassArray;
<br>
for( int x = 0; x < 2000; ++x )
{
MyClass* pMyClass = new MyClass;
m_myClassArray.Add( pMyClass );
}
This time a pointer was copied. This is far more efficient. It would be helpful later on as well. Take a look:
for( int x = 0; x < m_myClassArray.GetSize(); ++x )
{
MyClass* pMyClass = (MyClass*)m_myClassArray.GetAt( x );
pMyClass->DoSomething();
}
If this had been done the other way, a copy would have been created for every call to GetAt(). Once again a huge bottleneck. (keep in mind that you must iterate through this whole array and call delete on each pointer when you are done with the container).
2. When you want to create a complex class/data structure inside a method and then pass that back to the caller, you *must* use the heap:
MyClass* CreateMyClass( CString str )
{
MyClass* pMyClass = new MyClass( str );
return pMyClass;
}
You could have it pass back a copy, but again this is inefficient and probably not what you want--especially when you are passing back a container. You just have to be careful that you delete that object when you're done.
I could give some other points here, but I've run out of time. Maybe some others can pick up where I left off.
In general, knowing when to use one over the other (i.e. stack v. heap), depends on the context of where you're working in the code. It is something that starts to make more sense the more programming you do.
-Matt
------------------------------------------
The 3 great virtues of a programmer:
Laziness, Impatience, and Hubris.
--Larry Wall
|
|
|
|
|
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
|
|
|
|
|