|
Christian Graus wrote:
Sounds to me like your main problem is design skills.
Get a life. There are words for geeks like you, but I will spare
this fine forum. You have no idea what the requirements/design problems are. Nor do you know whether or not I'm the designer!
So you are completely out of line to suggest that I lack design skills.
The fact is, the software does need UI rework, but I've seen many a fine
application with more than 256 controls on a single dialog.
|
|
|
|
|
burnafatty wrote:
There are words for geeks like you,
Professional is one that springs to mind.
burnafatty wrote:
You have no idea what the requirements/design problems are.
Sorry for guessing that 'usable' was among them.
burnafatty wrote:
Nor do you know whether or not I'm the designer!
I didn't say you were, you moron. Whoever the designer is should be taken out the back and shot, and replaced with a monkey in a suit.
burnafatty wrote:
but I've seen many a fine
application with more than 256 controls on a single dialog.
Bollocks. You, sir, are an idiot.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
VC++ (v6, anyway) only allows 256 (I think...) controls to be placed using the dialog editor. The rest you'll have to manually put in the .rc file and not use the dialog editor, or create them dynamically.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Thank you Ryan and John for some useful
input!
It does indeed seem to be the case that the VC++ allows one to only add
256 controls via the dialog editor.
A shame. Somewhat of an arbitrary limit, no?
Of course, I can simply add them by hand as Ryan suggests.
And speaking of design weaknesses... wouldn't surprise me if Christian
was the geek who decided a byte was enough to store the control count in
the VC++ Dialog Editor and that there is no need to inform the user when
the limit is reached !
Excellent help from the forum, despite the flames... Thanks again.
|
|
|
|
|
I have a class structure forming a linked list where there is another class (declared as private within the main class) such as
class Link
{
private:
class LinkElement {
friend class Link...
...
Is it possible to access the PRIVATE members of the LinkElement class from a function that is not part of either of the two classes? I am trying to go through the linked list in a thread and trying to set various pointers to both the class Link and LinkElement but can't get access to that member. Is this possible or am I wasting my time?
|
|
|
|
|
#define private public
Or cast (LinkElement *)(classpointer + whatoffestis)
Or make the accessing class a friend or make som
accessor functions.
/M
- Don't sweat the petty things, and don't pet the sweaty things.
|
|
|
|
|
Thanks for the speedy reply, but I'm a bit confused with your answer. Here is what compiles and what doesn't for me
cLink::cLinkElement *pPointer; (compiles with the class warning that it's not initialized to anything)
now doing this: pPointer->pNextLink = NULL; (it shows up fine on class view btw but I get this compilation error: error C2248: 'pNextLink' : cannot access private member declared in class 'cLink::cLinkElement'
Is there anyway to get around this by not making the privates publics?
|
|
|
|
|
You do get what private means, right? It's an implementation detail that you shouldn't rely on, because somebody is guaranteed to change it the moment you start monkeying about with it.
Ignore the suggestion of #define private public (although made in jest), because that's the sort of thing that shots you in the foot later on.
You can fudge a solution by declaring an identical class/struct (with the same compiler packing options, etc!), but without the use of private. If you're lucky, the compiler will generate matching object layouts, and you can reinterpret_cast a pointer from one type to the other, and then access the private members through that.
Use of this technique is extremely brittle, and if I was your boss or peer, I'd be distinctly unimpressed with you, and make you junk that code.
Generally speaking, what you're trying to do indicates you don't understand the problem correctly, you don't understand the language properly, or you have a crap design that needs rethinking.
And if this is homework, then go back to the textbooks
Ian Darling
"The different versions of the UN*X brand operating system are numbered in a logical sequence: 5, 6, 7, 2, 2.9, 3, 4.0, III, 4.1, V, 4.2, V.2, and 4.3" - Alan Filipski
|
|
|
|
|
You are right on the issue that I have crap design, but this is no means homework. I have been programming c++ for about 2 years, completely self taught, and learning by my mistakes as I go along, since I have no one to teach me and I am not doing this for a living.
I have found a workaround to this by not declaring that member private anymore.
My understanding of private is that it's a member of a class that can be accessed only by the functions of that class and/or the class object, correct?
Also, although your criticism is appreciated, and I know I am a really bad coder (should have seen me 2 years ago!!!!) a little help would be appreciated to go along with the criticism.
|
|
|
|
|
georgiek50 wrote:
a little help would be appreciated to go along with the criticism.
Point taken
What exactly are you trying to achieve? I might be able to provide more constructive guidance with a brief outline of the task you're trying to solve.
Ian Darling
"The different versions of the UN*X brand operating system are numbered in a logical sequence: 5, 6, 7, 2, 2.9, 3, 4.0, III, 4.1, V, 4.2, V.2, and 4.3" - Alan Filipski
|
|
|
|
|
I have read some of the replies and the best way to learn is by doing.
If you wish to access a private memvebers of a class from a function that is not part of the class, you need to do one of three things: Provide member functions in your class to access the private member variables (preferded method), declare your function(s) as a friend of the class (this says the function knows what it is doing), or make the member data public (this is normaly a bad idea).
I recommend the books by Bruce Eckel for learning more about the C++ language itself, although they concern the langauge and not any specific OS.
Good luck, and have fun!
P.S. I love programming!
INTP
|
|
|
|
|
Thanks to everyone for their replies. Although I don't think that books can help me out any more because I am stubborn and never learn until I make the mistake. John's comment about creating another member function to get the details from the private members sounds the best way (don't know why I didn't think of it myself...been at it for 10 hours today, probably that's why!)
Thanks, again.
|
|
|
|
|
I would like to know if it is possible to have BOTH VC++ 7.1 and VC++ 6 installed on the same computer without anything going haywire?
|
|
|
|
|
Dunno why no-one has responded - am I the only one who does this ? I've run both for months with no hassles.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
Same here. Works perfectly!
As a matter of fact, I literally have VC 6, and VS .NET 2002 and just recently installed VS .NET 2003 as well and I've had no problems.
|
|
|
|
|
Yes, all three versions 6, 7, and 7.1 work just fine. We have a few systems at work running all three versions.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
I'm trying to make an application that uses a speech recognizer engine but it should write from a .cpp file in the dialogbox defined in other .cpp file and I don't know how could I do.
Here is some of my code so you can understand me better:
In my main code1.cpp I have defined a edit box with a member variable. In my code it appears on this way:
<br />
CIVOCOMDlg::CIVOCOMDlg(CWnd* pParent )<br />
: CDialog(CIVOCOMDlg::IDD, pParent)<br />
{<br />
m_strHeard = _T("");<br />
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);<br />
}<br />
<br />
void CIVOCOMDlg::DoDataExchange(CDataExchange* pDX)<br />
{<br />
CDialog::DoDataExchange(pDX);<br />
DDX_Text(pDX, IDC_GOT, m_strHeard);<br />
}<br />
Then in this code1.cpp I create a Grammar object:
<br />
BOOL loadGrammar( TCHAR *pszFile, BOOL bDictGram,<br />
ISRGramCommon **ppISRGramCommon )<br />
{<br />
...<br />
IUnknown * pIUnkGram;<br />
CGramDictSink *pGramDictSink = new CGramDictSink(NULL);<br />
pGramDictSink->AddRef();<br />
<br />
hRes = g_pISRCentral->GrammarLoad( SRGRMFMT_DICTATION, sData,<br />
pGramDictSink, IID_ISRGramNotifySink,<br />
&pIUnkGram );<br />
<br />
pGramDictSink->Release();<br />
...<br />
hRes = pIUnkGram->QueryInterface( IID_ISRGramCommon,(void **)ppISRGramCommon );<br />
pIUnkGram->Release();<br />
<br />
hRes = (*ppISRGramCommon)->Activate( NULL, FALSE, NULL );<br />
<br />
return SUCCEEDED( hRes );<br />
}<br />
In the code2.cpp file I have:
<br />
STDMETHODIMP CGramCFGSink::PhraseFinish( DWORD dwFlags,<br />
QWORD ,<br />
QWORD ,<br />
PSRPHRASE pSRPhrase,<br />
LPUNKNOWN )<br />
{<br />
if( !( dwFlags & ISRNOTEFIN_RECOGNIZED ) ||<br />
!( dwFlags & ISRNOTEFIN_THISGRAMMAR ) )<br />
{<br />
return S_OK;<br />
}<br />
<br />
PSRWORD pSRMax = (PSRWORD)( (BYTE*)pSRPhrase + pSRPhrase->dwSize );<br />
PSRWORD pSRWord = (PSRWORD)( pSRPhrase->abWords );<br />
TCHAR szText[256] = { _T('\0') };<br />
int nWords = 0;<br />
while( pSRWord < pSRMax )<br />
{<br />
if( nWords++ != 0 )<br />
_tcscat( szText, _T(" ") );<br />
<br />
_tcscat( szText, pSRWord->szWord );<br />
pSRWord = (PSRWORD)( (BYTE *)pSRWord + pSRWord->dwSize );<br />
}<br />
<br />
SetDlgItemText(m_hDlg, IDC_GOT, "Unrecognized\0");<br />
return S_OK;<br />
}<br />
This SetDlgItemText(m_hDlg, IDC_GOT, "Unrecognized\0"); doesn't work... It should write in the edit box the text "Unrecognized" whichever I say. I don't know what could I do so it works. Please, help me!
Thank you!
I have no idea
|
|
|
|
|
I'd like to make and edit control that only allows numeric entry with nothing else. Is the best way to do this through subclassing or simply deriving my control from CEdit. Also, what are the advantages or each? I'm new to this whole subclassing thing so I'm not really sure what it's best used for. Thanks in advance.
- monrobot13
|
|
|
|
|
If the edit control is on a dialog box, select the styles property tab in the resource editor and check number. This only applies to integer values though and not floating point or doubles values.
If you need to validate that the contents will only be values of the form "00.00", then you will need to derive you own class from the edit control and override entry validation. In this case I sugest a search of codeproject and its' afiliates to find articles on overriding the edit control, who knows may be someone has already solved the problem for you.
INTP
|
|
|
|
|
If you only want to use integers then the previously mentioned solution is definitely best. However if you want to use floating point numbers then you need create your own class derived from CEdit. You then must overload one function..the OnChar() function. This is called when the WM_CHAR message is passeg to your edit control. In the OnChar() function put the following..
void CNewEdit::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
// Ascii character for 0-9 is 48 to 57 inclusive
//Allows num characters and the backspace and delete chars
if(((nChar >= 48)&&(nChar <= 57))
||(nChar == 127)||(nChar == 8))
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
// only needed if floating point numbers being used.
// 46 is ascii code for '.'
if(nChar == 46)
{
// Get the existing text
char line[100];
LPTSTR buffer = line;
this->GetLine(0,buffer);
CString str = line;
// check if '.' is already present
if(str.Find('.') == -1)
{
int lineLen = this->LineLength();
// if no numbers already put a zero first
if(lineLen == 0)
{
this->SetSel(0,0);
this->ReplaceSel("0.");
}
else CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
}
its not perfect code but it does the job fine.
Then just add an edit control to your dialog and define a member variable(control) for your edit and it should work fine.
|
|
|
|
|
Thanks for the replies folks. It's put me on the right track.
- monrobot13
|
|
|
|
|
I have run into a strange memory overrun problem.
Note: The following example code may not reproduce the problem,
they are for illustation only.
Note: There are no compiler errors generated by either of the following
2 cases.
CASE 1: TEST_CTESTCLASS define in Test.cpp file.
Bounds Checker reported an overrun, when my application existed.
The VC++ 6.0 debugger does not show m_pTestClass1 as being a
member of CTestClass2 and yet I can still set it to NULL, with no
complants. If I do not set it to NULL, there is no overrun reported.
Note: The variable type CTestClass2 is declared as a member of a
CScrollView derived class. If the member is removed and made global,
then the overrun is not reported.
#ifndef __TEST_H__
#define __TEST_H__
class CTestClass1
{
int m_donothing;
public:
CTestClass() : m_donothing(0) {}
};
class CTestClass2
{
#ifdef TEST_CTESTCLASS
CTestClass1* m_pTestClass1;
#endif
public:
CTestClass2();
}
#endif // __TEST_H__
#include "stdafx.h"
#define TEST_CTESTCLASS
#include "Test.h"
CTestClass2::CTestClass2()
{
#ifdef TEST_CTESTCLASS
m_pTestClass1 = NULL;
#endif
}
CASE 2: TEST_CTESTCLASS define in Test.h file.
In case 2 below Bounds Checker reports no overruns and the VC++ 6.0
debugger shows m_pTestClass1 as being a member of CTestClass2.
#ifndef __TEST_H__
#define __TEST_H__
#define TEST_CTESTCLASS
class CTestClass1
{
int m_donothing;
public:
CTestClass() : m_donothing(0) {}
};
class CTestClass2
{
#ifdef TEST_CTESTCLASS
CTestClass1* m_pTestClass1;
#endif
public:
CTestClass2();
}
#endif // __TEST_H__
#include "stdafx.h"
#include "Test.h"
CTestClass2::CTestClass2()
{
#ifdef TEST_CTESTCLASS
m_pTestClass1 = NULL;
#endif
}
Does anyone have a clue as to what is causing this problem?
Thanks for any hints, etc..., that you can give me.
INTP
|
|
|
|
|
A couple of things I noticed:
- Shouldn't the compiler complain that definition for CTestClass2 is not terminated by a ; ?
- In general its bad mojo to put #ifdef s in the middle of a class definition. Change your compiler directives and you have a class with the same name but different addresses. You'll get random memory access violations with this type of object.
In fact the second thing is what is going on. The first example you only enable the directive when you compile just that file. In essence, what you defined and what you compiled don't match and hence the memory violation. Any other file that includes this will believe the object is defined the wrong way. The second one is "foolproof" since any inclusion will enable the directive.
As I said, its bad mojo to have precompiler directives in the middle of your definition. You really should avoid it to avoid problems just like this.
|
|
|
|
|
Thanks!
My brain must have been out to lunch! As soon as I read your answer it all became clear. Why I did not realize this for myself, I do not know.
Tom Larsen wrote:
- Shouldn't the compiler complain that definition for CTestClass2 is not terminated by a ; ?
:-DSorry about that! It was just an illustration of the problem, not the actual code that created it.
Tom Larsen wrote:
As I said, its bad mojo to have precompiler directives in the middle of your definition. You really should avoid it to avoid problems just like this.
Normaly I do not do this sort of thing. In this case, however, the code used to generate some data for analisys required direct access to member variables to produce the required charts.
I do not like the solution I came up with and will try to find a better way.
Thanks again!
INTP
|
|
|
|
|
What I recommend in cases like this is to wrap the entire class definition for both versions in #ifdef and then make typedef the type to the name you need. It is easier to manage a typedef than it is to manage and entire class that has its internal possibly changing. It also makes problems easier to track down because the code won't compile or link if the pre-compile directives are out of wack.
|
|
|
|
|