Inserting item in TreeView - visual-c++

I created two panes in a splitter window, one pane for tree view and another is for list view.
After creating these panes in splitter window, I am not getting how to add items to treeview and listview.
CXTreeView is derived from CTreeView and CXListView is derived from CListView.
CXTreeView is used for created left pane that is tree and CXTreeView is used for creating right pane that is list.
I created like this:
int CTreeWnd:: OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_oSplitterWnd = DEBUG_NEW CXSplitterWnd;
if(!m_oSplitterWnd.CreateStatic(this, 1, 2))
{
TRACE0("Failed to create splitter\n");
return -1;
}
m_oSplitterWnd.SetLeftRTPane(RUNTIME_CLASS (CXTreeView));
m_oSplitterWnd.SetRightRTPane(RUNTIME_CLASS (CXListView));
if(!m_oSplitterWnd.CreateView(0, 0, m_oSplitterWnd.GetLeftRTPane(), CSize(250, 100), NULL)||
!m_oSplitterWnd.CreateView(0, 1, m_oSplitterWnd.GetRightRTPane(), CSize(100, 100), NULL))
{
TRACE0("Failed to create views in splitter\n");
return -1;
}
return 0;
}
Please help me out from this.

You first need to get your views from the splitter, which you can do like this:
CXTreeView *pTreeView = (CXTreeView*)m_oSplitterWnd.GetPane(0, 0);
CXListView *pListView = (CXListView*)m_oSplitterWnd.GetPane(0, 1);
Then, from those views, access the underlying tree control and list control:
CTreeCtrl &pTreeCtrl = pTreeView->GetTreeCtrl();
CListCtrl &pListCtrl = pListView->GetListCtrl();
Now, you can use the functions exposed by CTreeCtrl and CListCtrl to change the content of the tree and the list respectively, for example by using CTreeCtrl::InsertItem and CListCtrl::InsertItem to add new items:
pTreeCtrl.InsertItem( /* ... whatever ... */ );
pListCtrl.InsertItem( /* ... whatever ... */ );

Use CSplitterWnd::GetPane to retrieve a pointer to each Pane, they will be pointers to your CXTreeView and CXListView classes.

Related

MFC dialog form freezes

I have simple MFC dialog type window that calls external dll function and one of parameters is callback function. Callback function creates another dialog window if it is not created and updates label with information from function parameter:
int userNotify ( int iNotificationType, char* pcNotificationText )
{
if(statusDlg)
{
if ( !(statusDlg->IsWindowVisible()) )
{
statusDlg->ShowWindow(SW_SHOW);
}
statusDlg->showNotification(iNotificationType,pcNotificationText);
} else
{
statusDlg = new StatusDlg(NULL);
statusDlg->Create(StatusDlg::IDD,CWnd::GetDesktopWindow());
statusDlg->ShowWindow(SW_SHOW);
statusDlg->showNotification(iNotificationType,pcNotificationText);
}
return 0;
}
statusDlg is global variable and is very simple MFC dialog form with one static label. And it has one feature - it is placed on topmost.
BOOL StatusDlg::OnInitDialog()
{
staticStatus = (CStatic*)GetDlgItem(IDC_STATIC_TRN_STATUS_DIALOG);
...
SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
return TRUE; // return TRUE unless you set the focus to a control
}
Dialog form is shown during callback and label shows required information. But if I try to move form with mouse it becomes like frozen like in picture below and information on label is not updated anymore. Why this happens? How to solve this problem?
When you create StatusDlg you give it a parent of the Desktop. That is very likely wrong and leads to your later issues. The parent of your second dialog should be the main dialog that invokes it.
int userNotify ( CWnd *pParentWnd, int iNotificationType, char* pcNotificationText )
{
...
statusDlg->Create(StatusDlg::IDD, pParentWnd);
...
}
The parent window pointer will simply be the this pointer when you call userNotify.

How to lock a resource using multithreading?

I am having a property sheet where I had four pages .In the second page I am having a list control and a button.And in the second page I created two threads .When I click next in the first page,I am trying enumerating the list control with some values which are being retrieved from the network .So,here the a search dialog and enumerating the list are being handled in two different threads which runs in parallel.On front of the page the search dialog got popped up and background the values from network are retrieved and list is getting enumerated with those values.During that time if I click on the client area then this search dialog is getting minimized.But this should not happen until unless the search dialog is dismissed I must not be given access to the parent window(same scenario as ModalDiaolg box,as we know until unless the child window is closed we will not be able to access the parent right,similarly scenario is required for me.)this is the code I had done for getting those threads to be run at a time.
BOOL CModelSelectionView::CreateModelThread()
{
unsigned threadID;
if( NULL == ( m_hModelThread = (HANDLE)_beginthreadex(
NULL,
0,
&CModelSelectionView::ModelThreadProc,
reinterpret_cast<void*>(this),
0,
&threadID)) )
{
return FALSE;
}
return TRUE;
}
//this thread is for search dialog
UINT CModelSelectionView::ModelThreadProc( void* lpContext )
{
CModelSelectionView *pSelectModelFromList =
reinterpret_cast<CModelSelectionView*> (lpContext);`
AfxSetResourceHandle(theApp.m_hDialogResource);
CSearchingView SearchView(IDD_DIALOG_SEARCH);
INT nRes = SearchView.DoModal();
::CloseHandle( pSelectModelFromList->m_hModelThread );
pSelectModelFromList->m_hModelThread = NULL;
_endthreadex( 0 );
return TRUE;
}
BOOL CModelSelectionView::CreateInstallerThread()
{
unsigned threadID;
if( NULL == ( m_hInstallerThread = (HANDLE)_beginthreadex(
NULL,
0,
&CModelSelectionView::InstallerThreadProc,
reinterpret_cast<void*>(this),
0,
&threadID)) )
{
return FALSE;
}
return TRUE;
}
//Second thread for Initializing the list with some values
UINT CModelSelectionView::InstallerThreadProc( void* lpContext )
{
CModelSelectionView *pSelectModelFromList =
reinterpret_cast<CModelSelectionView*> (lpContext);
pSelectModelFromList->m_listCtrl.DeleteAllItems();
LVITEM lvitem;
lvitem.mask = LVIF_TEXT;
lvitem.iItem = 0;
lvitem.iSubItem = 0;
lvitem.pszText = L"";
lvitem.cchTextMax = sizeof(lvitem.pszText);
int nItem = pSelectModelFromList->m_listCtrl.InsertItem(&lvitem);
::Sleep(200);
pSelectModelFromList->m_listCtrl.SetItemText(0,1,L"XXX");
pSelectModelFromList->m_listCtrl.SetItemText(0,2,L"YYY");
pSelectModelFromList->m_listCtrl.SetItemText(0,3,L"ZZZ");
pSelectModelFromList->m_listCtrl.SetItemText(0,4,L"AAAA");
::Sleep(200);
::TerminateThread(pSelectModelFromList->m_hModelThread, 0);
::CloseHandle(pSelectModelFromList->m_hModelThread );
pSelectModelFromList->m_hModelThread = NULL;
::CloseHandle( pSelectModelFromList->m_hInstallerThread );
pSelectModelFromList->m_hInstallerThread = NULL;
_endthreadex( 0 );
return TRUE;
}
Until unless the search dialog is closed it should not be allowed to access the parent window.For instance when click a button and for that button handler I was calling domodal then a child dialog pop-up appears until unless we dismiss that dialog we will not be allowed to access the parent right ,similarly I have to get in this scenario.
Can anyone suggest me how can I achieve that.
Can anyone please suggest me how
Simply EnableWindow(FALSE) for the window that should not receive any input. It will still be displayed and its contents is updated, but mouse and keyboard events will not reach this window.

Vaadin - Iterate over components in a layout

I'm working on a project in Vaadin 7. In that I need to parse over all the components in a Layout and find a component I need.
The above is the pictorial representation of my layout.
I'm dynamically creating the green coloured Vertical layout inside blue coloured Vertical layout. Since I'm creating them dynamically, I can't have any instance for those dynamically created things. But, I have unique ID's for all the components.
Now I need to find a Combobox using the Id. I donno how to parse in to the combobox from the Blue coloured vertical layout.
All I have is an instance of the blue coloured vertical layout and Id's for combobox.
And, I can have ID's for green and red layouts too if needed.
I need something like this, But stuck..
Iterator<Component> iterate = blueMainLayout.iterator();
Combobox cb;
while (iterate.hasNext()) {
Component c = (Component) iterate.next();
cb = (Combobox) blueMainLayout.....;
if (cb.getId().equals(something.getId())) {
// do my job
}
}
You have to check component recursively.
class FindComponent {
public Component findById(HasComponents root, String id) {
System.out.println("findById called on " + root);
Iterator<Component> iterate = root.iterator();
while (iterate.hasNext()) {
Component c = iterate.next();
if (id.equals(c.getId())) {
return c;
}
if (c instanceof HasComponents) {
Component cc = findById((HasComponents) c, id);
if (cc != null)
return cc;
}
}
return null;
}
}
FindComponent fc = new FindComponent();
Component myComponent = fc.findById(blueMainLayout, "azerty");
Hope it helps
Though using HasComponents.iterator() is still possible com.vaadin.ui.AbstractComponentContainer implements java.lang.Iterable<Component>, which makes the iteration a bit more comfortable:
...
for ( Component c : layout ) {
if ( id.equals( c.getId() ) ) {
return c;
}
}
...

C++ Builder XE - customizing TCategoryPanel

This is part of screenshot of my application:
I need to do following things:
remove lines separating collapsed panels
remove line on bottom border of expanded panel
The lines I am talking about are highlighted by character '!' in image.
I accomplished the second task by creating formal descendent class of TCategoryPanel:
class MyCategoryPanel : public TCategoryPanel
{
public:
__property BevelWidth;
};
The goal is to change visibility of BevelWidth property from protected to public. Now we can set bevel width to zero for example like this (code is called from parent form class):
int i;
for (i = 0; i < ComponentCount; i++) {
TComponent *component = Components[i];
TCategoryPanel *cat_panel = dynamic_cast<TCategoryPanel*>(component);
if (cat_panel == NULL) {
continue;
}
((MyCategoryPanel*)cat_panel)->BevelWidth = 0;
}

Splitting Child Window in MFC MDI Program

I am trying to split the Child Window of an MFC MDI progarm that I am working on but am having some problems. I know I have to use the CSplitterWnd class and have been trying to follow the instructions on the post here:
Create multi views in a CChildFrame using CSplitterWnd
but can't seem to get it to work, would anyone be able to offer me some advice with regard to these instructions, I have some specific questions:
Is CRightView also a CView derived class and what code should go in there if any?
Are m_pLeftView, m_pRightView, m_pPhongView and m_pPhongInfo all variables of the appropriate classes and do they have any particular type?
Where does CTreeView come from, does not seem to be a standard base class?
rc.Width in CChildFrame::OnCreateClient gives an undeclared identifier error, is there something I should be declaring somewhere here?
I would appreciate any advice about this, really struggling to get the splitter to work.
Thanks
After working on it for a couple of days I've managed to solve my own problem, I'm adding the solution here for anyone else who might have the same problem.
Declare the two view classes, in my case CElement View which is a CWnd derived class and CSampleViewer3dView which is a CView derived class.
In CChildFrame add a variable with access private, type CSplitterWnd and name m_wndSplitter.
Add an override for the OnCreateClient function in CChildFrame, this should add the code:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
to ChildFrm.h, you should also add a boolean flag m_bInitSplitter to ChildFrm.h:
BOOL m_bInitSplitter;
you also have to add:
m_bInitSplitter = false;
to the constructor of ChildFrm.cpp, the following code is added to ChildFrm.cpp when you add the variable using the wizard:
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
}
Put the following code into CChildFrame::OnCreateClient:
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
CRect cr;
GetWindowRect( &cr );
if (!m_wndSplitter.CreateStatic(this, 1, 2))
{
MessageBox("Error setting up splitter frames!", "Init Error!", MB_OK | MB_ICONERROR);
return FALSE;
}
if (!m_wndSplitter.CreateView( 0, 0, RUNTIME_CLASS(CElementView),
CSize(cr.Width()/2, cr.Height()), pContext ) )
{
MessageBox("Error setting up splitter frames!", "Init Error!", MB_OK | MB_ICONERROR);
return FALSE;
}
if (!m_wndSplitter.CreateView( 0, 1, RUNTIME_CLASS(CSampleViewer3dView),
CSize(cr.Width()/2, cr.Height()), pContext))
{
MessageBox("Error setting up splitter frames!", "Init Error!", MB_OK | MB_ICONERROR);
return FALSE;
}
m_bInitSplitter = TRUE;
return TRUE;
}
Add an override for the WM_SIZE message to CChildFrame and insert the following code:
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIChildWnd::OnSize(nType, cx, cy);
CRect cr;
GetWindowRect(&cr);
if (m_bInitSplitter && nType != SIZE_MINIMIZED)
{
m_wndSplitter.SetRowInfo( 0, cy, 0 );
m_wndSplitter.SetColumnInfo(0, cr.Width()*0.25 / 2, 50);
m_wndSplitter.SetColumnInfo(1, cr.Width()*0.75 / 2, 50);
m_wndSplitter.RecalcLayout();
}
}
You can edit the size of each window by changing the values of 0.25 and 0.75 to the required percentage of the screen that you want each view to take up.
Add header files for the two views to ChildFrm.cpp, e.g. ElementView.h and SampleViewer3dView.h.
You should then have two independent views in the child window of an MDI program.

Resources