CTreeCtrl setting selected item programmatically - mfc

I want to programmatically set the state of a tree ctrl item to be selected and then process it elsewhere. I want to do this to reuse the code that is called when the user clicks it. I try this but its failing, why?
// somewhere in the code
m_tree.SetItemState(hItemToBeSelected, TVIS_SELECTED, TVIS_SELECTED);
CommonFunction();
// elsewhere
CommonFunction()
{
HTREEITEM h = m_tree.GetSelectedItem();// this returns NULL.
}
How can I do this?

You want to use SelectItem instead of SetItemState: http://msdn.microsoft.com/en-us/library/w8hy20sy(v=VS.100).aspx

Related

CMFCOutlookBarTabCtrl::SetActiveTab not working

I have added a CMFCOutlookBar control to a dialog. This outlookbar contains some 12 trees.
As per following link https://msdn.microsoft.com/en-us/library/bb983453.aspx
we can set active tab (in my case tree control) of our wish.
but it doesn't seems to work.
as per above link this function returns non zero value on success. Indeed it is returning 1 when i used it to set tree of my choice. but visually it's not changed.
can someone help me?
Problem solved.
CMFCOutlookBarTabCtrl::SetActiveTab() only works after window has been displayed.
I guess this is because CMFCOutlookBar stores it's previous state to registory and reloads on next run. And this overrides changes made by SetActiveTab(), if we use it before displaying of window.
I had the same problem, and you are correct that on load the tab gets set to the last session value - actually it seems to get set several times during the load process - some of them seem to correspond to each time a tab is added, and then the last time it is called seems to be the tab from the previous session.
The solution is to set the value once the window is ready to be shown. This can be done by overriding the OnShowWindow callback on the view which contains the tab bar.
In my case the tab bar is added in a view called MainFrame, which has a member variable CMFCOutlookBarTabCtrl* m_pOutlookBar; which is initialised in the OnCreate callback.
I can then correctly set the tab by overriding OnShowWindow to contain the following:
void MainFrame::OnShowWindow(BOOL bShow, UINT nStatus)
{
CFrameWndEx::OnShowWindow(bShow, nStatus);
if ((m_pOutlookBar != NULL) && bShow) {
//When the tab bar is shown, select the correctview
for (int tabIdx = 0; tabIdx < m_pOutlookBar->GetTabsNum(); tabIdx++) {
CString requiredLabel;
CString thisLabel;
requiredLabel.LoadString(IDS_OF_TAB); //The ID of the tab wanted
m_pOutlookBar->GetTabLabel(tabIdx,thisLabel);
if (requiredLabel.Compare(thisLabel) == 0) {
//If the tab label matches the one required
m_pOutlookBar->SetActiveTab(tabIdx); //set it as the active one.
break; //done.
}
}
}
}

MFC Spin/Edit Control

I am using an Spin Control with an Edit Control buddy. I have an OnEnChanged event as below
void MyClass::OnEnChangeSnrEdit()
{
UpdateData(TRUE);
wizard_data->wlan.min_snr = m_snr_spin.GetPos();
CheckValid();
}
CheckValid enables the next button on my dialog page if the value is within the range I want it to be. The problem I have is that if I manually delete the value from the Edit Control so it is blank then GetPos above returns 0. 0 is within the range I allow and so my Next button is enabled and the value 0 is set when there is actually no value in the Edit Control.
How do I solve this issue?
Simply check the Contents of the edit Control first. Only if it is not empty, then get the spin button Control.
But why to relay on the value of the spin Control. always use the value from the edit Control!

SetItemState doesnt mark automatically

Ive made a search function for my List Control in Report View in my MFC Dialog. It looks like this
m_List.SetItemState((m_List.FindItem(&Finde)),LVIS_SELECTED,LVIS_SELECTED );
It searches the Content that is in the Variable Finde and marks it. Now it should mark the row. But I first have to click somewhere in the program. It doesnt mark the row directly after the function gets called.
Can anyone help me?
Here is the full function
LVFINDINFO Finde;
Finde.flags = LVFI_PARTIAL|LVFI_STRING;
Finde.psz = _T("Siffert");
if ((m_List.FindItem(&Finde)) != -1)
{
m_List.SetItemState((m_List.FindItem(&Finde)),LVIS_SELECTED,LVIS_SELECTED );
//m_List.SetSelectionMark((m_List.FindItem(&Finde)));
}
else
{
MessageBox(_T("No Results"));
}
You need to use the style LVS_SHOWSELALWAYS
Otheriwse the selection is only shown when the control has the focus and is active.
EDIT: Also keep in mind that there is also a LVIS_FOCUSED style, that also forces scrolling to this item.

CheckBox value in different file

I need to access the checkbox value in a different program. Check box is initiated in ToolDlg.cpp
DDX_Control(pDX, IDC_CalculateTBA, m_CalculateTBA);
in the oninitdialog initiated like this:
m_CalculateTBA.SetCheck(0);
CalculateAnalyticTBA = false;
void CToolDlg::OnBnClickedCheck3()
{
CalculateAnalyticTBA = m_CalculateTBA.GetCheck();
}
I need checkbox value in SetCal.cpp program. Here is the code i am trying in this program:
CToolDlg dialog;
if( dialog.CalculateAnalyticTBA )
{
Do some thing
}
But the dialog.CalculateAnalyticTBA is always tru even though i don't check the check box.
Plz let me know if you need any other info. Thanx for help.
It looks like you're creating a dialog, and never showing it. So CalculateAnalyticTBA has whatever value you gave it in the constructor of your CToolDlg class (or, if you didn't, whatever value the compiler gave it).
In order for this value to be set you must at least create the dialog so that the Data Exchange code (which invokes the DDX_Control and handles the binding of the checkbox and the variable) has a chance to run.
The correct way is to create and display the CToolDlg dialog and wait for the user to select his choices then only process the choices when the user finally click the "OK" button.
CToolDlg dialog;
// create and display the dialog
if (dialog.DoModal()==IDOK)
{ // user clicked the ok button, now do the work
....
}

Programmatically change combobox

I need to update a combobox with a new value so it changes the reflected text in it. The cleanest way to do this is after the comboboxhas been initialised and with a message.
So I am trying to craft a postmessage to the hwnd that contains the combobox.
So if I want to send a message to it, changing the currently selected item to the nth item, what would the postmessage look like?
I am guessing that it would involve ON_CBN_SELCHANGE, but I can't get it to work right.
You want ComboBox_SetCurSel:
ComboBox_SetCurSel(hWndCombo, n);
or if it's an MFC CComboBox control you can probably do:
m_combo.SetCurSel(2);
I would imagine if you're doing it manually you would also want SendMessage rather than PostMessage. CBN_SELCHANGE is the notification that the control sends back to you when the selection is changed.
Finally, you might want to add the c++ tag to this question.
A concise version:
const int index = 0;
m_comboBox.PostMessage(CBN_SELCHANGE, index);
What might be going wrong is the selection is being changed inside the selection change message handler, which result in another selection change message.
One way to get around this unwanted feedback loop is to add a sentinel to the select change message handler as shown below:
void onSelectChangeHandler(HWND hwnd)
{
static bool fInsideSelectChange = 0;
//-- ignore the change message if this function generated it
if (fInsideSelectChange == 0)
{
//-- turn on the sentinel
fInsideSelectChange = 1;
//-- make the selection changes as required
.....
//-- we are done so turn off the sentinel
fInsideSelectChange = 0;
}
}
if you fx want to change the title - which is the line shown when combobox is closed, then you can do following:
m_ComboBox.DeleteString(0); // first delete previous if any, 0 = visual string
m_ComboBox.AddString(_T("Hello there"));
put this in fx. in OnCloseupCombo - when event close a dropdownbox fires
ON_CBN_CLOSEUP(IDC_COMBO1, OnCloseupCombo)
This change is a new string not a selection of already assigned combobox elements