|
Hi
When posted I was under the impression that Drawitem runs after window Creation which in my case is the DDX_Control however it runs after the return of the OnInitDialog
Sorry and thanks
|
|
|
|
|
This subject is a foggy topic in my head could you help me clarify things a little.
basically there are two ways to write a class in c++
-declare a class and add in the class body only class member variables and function declarations and then layout the code for function bodies somewhere outside (in the same cpp file or in a different cpp file if the class declaration was made in a header file)
-declare a class and add in the class body class member variables and function bodies (not just the declarations), the later solution resembling how things are done in C#. The former approach can be used in the main cpp file but also in a c++ header file. The later approach can only be used in the main cpp file is that correct? could you place for instance a class declaration containing function bodies (not just declarations) in a another cpp file belonging to the same project or in a header file?
Is it that the h and cpp file of the same name are compiled into a single binary file which is then used by the binary form of the main cpp file? and that the header file is there just as an index/entry point to the class functions
|
|
|
|
|
Let's talk first about C where the C++ came from. From the compiler's point of view there is not difference between .h and .cpp files. They are both source files and it treats them identically. By convention (and only by convention) we place declarations in the .h file and code in .cpp one. Also we have to make sure that the compiler sees the code generating lines only once. For instance if you place a function definition:
int my_function () {return 3;} in a .h file and that file is included by two different .cpp files, the compiler will happily compile them but the linker will complain that it has two instances of the same function and it doesn't know which one to pick.
What we do in this case is to place a function declaration in the .h file:
int my_func (); Now we can put the function definition in one of the .cpp files and everyone will be happy: the compiler has a declaration for the function so it can check all calls against the function prototype and the linker has only one body for the function.
Now we move to C++. Assume you place this:
class A {
public:
int func1 ();
int func2 () {return 2;}
}; in a header file. The member func1 is only declared while the member func2 is also defined. Here the compiler performs a little trick: because the definition of func1 is within the body of a class it tells the linker to use only one instance of the generated code.
If we add a definition for func1 inside the same header file:
class A {
public:
int func1 ();
int func2 () {return 2;}
};
int A::func1 () {return 1;}
the compiler will treat it as a regular function and again, if the header is included by two different .cpp file, the linker will complain that the function is doubly defined.
We can do two things now. One is to place an inline specifier in front of the function:
class A {
public:
int func1 ();
int func2 () {return 2;}
};
inline int A::func1 () {return 1;} The compiler will use the same trick as if the function would have been defined inside the body of the class and tell linker to use only one instance.
The other is to simply place the function definition in a .cpp file and in that case the linker will see it only once.
So in the end you have 3 alternatives:
1. place the function definition in the class body.
2. place it in the header file and make it inline.
3. place it in one .cpp file
Which solution you choose depends on your teste and what you want to achieve. The difference between 1 and 2 is purely a question of style (I prefer 2, but that's just me). Number 3 used to be by far the most popular choice until recently when header only libraries have proliferated. It's up to you to decide.
Mircea
|
|
|
|
|
To add to what Mircea said, function definitions (implementations) usually go in a .cpp for two reasons:
- By default, a header is recompiled each time that a .cpp
#include s it, so defining large functions in headers can really slow down a compile. Some compilers optimize this, but it isn't guaranteed. - A header should be an interface, with implementation details going in a .cpp rather than cluttering the header.
However, there are two situations when function definitions go in a header:
- If a function is simple, usually just a single line, it's expedient to just define it in the header.
- A function template, or a function in a class template, is defined in a header.
As far as where to define functions is concerned, I prefer to define each class in its own header (Class.h) and implement its functions in Class.cpp. This isn't mandatory, because the .h and .cpp are not compiled into a single binary. Each .cpp, along with all the headers that it #include s, is compiled into its own binary, after which the linker merges them all.
Some C++ gurus say there is no rationale for putting each class in its own .h and .cpp. They're wrong, but there are exceptions:
- A "helper" class (used only to implement another one) can be defined in the same .cpp as the only class that uses it.
- Small, related classes can be defined in a common .h and implemented in a common .cpp.
However, each important class gets its own .h and .cpp. This makes code easy to find, even outside the IDE. Besides, anything else is arbitrary; no one would suggest that one big .cpp is good for a project with 10,000+ lines of code. Some kind of organization is needed, and the approach that I've described is the obvious one.
|
|
|
|
|
thanks Greg that`s very descriptive
|
|
|
|
|
you are a tax calculator in company, and you should calculate the tax based on staff’s salary as follows:
-the salary is less than 600, the tax is 0.
-the salary is greater than 600 and less than 800, the tax is 10% of the salary.
-the salary is greater than 800 and less than 1000, the tax is 13% of the salary.
-the salary is greater than 1000 and less than 1500, the tax is 18% of the salary.
-the salary is greater than 1500, tax is 20% of the salary.
Write a program in C++ to ask the user to enter the salary then calculate the tax using:
If-Only structure, If-Else structure, Switch-Case structure.
|
|
|
|
|
So do it! Write that program! It won't write itself ...
|
|
|
|
|
It looks like a good start to develop a working program!
|
|
|
|
|
Hi there!
I have started this Tax software program for you:
#include <iostream>
using namespace std;
int main()
{
cout<< "Tax software developed by https://iq.direct" << endl;
cout<< "Enter Salary:";
double s = 0, t = 0;
cin >> s;
cout<<"you entered: " << s << endl;
if (s < 600)
{
t = 0;
}
if (s >= 600 && s < 800 )
{
t = s * 0.1;
}
if (s >= 800 && s < 1000 )
{
t = s * 0.13;
}
cout<< "The tax will be :" << t;
return 0;
}
|
|
|
|
|
Hi
I have done this many times streamin text, this time however the text just doesn't appear I do a SW_SHOW on both the rich edit and the dialog
So I decided just to do a simple test copy "this is a test\r\n": info the pBuff *pcb = 16 for the next call I have *pcb = 0 to tell rich edit no more
The Dialog box and rich edit appear with no test however When I press any character on my keyboard e.g type D The text This is a text magically appears in front of D
Any ideas are appreciated
|
|
|
|
|
No idea until we will see your actual code.
|
|
|
|
|
I’ll post it about 7 am thank you
|
|
|
|
|
i'LL POST THREE pieces 1) the oninitdialog of the parent Cdialog 2) the Steamin 3) resource file Tell me if you want to see more thanks you
BOOL CStorge::OnInitDialog()
{
int numolines;
storagepointer = new CRichEditCtrl;
CDialog::OnInitDialog();
CHARFORMAT cf2 = { 0 };
STREAMIN((WPARAM)storage_ptr, (LPARAM)storagelen);
storagepointer->SetSel(0, -1);
cf2.cbSize = sizeof(cf2);
cf2.dwMask = CFM_FACE | CFM_PROTECTED;
cf2.dwEffects = CFE_PROTECTED;
memcpy(&cf2.szFaceName[0], "Courier New",12);
storagepointer->SetSelectionCharFormat(cf2);
storagepointer->SetSel(0, 0);
storagepointer->ShowWindow(SW_SHOW);
ShowWindow(SW_SHOW);
return TRUE;
}
call to setup STREAMIN
LRESULT CStorge::STREAMIN(WPARAM mywparam, LPARAM mylparam)
{
char *sendptr;
sendptr = (char*)mywparam + 4;
streaminparm parms;
parms.storpointer = (char *)sendptr;
parms.storlen = (int)mylparam;
EDITSTREAM STORAGESTREAM;
STORAGESTREAM.pfnCallback = storagestreamin;
STORAGESTREAM.dwCookie = mywparam;
STORAGESTREAM.dwCookie = (DWORD_PTR) &parms;
long numstream = storagepointer->StreamIn(SF_TEXT,STORAGESTREAM);
return TRUE;
}
the Streamin function
DWORD storagestreamin(DWORD_PTR dwCookie,
LPBYTE pbBuff,
LONG cb,
LONG* pcb)
{
static BOOL flag = 0;
if (flag == 0)
flag = 1;
else
{
*pcb = 0;
flag = 0;
return 0;
}
int i;
streaminparm* inparms = (streaminparm *)dwCookie;
void* holdptr = inparms->storpointer;
char* holdptr1 = (char*)pbBuff;
int totalen = inparms->storlen;
memcpy((char *)pbBuff, "This is a test\r\n",16);
*pcb = 16;
return 0;
for (i = 0; i < totalen; i += storageline)
{
memcpy(holdptr1, holdptr, storageline);
holdptr = (char*)holdptr + storageline;
holdptr1 = (char*)holdptr1 + storageline;
*holdptr1 = '\r';
holdptr1 = (char*)holdptr1 + 1;
*holdptr1 = '\n';
*pcb += 74;
}
return 0;
}
the Dataexchange member to create the rich edit HWND
void CStorge::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_ASID, asidstr);
DDX_Text(pDX, IDC_SP, spstr);
DDX_Text(pDX, IDC_TCB, tcbstr);
DDX_Text(pDX, IDC_FP, fpstr);
DDX_Control(pDX, IDC_EDIT2, (CWnd&) *storagepointer);
}
The resource indentfier of the cdialog with richedit
IDD_DIALOG10 DIALOGEX 0, 0, 769, 429
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Storage View / Change"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CTEXT "",IDC_TCB,45,30,47,8
CTEXT "OwnIng TCB",IDC_STATIC,41,13,58,8
CTEXT "",IDC_SP,164,28,43,8
CTEXT "Storage SubPool",IDC_STATIC,162,12,55,8
CTEXT "",IDC_ASID,265,26,32,8
CTEXT "Asid",IDC_STATIC,269,9,31,8
CTEXT "",IDC_FP,399,31,19,8
CTEXT "Fetch Protect Key",IDC_STATIC,392,15,63,8
CONTROL "",IDC_CUSTOM5,"PieCOntrol",WS_TABSTOP,617,99,109,109
COMBOBOX IDC_COMBO1,491,236,48,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_EDIT2,"RichEdit20A",ES_MULTILINE | WS_BORDER | WS_TABSTOP | WS_VISIBLE, 45,106,494,314 THE RICH EDIT
EDITTEXT IDC_EDIT1,45,110,494,314,ES_AUTOHSCROLL
COMBOBOX IDC_COMBO2,637,244,67,16,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_LIST2,641,310,68,11,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
|
|
|
|
|
ForNow wrote: CDialog::OnInitDialog();
CHARFORMAT cf2 = { 0 };
STREAMIN((WPARAM)<b>storage_ptr</b>, (LPARAM)storagelen);</blockquote>
What is storage_ptr? Its type and value?
|
|
|
|
|
you think thats the problem I should make it a CRicheditrl *
BTW I did Call AfxRichEditInit and I did observer that storage__ptr had a Hwnd after the DoDataExange
void* storage_ptr;
|
|
|
|
|
ForNow wrote: C++Copy Code
void* storage_ptr;
You mean you pass an uninitialized pointer into your STREAMIN method?
BTW, did you debug your code (and, particularly, this STREAMIN method)?
|
|
|
|
|
The Ponter I pass to the streamin is 1) the data ptr and 2) the length of it I did debug it and it passed the value back that I wanted in pBuff and *pcb
storage_ptr should be of type CrRicheditCtrl * instead of void * but it does a value and After the Call Cdialog::OnInitDialog it Called my DoDataExchage and had a valid HWND
In in fact if you look at that small test when I pass "this is a test\r\n" back to pBuff and *pcb = 16 that doesn't display
When I type any chanarcter in the rich edit for example a D this is a test follow it for example looks like this DThis is a test
thanks
|
|
|
|
|
I could not test your "code" because there is a lot of problems with:
undeclared identifier
undeclared identifier
cannot convert from 'DWORD (__cdecl *)(DWORD_PTR,LPBYTE,LONG,LONG *)' to 'EDITSTREAMCALLBACK'
...
and so on.
Could you post a code (sample project) that would reproduce your problem?
|
|
|
|
|
is there anywhere I could zip it if not the total project is 6 .cpp files with 6 headers and resource file
thanks you are really nice
|
|
|
|
|
Sorry! I don't know.
But if you won't find a way to do that then you could repost your question in Visual C++ Programming
Or just email it to me: <my surname=""> at <onlinehome.de>
|
|
|
|
|
Ill take the latter thanks but this mini project is a tcp/ip application that gets data into the RichEdit from a z z/os machine
let me see if I can somehow segregate it The rich edit portion that is causing the problems and then get a clean build and i'll send it over thanks you are very nice
|
|
|
|
|
You have to simplify your project code until it will reproduce the problem. Just make a very simple project with your RichEdit without any TCP/IP and other IPCs.
Test it. If you won't find the reason of the trouble while debugging this test project then post it to me or/and to the community.
|
|
|
|
|
|
Victor
commented out IDC_EDIT1 and the stream out worked
you are very nice guy for your offer
IDD_DIALOG10 DIALOGEX 0, 0, 769, 429
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Storage View / Change"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CTEXT "",IDC_TCB,45,30,47,8
CTEXT "OwnIng TCB",IDC_STATIC,41,13,58,8
CTEXT "",IDC_SP,164,28,43,8
CTEXT "Storage SubPool",IDC_STATIC,162,12,55,8
CTEXT "",IDC_ASID,265,26,32,8
CTEXT "Asid",IDC_STATIC,269,9,31,8
CTEXT "",IDC_FP,399,31,19,8
CTEXT "Fetch Protect Key",IDC_STATIC,392,15,63,8
CONTROL "",IDC_CUSTOM5,"PieCOntrol",WS_TABSTOP,617,99,109,109
COMBOBOX IDC_COMBO1,491,236,48,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "",IDC_EDIT2,"RichEdit20A",ES_MULTILINE | WS_BORDER | WS_TABSTOP,45,106,494,314
COMBOBOX IDC_COMBO2,637,244,67,16,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_LIST2,641,310,68,11,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
|
|
|
|
|
Does it mean that your text was under the IDC_EDIT1 control? Or what???
|
|
|
|
|