Solved

Question on Combo Box.

Posted on 1998-11-13
11
254 Views
Last Modified: 2013-11-20
Hi there,
           Say I have a file called RESIDENTS.TXT and this file contains some informations like:
--------------------------------------
John alive
David dead
Alvin alive
..
..
..
--------------------------------------
My question is how can I retrieve all the informations in the file and displayed only the NAME in the combo box and when a user selected a name, a MessageBox will appear showing whether the selected name is alive or dead.

I'm new to MFC programming and using VC5.0 to write a dialog-based program. I'm working on Win98 platform.

Any help offered is very much appreciated!!!
0
Comment
Question by:justinng
  • 5
  • 4
  • 2
11 Comments
 
LVL 4

Expert Comment

by:pagladasu
ID: 1324673
Here also I will offer you the basic outline.
I assume that you have reading one line at a time from your file. I also assume that you are reading it into a CString variable.
Use the CString's Find() member function to obtain the position of the space between the name and its status.
Use the CString function MId to extarct them into 2 CString variables.
Now while adding the first string(i.e name) to the Combo Box use the CCombo' member function SetItemDataPtr() to associate the status(alive / dead / halfdead!!) with that index.
When you select a name from the combo box, use its index in the GetItemDataPtr() member function to retrieve the status.
Hope the above guidelines will help you.
Thanks and best of luck.
pagladasu.

0
 

Author Comment

by:justinng
ID: 1324674
How abt putting it in codes? Thanks! I'm new to MFC...
0
 

Author Comment

by:justinng
ID: 1324675
How can I read the informations inside the file line by line and store only the name into the combo box? Please illustrate with code segments thanks!
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 8

Expert Comment

by:Answers2000
ID: 1324676
1. Create a dialog box with combo box in the resource editor.  Make sure the drop down area is sized how you want (click the down arrow on the combo and size the "ghost box")

2. Press Ctrl-W to make a new a dialog class for it - say CMyDialog in mydialog.h and mydialog.cpp

3. Make sure the dialog can be brought up from a menu or whatever (e.g. add a menu command, and use class wizard to add a handler for this menu command - click the id of the menu in LHS list, and BN_CLICKED in RHS list, then click "Edit Code"   [Put this handler in your document or view - you can pick the class from class wiz before doing the previous steps]

4. Edit the function from #3, make sure top of file has
#include "mydialog.h"

5. In the handler function add
CMyDialog oDlg ;
oDlg.DoModal() ;

6. Run this program, if you've done 1-5 correctly, you menu option will pop up the dialog.

Answered continued in the following comment...


0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1324677
Oops... missed it was a dialog based app - ingore the previous instructions and read these instead.

1. Modify the dialog box with combo box in the resource editor.  Make sure the drop down area is sized how you want (click the down arrow on the combo and size the "ghost box")

2. Ctrl-W for class wiz, select the dialog class

3. Go to member variables tab, you should see you combo listed as IDC_COMBO1, double click it, to add a member variable to the class, say m_combo.  Make sure this a control listed and CComboBox type.

4. Press OK

5. Ctrl-W, select class name on LHS list, double click WM_INITDIALOG on RHS list, press OK.  This adds code to handle the message for the dialog being intialized.  The function is called OnInitDialog.

6. Ctrl-W, select IDC_COMBO1, select IDC_COMBO1 on LHS list, double click CBN_SELCHANGE on RHS list, press OK.  This adds code to handle message for combo box selection changing.  This function will be call something _like_ OnSelChangeCombo1.

Answered continued in following comment...

4. You should now be


0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1324678
Oops again ignore the 2nd item #4...

7.Goto to the OnInitDialog function (used class wiz if you want to locate it, by Ctrl-W, finding the handler in the bottom list, and pressing Edit Code)

8. Before the return TRUE at the end, we need to populate the combo, basically read the file into memory, and fill the combo

// READ IN FILE

// use \\ in paths for sub-directories!, e.g.this assumes file name is C:\RESIDENTS.TXT
char sBuffer[1000000] ; // big enough buffer ?
memset( sBuffer, 0, sizeof sBuffer ) ;
HFILE hFile = _lopen( "C:\\RESIDENTS.TXT", OF_READ ) ;
if ( hFile == HFILE_ERROR)
{
AfxMessageBox( "Can't read file" ) ;
return TRUE ;
} else
{
UINT uRead = _lread( hFile, sBuffer, sizeof sBuffer ) ;
_lclose(hFile) ;
}

// add strings to combo, (assumes each line is less than 1024 characters, and lines
// are separated by CR/LF sequences as used by notepad, etc.
// assumes also only 1 space between name & status
int pp = 0 ;
char szLine[1024] ;
int ll = 0 ;
memset( szLine, 0, sizeof szLine ) ;
while ( sBuffer[pp] != '\0' )
{
 char cc = sBuffer[pp] ;

// end of line marked by carriage return
 if ( cc == '\r' )
 {
   szLine[ll] = '\0' ;
   m_combo.AddString( szLine ) ;
   ll++ ;
 }

 else if ( cc == '\n' )
 {
   // do nothing
 }

 else if ( cc == ' ' )
 {
   //spaces become tabsspaces to shift dead/alive off right handside of the combo
  szLine[ll] = '\t' ;
  ll++ ;
 }  

 else
 {
  szLine[ll] = sBuffer[pp] ;
  ll++ ;
 }
  pp++ ;
}


// select first combo item
m_combo.SetCurSel(0) ;
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1324679
9. In the handler for OnSelChangeCombo1 add code to pick up the new selection

int nSel = m_combo.GetCurSel() ;
if ( nSel != -1 )
{
char szLine[1024] ;
m_combo.GetLBText( nSel, szLine ) ;
char * pc = strchr( szLine, '\t' ) ;
if ( pc != NULL )
{
*pc = '\0' ;
CString str ;
str.Format( "%s is %s", (LPCSTR)szLine, (LPCSTR)(pc+1) ) ;
AfxMessageBox(str) ;
} else
{
AfxMessage( "This item did not contain spaces" ) ;
}

}

This is hacked together, and rough and ready but should give you enough to get started.

Sorry for any typos -

To learn MFC, get the Prosise book
http://www.amazon.com/exec/obidos/ASIN/1572316950/answers2000limit


0
 

Author Comment

by:justinng
ID: 1324680
Hi you've provided me with an excellent solution. But I think I forgot to give you informations about how I go about saving the data in the file. I've got a combo box and a dialog box and they deal with name and status respectively. This is how I saved the data of the combo box and dialog box into RESIDENTS.TXT
----------------------------------
UpdateData(TRUE);
CString selectedstr;
m_combo.GetLBText(m_combo.GetCurSel(), selectedstr);
CFile f;
if(f.Open("address.dat", CFile::modeRead) == FALSE)
{
      MessageBox("Unable to read file");
}
f.Close();
f.Open("address.dat", CFile::modeWrite);
// Append data to the file
f.SeekToEnd();
CArchive ar(&f, CArchive::store);
ar << '\n' << selectedstr << m_statusl;
ar.Close();
f.Close();
---------------------------------------------
My intention was to allow the user to update both data in combo box and dialog box if the data do not exist in the file but I was unable to do so. What I've done above is to allow the user to update the file by selecting a name and enter a status then by clicking on the STORE button, informations will be saved into RESIDENTS.TXT but this is not what I wanted but still I would like to know how the informations in the RESIDENTS.TXT could be displayed into the combo box and by choosing name in the combo box, the status of the selected name will appear at the dialog box. How can I update the name TYPED in the combo box into the file?? Because I often got Assertion error. But it is fine when I selected a name and updated the name into the file. Please help thank you very much!!!
0
 

Author Comment

by:justinng
ID: 1324681
It will be better if you can use CFile and CArchive to do file serialization because I'm more comfortable with them hehee... :P
0
 

Author Comment

by:justinng
ID: 1324682
I've been able to shown the correct status of the selected name at the status dialog box and add all the names in the file into the combo box. My problem left now is how can I read the number of data stored in RESIDENTS.TXT or ADDRESS.DAT? From the way I serialized the data, the data in RESIDENTS.TXT or ADDRESS.DAT looks like this:
--------
JohnaliveDaviddeadAlvinalive
--------
where the '' represents some ascii characters.
So I know that there are 3 names in the file. So how can I write a code segment which will count the number of names inside the file?

And also when I entered a new name instead of choosing from the list of combo box, it gives me an assertion error when I try to saved the name and status into the file. Serializing the data in the status dialog box is fine but the error occur at the code segment when I try to serialize the name entered in the combo box into the file. So how can I go about solving the left-over problem? Thanks a zillion in advance!
0
 
LVL 4

Accepted Solution

by:
pagladasu earned 200 total points
ID: 1324683
As I had suggested before, your problem can be sorted out. First let us see how the file RESIDENTS.TXT should be created.
To do this, you can use the following code:
// *****My Code ***************************************************
CString strTowrite;
CFile f;
f.Open("RESIDENTS.TXT",
      CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
f.SeekToEnd();
CArchive a(&f,CArchive::store);
//I am adding some data here - all hardcoded - you can use variables also
strToWrite="Chagol alive";
strToWrite += "\n";
a.WriteString(strToWrite);
strToWrite="Gadha dead";
strToWrite += "\n";
a.WriteString(strToWrite);
strToWrite="Gondar alive";
strToWrite += "\n";
a.WriteString(strToWrite);
strToWrite="Goru alive";
strToWrite += "\n";
a.WriteString(strToWrite);
a.Close();
f.Close();
// *****My Code To Create and/or add data to file ends**************

The above method will work with both new files as well as existing ones.

The next part of your problem is to display only the names in a combo box. The solution is as I had said before. Before the code I would suggest to you to use a static control to display the status of the selected person. Let us assume that the ID value of this static control is IDC_STATUS. Associate a CString member variable(value type) called m_status with this control. Also associate a CCombo member variable(control type), say called m_combo with the combo box containing the names.
Now in the InitDialog() function, add the following code:

// ************My Code Begins*******
CFile f;
CString strToRead,namePart,statusPart;
CString *ptrStr;
f.Open("RESIDENTS.TXT",CFile::modeRead);
CArchive b(&f,CArchive::load);
while(b.ReadString(strToRead)){
      int pos=strToRead.Find(' ');//find the position of space
      namePart=strToRead.Left(pos);
      statusPart=strToRead.Mid(pos+1);
      int ndx=m_combo.AddString(namePart);
      ptrStr=new CString(status);
      m_combo.SetItemDataPtr(ndx,ptrStr);
}
b.Close();
f.Close();
//***********My Code Ends For InitDialog*******

Now the other part - i.e. selecting a name from the combo box and displaying the corresponding status. You can do this by mapping the CBN_SELCHANGE event of the combo box. Assume that it had been mapped to a function called OnSelchangeCombo1(). Here is the code for it.

void CComboQDlg::OnSelchangeCombo1()
{
// ****************My code begins *****************
// TODO: Add your control notification handler code here
      CString *pstr;
      int ndx=m_combo.GetCurSel();
      pstr=(CString *)m_combo.GetItemDataPtr(ndx);
      m_status=*pstr;
      UpdateData(FALSE);
}
// ************* My Code Ends Here *****************
So there you are. Hopefully it will solve your problem. You can, if you want contact me at my email address: espical@hotmail.com
Thanks,
pagladasu.
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
dog bark java program 15 94
fizzArray2 challenge 1 78
modThree challenge 4 88
wordcount challenge 11 121
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

816 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now