界面(2):BAR(CDialogBar,CStatusBar,CToolBar等)和TreeView

QCDialogBar中的CButton的问题
T我继承了CDialogBar类,在其中家了个CButton成员变量,
我用CButton 的create来创建button,用ON_BN_CLICKED来接收消息,
可总是不行。代码如下
mybutton.Create(_T("mybutton"),BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,
rect,this,IDC_BUTTON);

ON_BN_CLICKED(IDC_BUTTON,OnPushBt)
当我把IDC_BUTTON 设成0时button才被激活,但按下后,没有调用OnPushBt()
我都搞了一个上午了,还没搞定,望各位指点,十分感谢
AON_BN_CLICKED应该放到CDialogBar的父窗口(通常是框架)中

While it is normal to derive your own dialog classes from CDialog, you do not typically derive your own class for a dialog bar. Dialog bars are extensions to a main window and any dialog-bar control-notification messages, such as BN_CLICKED or EN_CHANGE, will be sent to the parent of the dialog bar, the main window.

See  Visual C++ MFC Samples   CTRLBARS Sample: Illustrates Custom Control Bars

can not assign CDialog to CDialogBar
to derive your own CDialogBar class,see More Information section in MSDN Knowledge Base Q185672 HOWTO: How to Initialize Child Controls in a Derived CDialogBar
see also Q99161 HOWTO: Derive From Classes not Listed in ClassWizard 
Q如何在CDialogBar中添加位图,请教各位,尤其是jiangsheng
T如何在CDialogBar中添加位图



 jiangsheng(蒋晟) 回复于2001-9-5 22:38:43  
的确可以,但是需要捕获WM_INITDIALOG,执行
HandleInitDialog()
和UpdateData(FALSE)之后再AutoLoad. 

请问:
是否可以再详细些,我找不到HandleInitDialog()函数
A
HandleInitDialog是未公开的函数。
HOWTO: How to Initialize Child Controls in a Derived CDialogBar
ID: Q185672


--------------------------------------------------------------------------------
The information in this article applies to:

The Microsoft Foundation Classes (MFC), used with:
Microsoft Visual C++, 32-bit Editions, versions 5.0, 6.0

--------------------------------------------------------------------------------


SUMMARY
When creating a simple CDialogBar, such as one with only CButtons similar to MFC's print preview, it is not necessary to derive from CDialogBar because the parent of CControlBar receives the notification messages from any child controls.

However, in the case of a more complex CDialogBar, which might have a drop- down combo box, a treeview, or ActiveX control, it might be useful to derive from CDialogBar to provide initialization for the child controls.

Because ClassWizard does not support deriving a class from CDialogBar, this article shows the steps necessary to create a class from CDialog and then "convert" the class to CDialogBar.



MORE INFORMATION
To start out, create a CDialog class with the child controls you want to use. You can transform the CDialog class into a CDialogBar class using the following nine steps:



Change the base class from CDialog to CDialogBar in the class declaration. Don't forget to also change the base class in BEGIN_MESSAGE_MAP in the .cpp file.


Change the constructor in both the .h and the .cpp files. Also make the change to the DoDataExchange(). Below are three items to change.

Change the following from



      CMyDlgBar (CWnd* pParent = NULL);   // standard constructor

      CMyDlgBar:: CMyDlgBar (CWnd* pParent /*=NULL*/)
         : CDialog(CMyDlgBar::IDD, pParent)
      {
         ...

      void CMyDlgBar::DoDataExchange(CDataExchange* pDX)
      {
         CDialog::DoDataExchange(pDX);
         ...
to the following:

      CMyDlgBar ();   // standard constructor

      CMyDlgBar:: CMyDlgBar ()
      {
         ...

      void CMyDlgBar::DoDataExchange(CDataExchange* pDX)
      {
         CDialogBar::DoDataExchange(pDX);
         ...
The key to the transformation is the conversion of the virtual OnInitDialog() member function to the WM_INITDIALOG message mapped method by changing the OnInitDialog method and by adding the ON_MESSAGE() handler. You may not have an override of OnInitDialog(). If not, add one before proceeding.
Remove "virtual BOOL OnInitDialog();" from the class header and add "afx_msg LONG OnInitDialog ( UINT, LONG );" in its place. For example:

      class CMyDlgBar : public CDialogBar
      {
         ...
      // Implementation
      protected:

         // Generated message map functions
         //{{AFX_MSG(CMyDlgBar)
         virtual BOOL OnInitDialog();                // <-Remove this line.
         //}}AFX_MSG

         afx_msg LONG OnInitDialog ( UINT, LONG );   // <-Add this line.
         DECLARE_MESSAGE_MAP()
      };
Now, in the class implementation section, make the corresponding changes.


Add "ON_MESSAGE(WM_INITDIALOG, OnInitDialog );" to the message map in the .CPP implementation file. For example:

      BEGIN_MESSAGE_MAP(CMyDlgBar, CDialogBar)

         //{{AFX_MSG_MAP(CMyDlgBar)
         ...
         //}}AFX_MSG_MAP
         ON_MESSAGE(WM_INITDIALOG, OnInitDialog )    // <-- Add this line.
      END_MESSAGE_MAP()
Now, convert the virtual OnInitDialog() to the message-mapped OnInitDialog().


Make the OnInitDialog() conversion as follows:

   Change the following:

      BOOL CMyDlgBar::OnInitDialog()
      {
         CDialog::OnInitDialog();   // <-- Replace this line:
            ...
to the following:

      LONG CMyDlgBar::OnInitDialog ( UINT wParam, LONG lParam)
      {
                       // <-- with these lines. -->

         if ( !HandleInitDialog(wParam, lParam) || !UpdateData(FALSE))
         {
            TRACE0("Warning: UpdateData failed during dialog init./n");
            return FALSE;
         }
         ...
The CDialogBar class doesn't have a virtual OnInitDialog(), and therefore calling one does not work. UpdateData is called to subclass or initialize any child controls.


Make sure the dialog box resource styles to the following:
Style: Child
Boarder: None
Visible: Unchecked
At this point, everything has been reconnected to make the transformation from a CDialog class to a CDialogBar class work correctly. Now, create and use it.


Add an instance of the derived CDialogBar to the CframeWnd-derived class (normally called CMainFrame). For example:



      class CMainFrame : public CFrameWnd
      {
          ...
          CMyDlgBar m_myDlgBar;
          ...
      };
Call the create method for the m_myDlgBar variable in the CFrameWnd::OnCreate() method similar to the following:



      int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
      {
         ...
         if (!m_myDlgBar.Create(this, IDD_DLGBAR1, CBRS_LEFT,
            IDD_DLGBAR1))
         {
            TRACE0("Failed to create dialog bar/n");
            return -1;      // fail to create
         }
         ...
      }
Finally, if you want to support dynamic docking and resizing of the CDialogBar, add the following lines to the end of CMainFrame::OnCreate():



      int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
      {
         ...
         m_myDlgBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
            CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
         m_myDlgBar.EnableDocking(CBRS_ALIGN_ANY);
         DockControlBar(&m_myDlgBar);

         return 0;
      }



REFERENCES
For additional information, please see the following article in the Microsoft Knowledge Base:

Q99161 HOWTO: Derive From Classes not Listed in ClassWizard

Additional query words:

Keywords : kbwizard kbMFC KbUIDesign kbVC500 kbVC600 kbGrpMFCATL kbMFCCtrlBar
Version : winnt:5.0,6.0
Platform : winnt
Issue type : kbhowto
Technology : kbvc


Last Reviewed: March 8, 2000
&copy; 2000 Microsoft Corporation. All rights reserved. Terms of Use.
 



--------------------------------------------------------------------------------

INFO: Using CBitmapButton in CDialogBar and CFormView
ID: Q98041


--------------------------------------------------------------------------------
The information in this article applies to:

The Microsoft Foundation Classes (MFC), used with:
Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5, 1.51, 1.52
Microsoft Visual C++, 32-bit Editions, versions 1.0, 2.0, 2.1, 2.2, 4.0

--------------------------------------------------------------------------------
To attach a CBitmapButton object to a button in a dialog box, call the CBitmapButton::AutoLoad() function in the OnInitDialog() function for the dialog box. Note, that the CDialogBar and CFormView classes are not derived from the CDialog class and do not have an OnInitDialog() function.

To use a CBitmapButton with a CDialogBar, override the Create() function and call AutoLoad() after calling the base class version of Create(). In the following code, which demonstrates this process, the CMyDialogBar class is derived from CDialogBar and m_MyBitmapButton is a CBitmapButton member of CMyDialogBar:

   BOOL CMyDialogBar::Create(CWnd* pParent, UINT nIDTemplate,
                             UINT nStyle, UINT nID)
   {
      // Call base class create to create the dialog bar window.
      BOOL bReturn = CDialogBar::Create(pParent, nIDTemplate,
                                        nStyle, nID);
      // Load bitmaps for the button and attach
      // to the control in the dialog box.
      if (bReturn)
         m_MyBitmapButton.AutoLoad(IDC_MYBITMAPBUTTON, this);

      return bReturn;
   }
To use a CBitmapButton with a CFormView, call AutoLoad() in the CFormView OnInitialUpdate() function. In the following code, which demonstrates this, the CMyFormView class is derived from CFormView and m_MyBitmapButton is a CBitmapButton member of CMyFormView:

   void CMyFormView::OnInitialUpdate()
   {
      CFormView::OnInitialUpdate();
      m_MyBitmapButton.AutoLoad(IDC_MYBITMAPBUTTON, this);
   }


Q如何在CDialogBar中添加位图,进一步提问,jiangsheng还在吗,各位能把邮件地址告诉我吗?
T
我使用了
CBitmapButton with a CDialogBar,是否仅使用CDialogBar或CFormView之一就可?
现在我使用了CDialogbar的派生类,在该类中使用:
      BOOL bReturn = CDialogBar::Create(pParent, nIDTemplate,
                                        nStyle, nID);
      if (bReturn)
        m_MyBitmapButton.AutoLoad(IDC_MYBITMAPBUTTON, this);
    
      m_MyBitmapButton.LoadBitmapsIDB_BITMAP2,IDB_BITMAP2,IDB_BITMAP2,IDB_BITMAP2);

      return bReturn;
 
1.是否还需要在CMainFrame中通过OnCreat来建dialogbar?
2.为什么我的dialogbar上的按钮还没图象?
3.是否仅使用CDialogBar或CFormView之一就可?
A
1:是
3:是
2:
To create a bitmap-button control in a window’s client area, follow these steps:

Create one to four bitmap images for the button.


Construct the CBitmapButton object.


Call the Create function to create the Windows button control and attach it to the CBitmapButton object.


Call the LoadBitmaps member function to load the bitmap resources after the bitmap button is constructed.
To include a bitmap-button control in a dialog box, follow these steps:

Create one to four bitmap images for the button.


Create a dialog template with an owner-draw button positioned where you want the bitmap button. The size of the button in the template does not matter.


Set the button’s caption to a value such as “MYIMAGE” and define a symbol for the button such as IDC_MYIMAGE.


In your application’s resource script, give each of the images created for the button an ID constructed by appending one of the letters “U,” “D,” “F,” or “X” (for up, down, focused, and disabled) to the string used for the button caption in step 3. For the button caption “MYIMAGE,” for example, the IDs would be “MYIMAGEU,” “MYIMAGED,” “MYIMAGEF,” and “MYIMAGEX.” You must specify the ID of your bitmaps within double quotes. Otherwise the resource editor will assign an integer to the resource and MFC will fail when loading the image.


In your application’s dialog class (derived from CDialog), add a CBitmapButton member object.


In the CDialog object’s OnInitDialog routine, call the CBitmapButton object’s AutoLoad function, using as parameters the button’s control ID and the CDialog object’s this pointer.


1重载一个CDialogBar出来
2可以不用,这个是示例,说明原理用的。
Q有关CWnd::RepositionBars的问题,如何改变DialogBar的尺寸,位置,请教,jiangsheng还在吗?谢谢各位大虾
T
我把CDialogBar放在CMainFrame类里了

if (!m_wndDlgBar.Create(this, IDD_VIEWSELECT,
        CBRS_TOP&brvbar;CBRS_TOOLTIPS&brvbar;CBRS_FLYBY&brvbar;WS_DLGFRAME, IDD_VIEWSELECT))
    {
        TRACE0("Failed to create DlgBar/n");
        return -1;      // Fail to create.
    }
上述语句产生controlbar(即CDialogBar)

接着改变CDialogBar的尺寸,位置
我使用了RepositionBars函数,现在不知参数具体定义,希望能详细给出值,或用其他方法改变dialogbar的尺寸,位置
ADialogBar停靠的时候是固定大小的,可以在浮动的时候修改大小。
HOWTO: Make a Resizable Dialog Bar
ID: Q143255
CFrameWnd Class Members
......
DockControlBar Docks a control bar.
FloatControlBar Floats a control bar.
Q为什么我在CDialogBar上加的按钮老是灰的!
T在toolbar上也是灰色的!
老是不可用!
A
可以
// Generated message map functions
protected:
 //{{AFX_MSG(CMyDlgBar)
 virtual BOOL OnInitDialog();
 //}}AFX_MSG
 afx_msg LRESULT HandleInitDialog(WPARAM, LPARAM);
 DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyDlgBar, CDialogBar)
 //{{AFX_MSG_MAP(CMyDlgBar)
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_INITDIALOG, HandleInitDialog)
END_MESSAGE_MAP()
/
// CEMapDlgBar message handlers

BOOL CMyDlgBar::OnInitDialog()
{
 // TODO: Add extra initialization here
 return TRUE;  // return TRUE unless you set the focus to a control
               // EXCEPTION: OCX Property Pages should return FALSE
}

LRESULT CMyDlgBar::HandleInitDialog(WPARAM wParam, LPARAM lParam)
{
 //Default();  // allow default to initialize first (common dialogs/etc)
 if(!CDialogBar::HandleInitDialog(wParam, lParam)||!UpdateData(FALSE)){
  TRACE0("Warning: UpdateData failed during dialog init./n");
  return FALSE;
 }
 return OnInitDialog();
}

这样你就可以派生一个DialogBar类,并且把空间关联到成员了


BOOL CMyFrm::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
 // TODO: Add your specialized code here and/or call the base class
 static BOOL bInThis=FALSE;//avoid re-enterence
 CWnd* pFocus= GetFocus();
 if(pFocus&&!bInThis){
  bInThis=TRUE;
  if(pFocus->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))//enable the focused inplace frame to handle this command
       return TRUE;
 }
 bInThis=FALSE;
 return CMDIChildWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
Q怎样使两个自己的toolbar Dock在MainFrame上的一行中,怎么默认的总是按列左对齐排的。
T怎样使两个自己的toolbar Dock在MainFrame上的一行中,怎么默认的总是按列左对齐排的。
A
void g_DockControlBarOn(CFrameWnd*pFrame,CControlBar* pBarToDock,CControlBar* pBarOn,CSize sizeOffset)
{
 CRect rect;
 DWORD dw;
 UINT n;

 // get MFC to adjust the dimensions of all docked ToolBars
 // so that GetWindowRect will be accurate
 pFrame->RecalcLayout();
 pBarOn->GetWindowRect(&rect);
 rect.OffsetRect(sizeOffset);
 dw=pBarOn->GetBarStyle();
 n = 0;
 n = (dw&CBRS_ALIGN_TOP) ? AFX_IDW_DOCKBAR_TOP : n;
 n = (dw&CBRS_ALIGN_BOTTOM && n==0) ? AFX_IDW_DOCKBAR_BOTTOM : n;
 n = (dw&CBRS_ALIGN_LEFT && n==0) ? AFX_IDW_DOCKBAR_LEFT : n;
 n = (dw&CBRS_ALIGN_RIGHT && n==0) ? AFX_IDW_DOCKBAR_RIGHT : n;

 // When we take the default parameters on rect, DockControlBar will dock
 // each Toolbar on a seperate line.  By calculating a rectangle, we in effect
 // are simulating a Toolbar being dragged to that location and docked.
 pFrame->DockControlBar(pBarToDock,n,&rect);

}
Q怎样动态修改工具栏上按钮的提示呢
T 
A自己捕获TTN_NEEDTEXT
QStreamBox的flat滚动条如何实现??
T 
A
Flat Scroll Bars


Microsoft&reg; Internet Explorer Version 4.0 introduced a new visual technology called flat scroll bars. Functionally, flat scroll bars behave just like standard scroll bars. The difference is that you can customize their appearance to a greater extent than standard scroll bars.

The following illustration shows a window that contains a flat scroll bar.


 

Note Flat scroll bar APIs are implemented in version 4.71 and later of Comctl32.dll.

Using Flat Scroll Bars

Flat Scroll Bars Reference

Using Flat Scroll Bars
This section describes how to implement flat scroll bars in your application.

Before You Begin
To use the flat scroll bar APIs, you must include Commctrl.h in your source files and link with Comctl32.lib.

Adding Flat Scroll Bars to a Window
To add flat scroll bars to a window, call InitializeFlatSB, passing the handle to the window. Instead of using the standard scroll bar functions to manipulate your scroll bars, you must use the equivalent FlatSB_XXX function. There are flat scroll bar functions for setting and retrieving the scroll information, range, and position. If flat scroll bars haven't been initialized for your window, the flat scroll bar API will defer to the corresponding standard functions, if any are used. This allows you to turn flat scroll bars on and off without having to write conditional code.

Because an application may have set custom metrics for its flat scroll bars, they are not automatically updated when system metrics change. When the system scroll bar metrics change, a WM_SETTINGCHANGE message is broadcast, with its wParam set to SPI_SETNONCLIENTMETRICS. To update flat scroll bars to the new system metrics, applications must handle this message and change the flat scroll bar's metric-dependent properties explicitly.

To update your scroll bar properties, use FlatSB_SetScrollProp. The following code fragment changes a flat scroll bar's metric dependent properties to the current system values.

void FlatSB_UpdateMetrics(HWND hWnd)
{
FlatSB_SetScrollProp(hWnd, WSB_PROP_CXVSCROLL, GetSystemMetrics(SM_CXVSCROLL), FALSE);
FlatSB_SetScrollProp(hWnd, WSB_PROP_CXHSCROLL, GetSystemMetrics(SM_CXHSCROLL), FALSE);
FlatSB_SetScrollProp(hWnd, WSB_PROP_CYVSCROLL, GetSystemMetrics(SM_CYVSCROLL), FALSE);
FlatSB_SetScrollProp(hWnd, WSB_PROP_CYHSCROLL, GetSystemMetrics(SM_CYHSCROLL), FALSE);
FlatSB_SetScrollProp(hWnd, WSB_PROP_CXHTHUMB, GetSystemMetrics(SM_CXHTHUMB), FALSE);
FlatSB_SetScrollProp(hWnd, WSB_PROP_CYVTHUMB, GetSystemMetrics(SM_CYVTHUMB), TRUE);
}

Enhancing Flat Scroll Bars
FlatSB_SetScrollProp allows you to modify the flat scroll bars to customize the look of your window. For vertical scroll bars, you can change the width of the bar and the height of the direction arrows. For horizontal scroll bars, you can change the height of the bar and the width of the direction arrows. You can also change the background color of both the horizontal and vertical scroll bars.

FlatSB_SetScrollProp also allows you to customize how the flat scroll bars are displayed. By changing the WSB_PROP_VSTYLE and WSB_PROP_HSTYLE properties, you can set the type of scroll bar that you wish to use. Three styles are available.

FSB_ENCARTA_MODE  A standard flat scroll bar is displayed. When the mouse moves over a direction button or the thumb, that portion of the scroll bar will be displayed in 3-D.
FSB_FLAT_MODE  A standard flat scroll bar is displayed. When the mouse moves over a direction button or the thumb, that portion of the scroll bar will be displayed in inverted colors.
FSB_REGULAR_MODE  A normal, nonflat scroll bar is displayed. No special visual effects will be applied.


Removing Flat Scroll Bars
If you wish to remove flat scroll bars from your window, call the UninitializeFlatSB API, passing the handle to the window. This API only removes flat scroll bars from your window at run time. You do not need to call this API when your window is destroyed.


September 1998
Microsoft System Journal
Control Spy Exposes the Clandestine Life of Windows Common Controls, Part II
Download ControlSpy.exe (2,914KB)

这里有示例代码
这个例子没有问题
Q如何在状态条中加入一个进度条
T 
A
HOWTO: Create a Progress Bar on the Status Bar

Q142202

 /* Compile options needed: default
   */

   // This is a menu option handler that takes a long period of time
   void CMainFrame::OnLengthyProcess()
   {
       // Create the CProgressCtrl as a child of the status bar positioned
       // over the first pane.

       RECT rc;
       m_wndStatusBar.GetItemRect (0, &rc);
       CProgressCtrl wndProgress;
       VERIFY (wndProgress.Create(WS_CHILD | WS_VISIBLE, rc,
                                               &m_wndStatusBar, 1));
       wndProgress.SetRange(0, 50);
       wndProgress.SetStep(1);

       // Perform some lengthy process, simulated here with a for loop
       // and the Sleep function.

       for(int i=0;i<50;i++)
       {
          Sleep(50);
          wndProgress.StepIt();
       }
   }
Q如何取得FormView指针,送28分,救急,help me!!! thanks! 
T
我在程序中用了一个CSizingControlBar,是一个人编写的控件,从CControlBar派生的,
他把一个FormView放入这个控件,我用了后遇到一个问题,如下:

我在我的主程序CLEditView中需要取得CFormView *pView;
pView可是老取不到,为空,出现异常,
程序控件如下:
#define TViewBarBase CSizingControlBar

class CViewBar : public TViewBarBase
{
 DECLARE_DYNAMIC(CViewBar);
public:
 CViewBar();
 virtual ~CViewBar();
    virtual BOOL Create(
  CWnd* pParentWnd,   // mandatory
        CRuntimeClass *pViewClass, // mandatory
  CCreateContext *pContext = NULL,
  LPCTSTR lpszWindowName = NULL,
  DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP,
  UINT nID = AFX_IDW_PANE_FIRST);
 CCreateContext m_Context;

protected:
 CFrameWnd *m_pFrameWnd;

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CViewBar)
 public:
 //}}AFX_VIRTUAL

    //{{AFX_MSG(CViewBar)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 afx_msg void OnSize(UINT nType, int cx, int cy);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

#endif

// ViewBar.cpp: implementation of the CViewBar class.
//
//

#include "stdafx.h"
#include "ViewBar.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(CViewBar, TViewBarBase);

//
// Construction/Destruction
//

CViewBar::CViewBar()
{
 ZeroMemory(&m_Context, sizeof(m_Context));
 // Create a frame object.
 CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(CFrameWnd);
 CObject* pObject = pRuntimeClass->CreateObject();
 ASSERT( pObject->IsKindOf( RUNTIME_CLASS( CFrameWnd ) ) );
 m_pFrameWnd = (CFrameWnd *)pObject;
}


CViewBar::~CViewBar()
{
}


BEGIN_MESSAGE_MAP(CViewBar, TViewBarBase)
 //{{AFX_MSG_MAP(CViewBar)
 ON_WM_CREATE()
 ON_WM_SIZE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CViewBar message handlers

/* ---------------------------------------------------------------
  Overridden to set the view class before calling the
 base create function. Note the other version of the create
 function is "obsolete" so I don't support it.
  For an SDI application the main frame window is created
 when the document template is created and a valid
 CreateContext is passed through (hurray!). Meaning there is
 no problem creating the ViewBar in the frame window create.
 However, for an MDI application the main frame window is
 constructed outside the document creation, so the
 CreateContext isn't present. In this case you can either
 create and setup a CreateContext object with the desired
 characteristics (doc template, frame window, etc.) and pass
 it, or let the CViewBar::Create() create a CreateContext
 with only the runtime class of the view, and the main frame
 window set.
--------------------------------------------------------------- */
BOOL CViewBar::Create(
 CWnd* pParentWnd,
 CRuntimeClass *pViewClass,
 CCreateContext *pContext,
 LPCTSTR lpszWindowName,
 DWORD dwStyle,
 UINT nID)
{
 ASSERT(pViewClass != NULL);
 ASSERT(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
 if (pContext)
  memcpy(&m_Context, pContext, sizeof(m_Context));
 else {
  CFrameWnd *fw = (CFrameWnd *)AfxGetMainWnd();
  if (fw) {
//   cc.m_pCurrentDoc = fw->GetActiveDocument();
   m_Context.m_pCurrentFrame = fw;
  }
 }
 m_Context.m_pNewViewClass = pViewClass;
 
 return TViewBarBase::Create(
  lpszWindowName,
  pParentWnd,
  nID,
  dwStyle);
}


/* ---------------------------------------------------------------
  Create the frame window associated with the view bar.
--------------------------------------------------------------- */
int CViewBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (TViewBarBase::OnCreate(lpCreateStruct) == -1)
  return -1;

 if (!m_pFrameWnd->Create(NULL, NULL,
  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
  CRect(0,0,0,0), this, NULL, 0,
  &m_Context))
  return -1;
 return 0;
}


/* ---------------------------------------------------------------
  Must remember to move the frame window as well...
--------------------------------------------------------------- */
void CViewBar::OnSize(UINT nType, int cx, int cy)
{
 CRect rc;

 TViewBarBase::OnSize(nType, cx, cy);
 GetClientRect(rc);
 m_pFrameWnd->MoveWindow(rc);
}

我在CMainFrame创建控件,FormView也在控件里面,我试过不少办法,可就是取不到,

help me?thank you!!!

AGetDocument,然后遍历所有视图。

int CCardFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
  return -1;
 
 // TODO: Add your specialized creation code here
 MDICREATESTRUCT* lpmcs=(MDICREATESTRUCT*)lpCreateStruct->lpCreateParams;
 CCreateContext* pContext = (CCreateContext*)lpmcs->lParam;
 if(!m_wndDeptViewBar.Create(this, RUNTIME_CLASS(CCWDeptTreeView),pContext,"部门栏",
  WS_CHILD | WS_VISIBLE | CBRS_RIGHT|CBRS_GRIPPER,AFX_IDW_CONTROLBAR_FIRST + 33 )){
  TRACE0("Failed to create dept bar/n");
  return -1;  // fail to create
 }
m_wndDeptViewBar.SetSCBStyle(SCBS_SIZECHILD);

跟一下看有没有进到CDocument::AddView啦,我这个代码可以多个视图共享Document对象的。

CDocument::AddView这个函数是建立文档/视图之间的联系,由系统自动调用。
注意只有pView->m_pDocument=NULL时才能AddView(pView)

是啊
只要你指定了CreateContext的m_pDocument,它自己就会AddView。

这是我修改过的viewbar
// ViewBar.cpp: implementation of the CViewBar class.
//
//
#include "stdafx.h"
#include "ViewBar.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(CViewBar, TViewBarBase);

//
// Construction/Destruction
//

CViewBar::CViewBar()
{
 ZeroMemory(&m_Context, sizeof(m_Context));
 // Create a frame object.
 CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(CFrameWnd);
 CObject* pObject = pRuntimeClass->CreateObject();
 ASSERT( pObject->IsKindOf( RUNTIME_CLASS( CFrameWnd ) ) );
 m_pFrameWnd = (CFrameWnd *)pObject;
}


CViewBar::~CViewBar()
{
}


BEGIN_MESSAGE_MAP(CViewBar, TViewBarBase)
 //{{AFX_MSG_MAP(CViewBar)
 ON_WM_CREATE()
 ON_WM_SIZE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CViewBar message handlers

/* ---------------------------------------------------------------
  Overridden to set the view class before calling the
 base create function. Note the other version of the create
 function is "obsolete" so I don't support it.
  For an SDI application the main frame window is created
 when the document template is created and a valid
 CreateContext is passed through (hurray!). Meaning there is
 no problem creating the ViewBar in the frame window create.
 However, for an MDI application the main frame window is
 constructed outside the document creation, so the
 CreateContext isn't present. In this case you can either
 create and setup a CreateContext object with the desired
 characteristics (doc template, frame window, etc.) and pass
 it, or let the CViewBar::Create() create a CreateContext
 with only the runtime class of the view, and the main frame
 window set.
--------------------------------------------------------------- */
BOOL CViewBar::Create(
 CWnd* pParentWnd,
 CRuntimeClass *pViewClass,
 CCreateContext *pContext,
 LPCTSTR lpszWindowName,
 DWORD dwStyle,
 UINT nID)
{
 ASSERT(pViewClass != NULL);
 ASSERT(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
 if (pContext){
  memcpy(&m_Context, pContext, sizeof(m_Context));
 }
 else {
  CFrameWnd *fw = (CFrameWnd *)AfxGetMainWnd();
  if (fw) {
   m_Context.m_pCurrentDoc = fw->GetActiveDocument();
   m_Context.m_pCurrentFrame = fw;
  }
 }
 m_Context.m_pNewViewClass = pViewClass;
 return TViewBarBase::Create(
  lpszWindowName,
  pParentWnd,
  nID,
  dwStyle);
}


/* ---------------------------------------------------------------
  Create the frame window associated with the view bar.
--------------------------------------------------------------- */
int CViewBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (TViewBarBase::OnCreate(lpCreateStruct) == -1)
  return -1;

 if (!m_pFrameWnd->Create(NULL, NULL,
  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
  CRect(0,0,0,0), this, NULL, 0,
  &m_Context))
  return -1;
 return 0;
}


/* ---------------------------------------------------------------
  Must remember to move the frame window as well...
--------------------------------------------------------------- */
void CViewBar::OnSize(UINT nType, int cx, int cy)
{
 CRect rc;

 TViewBarBase::OnSize(nType, cx, cy);
 GetClientRect(rc);
 if(::IsWindow(m_pFrameWnd->GetSafeHwnd()))
  m_pFrameWnd->MoveWindow(rc);
}

Q如何在SplitterWindow里面的view上加一个工具条
T 
A1 place your toolbar in a fixed height splitter pane
or 
2 place toolbars on a formview ,see DLGCBR32 sample (MFC) in MSDN

how about a splitter pane window derived from CFramed or CMiniFrameWnd?
QTreeView是否支持序列化?? 
T我把TV_INSERTSTRUCT作为序列化的对象,为什么不可以呢?

是否需要外抱?
A去看看Visual Foxpro的Solutions示例怎么从数据库读写树结构的……

社区服务: 查询网友 网吧联盟 传纸条 珍藏配置 资料配置 进站画面
欢迎投放版面广告
欢迎投放版面广告
欢迎投放版面广告 
精华区  [打包][返回] 

--------------------------------------------------------------------------------
当前位置:网易精华区>>讨论区精华>>编程开发>>● C语言>>WINDOWS界面设计>>TreeCtrl各子项的保存问题? 

主题:TreeCtrl各子项的保存问题?
发信人: jiangsheng()
整理人: wenbobo(2002-12-06 22:33:17), 站内信件 
【 在 wangf (原) 的大作中提到: 】
: 请问有没有比较方面的方法把一个深层次的树保存在一个文件中,再次读入时
: 有能很快的按照上次的层次排列显示出来?
Project Name:E ,SDI interface

class CEDoc :public CDocument;
class CEView:public CTreeview;

void CEDoc::Serialize(CArchive& ar)
{
POSITION position=GetFirstViewPosition ();
         //get treeview
CEView* view=(CEView* )this->GetNextView (position);
CString strItemText;
HTREEITEM hCurrent=NULL;
HTREEITEM hTest=NULL;
         //ctreectrl* m_ptree

m_ptree=&(view->GetTreeCtrl ());
if (ar.IsStoring())
{
// TODO: add storing code here
//ar<<m_ptree->GetCount();
                  //UINT m_iNest
                  //to save position of next item relative to this ite
m
m_iNest=0;
if(m_ptree->GetCount()=0)//no items
return;
                  //access the whole tree
hCurrent=m_ptree->GetRootItem( );
m_iDirection=CHILD;
while(m_iDirection!=OVER)
{
switch(m_iDirection)
{
case CHILD:
char szBuffer[256];
TV_ITEM item;
item.hItem = hCurrent;
item.mask = TVIF_TEXT | TVIF_CHILDREN;
item.pszText = szBuffer;
item.cchTextMax = 255;
m_ptree->GetItem(&item);
//save information
ar<<m_iNest;
strItemText=szBuffer;
ar<<strItemText;
m_iDirection=CHILD;//get child item if possible
//getchild item
if( m_ptree->ItemHasChildren(hCurrent))
{
m_iNest=1;//next item is the child of this item
hCurrent= m_ptree->GetChildItem(hCurrent);
m_iDirection=CHILD;
break;
}
else//no child item
{
//set base item nest if item has no child
m_iNest=0;
         // Try next sibling item.
hTest = m_ptree->GetNextSiblingItem(hCurrent);
if(hTest!=NULL)
{
hCurrent=hTest;
m_iDirection=CHILD;
break;
}
else
{
//No slibing, goto parent
hTest= m_ptree->GetParentItem(hCurrent);
if(hTest==NULL)//no parent,no sibling,i.e. end of tree
m_iDirection=OVER;
else
{
hCurrent=hTest;
m_iNest=-1;
m_iDirection=PARENT;
}
break;
}
}
case PARENT:
// Try next sibling item.
hTest = m_ptree->GetNextSiblingItem(hCurrent);
if(hTest!=NULL)
{
hCurrent=hTest;
m_iDirection=CHILD;
break;
}
else
{
//No slibing, goto parent
hTest= m_ptree->GetParentItem(hCurrent);

if(hTest==NULL)//no parent,no sibling,i.e.end of tree
{
m_iDirection=OVER;
break;
}
hCurrent=hTest;
m_iNest--;
m_iDirection=PARENT;
break;
}
}
}
ar<<32767;//end of file

}
else
{
// TODO: add loading code here
//clear contents
m_ptree->DeleteAllItems();
ar>>m_iNest;
                  //the first interger must be 0
if(m_iNest!=0){
MessageBox(NULL,"非法文件头!","错误",MB_OK);
return;
}
ar>>strItemText;
hCurrent=m_ptree->InsertItem(strItemText);
while(hCurrent!=NULL)
{
ar>>m_iNest;
if(m_iNest==32767)//end of file
return;
ar>>strItemText;
if(m_iNest==1)
{
hCurrent=m_ptree->InsertItem(strItemText,hCurrent);
m_ptree->EnsureVisible(hCurrent);
continue;
}
while(m_iNest<0)
{
hCurrent=m_ptree->GetParentItem(hCurrent);
m_iNest++;
}
//get parent;if root,set root.
hTest=m_ptree->GetParentItem(hCurrent);
if(hTest==NULL)
hTest=TVI_ROOT;
m_ptree->InsertItem(strItemText,hTest);

}
}
}


--
※ 来源:.网易虚拟社区 http://club.netease.com.[FROM: 203.93.7.52]
 

--------------------------------------------------------------------------------
[打包][返回] 
 

About Netease - 公司简介 - 网站导航 - 联系方法 - 广告服务 - 招聘信息 - 客户服务 - 相关法律
网易公司版权所有
&copy;1997-2003 
QSDK中操作TreeView通用控健的问题
T
我为了形象的表示我写的一个n叉树,用TreeView控件来显示我的n叉树节点星系,但是我不喜欢用MFC,所以用的sdk,但在dialog的回调函数的时候我利用下面的notify消息来得到选择的节点的文字,失败了,不知道为什么,请高手指点:
错误是 lpTree->itemNew.pszText的值不是节点的文字
case WM_NOTIFY:
  {
   if((int) wParam==IDC_TREE_NODE)
   {
    NMHDR* pnmh = (LPNMHDR) lParam;
    if(pnmh->idFrom==IDC_TREE_NODE)
    {
     if(pnmh->hwndFrom!=GetDlgItem(dialog, IDC_TREE_NODE))
     {
      return TRUE;
     }
     switch (pnmh->code)
     {
     case TVN_SELCHANGED:
      NMTREEVIEW* lpTree=(LPNMTREEVIEW) lParam;
      char Buffer[256];
      /*TV_ITEM  tvi;
      ZeroMemory(&tvi,sizeof(TV_ITEM));
      tvi.mask=TVIF_TEXT | TVIF_PARAM;
      tvi.hItem=lpTree->itemNew.hItem;
      TreeView_GetItem(pnmh->hwndFrom,&tvi);*/
      strcpy(Buffer,lpTree->itemNew.pszText);
      J3DINode* pNode=FindJ3DNode(pRoot3DNode,Buffer);
     }
    }
   }
  }
A
如果节点文本和节点数据有关的话,建议使用回调节点(callback item)根据节点数据显示文本内容。
插入节点时,每个节点的lParam是一个指向节点数据的指针。
HTREEITEM CCWDeptTree::InsertItem( HTREEITEM hParent, CRecordBase* pRecord)
{
 ASSERT(IsWindow(m_hWnd));
 TVINSERTSTRUCT InsertStruct;
 memset(&InsertStruct,0,sizeof(TVINSERTSTRUCT));
 if(hParent==NULL)
  InsertStruct.hParent=TVI_ROOT;
 else
  InsertStruct.hParent=hParent;
 InsertStruct.hInsertAfter =TVI_LAST;

 InsertStruct.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
 InsertStruct.item.pszText =LPSTR_TEXTCALLBACK ;
 InsertStruct.item.iImage  =I_IMAGECALLBACK ;
 InsertStruct.item.iSelectedImage  =I_IMAGECALLBACK ;
 InsertStruct.item.lParam=(LPARAM)pRecord;
 HTREEITEM hItem=CTreeCtrl::InsertItem(&InsertStruct);
 ASSERT(hItem!=NULL);
 m_mapItemToRecord.SetAt(hItem,pRecord);
}

我这里使用一个HTREEITEM到数据的映射来存储数据,当然你也可以用其他方法,比如
InsertStruct.item.lParam=(LPARAM)new CMyObject;分配一块内存来存储数据。

然后截获TVN_GETDISPINFO,来显示信息
void CCWDeptTree::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
 // TODO: Add your control notification handler code here
 TVITEM* pItem=&pTVDispInfo ->item;
 CRecordBase* pItemRecord=(CRecordBase*)pItem->lParam;
 if(pItemRecord->IsKindOf(RUNTIME_CLASS(CCWDeptRecord))){
  CCWDeptRecord* pDept=DYNAMIC_DOWNCAST(CCWDeptRecord,pItemRecord);
  if(pDept){
   if(pItem->mask&TVIF_TEXT){
    StrCpyN(pItem->pszText,pDept->m_strName,pItem->cchTextMax);
   }
   if(pItem->mask&TVIF_IMAGE){
    pItem->iImage=IMAGE_DEPT;
   }
   if(pItem->mask&TVIF_SELECTEDIMAGE){
    pItem->iSelectedImage=IMAGE_DEPT;
   }
  }
 }
 if(pItemRecord->IsKindOf(RUNTIME_CLASS(CCWCardRecord))){
  CCWCardRecord* pCard=DYNAMIC_DOWNCAST(CCWCardRecord,pItemRecord);
  if(pCard){
   if(pItem->mask&TVIF_TEXT){
    StrCpyN(pItem->pszText,pCard->Format(),pItem->cchTextMax);
   }
   if(pItem->mask&TVIF_IMAGE){
    pItem->iImage=IMAGE_CARD;
   }
   if(pItem->mask&TVIF_SELECTEDIMAGE){
    pItem->iSelectedImage=IMAGE_CARD;
   }
  }
 }
 *pResult = 0;
}
要访问一个HTREEITEM对应的数据就很简单了
CRecordBase* CCWDeptTree::GetRecord(HTREEITEM hItem)
{
 if(hItem==NULL)return NULL;
 TVITEM tvi;
 tvi.mask=TVIF_PARAM|TVIF_HANDLE;
 tvi.hItem=hItem;
 GetItem(&tvi);
 return (CRecordBase*)tvi.lParam;
}
如果你的节点数据是插入时分配的
InsertStruct.item.lParam=(LPARAM)new CMyObject;
那么在退出的时候要手动删除
 TVITEM tvi;
 tvi.mask=TVIF_PARAM|TVIF_HANDLE;
 tvi.hItem=hItem;
 GetItem(&tvi);
         delete (CMyObject*)tvi.lParam
QTreeCtrl和rect的问题
T我用GetItemRect得到了一个TreeCtrl的一个item的rect,如何改变rect中的color呢
ACUSTOMDRAW

BOOL CMainFrame::OnNotify(WPARAM wParam,
  LPARAM lParam, LRESULT* pResult)
{
  LPNMHDR lpnm  = ((LPNMHDR)lParam);
  if(!lpnm)
    return 0;
  switch(lpnm->code)
  {
    //... other notify messages
    case NM_CUSTOMDRAW:
      {
        LPNMCUSTOMDRAW pnmCustDraw =
          (LPNMCUSTOMDRAW)lParam;
        switch(pnmCustDraw->dwDrawStage)
        {
          case CDDS_PREPAINT:
            *pResult = CDRF_NOTIFYITEMDRAW ;
            return 1;
          case CDDS_ITEMPREPAINT:
            *pResult = CDRF_NOTIFYPOSTPAINT ;
            return 1 ;
          case CDDS_ITEMPOSTPAINT:
            {
              CDC memDC1;
              LPNMTBCUSTOMDRAW  lpnmtbcd =
                (LPNMTBCUSTOMDRAW)lParam;
              if( pnmCustDraw->dwItemSpec ==
                ID_MYTOOLBARBTN)
              {
                HBITMAP hbitmap ;
                if(CDIS_SELECTED & lpnmtbcd->
                  nmcd.uItemState)
                {
                  hbitmap = ::LoadBitmap
                    (GetModuleHandle(NULL),
                      MAKEINTRESOURCE
                       (IDB_SELBITMAP));

                }
                else
                if(CDIS_HOT & lpnmtbcd->
                  nmcd.uItemState)
                {
                  hbitmap = ::LoadBitmap
                    (GetModuleHandle(NULL),
                      MAKEINTRESOURCE
                       (IDB_HOTBITMAP));
                }
                else
                {
                  hbitmap = ::LoadBitmap
                    (GetModuleHandle(NULL),
                      MAKEINTRESOURCE
                       (IDB_NOSELBITMAP));
                }
              memDC1.CreateCompatibleDC (NULL);
              RECT rect,rect1;
              int nIndex =
                m_wndToolBar.CommandToIndex
                (ID_MYTOOLBARBTN);
              m_wndToolBar.GetToolBarCtrl().
               GetItemRect(nIndex,&rect);

              // Get the rect of any other
              // non-arrow button so that
              // we can draw only on the
              // arrow area with our arrow bitmap

              m_wndToolBar.GetToolBarCtrl().
                GetItemRect(1,&rect1);
              ::SelectObject(memDC1.m_hDC,hbitmap);
              ::BitBlt(pnmCustDraw->hdc,rect.left
                +  rect1.right - rect1.left ,
                rect.top ,rect.right - (rect.left
                +  rect1.right - rect1.left)  ,
                rect.bottom ,memDC1.m_hDC,0,0,SRCCOPY);
              }
              *pResult = CDRF_DODEFAULT;
              return 1;
            }
            default:
              *pResult = CDRF_DODEFAULT;
              return 1;
          }
        }
      }
    return CFrameWnd::OnNotify
      (wParam, lParam, pResult);
}



忘记说了,你判断一下subitem再设置color行不行?
每个SubItem应该是单独画的
Q怎样保存CTreeCtrl的数据。大家快来救命啊。
T
小弟自己从CTreeCtrl派生了一个DriverTree控件。现在想保存DriverTree实例中的数据。我自己重载DirverTree的Serialize虚函数。但是接下来由于在文档类中没有为DriverTree创建实例,是在一个叫做CWorkspaceBar(派生自CBCGSizingControlBar,CBCGSizingControlBar是BCG库里面的类。)的类中创建的实例。所以菜得不知道该怎么做了。惭愧!惭愧!还望各位大虾指教啊。。问题解决后一定给分。不够还可以加:)
A
#define PARENT 0
#define CHILD 1
#define OVER -1

 int m_iDirection;
 INT m_iNest;
 CTreeCtrl* m_ptree;

void CEDoc::Serialize(CArchive& ar)
{
 POSITION position=GetFirstViewPosition ();
 CEView* view=(CEView* )this->GetNextView (position);
         CEFrame* pFrame=(CEFrame*)view->GetParentFrame();
 CString strItemText;
 HTREEITEM hCurrent=NULL;
 HTREEITEM hTest=NULL;
 m_ptree=&(pFrame->m_wndWorkspacebar.m_wndTreeCtrl);
 if (ar.IsStoring())
 {
  // TODO: add storing code here
  //ar<<m_ptree->GetCount();
  m_iNest=0;
  if(m_ptree->GetCount()<1)
   return;
  hCurrent=m_ptree->GetRootItem( );
  m_iDirection=CHILD;
  while(m_iDirection!=OVER)
  {
   switch(m_iDirection)
   {
   case CHILD:
    char szBuffer[256];
    TV_ITEM item;
    item.hItem = hCurrent;
    item.mask = TVIF_TEXT | TVIF_CHILDREN;
    item.pszText = szBuffer;
    item.cchTextMax = 255;
    m_ptree->GetItem(&item);
    //save information
    ar<<m_iNest;
    strItemText=szBuffer;
    ar<<strItemText;
    m_iDirection=CHILD;//get child item if possible
    //getchild item
    if( m_ptree->ItemHasChildren(hCurrent))
    {
     m_iNest=1;//next item is the child of this item
     hCurrent= m_ptree->GetChildItem(hCurrent);
     m_iDirection=CHILD;
     break;
    }
    else//no child item
    {
     //set base item nest if item has no child
     m_iNest=0;
           // Try next sibling item.
     hTest = m_ptree->GetNextSiblingItem(hCurrent);
     if(hTest!=NULL)
     {
      hCurrent=hTest;
      m_iDirection=CHILD;
      break;
     }
     else
     {
      //No slibing, goto parent
      hTest= m_ptree->GetParentItem(hCurrent);
      if(hTest==NULL)//no parent,no sibling,i.e. end of tree
       m_iDirection=OVER;
      else
      {
       hCurrent=hTest; 
       m_iNest=-1;
       m_iDirection=PARENT;
      }
      break;
     }
    }
   case PARENT:
     // Try next sibling item.
     hTest = m_ptree->GetNextSiblingItem(hCurrent);
     if(hTest!=NULL)
     {
      hCurrent=hTest;
      m_iDirection=CHILD;
      break;
     }
     else
     {
      //No slibing, goto parent
      hTest= m_ptree->GetParentItem(hCurrent);

      if(hTest==NULL)//no parent,no sibling,i.e.end of tree
      {
       m_iDirection=OVER;
       break;
      }
      hCurrent=hTest;
      m_iNest--;
      m_iDirection=PARENT;
      break;
     }
   }
  }
  ar<<32767;//end of file
       
    }
 else
 {
  // TODO: add loading code here
  m_ptree->DeleteAllItems();
  ar>>m_iNest;
  if(m_iNest!=0)
  {
   MessageBox(NULL,"·&Ccedil;·¨&Icirc;&Auml;&frac14;&thorn;&Iacute;·!","&acute;í&Icirc;ó",MB_OK);
   return;
  }
  ar>>strItemText;
  hCurrent=m_ptree->InsertItem(strItemText);
  while(hCurrent!=NULL)
  {
   ar>>m_iNest;
   if(m_iNest==32767)//end of file
    return;
   ar>>strItemText;
   if(m_iNest==1)
   {
    hCurrent=m_ptree->InsertItem(strItemText,hCurrent);
    m_ptree->EnsureVisible(hCurrent);
    continue;
   }
   while(m_iNest<0)
   {
    hCurrent=m_ptree->GetParentItem(hCurrent);
    m_iNest++;
   }
   //get parent;if root,set root.
   hTest=m_ptree->GetParentItem(hCurrent);
   if(hTest==NULL)
    hTest=TVI_ROOT;
   m_ptree->InsertItem(strItemText,hTest);

  }
 }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值