VC++ GUI Programming made simple

JDT
09-16-2002, 12:21 AM
---------------------Creating windows with VC++ ----------

Skill level
If you can follow directions then somebody who
has never heard of VC++ can do this if they
know how to start VC++ :)
To do this is simple but to understand it I would
think an intermediate skill level is needed.


Part one readme

This is the minimum code needed to create
windows with VC++. All the fat (well almost)
has been cut out so you can see what is actually
needed to make a window. There are things
left out that really should be there but I left
it out so you could focus on the least amount of code.
If you want to see what was left out then follow
the instructions below to step 8. In step 8, select
A Typical Hello World Application, click ok and skip
to step 17. This will show you how MS did it. It's
very confusing if you have not studied it before.

I have built a very extensive class of Controls that take
just a line or two to create and use. They mimic VB's events,
methods, and properties. I will use that starting at part 3
of this tutorial. With a couple exceptions and the lack
of draging and dropping controls on a form, it is just
as easy to use as VB but with the power of C++. This tutorial
will be based on my methods of class building (starting part 3,)
if they are not the same as yours, you get what you pay for ;)





1. Start VC++
2. Go to the file menu and select new
3. In the projects tab select Win32 Application
4. In the Project name box enter "Tutorial" (do not enter the quotes)
5. Choose a location to save the work to. I chose
C:\DOCUMENTS AND SETTINGS\ADMINISTRATOR\DESKTOP\VC_TUTORIAL

6. Leave Win32 checked in the platforms section.
7. Now click OK
8. Select "An Empty Project and click finish
9. Now click OK to the next window.
10. Now go back to the file menu and select New again.
11. In the Files tab select C++ Source File
12. Name it "Tutorial" (do not add quotes)
13. Check the Add to Project Box
14. The Location should default to where the project was saved in the previous steps.
15. Click OK
16. Now paste this code in the file you just created (It should be shown now and have the focus).

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////


#include <windows.h> //<--Include windows specific functions for the project

//Prototype of Window Process function
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

//Heres our main function. The program starts here
//**********************************************************************
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;//<---------Handle to the window
MSG msg;//<-----------Used to get messages from the thread's message queue
WNDCLASSEX wcex; //---Used to register window class information

wcex.cbSize = sizeof(WNDCLASSEX); //<-----Needs to know the size of the structure
wcex.style = CS_HREDRAW | CS_VREDRAW;//<-Window will redraw if resized
wcex.lpfnWndProc = (WNDPROC)WndProc;//<--------Messages will be sent to this procedure
wcex.cbClsExtra = 0;//<-----------------------No extra bytes following class structure
wcex.cbWndExtra = 0;//<-----------------------No extra bytes following instance
wcex.hInstance = hInstance;//<---------------Handle to the instance that contains the window procedure.
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);//<---Default application icon.
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//<------------Standard arrow cursor
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW); //<----------------Gray back color for window
wcex.lpszMenuName = NULL;//<-----------------------------------No Menu for this window
wcex.lpszClassName = "TutorialClass";//<-------Name of the class to be registered
wcex.hIconSm = NULL;//-----------------------Find an appropriate small icon for us

//Class must be registered with the system before we can create the window
RegisterClassEx(&wcex);

//--------------------Lets create a window-----------

//"TutorialClass" - the name of the class we Registered
//"Tutorial" - This will be the name of the window displayed in the title bar
//WS_OVERLAPPEDWINDOW is a window with a title bar and a border
//CW_USEDEFAULT - Use the default horizontal position for the window
//CW_USEDEFAULT - Use the default vertical position for the window
//CW_USEDEFAULT - Use the default width for the window
//CW_USEDEFAULT - Use the default height for the window
//NULL - This window has no parent
//NULL - This window has no menu
//hInstance - The application instance
//NULL - Add no extra data for the WM_CREATE message
hWnd = CreateWindow("TutorialClass", "Tutorial", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
hInstance, NULL);

//Lets show the window we just created maximized
ShowWindow(hWnd, SW_MAXIMIZE);

//This is the message pump that retrieve all
//message from the calling thread's message queue
while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);//Dispatches the message to our WndProc
}

return msg.wParam; //return exit code to the OS
}
//******************************************************************

//This is where all the messages will be processed
//******************************************************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch(message)//<----------Lets find out what message was sent
{
case WM_DESTROY://<-------User wants to quit so lets process this message
PostQuitMessage(0);//This will send GetMessage (in WinMain above) a zero and
//will exit that loop and quit our program
break;
default:
//Send unprocessed messages to the default windows procedure
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//*******************************************************************

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

17. Now go to the menu bar and select Build
18. Select Execute Tutorial.exe
19. Select yes to the message box asking you if you want to build files.
20. Your done, thats the very basics to creating a window in VC++




In part two I will add a command button to interact with the window and display
a message box.

From there I will Wrap the code into a class object. The final
part of this tutorial should have code for a fully wrapped Window (form) and a
Command button. With default events, default wndprocs that map to user defined events,
built in subclassing and several of the popular methods and properties that
go with these types of windows. For those of you new to VC++, you'll be
surprised at how simple GUI programming can be once you build your own
reusable objects. Its not quite as simple as VB, but its not too far off.


BTW - I use VS6 SP5 on win2k and winME

JDT
09-17-2002, 03:59 PM
Part Two Readme

In this part I have added two command buttons, changed the
back color to white instead of gray, wrote some text on the
window, eliminated the control box, window is now shown
in its restore state instead of maximized, and gave the
handles to the windows global scope. There are calls to
MessageBox(), ShellExecute(), and DrawText() along with
a few others.


Buttons added will do the following:
Button1 - Launch www.VisualBasicForum.com with message box confirmation.
Button2 - Exit the application with message box confirmation.



This code has a "messy" Switch statement in the WndProc. It is still
procedural and is not OOP at all. This is an old style of GUI C++
that many programmers still do. There is still a few things left out
that should not be left out but I tried to show the least amount
of code to accomplish the advertised results.


A brief explanation on messages and the WndProc:

Windows is a message passing OS. It responds to events by
passing messages to the windows who have requested them.
For example, if you click a button, the OS will pass a
WM_COMMAND message to the window the button belongs to.
Which we will filter for and respond to in our window
procedure (WndProc). WinMain() function just starts our
program and sets a few things up. The real flow of the
program happens in the windows procedure (WndProc.) There must
be at least one message sent for anything you can think of.
All you have to do is find out what message you want to
respond to and add it to the Switch statement in the WndProc.
Then just add the code to do whatever you want to do when the
message is received.





Either open up the project you made in part 1 (tutorial.dsw)
and delete the code from part one and replace it with the
following code. Or follow the steps in part one to step 16
and paste the following code instead then continue at step 17.

JDT
09-17-2002, 04:00 PM
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////


#include <windows.h> //<--Include windows specific functions for the project

//Prototype of Window Process function
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HWND hWnd;//<---------Handle to the window
HWND Button1hWnd;//<--Handle to the command button 1
HWND Button2hWnd;//<--Handle to the command button 2

//Heres our main function. The program starts here
//**********************************************************************
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{

MSG msg;//<-----------Used to get messages from the thread's message queue
WNDCLASSEX wcex; //---Used to register window class information

wcex.cbSize = sizeof(WNDCLASSEX); //<---------Needs to know the size of the structure
wcex.style = CS_HREDRAW | CS_VREDRAW;//<-----Window will redraw if resized
wcex.lpfnWndProc = (WNDPROC)WndProc;//<------------Messages will be sent to this procedure
wcex.cbClsExtra = 0;//<---------------------------No extra bytes following class structure
wcex.cbWndExtra = 0;//<---------------------------No extra bytes following instance
wcex.hInstance = hInstance;//<-------------------Handle to instance that contains the wndProc.
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);//<-Default application icon.
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//<-Standard arrow cursor
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //<-White back color for window
wcex.lpszMenuName = NULL;//<------------------------No Menu for this window
wcex.lpszClassName = "TutorialClass";//<-------------Name of the class to be registered
wcex.hIconSm = NULL;//-------------------------Find an appropriate small icon for us

//Class must be registered with the system before we can create the window
RegisterClassEx(&wcex);

//--------------------Lets create a window------------------------

//"TutorialClass"-------The name of the class we Registered
//"Tutorial"------------This will be the name of the window displayed in the title bar
//WS_TILED--------------Is a window with a title bar and a border
//CW_USEDEFAULT---------Use the default horizontal position for the window
//CW_USEDEFAULT---------Use the default vertical position for the window
//CW_USEDEFAULT---------Use the default width for the window
//CW_USEDEFAULT---------Use the default height for the window
//NULL------------------This window has no parent
//NULL------------------This window has no menu
//hInstance-------------The application instance
//NULL------------------Add no extra data for the WM_CREATE message

hWnd = CreateWindow("TutorialClass", "Tutorial", WS_TILED,CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

//Now we will create two buttons to put on the form.
//These windows do not need to be registered with RegisterClass
//because they are predefined button classes.

//Button----------------Name of predefined class that creates a command button for us
//WS_CHILD--------------A flag that indicates these are to be children of a parent window
//290,30,90,30----------Left, right, width, and height of the buttons
//hWnd------------------The handle to the parent window

Button1hWnd = CreateWindow("Button","Extreme VB",WS_CHILD,
290,30,90,30,hWnd,NULL,hInstance,NULL);

Button2hWnd = CreateWindow("Button","Exit",WS_CHILD,
380,30,90,30,hWnd,NULL,hInstance,NULL);

ShowWindow(hWnd, SW_SHOW);//<--------Lets show our main window
ShowWindow(Button1hWnd,SW_SHOW);//<--Lets show button number 1
ShowWindow(Button2hWnd,SW_SHOW);//<--Lets show button number 2

//This is the message pump that retrieve all
//message from the calling thread's message queue
while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);//Dispatches the message to our WndProc
}

return msg.wParam; //return exit code to the OS
}
//******************************************************************



//This is where all the messages will be processed
//******************************************************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

PAINTSTRUCT ps;//<---Structure needed for BeginPaint() and EndPaint()
HDC hdc;//<----------Handle to the display DC to be used for painting.
RECT rt;//<----------Structure use with GetClientRect() and DrawText()
char Title[] = "You found this tutorial at www.VisualBasicForums.com";

switch(message)//<----------Lets find out what message was sent
{

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);//<---Prepare window for painting

GetClientRect(hWnd,&rt);//<------Get coordinates of the window to draw on
DrawText(hdc,Title,strlen(Title), &rt, DT_CENTER);//<--Draw some text
EndPaint(hWnd,&ps);//<-----------Tel the OS we are done painting

break;
case WM_COMMAND://<-------Was one of our command buttons clicked?

//lParam = handle to control that fired this message
if((HWND)lParam == Button1hWnd)//<---Was it button number 1?
{
if(MessageBox(hWnd,"Do you want to visit the best site on the web?",
"VisualBasicForum.com",MB_YESNO) == IDYES)
{
//Lets see whats going on over at exvb
ShellExecute(hWnd,"open","www.visualbasicforum.com",NULL,"C:\\", SW_SHOWNORMAL);
}
}
else //<----If it was not button 1 then it should be button number 2
{
if(MessageBox(hWnd,"Do you want to exit program","Quit",MB_YESNO) == IDYES)
{
DestroyWindow(hWnd);//<---Sends a destroy message to the parent window
}
}

break;
case WM_DESTROY://<------User wants to quit so lets process this message

{
PostQuitMessage(0);//This will send GetMessage (in WinMain above) a zero and
//will exit that loop and quit our program
}

break;
default:
//Send unprocessed messages to the default windows procedure
return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;
}
//*******************************************************************

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////






Now go to the menu bar and select Build
Select Execute Tutorial.exe
Select yes to the message box asking you if you want to build files.



In part three we will scrap all of the previous code and take
the object oriented approach. We will build a reusable base class
with derived classes, and a new file for our events.

I've been real busy. Part three is on hold for a while.

JDT
11-11-2002, 09:13 PM
I was asked how to make edit boxes and static controls so I made a little demo that uses - Buttons, Static, Edit, and List controls. For you VB guys, that is a Command Button, Label, Text box, and List Box.

You *could* recreate this by following similar steps in the above tutorial but this was not made by the above step by step. I'm just adding it here because it fits in.

This will be called part 2.2. This is still the very basic code to get the app running and it is not OOP. When i get more time I'll put together a OOP version for part 3.

Unzip the file to a folder and run the .dsw file. Start at step 17 in the above tutorial to see it work.

Bug info - i just threw this together so remember, you get what you pay for ;)

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum