|
Mil10 wrote:
Yes it is possible, provided the user-defined binary predicate function shud b static. Otherwise u know, while linking a class, every member function will get an _this pointer automatically. This changes the function signature of a predicate function and will show error while compilation.
From Section 11.5 in "The C++ Programming Language, 3rd":
An ordinary member function declaration specifies three logically distinct things:
(1) The function can access the private part of the class declaration, and
(2) the function is in the scope of the class, and
(3) the function must be invoked on an object (has a this pointer).
By declaraing a member function static ($10.2.4), we can give it the first two properties only. By declaring a function a friend, we can give it the first property only.
Maxwell Chen
|
|
|
|
|
Thanks very much for the help.
James.
|
|
|
|
|
From Section 11.5 in "The C++ Programming Language, 3rd":
An ordinary member function declaration specifies three logically distinct things:
(1) The function can access the private part of the class declaration, and
(2) the function is in the scope of the class, and
(3) the function must be invoked on an object (has a this pointer).
By declaraing a member function static ($10.2.4), we can give it the first two properties only. By declaring a function a friend, we can give it the first property only.
very nice explanation - thanx Chen.
rgds...mil10
|
|
|
|
|
I think you want the mem_fun adapter function, which returns an appropriate functor object (typically a mem_fun1_t object).
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Do you mean something like,
class Sort1
{
private :
std::vector<int> v_ ;
static bool Cmp ( const int l, const int r )
{
return l > r ;
}
public :
Sort1 ()
{
v_.resize ( 10 ) ;
for ( int i = 0; i < 10; ++i )
{
v_ [ i ] = i ;
}
}
void DoSomething ()
{
std::sort ( v_.begin (), v_.end (), Cmp ) ;
}
void PrintV_ ()
{
for ( unsigned i = 0; i < v_.size (); ++i )
{
std::cout << v_ [ i ] << " " ;
}
std::cout << "\n" ;
}
} ;
int main()
{
Sort1 s ;
s.PrintV_ () ;
s.DoSomething () ;
s.PrintV_ () ;
return 0;
}
Or are you trying to use a member of the sortable class as the comparison function?
class Sortable
{
private :
int val_ ;
public :
Sortable ()
{
}
static bool Cmp ( const Sortable& l, const Sortable& r )
{
return l.val_ > r.val_ ;
}
} ;
...
std::vector<Sortable> vs ;
...
std::sort ( vs.begin (), vs.end (), Sortable::Cmp ) ;
Paul
|
|
|
|
|
Hi.
I have looked at all the updates to this thread and I am a little unsure as to how to proceed.
I appreciate all the advice and the different types of approach. However, if I may describe the problem with some additional constraints.
I cannot use the static member function approach as I need to be able to access a set of compound sort ranges defined in a vector table declared privately within the class.
I therefore need a mechanism that would allow me to specify a non-static class member function as the comparison function on the sort call.
Any more advice would be most welcome.
James.
|
|
|
|
|
Hi.
If no one has a solution to this particular situation, then I might be better served by simply writing my own sort routine. That way I can provide a comparison function with the operands and access that I require. I have written numerous sort routines before, especially in the days before C++ and the STL ( as you might have guessed, I am quite new to C++). I was hoping, prehaps naively, that the STL could solve all my algorithmic problems elegantly but maybe that is just not the case.
Thanks for the contributions.
James.
|
|
|
|
|
You may consider this too ugly...
template <typename C, typename S> struct MemFunCmp_t
{
bool (C::*pmf_ )( const S&, const S& ) ;
C& rC_ ;
MemFunCmp_t ( C& rC, bool (C::*f)( const S&, const S& )) : rC_ ( rC ), pmf_ ( f )
{
}
bool operator () ( const S& l, const S& r )
{
return (rC_.*pmf_) ( l, r ) ;
}
} ;
template <typename C, typename S> MemFunCmp_t< C, S > MemFunCmp ( C& c, bool (C::*f)( const S&, const S&))
{
return MemFunCmp_t <C, S>( c, f ) ;
}
class Sort2
{
private :
std::vector<int> v_ ;
bool Cmp2 ( const int& l, const int& r )
{
return l > r ;
}
public :
Sort2 ()
{
v_.resize ( 10 ) ;
for ( int i = 0; i < 10; ++i )
{
v_ [ i ] = i ;
}
}
void DoSomething ()
{
std::sort ( v_.begin (), v_.end (), MemFunCmp ( *this, Cmp2 )) ;
}
void PrintV_ ()
{
for ( unsigned i = 0; i < v_.size (); ++i )
{
std::cout << v_ [ i ] << " " ;
}
std::cout << "\n" ;
}
} ;
int main()
{
Sort2 s ;
s.PrintV_ () ;
s.DoSomething () ;
s.PrintV_ () ;
return 0;
}
But I think it does what you're asking for.
It builds and runs on VC7.1, I believe it's standard C++. YMMV.
Paul
|
|
|
|
|
Hi.
Thanks for the update. The 'work around' is not at all ugly but prehaps slightly convoluted. Nevertheless, I have incorporated it into my application and it works prefectly. I like your solution because I have learnt something new from it.
Best Regards.
James.
|
|
|
|
|
Ok, im a complete newb at C++ and am just starting off. I wanna make a program MFC of course and when i click button "Create" i want it to bring up Dialog "B" which is the other dialog besides "A" can someone tell me the quickest and eastesy way of doing this? If it wouldnt be too much trouble of course...
Thanks
|
|
|
|
|
You create a dialog in your resource editor, and then it will create a class derived from CDialog, say you call the class CNewDlg. Then the code looks like this:
OnClickCreate() // this method is created by the IDE for you on request, I'm not sure of it's signature anymore, it's been too long
{
CNewDlg dlg;
if (dlg.DoModal() == IDOK) //OK was clicked
{
//respond to the OK button being clicked. At this point, any member variables in the CNewDlg instance
// you created are still accessible, but anything in windows ( edit boxes, etc. ) isn't, as they have been destroyed.
}
}
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
hey, I override WM_MOVING to change the drag rectangle of a moving window to "snap" to the borders of the desktop... the problem is "unsnapping" -- i can't unsnap because the original drag rectangle isn't stored and whenever i want to move the drag rectangle it keeps moving back to the snapped position:
case WM_MOVING:
{
RECT rcWorkArea;
if (SystemParametersInfo(SPI_GETWORKAREA,0,&rcWorkArea,0))
{
RECT* pRC = (RECT*)lParam;
if (pRC->bottom >= rcWorkArea.bottom - 10)
OffsetRect(pRC,0,rcWorkArea.bottom - pRC->bottom);
else if (pRC->top <= rcWorkArea.top + 10)
OffsetRect(pRC,0,rcWorkArea.top - pRC->top);
}
return TRUE;
}
also, how the hell do i get the position of the mouse! i thought there was a function GetMousePos which took in a pointer to a POINT structure but it doesn't exist... so how do i do it?
r -€
|
|
|
|
|
for mouse pos, try with
GetCursorPos(LPPOINT);
or
DWORD pos = GetMessagePos();
CPoint pt(LOWORD(pos), HIWORD(pos));
ScreenToClient(&pt);
KalliMan
|
|
|
|
|
If you want to unsnap you will need to track the direction of the mouse movement. i.e. if it is moving away from the edge then do not apply the snap criteria.
For this you will need to store the last position of the mouse then compare with current position. You can then decide whether to snap or not.
Ant.
|
|
|
|
|
Hi.
I am writing an application where I have a dialog with one combo box and 4 edit controls. Now when I open that dialog there is always first edit control focused. How can change this behaviour so for example rather than the first I would like the third edit control to be automatically focused, so when the user opens the dialog one can start typing into that (third) edit control rather than using a mouse to click on it first.
I thought it would be as simple as that:
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CtrlSourceExt.SetFocus(); // PROBLEM IS HERE - Set foucus to this edit control (this Doesn't work) (NOTE: variable CtrlSourceExt is of type CEdit)
UpdateData();
return TRUE; // return TRUE unless you set the focus to a control
}
Actually I remember in VC++ 6 I could specify the order of things to be focused in resource editor when designing a dialog. So if I had say 4 edit controls I could set focus in this order 4,2,1,3 so the first hightlighed edit control would be 4 then if the user pressed tab once it would take him to edit control 2 then 1 and 3. But now in VC++ 2003 .NET it doesnt work. Same thing with profiler I just cant find it. I dont know why they got rid of such useful thing. Anyway going back to the subject. Can anybody help?
Thanks.
|
|
|
|
|
Perhaps u must set the focus in 'CTestDlg::OnShowWindow()'.
KalliMan
|
|
|
|
|
robert_s wrote:
return TRUE; // return TRUE unless you set the focus to a control
TOXCCT >>> GEII power
|
|
|
|
|
Thanks toxcct ) Returning FALSE fixes the problem
HAHA!!! S*** I haven't noticed these comments generated by a wizard. How embarassing....
Sorry!
But still its a bit silly to me to return FALSE. The function name (OnInitiDialog) suggests that I am initializing a dialog and if successfully initialized it should return TRUE otherwise FALSE if unsuccessful. But here even though the dialog is initialized I am returning FALSE. hehe! I cant see any logic here? Perhaps I still need to learn more the way how MS people think ) hehe..
Thanks all for help!!
|
|
|
|
|
robert_s wrote:
But still its a bit silly to me to return FALSE. The function name (OnInitiDialog) suggests that I am initializing a dialog...
The return value has nothing to with success/failure. It simply denotes whether the application has set the input focus to one of the controls in the dialog box.
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
hello,
do you know the name of any book that explain how to program a cd writer I need to know how to burn cds -erase cds etc.
Thanks in advance
|
|
|
|
|
|
I would like to know how create child windows at runtime and get them all displyed
Yes I've used:
- a pointer for the control
- the new operator for the window type
- CWnd::Create method
- CWnd::ShowWindow method
- CWnd::MoveWindow method
All I'm getting is a blank dialog box. I can't understand why.
What do I have to do display them?
|
|
|
|
|
Please show us a little bit of your source code...
|
|
|
|
|
This is a snippets of my code
in the dialog header file
class CMyDialouge : public CDialog{<br />
public CEdit *m_EditWnd;<br />
CRect m_WndRect;<br />
};
The dialog's constructor
CMyDialouge::CMyDialouge(CWnd* pParent )<br />
: CDialog(CMyDialogue::IDD, pParent)<br />
{<br />
m_EditWnd = NULL;<br />
m_Rect = CRect(23,30,54,14);<br />
}<br />
Create 5 versions of the edit control
BOOL CMyDialouge::OnInitDialog()<br />
{<br />
this->m_EditWnd = new CEdit[5];<br />
<br />
for(int i = 0; i < 5; i++)<br />
{<br />
m_EditBox[i].Create(WS_CHILD|ES_MULTILINE| WS_VISIBLE|ES_WANTRETURN,CRect(0,0,0,0),this,1000 + i);<br />
m_EditWnd[i].MoveWindow(m_Rect);<br />
m_EditWnd[i].ShowWindow(SW_SHOW);<br />
<br />
m_Rect.top += 30;<br />
}<br />
return TRUE;
<br />
}
void CMyDialouge::OnDestroy<br />
{<br />
for (int i=0; i <5; i++)<br />
m_EditWnd[i].DestroyWindow();<br />
<br />
CDialog::OnDestroy();<br />
<br />
delete[] m_EditWnd;<br />
}<br />
I hope I've clarified it.
Thanks Alton
|
|
|
|
|
In CMyDialouge::OnInitDialog() you wrote
m_EditBox[i].Create(WS_CHILD|ES_MULTILINE| WS_VISIBLE|ES_WANTRETURN,CRect(0,0,0,0),this,1000 + i);
m_EditWnd[i].MoveWindow(m
You used m_EditBox AND m_EditWnd, may it be that this is your mistake?
Jens
|
|
|
|