Google Answers Logo
View Question
 
Q: c++/question ( Answered 5 out of 5 stars,   3 Comments )
Question  
Subject: c++/question
Category: Computers > Programming
Asked by: jimmyjrosu-ga
List Price: $5.00
Posted: 30 Apr 2003 10:18 PDT
Expires: 30 May 2003 10:18 PDT
Question ID: 197514
say I write a program in c++ that asks the user for names of students
and their cooresponding midterm scores, at the end, it displays each
person, their average, gpa, class ave, total a's, b's, etc.  I make
the exe and it works fine, how do I make it run in something other
than the command prompt, I mean, make it so that it is like a page
where you can just enter the info in and hit enter and it display the
calculates in say, a box that was empty at the bottom of the page.
This is just a general question, so links would be fine, I dont expect
you to write the code for the situation, as this situation is
ficticious(sp?), i just need introduced to this type of thing.

Request for Question Clarification by spot_tippybuttons-ga on 30 Apr 2003 10:38 PDT
Just for clarification, are you asking how to convert a command-line
application to use a GUI? aka.: What are the general steps in building
an application that uses a Windows (or other graphical OS) interface?

Or do you have something else in mind?

Thanks.

Clarification of Question by jimmyjrosu-ga on 30 Apr 2003 16:27 PDT
Yes, an example would be i guess, like a program, excel, money, any
program, where would I go to get started learning to transform c++
applications to interfaces like that.
Answer  
Subject: Re: c++/question
Answered By: spot_tippybuttons-ga on 01 May 2003 05:15 PDT
Rated:5 out of 5 stars
 
Indeed, as noted in the comments, there are volumes that could be
written about how to write a graphical user interface (GUI) as well as
an enormous number of different tools and techniques you can use to do
it. However, while there are many different tools, the fundamental
concepts behind how they work are more or less the same. I've
programmed GUI applications in everything from C++, Java and TCL to
Rexx, for platforms ranging from Windows, Mac, Sun and even OS/2. Even
though the way certain tasks are achieved are clearly different on
each platform, in the end most GUI apps do more or less the same
thing.

I can't tell you everything there is to know, but I can introduce you
to the major concepts that will help you on your way to learning more
on your own, which appears to be what you are after. As I introduce
the concepts, I'll give you some tips about how they apply to various
tools available. I'll bias the conversation toward C++ and Windows,
since you seem to have indicated that this is something that you are
familiar with; however, again, these ideas should hold no matter which
platform you choose to develop for.

-------------------------------------------------------
I. Event Driven Programming, Part #1
-------------------------------------------------------

The most challenging hurdle that most new programmers face when moving
from the command line to a graphical user interface is getting their
head around event-driven programming. While there are some rare
exceptions--I worked on a couple of PlayStation2 games that had menu
systems that were only semi-event driven--practically ALL graphical
applications use an event-driven architecture.

In a typical command line application, you get some input from the
user at startup, immediately do some work based on the input and then
exit. If you need more input from the user you display a prompt and
wait there until the user enters something. [KEY POINT: The *program*
controls the flow of execution.]

In an event driven application, the program starts up and then waits
there for "something" to happen. "Something" might be a keystroke,
mouse click, tick from a timer or any number of other things. Most
often, it's related to some sort of input from the user. When
"something" happens, the program then responds and does some work.
This "something" is called an EVENT. Events are the core of
event-driven programming. Events tell the program when the user does
something that the program needs to respond to. [KEY POINT: The *user*
controls the flow of execution.]

Here is some pseudo-code for a typical command line program:

void main()
{
     getKeystroke();
     doSomeWork();
     exit();
}


Here is the same pseudo-code converted into a home-brew event-driven
program:

void main()
{
    // do forever (this loop is also called the "pump")
     while(true) { 
          // every time "something" happens, call 
          // the function that goes along with it
          if ( getKeystroke() ) {
               onKeyPress();
          }         
          if ( exitKeyPressed) {
                exit();
          }
     }
}

void onKeyPress() {
    doSomeWork();
}


Cheesy as that sounds, that is exactly how most event-driven
applications work... including large Windows applications. I am
over-simplifying a bit, but not by much. In addition to events,
Windows adds an extra layer called MESSAGES to make its job easier.
Messages are just bits of data (a UINT to be exact) with some
parameters attached that get passed around in order to tell a program
what event just happened. Each MESSAGE passes a number, which
represents a specific EVENT. Then the program's EVENT HANDLER is
called with that message number. An event handler is a function in
your program that handles an event; or in other words, a function that
does "something" when "something" happens.

In our pseudo-code listing, this concept could be written like so:

void main()
{
    // do forever ("MESSAGE PUMP")
     while(true) { 

          // "translate" the events... every time "something" happens,
          // set the variable "message" to the number that corresponds
          int message;
          if ( getKeystroke() ) {
               message = 1;
          }         
          if ( exitKeyPressed) {
                message = 2;
          }

          // "dispatch" the events... call a main event handler to
          // figure out which sub-event handler to call
          doEvent(message);
     }
}

// MAIN EVENT HANDLER
void doEvent(int message)
{
     switch(message) {

           case 1:
                onKeyPress();
                break;

           case 2:
               exit();
               break;
     }
}

// KEYPRESS EVENT HANDLER
void onKeyPress() {
    doSomeWork();
}

This may seem like a round-about way to do things, but messages make
it easier for Windows to pass important events between different
programs. If the program doesn't know what to do with an event, it can
also pass it to the Windows default event handler. The default event
handler is just another function that figures out what to do with the
event when you aren't sure or simply don't want to deal with it.

Following is code for a real Windows program to show you what I mean.
This code will compile and run with Microsoft Visual C\C++6.0; it
should also run with Borland or any other C\C++ compiler that supports
the Windows API. Just in case you aren't sure, the Windows API is a
set of functions, libraries, etc., provided by the operating system to
do the basic things that are required by a graphical program. This
saves you from re-inventing the wheel every time you write a program;
the code for things that all windows programs need, like the basic
functionality of a button, is already done for you. Other platforms,
such as the Mac or X Windows\Motif, have similar APIs. From my
personal experience, I can say that the Windows API is more
full-featured and does a lot more things for you than many of the
other platforms, at the expensive of being enormous, sometimes
over-featured and often overwhelming.

The following code will create a basic window. It also handles the
PAINT event, and provides a sample function that draws a circle on the
window. (I apologize in advance if some of the code wraps funny. You
may need to copy and paste this into a mono-spaced editor to read it
more clearly.)

**********BEGIN LISTING****************

#define STRICT                  // strict type checking
#define WIN32_LEAN_AND_MEAN     // exclude seldom-used code
#include <windows.h>            // needed to write windows code


/*---------------------------------------------------------------------------
   Paints the Window Client Area 

   -- This is your event handler for the PAINT event. For each thing
you
   want to do, such as handle a keystroke or a button press, you'll
have
   an event handler function just like this.

   Parameters: HWND hWnd - handle to current window. Windows
identifies each
               form and control in an application by assigning it a
handle.
               Most API functions need to know the handle of a window
in order
               to do anything interesting to it.

      Returns: <nothing>
---------------------------------------------------------------------------*/
void onPaint(HWND hWnd)
{      
    PAINTSTRUCT ps;            // structure for paint info
    HDC hDC;                   // handle to graphics device context,
i.e. where to paint

    // create device context, prepare for painting 
    hDC = BeginPaint(hWnd, &ps);

    // draw a circle
    Ellipse(hDC, 0, 0, 50, 50);

    // update the window client area with whatever else we want
    
    // delete device context
    DeleteDC(hDC);

    // end painting 
    EndPaint(hWnd, &ps);
}


/*-------------------------------------------------------------------------
   Windows Message Pump Callback Routine

   -- This is your MAIN EVENT HANDLER. This function takes the events
that
   Windows passes in, figures out what they are, and then calls your
additional
   sub-event handler functions to handle the event. Any events that
aren't handled
   get passed on to the default event handler supplied by Windows
(DefWindowProc).
   This saves you from having to write code for events you don't care
about,
   like, say, a notice that the window was resized.
   
   Parameters: HWND hWnd     - our window's handle
               UINT wMsg     - message number
               WPARAM wParam - word parameter, contents differ for
each message
               LPARAM lParam - long parameter, contents differ for
each message

      Returns: 0 if we handled the message, result code otherwise
---------------------------------------------------------------------------*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM
lParam)
{
    // select and handle possible window messages 
    switch(wMsg){

        // window created, initialize application 
        case WM_CREATE:          
            // do whatever you need to do on startup here
            break;

        // window close suggested 
        case WM_CLOSE:
            // do whatever you need to do on shutdown here
            DestroyWindow(hWnd); 
            break;

        // paint window requested
        case WM_PAINT:
            onPaint(hWnd);
            break;

        // application terminated 
        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        // pass on other unhandled messages to default handler
        default:
            return(DefWindowProc(hWnd, wMsg, wParam, lParam));
    }

    // return 0 if we handled the message 
    return 0L;
}


/*-------------------------------------------------------------------------
   Main Entry Point             
   -- this is the equivalent of "void main()" for a windows program

   Parameters: HINSTANCE hInstance - current program instance
               HINSTANCE hPrevInst - handle to the previous instance
               LPSTR lpszCmdLine   - command-line arguments
               int nCmdShow        - window size/mode

      Returns: the value of PostQuitMessage
---------------------------------------------------------------------------*/
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR
lpszCmdLine, int nCmdShow)
{
   HWND hWnd;                                   // window handle from
create window
   MSG wMsg;                                    // message from
GetMessage
   WNDCLASS wndclass;                           // window class
structure
   char *strProgramName = "My Program Name";    // the name of your
program

   // if this is the first instance of the application, register the
window structure...

   // back in the day, system resources were very tight, and programs
that used several
   // similar looking windows could save loads of memory by storing
only one "design"
   // for a window in memory. new copies of the application in memory,
or "instances",
   // could point to the window design that was already in RAM instead
of loading it
   // again. even though it's less important today now that computers
have gobs of
   // memory, windows still works this way; it has a number of misc
advantages.
   if( ! hPrevInst ) {
      wndclass.style         = CS_HREDRAW | CS_VREDRAW;          //
window style
      wndclass.lpfnWndProc   = WndProc;                          //
address to event handling procedure
      wndclass.cbClsExtra    = 0;                                // no
extra class data
      wndclass.cbWndExtra    = 0;                                // no
extra window data
      wndclass.hInstance     = hInstance;                        //
handle to the current instance
      wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);      //
stock arrow cursor
      wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  //
stock icon
      wndclass.lpszMenuName  = NULL;							 // menu name
      wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1); //
background color brush
      wndclass.lpszClassName = strProgramName;                   //
window class name
      RegisterClass(&wndclass);
   } 

   // create the main window. you can change the parameters to this
function
   // to make different kinds of windows
   hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,	        // extended
window style
					     strProgramName,                    // program name
                         strProgramName,                    // window
titlebar caption
                         WS_OVERLAPPEDWINDOW | WS_SYSMENU,  // base
window style
                         CW_USEDEFAULT,                     // default
x position
                         CW_USEDEFAULT,                     // default
y position
                         CW_USEDEFAULT,                     // default
width
                         CW_USEDEFAULT,                     // default
height
                         NULL,                              //
parent's handle
                         NULL,                              // menu
handle
                         hInstance,                         // handle
to the instance
                         NULL);                             //
initialization data

    // display the main window; unless you make the window visible as
part of the window
    // style you specify, the window is invisible by default 
    ShowWindow(hWnd, nCmdShow);

    // windows "message pump"... remember that "while(true)" loop that
sat around
    // waiting for events in the pseudocode? well, here it is! through
this loop, messages
    // are parsed and eventually sent by windows to your main event
handler, WndProc
    while(GetMessage(&wMsg,0,0,0)){
        TranslateMessage(&wMsg);
        DispatchMessage(&wMsg);
    }
  
    // return exit code from program, obtained from PostQuitMessage
    return wMsg.wParam;
}

**********END LISTING****************


-------------------------------------------------------
II. Event Driven Programming, Part #2
-------------------------------------------------------

If you actually read the previous listing, you might be reeling a
little by now and wondering if there isn't an easier way. Thankfully,
the answer is "yes".

Most programmers don't want to deal with the whole window setup
routine (WinMain) or frankly the main event handler (WndProc) either.
Most programmers just want to cut to the chase and write the
application-specific code for the events they are interested in (i.e.
onPaint). Fortunately, the people who write development tools are not
insensitive to this need. Many tools exist that will help you do
exactly that.

MFC, for example, is a window framework that does the dirty work for
you. MFC handles the window setup and teardown that is basically the
same for all apps, and allows you to write only the onWhatever event
handler functions that are meaningful to you. Deep, deep down it still
has a message pump but you'll never see it... and for most people,
that's a good thing.

Many other window frameworks other than MFC are available and range
from basic application skeletons to libraries that--like MFC--contain
a lot of extra code for other things that GUI programs like to do:
such as send data over a network or write to a database. ViewKit, for
example, is a basic window framework for CDE and OSF/Motif developers
on Unix platforms.


-------------------------------------------------------
III. Widgets, Windows and Gadgets, Part #1
-------------------------------------------------------

The word WIDGET is a short for "window gadget". A widget is any
control you place on your main window (or FORM) such as a button,
textbox or scrollbar.

Once you understand the basics of how to get an event-driven window up
and running, you'll want to start adding widgets to make your app,
well, do something interesting. If you wanted to add a button using
the Windows-API, you might add the following code to your WinMain
function right before the call to ShowWindow:

CreateWindow(
"BUTTON",  // button class control name
"Click Me",  // default text
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,  // window style
30,  // horizontal position 
30,  // vertical position 
50,  // width  
50,  // height
hWnd,  // handle to parent or owner window
(HMENU)IDC_MYBUTTONID,  // button id, anything you like
hInstance,  // handle to application instance
NULL  // pointer to window-creation data
);

Be sure to make assign a unique ID to you button. Do this by pasting
the following line at the top of the example:

#define IDC_MYBUTTONID   100

Notice that the CreateWindow function is used to make a button.
Buttons, and other widgets, are really just windows themselves much
like your main application window, but with special functionality
written into them to make them operate as buttons.

To make the button actually do anything, you'll need to attach an
event to it. When a button is clicked, Windows fires the WM_COMMAND
event. It also sets the low-order word of the wParam message parameter
to the ID of the button, so that you know what button was clicked. To
process this event, you'll need to add the following code to your
WndProc function:

// button clicked
case WM_COMMAND:
   if (LOWORD(wParam) == IDC_MYBUTTONID) {
      onClickMyButton(hWnd);
   }
   else {
        // some other button got clicked
   }
   break;

Then you would add a function to serve as the event handler for your
button:

void onClickMyButton(HWND hWnd)
{
   MessageBox(hWnd, "Yeah, you clicked me!!", "I was Clicked", MB_OK);
}

Congratulations! You've just made a real, working fully graphical
pure-Windows API program that actually does something. It's not much,
but it fully demonstrates the core of what is involved in producing a
simple application with a GUI.



-------------------------------------------------------
IV. Widgets, Windows and Gadgets, Part #2
-------------------------------------------------------

Just like manually writing the code for the event pump, most
programmers have no tolerance for manually coding every button on
their form. Not only is it a pain to do, it's difficult to maintain
when you want to make design changes. While there's no reason you
can't do it that way, the truth is that most major applications do not
create all of their widgets by calling CreateWindow.

Most windows compilers include what is know as a RESOURCE COMPILER,
which generally also includes a graphical resource editor. A RESOURCE
EDITOR lets you design your form by dragging and dropping buttons,
scrollbars and other widgets onto it. When you are done designing,
your form is saved as a RESOURCE SCRIPT and the positions of your
buttons and other widgets are stored inside. When you compile your
application, this script is compiled into your application by the
resource compiler. Various API calls allow you to simply load even
complete window dialogs from a resource file, which saves you the
trouble of writing code to position all of the controls.

Tools such as MFC can help you simplify connecting your code to the
resources you create. However, you can use a resource editor to help
you design your user interfaces whether you use MFC (or any other
framework) or not.


-------------------------------------------------------
V. Toolkits
-------------------------------------------------------

Sometimes even a resource editor and window framework are not enough.
Many people like to shortcut designing their applications even further
by using one of many different toolkits. For example, Tcl and the Tk
Toolkit is one popular means for designing simple GUIs. Many people
develop just the graphical portion of their application in Tcl\Tk, and
then write the remainder of the application that does the actual work
in C++. This is often a very quick way for people to add a GUI to a
command-line application without investing a large amount of time
programming the interface in C++. Mktclapp is a tool that can help you
do that a bit more easily, and can be found here:
http://www.hwaci.com/sw/mktclapp/

Some other window toolkits and frameworks were already mentioned in
the comments.


-------------------------------------------------------
VI. What Tools to Use
-------------------------------------------------------

Which development tool(s) to use is a very personal decision based on
a large number of different factors. Different tools vary greatly in
both performance and ease of use. Some tools are also better suited to
different types of applications. For example, since we've been
discussing MFC, MFC would be a great choice for writing a spreadsheet
application for Windows because it is easy to use and creates many
standard kinds of window appearances with less effort. However, MFC
would be a terrible choice for developing a trendy screen hack because
it makes it far too difficult to get under the hood. MFC would also be
a poor choice for developing a spreadsheet application if you intended
to port the application to several different platforms, say Windows
and Linux. If you wanted to do something like that, you might be
better off using a different compiler entirely, perhaps such as GCC,
along with some sort of cross-platform window toolkit.

My best advice is just to shop around and see what feels right for
you. Think about what kind of application you want to write, and see
if you can find something similar that someone else has done and find
out what they used to do it. The other thing to consider is how much
you are willing to spend. Some tools--like many of the Linux
tools--are free, but some of the other tools--like the Microsoft
compilers--can be kind of pricey. On the flip side, if you take a
college course, you might be able to get the student edition of any of
them for fairly cheap.


-------------------------------------------------------
VII. Where to Learn More
-------------------------------------------------------

Obviously, there is a lot more to learn about developing applications
with graphical user interfaces. You might consider a course at your
local community college, or at the very least, a trip to your local
library. Many of the "For Dummies" books are actually very good as are
most of the books published by O'Reilly.

Don't forget to read the compiler documentation, either. Although I
had a programming background to begin with--both my parents are
programmers, so they taught me ever since I was little--I first taught
myself C years ago strictly from the Borland help files. The MSDN has
a wealth of information and lots of useful examples. Many of the
programming tools available come with some basic docs or sample files
to get you started.

The following sites have good links to information (and lots of code
you can swipe :-) ) as well as answers to common questions related to
programming graphical applications for various platforms:

Experts Exchange
http://www.experts-exchange.com/

Code Guru
http://www.codeguru.com/

Code Project
http://www.codeproject.com/

MSDN
http://msdn.microsoft.com/

Linoleum: Linux Programming Resources
http://leapster.org/linoleum/

Mac OS X Programming: Getting Started
http://developer.apple.com/macosx/gettingstarted/


I hope this answers your question, and helps you get started in the
right direction developing your own graphical applications.

Good luck with you endeavor,

-Spot
jimmyjrosu-ga rated this answer:5 out of 5 stars
Great answer, more than I expected, thanks!!!!

Comments  
Subject: Re: c++/question
From: bulls23-ga on 30 Apr 2003 10:58 PDT
 
Depends on which platform you want to do this. If you want to do this
on Windows, look at Win32 APIs for creating spreadsheet controls or do
it via MFC.
Subject: Re: c++/question
From: kpax-ga on 30 Apr 2003 15:22 PDT
 
You'll need to write a gui (Graphical User Interface). My
recommendation would be to use wxWindows (link:
http://wxwindows.org/). It's a cross-platform, high-level approach
that's very easy to learn. A close second would be Qt found at
http://www.trolltech.com/
Subject: Re: c++/question
From: efn-ga on 30 Apr 2003 20:10 PDT
 
As other commenters have indicated, there's more than one way to go
about this, and picking a way is really your first problem.

One relevant consideration is how you feel about being locked in to
Microsoft Windows.  If you want to learn how to write GUI applications
that can run on platforms besides Windows, you should use a toolkit
like wxWindows rather than the Microsoft Foundation Classes (MFC) or
the Win32 application programming interface (API).  I haven't used
such a toolkit, but it's possible that the cost of portability is that
you give up something with Windows applications compared to using a
Windows-specific API.  Perhaps performance would be slower or your
facilities for controlling the interface would be more limited.  But
as I say, this is just a guess.

I can't confirm or deny that a toolkit will make it easy, but I can
tell you that the Win32 and MFC APIs are fairly obscure and confusing.
 One can figure them out eventually, but it's not likely to be quick
and easy.  Just to give you a hint, the fifth edition of the classic
Win32 tutorial "Programming Windows" by Charles Petzold runs to 1435
pages, not counting the index or the contents of the CD-ROM that comes
with it.

--efn

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy