///////////////////////////////////////////////////////////////////// // BrowseForm.cpp - implements Browser members using parent form // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2004 // ///////////////////////////////////////////////////////////////////// // Notes: // // The member functions implemented here can't be inlined in // // BrowseForm.h. That would required including the Form1.h // // header in BrowseForm.h. But Form1.h already includes the // // BrowseForm.h file, and mutual includes between header files // // don't work. // ///////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "BrowseForm.h" #include "Form1.h" using namespace demoWinForm; //----< build tree after form loads >-------------------------------- System::Void BrowseForm::BrowseForm_Load( System::Object ^ sender, System::EventArgs ^ e) { tvPlus1->buildTree(); } //----< enables me to callback on my parent form >------------------- void BrowseForm::setBaseForm(Form^ baseForm) { _baseForm = baseForm; } // //----< event handler that sends selected path back to parent >------ System::Void BrowseForm::tvPlus1_AfterSelect( System::Object ^ sender, System::Windows::Forms::TreeViewEventArgs ^ e) { if(!_first) // don't call back if this is first selection { String^ path = e->Node->FullPath; Form1^ pForm = static_cast(_baseForm); /////////////////////////////////////////////////////// // statement below is simple way to communicate with // parent form, but not as flexible as delegate-based // method used here // pForm->setPath(path); // set up delegate argument array^ argArray = gcnew array(1); argArray[0] = path; // invoke delegate to callback on parent form's setPathEvent handler // in way that is safe even if called from a thread that did not create // form if(pForm->InvokeRequired) // // here is the syntax that looks like it should work, but fails with // the strange error message: "must be a data member" which it is. // // pForm->BeginInvoke(setPathEvent, argArray); // // I'm creating a new delegate instance instead of using the cached instance // // called by worker thread // pForm->BeginInvoke(gcnew setPathDelegate(pForm,&Form1::setPath), argArray); else // // called by UI thread // setPathEvent(path); return; } _first = false; }