Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Small Easy GUI

Status
Not open for further replies.

michaelkrauklis

Programmer
Dec 5, 2001
226
US
I have a simple win32 application that I run from the console. It's completely console based, but I would like to put a GUI on top of it. Is there an easy way to do this? All I need is a button to start the process and a text frame of some sort to output the results to. This would take about a minute in Java, but I've never done any GUI in VC++. Any help would be great. And as a side note my project is MFC enabled. I don't know if that's important. MY[red]enigma[/red]SELF:-9
myenigmaself@yahoo.com
 
It's probably easier to do this:

Create a new MFC AppWizard (exe) project, and when the wizard allows you to, choose "Dialog Based". The project starts you off with a dialog box and an OK and Cancel button.

Add a listbox of whatever size you like to the dialog.

Change the text of the OK button to "Start", then cut and paste your code and replace the Start button event code with yours, modifying it so the output goes to the listbox.
The user can click Cancel to quit (you might want to change the button text to say, "Quit").
 
As a side note, make sure the list box style doesn't include LBS_SORT (which IIRC is the default) or else your output will get sorted - which I'm guessing you don't want.
 
Ok, now here's my dilema. Since I was getting nowhere with the GUI stuff in VC++ I just taught myself how to create a GUI in VB and link it to my program by slightly modifying my project to be an MFC ActiveX Control Wizard and returning the strings I want printed out to screen. I've got a little to do but I'm almost done with that. What do you suggest I do. Would it be better and easier to keep it all in VC++? Faster? Easier to port to other computers? I do like the ease of GUI development in VB, but there are some limitations, or at least I don't know how to get around the limitations that I've seen... yet:-Q MYenigmaSELF:-9
myenigmaself@yahoo.com
"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra
 
Also, my cout statements are deeply nested. How easy is it going to be to print them to the listbox? Do I have to modify all my functions to accept a reference to the listbox?? MYenigmaSELF:-9
myenigmaself@yahoo.com
"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra
 
If you stick with the VC++ dialog based MFC app, you could possibly add a public member to your new dialog class that will add items to the list box from the console code. In that function you can use this to add items:

CListBox* theList = (CListBox*)GetDlgItem(IDC_LIST1);
theList->AddString("String one");
theList->AddString("String two");

HTH!

~Mike

Any man willing to sacrifice liberty for security deserves neither liberty nor security.

-Ben Franklin
 
You were sufficiently vague about the problems you were having with the VC++ MFC attempt ("Since I was getting nowhere with the GUI stuff in VC++..."), so that we are unable to help you with that. Many folks *do* lots of their GUI stuff in VB, so that's not a terrible idea.

I just thought from the description of what you wanted to do that the VC++/MFC Wizard gets you *so* close to where you want to go that we can probably help you with the rest, if you want to go that route.

I wouldn't try to modify a Console project to display a Dialog, because it's much better to start a new project (as I described above) and cut and paste your code into it, with some modifications. It's up to you though.
 
ok, I made the C GUI and tested it, and then did the VB GUI and tested that. In the VB example I switched my VC project to a ActiveXCommand MFC project or something like that. I ran them both the same way. My project ran twice as fast when it was all VC++, so that looks like the way to go. It's just going to be a pain switching all my cerr's and cout's to output to the window. Anyway, thanks for your help. I may need more, but things are going well I guess. Making some big steps. Now my project is pretty much all creating SQL stored procedures and calling them from VC++, but I already know that. Hopefully this GUI stuff will be pretty easy. Thanks again! MYenigmaSELF:-9
myenigmaself@yahoo.com
"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra
 
Is there any way to get a window or more specificly a component from a window such as an edit box without explicitly passing the window as a paramater? MYenigmaSELF:-9
myenigmaself@yahoo.com
"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra
 
One other thing... is there a main function in this? I'm having a little trouble following the execution of the code because I can't figure out where it starts! MYenigmaSELF:-9
myenigmaself@yahoo.com
"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra
 
It starts on this line in YourApp.cpp:

// The one and only CMyProgramApp object
CMyProgramApp theApp;

In MFC your program is a CWinApp derrived class, and the constructor acts like your int main() function.

In ur other post, I'm not sure what u mean "without explicitly passing the window as a paramater" to get a component from a window. If you need to work with an edit control on a dialog, u can use the GetDlgItem() function and pass it the IDC of the control (the IDC is specified when you right click on the control in the recource editor and select properties, and u can name it yourself here too). GetDlgItem() returns a pointer to a CWnd cuz MFC controls are windows. Here's some code that gets the string from an edit box:

CWnd* pMyEditBox = GetDlgItem(IDC_EDIT1);
CString theText;
pMyEditBox->GetWindowText(theText);

GetDlgItem() only works on controls that are contained in the current dialog, but that shouldn't be a problem if your app is dialog based.

Hopefully something here is useful to you, and I didn't confuse you even more... : )

~Mike
Any man willing to sacrifice liberty for security deserves neither liberty nor security.

-Ben Franklin
 
First off, thanks MikeCox, your information was informative. A lot of it I've already figured out myself, but I'm still running into a few problems. See, I'm trying to put a GUI on top of an already existing command based program. I've created the dialog and manipulated it so that when I press a start button it runs the program. Now the main thing I need to do is, instead of calling cout and cerr, I want to have the text outputed to my dialog box. I created an editable text field, but the problem is getting the text field from my other classes. I got the main window by:
CWnd *win = AfxGetMainWnd();

But then I run into the problem that my IDC is out of scope. You can't pass a string representation of the IDC, right? I would assume not. And I can't seem to specify it by bringing it into scope in the manner of CMyProgramDlg->IDC or somethign along those lines. So my specific question is how do I get the IDC of the text box? Do I have to pass it as a parameter throughout my program? I'm not even sure exactly how it's stored now so I don't know how to go about this. Thanks for your help. More is great! thanks MYenigmaSELF:-9
myenigmaself@yahoo.com
"If debugging is the process of removing bugs, then programming must be the process of putting them in." --Dykstra
 
Ok, you'll need to add variables to the dialog class to represent the values in the dialog's edit boxes. You'll generally make a member variable to hold values for each control on the dialog. It's best to let the class wizard do this by right-clicking on the control (edit box) and select ClassWizard. On the Member Variables tab, select the edit box from the list and click the Add Variable button. The Category should be 'value', and the Variable Type should be CString. Name the variable whatever u want and 'OK' out of the ClassWizard.
MFC will automatically populate the member variables with the values in the controls for you when CDialog::OnOK() is called (which calls DoDataExchange() to do the actual transfer). IAW the variables won't hold the right values until the OK button is clicked, so don't get bit by that :) The code you use to show the dialog and get the info from the edit boxes could look something like this:

CMyDialog* Dlg;
if (Dlg->DoModal() == IDOK)
{
// get new values from the dialog here
MyStrVar1 = Dlg->m_sVar1;
MyStrVar2 = Dlg->m_sVar2;
}

You can set the dialog's initial values the same way, DoDataExchange() will populate the controls from the member variables when you call DoModal():

CMyDialog* Dlg;
Dlg->m_sVar1 = MyStrVar1;
Dlg->m_sVar2 = MyStrVar2;
Dlg->DoModal();

Does that answer ur question?

~Mike
Any man willing to sacrifice liberty for security deserves neither liberty nor security.

-Ben Franklin
 
haha, every time I think I can't get any more confused I prove myself wrong. here's the code I have...
Code:
Field::Field()
:CObject()
{
#ifdef DEFINES_H_OUT_CONSTRUCTOR
	ofstream out(DEFINES_H_PATH,ios::app);
	out<<&quot;\t\tField::Field();&quot;<<endl;
	out.close();
#endif

	CWnd *win = AfxGetMainWnd()->GetDlgItem(IDC_EDIT1);
	CString tmp(&quot;&quot;);
	int work;
	work=win->GetDlgItemText(IDC_EDIT1, tmp);
	char *t = new char[100];
	itoa(work,t,100);
	tmp+=&quot;x&quot;;
	AfxMessageBox(tmp+t);
	win->SetDlgItemText(IDC_EDIT1, tmp);
	//int i=0;

}
This is the constructor for my Field class. I have a start button, and every time I click on the start button I have it call the constructor and destructor for the Field class, and subsequently the code above.

Now in my mind this should add an &quot;x&quot; to the text of the edit box every time. I think I'm way off base here though. Just to make sure it wasn't me forgetting to repaint or something I made the AfxMessageBox pop up and just as I had suspected, it prints out a single x and a single 0, meaning that no text was copied over from the GetDlgItemText call.

When I try to do this without using win-> the function takes a different number of parameters, three I think, and I can't figure out what they are. I'm unbelievably lost. What's up with this DoModal buisness? And shouldn't there already be a variable to hold the text of the Edit control? What's the point of having the control there if there isn't any text... frigger! MYenigmaSELF:-9
myenigmaself@yahoo.com
&quot;If debugging is the process of removing bugs, then programming must be the process of putting them in.&quot; --Dykstra
 
Does the IDC represent the nID and vice versa? MYenigmaSELF:-9
myenigmaself@yahoo.com
&quot;If debugging is the process of removing bugs, then programming must be the process of putting them in.&quot; --Dykstra
 
And what if I don't have an OK button? MYenigmaSELF:-9
myenigmaself@yahoo.com
&quot;If debugging is the process of removing bugs, then programming must be the process of putting them in.&quot; --Dykstra
 
I'm sorry, if you only have one dialog you won't need to call DoModal() to show it...
It seems GetDlgItemText() is returning 0 into 'work' and storing the window's text into 'tmp', which would explain the 'x0' message box, I think (I haven't used those functions, there may be wierd ways to use them).
What if you try creating a YourDialog object and using its GetDlgItem member function like this: (Your app is called Enigma)

------------------------
CEnigmaDlg* Dlg; // Your dialog box instance
CWnd* EditBox = Dlg->GetDlgItem(IDC_EDIT1);
CString tmp(&quot;Route &quot;);
int work = 66;
char *t = new char[100];
_itoa(work, t, 10);
tmp += t;
EditBox->SetWindowText(tmp);
delete[] t;
------------------------

This creates a CYourDialog object, retrieves a pointer to an edit control belonging to it, and sets its text. You should be able to do this from your console code (including the Field constructor) if that code is part of the project now.

Sorry for the confusion, it's cuz there's a couple ways to do this and I didn't show u the easiest way. Use Get/SetWindowText like I showed u above and you *should* be on ur way.

Let me know how it goes.

~Mike Any man willing to sacrifice liberty for security deserves neither liberty nor security.

-Ben Franklin
 
Got it!
got it got it got it
Ok, it works. This isn't really good but I'm not exactly sure why it works, but for now I'm happy. Thanks for all the help. If you wish to further clarify go ahead, it will be appreciated but it's not necessary. The problem was in the statement:
CWnd *win = AfxGetMainWnd()->GetDlgItem(IDC_EDIT1);
I changed that to just:
CWnd *win = AfxGetMainWnd();
and it works now. Something to do with IDC_EDIT1 not being a child of itself or something like that I think. I've got a headache... MYenigmaSELF:-9
myenigmaself@yahoo.com
&quot;If debugging is the process of removing bugs, then programming must be the process of putting them in.&quot; --Dykstra
 
Yes, nID is IDC_EDIT1 in the GetDlgItem() argument list, and you can call CDialog::OnOK() if u don't have an OK button, which will DoDataExchange() and close the dialog. You shouldn't need OnOK() unless you have member variables that need updated via DoDataExchange(), but you can use it anyway to close the dialog (and in a dialog based app, end the program).

BTW: I agree, to have a variable for each control seems wasteful. I'm not sure why MS did that, but one reason I can think of is there's extra features with an edit box if your variable is an int, you can specify the min and max values for the int. Then your GUI can let the MFC framework validate the value entered by the user, letting you concentrate on the meat of ur code. I also think it's more on the OOP side of things to modify member variables rather than controls from outside the class, so this gives you that foundation to work with...

~Mike
Any man willing to sacrifice liberty for security deserves neither liberty nor security.

-Ben Franklin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top