// BookTableDlg.cpp : implementation file // #include "stdafx.h" #include "BookTable.h" #include "BookTableDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CBookTableDlg dialog CBookTableDlg::CBookTableDlg(CWnd* pParent /*=NULL*/) : CDialog(CBookTableDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBookTableDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // load all bitmaps m_BookClosed.LoadBitmap(IDB_EXPANDABLE); m_BookOpen.LoadBitmap(IDB_EXPANDED); m_Topic.LoadBitmap(IDB_LEAF); m_Plus.LoadBitmap(IDB_PLUS); m_Minus.LoadBitmap(IDB_MINUS); m_Plain.LoadBitmap(IDB_PLAIN); } void CBookTableDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBookTableDlg) DDX_Control(pDX, IDC_CHECKUSEPLAIN, m_CheckUsePlain); DDX_Control(pDX, IDC_CHECKSHOWPLUSMIN, m_CheckPlusMin); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CBookTableDlg, CDialog) ON_COMMAND(ITEMMENU_ENTRY, OnMenu_ItemMenu_Entry) ON_COMMAND(HEADERMENU_SHOWALL, OnMenu_HeaderMenu_ShowAll) ON_COMMAND_RANGE(HEADERMENU_IDS+0, HEADERMENU_IDS+99, OnMenu_HeaderMenu_Entry) //{{AFX_MSG_MAP(CBookTableDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_CHECKSHOWPLUSMIN, OnCheckShowPlusMinClicked) ON_BN_CLICKED(IDC_CHECKUSEPLAIN, OnCheckUsePlainClicked) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBookTableDlg message handlers BOOL CBookTableDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon m_vTree = GetDlgItem(IDC_SFTTREE1)->GetControlUnknown(); ASSERT(m_vTree != NULL); #if 0 // This shows how to dynamically create a tree control. If created dynamically, // all properties must also be set dynamically. CWnd* pTree = new CWnd(); pTree->CreateControl(_T("SftTreeOCX70.SftTree.1"), _T(""), WS_CHILD|WS_VISIBLE, CRect(0,0,300,300), this, 123, NULL, FALSE, NULL); m_vTree = pTree->GetControlUnknown(); ASSERT(m_vTree != NULL); #endif // random numbers srand(0); m_vTree->BulkUpdate = VARIANT_true; // Mass update // set default item graphic. This can also be done at design time m_vTree->Items->ItemImageExpandable->PutBitmapHandle((OLE_HANDLE)(HBITMAP)m_BookClosed); m_vTree->Items->ItemImageExpanded->PutBitmapHandle((OLE_HANDLE)(HBITMAP)m_BookOpen); m_vTree->Items->ItemImageLeaf->PutBitmapHandle((OLE_HANDLE)(HBITMAP)m_Topic); // set the column header images (to indicate sorting) m_vTree->Header[0]->Image->Appearance = sftImageSortAsc; m_vTree->Header[1]->Image->Clear(); m_vTree->Header[2]->Image->Clear(); // make a copy of the tree control's font and make a bold // font for certain cells IFontPtr pFont = m_vTree->GetFont(); IFontPtr pCellFont; HRESULT hr = pFont->Clone(&pCellFont); ASSERT(SUCCEEDED(hr)); pCellFont->put_Bold(TRUE); // Add all available options for (int bk = 1 ; bk <= 4 ; ++bk) { // add a book CString str; str.Format("Book %d", bk); long BookIndex = m_vTree->Items->Add(_bstr_t(str)); str.Format("Description for book %d", bk); m_vTree->Cell[BookIndex][1]->Text = (_bstr_t)str; int size = (rand() % 999) + 1; str.Format("%d", size); m_vTree->Cell[BookIndex][2]->Text = (_bstr_t)str; m_vTree->Item[BookIndex]->Data = size; // add chapters for (int ch = 1 ; ch <= 2 ; ++ch) { str.Format("Chapter %d", ch); long Index = m_vTree->Items->Add((_bstr_t)str); m_vTree->Item[Index]->Level = 1; // add sections for (int sect = 1 ; sect <= 2 ; ++sect) { str.Format("Section %d", sect); Index = m_vTree->Items->Add((_bstr_t)str); m_vTree->Item[Index]->Level = 2; } } // after adding the book and all dependent items, we // collapse the item, so it's up to the user to expand it m_vTree->Item[BookIndex]->Collapse(VARIANT_FALSE); // set font IFontDispPtr pFontDisp = pCellFont; m_vTree->Cell[BookIndex][0]->PutFont(pFontDisp); } // End of Mass-Update m_vTree->BulkUpdate = VARIANT_FALSE; // Make columns optimal m_vTree->ColumnsObj->MakeOptimal(); // allow horizontal scrolling m_vTree->Items->RecalcHorizontalExtent(); return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CBookTableDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CBookTableDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CBookTableDlg::OnCancel() { CDialog::OnCancel(); } void CBookTableDlg::OnCheckShowPlusMinClicked() { if (m_CheckPlusMin.GetCheck()) { m_vTree->Items->PlusMinusImageExpandable->PutBitmapHandle((OLE_HANDLE)(HBITMAP)m_Plus); m_vTree->Items->PlusMinusImageExpanded->PutBitmapHandle((OLE_HANDLE)(HBITMAP)m_Minus); } else { m_vTree->Items->PlusMinusImageExpandable->Clear(); m_vTree->Items->PlusMinusImageExpanded->Clear(); } } void CBookTableDlg::OnCheckUsePlainClicked() { if (m_CheckUsePlain.GetCheck()) m_vTree->PutButtonPictureH((OLE_HANDLE)(HBITMAP)m_Plain); else m_vTree->PutButtonPictureH(NULL); } void CBookTableDlg::SortHeader(short colIndex) { if (m_vTree->Header[colIndex]->Image->Appearance == sftImageSortAsc) { // Sort the data. Note that column 2 is sorted by Item.Data, which is // an integer value (book size in pages) if (colIndex == 2) m_vTree->Items->SortDependents(-1, colIndex, sortSftTreeDscItemData); else m_vTree->Items->SortDependents(-1, colIndex, sortSftTreeDescending); m_vTree->Header[colIndex]->Image->Appearance = sftImageSortDesc; } else { m_vTree->Header[0]->Image->Clear(); m_vTree->Header[1]->Image->Clear(); m_vTree->Header[2]->Image->Clear(); // Sort the data. Note that column 2 is sorted by Item.Data, which is // an integer value (book size in pages) if (colIndex == 2) m_vTree->Items->SortDependents(-1, colIndex, sortSftTreeAscItemData); else m_vTree->Items->SortDependents(-1, colIndex, sortSftTreeAscending); m_vTree->Header[colIndex]->Image->Appearance = sftImageSortAsc; } } void CBookTableDlg::HeaderMenu(CPoint pt) { m_HeaderMenu.DestroyMenu(); m_HeaderMenu.CreatePopupMenu(); int count = 0; for (short c = 0 ; c < m_vTree->ColumnsObj->Count ; ++c) { m_HeaderMenu.AppendMenu(MF_STRING, HEADERMENU_IDS + c, m_vTree->Header[c]->Text); if (m_vTree->Column[c]->WidthPix > 0) { m_HeaderMenu.CheckMenuItem(HEADERMENU_IDS + c, MF_CHECKED|MF_BYCOMMAND); ++count; } else m_HeaderMenu.CheckMenuItem(HEADERMENU_IDS + c, MF_UNCHECKED|MF_BYCOMMAND); } if (count <= 1) { for (short c = 0 ; c < m_vTree->ColumnsObj->Count ; ++c) { if (m_HeaderMenu.GetMenuState(HEADERMENU_IDS + c, MF_CHECKED)) m_HeaderMenu.EnableMenuItem(HEADERMENU_IDS + c, MF_DISABLED|MF_GRAYED|MF_BYCOMMAND); else m_HeaderMenu.EnableMenuItem(HEADERMENU_IDS + c, MF_ENABLED|MF_BYCOMMAND); } } m_HeaderMenu.AppendMenu(MF_SEPARATOR); m_HeaderMenu.AppendMenu(MF_STRING, HEADERMENU_SHOWALL, _T("&Show All")); if (count < m_vTree->ColumnsObj->Count) m_HeaderMenu.EnableMenuItem(HEADERMENU_SHOWALL, MF_ENABLED|MF_BYCOMMAND); else m_HeaderMenu.EnableMenuItem(HEADERMENU_SHOWALL, MF_DISABLED|MF_GRAYED|MF_BYCOMMAND); m_vTree->CancelMode(); m_HeaderMenu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, pt.x, pt.y, this); } void CBookTableDlg::ItemMenu(CPoint pt) { m_ItemMenu.DestroyMenu(); m_ItemMenu.CreatePopupMenu(); m_ItemMenu.AppendMenu(MF_STRING, ITEMMENU_ENTRY, _T("Edit")); m_ItemMenu.AppendMenu(MF_STRING, ITEMMENU_ENTRY, _T("Insert")); m_ItemMenu.AppendMenu(MF_STRING, ITEMMENU_ENTRY, _T("Append")); m_ItemMenu.AppendMenu(MF_STRING, ITEMMENU_ENTRY, _T("Delete")); m_vTree->CancelMode(); m_ItemMenu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, pt.x, pt.y, this); } void CBookTableDlg::OnContextMenuSftTree1(short Button, short Shift, long x, long y) { CPoint pt(x, y); ::MapWindowPoints((HWND) m_vTree->hWnd, NULL, &pt, 1); // Determine click context menu for header or item long l, t, w, h; m_vTree->Headers->GetPositionPix(&l, &t, &w, &h); if (x >= l && x < l + w && y >= t && y <= t + h) { HeaderMenu(pt); return; } // determine item right-clicked long ItemIndex; ItemIndex = m_vTree->Items->HitTestPix(x, y); if (ItemIndex >= 0 && ItemIndex < m_vTree->Items->Count) { m_vTree->Items->Current = ItemIndex; m_vTree->Item[ItemIndex]->Selected = VARIANT_true; ItemMenu(pt); return; } } void CBookTableDlg::OnItemClickSftTree1(long ItemIndex, short ColIndex, short AreaType, short Button, short Shift) { if (AreaType == constSftTreeColumnHeader && Button == constSftTreeLeftButton) SortHeader(ColIndex); else if (AreaType == constSftTreeExpandAll) m_vTree->Item[ItemIndex]->Expand(VARIANT_FALSE, VARIANT_true); } void CBookTableDlg::OnItemDblClickSftTree1(long ItemIndex, short ColIndex, short AreaType, short Button, short Shift) { if (AreaType == constSftTreeColumnRes && Button == constSftTreeLeftButton) { m_vTree->Column[ColIndex]->MakeOptimal(); m_vTree->Items->RecalcHorizontalExtent(); } else if (AreaType == constSftTreeColumnHeader && Button == constSftTreeLeftButton) SortHeader(ColIndex); } afx_msg void CBookTableDlg::OnMenu_ItemMenu_Entry() { AfxMessageBox(_T("This sample doesn't implement any actions for the item menu. Try the column headers instead.")); } afx_msg void CBookTableDlg::OnMenu_HeaderMenu_ShowAll() { m_vTree->ColumnsObj->MakeOptimal(); } afx_msg void CBookTableDlg::OnMenu_HeaderMenu_Entry(UINT nID) { short colIndex = (short) (nID - HEADERMENU_IDS); if (m_HeaderMenu.GetMenuState(nID, MF_CHECKED)) m_vTree->Column[colIndex]->WidthPix = 0; else m_vTree->Column[colIndex]->MakeOptimal(); m_vTree->Items->RecalcHorizontalExtent(); } BEGIN_EVENTSINK_MAP(CBookTableDlg, CDialog) //{{AFX_EVENTSINK_MAP(CBookTableDlg) ON_EVENT(CBookTableDlg, IDC_SFTTREE1, 35 /* ContextMenu */, OnContextMenuSftTree1, VTS_I2 VTS_I2 VTS_I4 VTS_I4) ON_EVENT(CBookTableDlg, IDC_SFTTREE1, 4 /* ItemClick */, OnItemClickSftTree1, VTS_I4 VTS_I2 VTS_I2 VTS_I2 VTS_I2) ON_EVENT(CBookTableDlg, IDC_SFTTREE1, 5 /* ItemDblClick */, OnItemDblClickSftTree1, VTS_I4 VTS_I2 VTS_I2 VTS_I2 VTS_I2) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP()