|
Hi there,
I have a group of three checkboxes. When I click on CheckBox2, a dialog box appears asking for user input. What it's suppose to do is when a user cancels a selection it should default to the first checkbox by making a call to CheckRadioButton. It does default but once the user clicks away from the application, the dialog box reappears as if the function to open up the dialog box is called once again. I isolated the problem and found that its the CheckRadioButton() that performs the recursive calls. How can I stop it from doing that? Thanks.
void CCheckBox::OnCheckBox2
{
CMyDialog dlg;
int nRet = -1;
nRet = dlg.DoModal();
// Handle the return value from DoModal
switch ( nRet )
{
case -1:
AfxMessageBox("Dialog box could not be created!");
break;
case IDOK:
{
..code...
break;
}
case IDABORT:
{
OnCheckBox1();
break;
}
case IDCANCEL:
{
OnCheckBox1();
break;
}
default:
break;
};
}
void CCheckBox::OnCheckBox1()
{
CheckRadioButton(IDC_RADIO1, IDC_RADIO3, IDC_RADIO1); //problem lies here
}
|
|
|
|
|
elephantstar wrote:
...when a user cancels a selection...
Cancels what selection?
elephantstar wrote:
...once the user clicks away from the application...
Closes the application, or puts focus on another application?
elephantstar wrote:
CheckRadioButton(IDC_RADIO1, IDC_RADIO3, IDC_RADIO1);
While I don't think it is related to the problem, are the values for IDC_RADIO1 , IDC_RADIO2 , and IDC_RADIO3 contiguous?
Why are you using CheckRadioButton() with checkboxes and not radio buttons?
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
-When the user selects cancel (CASE IDCANCEL) in the popup dialog box, it would call OnCheckBox1() to check the first radio button. The first button is the default selection.
-Puts focus on another application.
-The radio button values are contiguous. The buttons are radio buttons not checkboxes. Sorry to confuse you with the names.
|
|
|
|
|
elephantstar wrote:
-When the user selects cancel (CASE IDCANCEL) in the popup dialog box, it would call OnCheckBox1() to check the first radio button. The first button is the default selection.
Blake's suggestion is definitely the cleanest. Assign each of the radio buttons a CButton member variable (e.g., m_btnRadio1, m_btnRadio2, m_btnRadio3). Something like:
void CCheckBox::OnCheckBox1( void )
{
m_btnRadio2.SetCheck(BST_UNCHECKED);
m_btnRadio3.SetCheck(BST_UNCHECKED);
}
void CCheckBox::OnCheckBox2( void )
{
CMyDialog dlg;
int nReturn;
nReturn = dlg.DoModal();
if (IDABORT == nReturn || IDCANCEL == nReturn)
m_btnRadio1.SetCheck(BST_CHECKED);
else
m_btnRadio1.SetCheck(BST_UNCHECKED);
m_btnRadio3.SetCheck(BST_UNCHECKED);
}
void CCheckBox::OnCheckBox3( void )
{
m_btnRadio1.SetCheck(BST_UNCHECKED);
m_btnRadio2.SetCheck(BST_UNCHECKED);
}
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
I did as you suggested but there's a problem. The second radio button does not uncheck so I inserted m_btnRadio2.SetCheck(BST_UNCHECKED) when nReturn is either IDABORT or IDCANCEL. The recursion appears once again. Why is that? I grouped the buttons such that the first button has group property checked while the other two does not. What is going on?
|
|
|
|
|
I would manually check or uncheck the OTHER radio or checkbox buttons in a handler for a particular button. You are getting recursed because the handler for button 1 is calling a function that will try to UNCHECK buttons 2 and three and CHECK button 1 AGAIN. As a result, your button 1 OnCheckBox1 is getting called from itself.
If you want these three items to be mutualy exclusive, you should try to use radio buttons, and not check boxes. If you group them properly and make them all automatic, you won't even need such a handler to 'set' them in your code. Windows will do it automatically.
If you insist on following your current path, you should do the following instead:
void CCheckBox::OnCheckBox1()
{
// button 1 will check or uncheck itself
// uncheck button 2
CButton* pButton = (CButton*)GetDlgItem(IDC_RADIO2);
pButton->SetCheck(0);
// uncheck button 3
pButton = (CButton*)GetDlgItem(IDC_RADIO3);
pButton->SetCheck(0);
}
void CCheckBox::OnCheckBox2()
{
// uncheck button 1
CButton* pButton = (CButton*)GetDlgItem(IDC_RADIO1);
pButton->SetCheck(0);
// button 2 will check or uncheck itself
// uncheck button 3
pButton = (CButton*)GetDlgItem(IDC_RADIO3);
pButton->SetCheck(0);
}
similarly for button 3.
|
|
|
|
|
Sorry to confuse you. These buttons are radio buttons and they are contiguous and grouped properly. It's just giving me problems with the CheckRadioButton in OnCheckBox1().
|
|
|
|
|
In that case, I would not bother with the call to 'set' the radio buttons in the radio button handler. They should be toggling on and off properly on their own.
Your call is just redundant - so redundant, it actually recurses on itself.
|
|
|
|
|
So then what was wrong with my initial code? All I want to do is call CheckRadioButton to check the first button when the user cancels the dialog box selection in OnCheckBox2().
|
|
|
|
|
elephantstar wrote:
So then what was wrong with my initial code?
I'm not sure, but this code snippet works for me:
void CT9Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_RADIO1, m_btnRadio1);
DDX_Control(pDX, IDC_RADIO2, m_btnRadio2);
DDX_Control(pDX, IDC_RADIO3, m_btnRadio3);
}
BEGIN_MESSAGE_MAP(CT9Dlg, CDialog)
ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
ON_BN_CLICKED(IDC_RADIO3, OnRadio3)
END_MESSAGE_MAP()
BOOL CT9Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_btnRadio1.SetCheck(BST_CHECKED);
return TRUE;
}
void CT9Dlg::OnRadio1()
{
}
void CT9Dlg::OnRadio2()
{
CMyDialog dlg;
if (IDCANCEL == dlg.DoModal())
{
m_btnRadio1.SetCheck(BST_CHECKED);
m_btnRadio2.SetCheck(BST_UNCHECKED);
}
}
void CT9Dlg::OnRadio3()
{
}
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
I have the exact same setup, but the button in its event handler function does not like to uncheck itself (ie. m_btnRadio2.SetCheck(BST_UNCHECKED);) This is what causes the recursion and it recursivelly calls OnRadio2() about four times. I tried to test this on OnRadio1() by doing the following:
void CT9Dlg:OnRadio1()
{
MessageBox("Hello");
m_btnRadio1.SetCheck(BST_UNCHECKED); //recursive calls
m_btnRadio2.SetCheck(BST_CHECKED);
m_btnRadio3.SetCheck(BST_UNCHECKED);
}
OnRadio1() is repeately called because of that line of code. I just don't understand it. Should the group properties for each radio button be checked or just the first in the group? This bug is really bugging me.....
|
|
|
|
|
elephantstar wrote:
Should the group properties for each radio button be checked or just the first in the group?
Yes. The three radio buttons must also be next to each other in the Z-order.
elephantstar wrote:
This bug is really bugging me
If you can package the project up fairly small and still be able to reproduce the problem, feel free to send it to me and I'll take a look.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
My question is simple enough, I have project that I have been working on for probably 1 and a half years. It is written in C++ and is a fully fucntional RAM/memory searcher capable of searching for floats, ints, bytes , etc in RAM. I was curious as to WHERE I would have to go, to sell this project. By sell I meant give away the rights, and source code. I am looking for a site that allows one to sell their source codes/rights to it. If anyone knows any, please tell me.
|
|
|
|
|
www.download.com comes to mind, while www.tucows.com is another.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Im loading a menu from a resource with LoadMenu and then i insert an extra item using InsertMenuItem, this item has a bitmap, which causes the menu to be extended on the left, adding room for the bitmap. However, now the little arrows on the right that indicates submenus are drawn over the texts. Ive tried making the new item longer than all preexisting items and then everything looks okay. So my guess is that somewhere the width of the menu is precomputed and it doesnt get updated correctly when the extra room for the bitmap is added.
The documentation tells me to call DrawMenuBar(HWND) after changing a menu, but my menu is for a contextmenu not a window.
What am i doing wrong?
|
|
|
|
|
Hi there!
I'm working on a little service creating an icon in the syste tray. I want it to provide information through tooltips. Now my problem is that neither the system tray icons nor their tooltips can (afaik) be handled like other controls.
Is there a way to modify a tooltip's text while it is displayed or to display one without moveing the mouse over it? If not is it possible to receive a tooltip's mouse-over messages or it's position for implementing my own tooltip-like control?
thx
EDIT: i would prefer plain win32 code to mfc...
|
|
|
|
|
|
you can see my my article at following location it easy to understand here[^]
I Think It will Work
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
|
|
|
|
|
subject. Please!
Thanks a lot in advance.
|
|
|
|
|
Rigid programming discipline.
If that is not enough, Boundschecker.
|
|
|
|
|
You had to go out and type in that first remark, right? What if it's not my code?
"Boundschecker" - now I remember.
|
|
|
|
|
inner wrote:
You had to go out and type in that first remark, right? What if it's not my code?
Of course I had There is an almost religious belief in leak finding tools, garbage collectors etc. With stricter discipline, leaks are much less of a problem.
And even if the code is not yours, a global search for all instances of new , replacement of dynamically allocated stuff with static variables etc. will increase code quality - something that a memory leak tool will not - you'll only fix leaks, not bad memory usage. An example:
void SomeFunction()
{
CSomething* obj = new CSomething;
}
Boundschecker will find that you never deallocate obj . The chances are big that you replace the code with:
void SomeFunction()
{
CSomething* obj = new CSomething;
delete obj;
}
No leak. So far, so good. Now, the next maintaining developer copies part of the code to another function, so:
void SomeOtherFunction()
{
CSomething* obj = new CSomething;
}
New leak. If you instead corrected the code from the beginning to:
void SomeFunction()
{
CSomething obj;
}
you'll have less lines of code to analyze for the next maintainer, easier to find the necessary but risky dynamic allocations, and no temptations for the copy and paste brigade = higher quality code!
|
|
|
|
|
I understand all that! Thanks!
In 8 years of programming I never had to use boundschecker! Heck, that's why I even forgot the name of it and asked here. Used to hear about it from people but I always was able to find/fix issues with just what VC has to offer.
Now about the new and replacing it. You don't suggest to not use pointers at all, do you? Plus some of the problems that come up are not even related (seemingly - excuse my spelling ) to our in house code as you described with different maintainers. Our code uses libraries from other vendors. And right now I'm having a problem with this:
<br />
Detected memory leaks!<br />
Dumping objects -><br />
{67} client block at 0x015B4CE8, subtype 0, 64 bytes long.<br />
a CDynLinkLibrary object at $015B4CE8, 64 bytes long<br />
{63} client block at 0x015B4A08, subtype 0, 64 bytes long.<br />
a CDynLinkLibrary object at $015B4A08, 64 bytes long<br />
{56} client block at 0x015B2E18, subtype 0, 64 bytes long.<br />
a CDynLinkLibrary object at $015B2E18, 64 bytes long<br />
Object dump complete.<br />
Of course the issue is probably in my code but it comes up as a leak of a MFC class. Now I would just like to see where exactly those objects are created. How else can I see when the process loads like 50 DLLs? Only 4 of them are mine and the leak is not in them.
|
|
|
|
|
inner wrote:
Now about the new and replacing it. You don't suggest to not use pointers at all, do you?
No, of course not. But it should be used sparingly, and with care. An example where new is necessary is in containers, where lots of objects are stuffed in vector s or CObArray s. But in this case, by creating a container wrapper class, where the dtor deletes all memory, you'll avoid possible leaks. Another rule of thumb that I've used with great success is always writing the deallocation code at the same time as the allocation.
inner wrote:
Of course the issue is probably in my code but it comes up as a leak of a MFC class. Now I would just like to see where exactly those objects are created. How else can I see when the process loads like 50 DLLs?
This might very well be because a dtor is not called, so it's not certain that Boundschecker or other tools will point out the real error.
But I'm a great fan of Boundschecker. That tool has saved lots of development time around the word! It shouldn't be difficult to be allowed to buy it, if you are in a situation where you can't decide such stuff yourself - running your application(s) through it, it will most likely earn its cost the first day, when leaks and GDI-losses are detected
|
|
|
|
|
The thing about CDynLinkLibrary is that it's created like this, right? :
<br />
new CDynLinkLibrary(TrymfcdefDLL);<br />
Without assigning it to anything. And MFC knows to kill it when DLL is about to be unloaded, right?
And each MFC extension DLL has this, right? Well. In my DLLd dtors deffinitely get called. Cause I've replaced CDynLinkLibrary with my own CDynLinkLibrary derived class and ctor and dtor TRACE to output. So there are some other DLLs that have a problem I assume.
Do you know by any chance if latest is compatible with VC6? Cause I still have my projects there. I want to go VC 7 but, our management doesn't like to take such steps in a hurry.
|
|
|
|