Author Topic: 11. Creating a Skeleton Project  (Read 941 times)

0 Members and 1 Guest are viewing this topic.

Offline LarryMc

  • Administrator
  • Hero Member
  • *****
  • Posts: 5965
  • 'All I like is finishing'
11. Creating a Skeleton Project
« on: August 17, 2011, 08:05:03 PM »
We've finally arrived at the point of actually writing code for our custom control. We'll start by creating an IWBasic project to hold both our testing code and our control code.

Select File/New/Project   from the IWBasic IDE main menu.  This will open a New Project dialog.  Make the following entries:
- Project Name   -'CCT'
- Project Path   - A path of your choosing.
- Project Type   - 'Windows Executable'
- Output File   - 'CCT.exe'

and then click OK.  Leave the project open.

Now we need to create our two source files.

Select File/New/IWBasic Source File   from the IWBasic IDE main menu. This will open an empty IWBasic source file with an automatically generated name of IWBASICx where x is a sequential number.

Select File/SaveAs   from the IWBasic IDE main menu.  This will open a Save As dialog.  Navigate to the folder specified in the Project Path entry above. Enter 'CCT_test.iwb' for the file name and click Save. Right click on the just renamed file and select Insert File Into Project.  The popup menu will disappear and the file name will appear in the IDE's File View panel in the lower right corner of the IDE.

Create the second source file following the exact same procedure, saving the file as 'CCT_lib.iwb' and insert it into the project.

CCT_test.iwb

The CCT_test file will contain code that we need to test our control code as we develop it.  Once we are through with development we will convert the file to an example.
The following shows the code in the different parts of the skeleton.
Code: [Select]
/*===========================================================
* CCT_test.iwb
* Custom Control Tutorial Testing File
*  PART 01
* Copyright (c)T.L. McCaughn 2011
*  This file may be freely shared
*============================================================*/
I have a habit of putting title blocks on my source files.  The significant thing here is that as we progress  through the development of our control I will be creating updated versions of this file.  This one is identified as "Part 1".

Next is:
Code: [Select]
AUTODEFINE "OFF" /* I always use this - personal preference */
$MAIN /* Reguired for this develpoment project not required when making single example file */
$include "windowssdk.inc"  /* I always use this - personal preference */

AUTODEFINE "OFF" - keeps me from inadvertently assigning the wrong type of value to a variable.
$INCLUDE "windowssdk.inc" - saves me a lot of time in not having to look up declarations for system functions, except in rare cases.
$MAIN - All projects require a $MAIN directive.  It is used to define where program execution starts when there are multiple source files.  When this source file is converted to a single file example this directive can be removed.

Code: [Select]
/*----------------SECTION 1----------------------------------
 This section contains declarations that will be converted into an include file that
 User's will use in there applications with the following line:
$INCLUDE "myControl.inc"
------------------------------------------------------------*/
'$USE "myControl.lib /* uncomment when converted to include file */

/*=============== END OF SECTION 1 =========================*/
Section 1 contains constant definitions and function declarations that are required for the test program to interact with the custom control code.  When the test file is converted to an example the contents of this section will be replaced by an include file with the $INCLUDE "myControl.inc" directive.  The include file will contain all the code previously in this section. Also, at that time, the $USE "myControl.lib directive will be uncommented.  This include file will allow user's to link the custom control library into their applications.

Code: [Select]
/*----------------SECTION 2---------------------------------
 This section contains declarations needed for the test program
and the converted example along with any needed initialization
-------------------------------------------------------------*/
window main
int run
/*=============== END OF SECTION 2 ===========================*/

Section 2 contains constant definitions and function definitions that are required by the test/example program itself.  There is no direct connect between them and the library other than as interim variables that are passed to the control.

Code: [Select]
/*----------------SECTION 3-----------------------------------
 This section creates our test/example parent window and its associated parts
--------------------------------------------------------------*/
openwindow main, 0, 0, 880, 780, @CAPTION|@SYSMENU, 0, "Gage Demo", &mainHandler
centerwindow main
BEGINMENU main
MENUTITLE "&File"
MENUITEM "Quit", 0, 100
ENDMENU

/*=============== END OF SECTION 3 ===========================*/
Section 3 contains the basic creation and setup code for any standard window.

Code: [Select]
/*----------------SECTION 4---------------------------------------
 This section is where we create one or more instances of our control.
------------------------------------------------------------------*/


/*=============== END OF SECTION 4 ==========================*/

Section 4 is where we place our user code that creates an instance of our control.

Code: [Select]
/*----------------SECTION 5-----------------------------------------
 This section is where we configure each instance of our control.
--------------------------------------------------------------------*/


/*=============== END OF SECTION 5 ===========================*/

After creating our controls in Section 4 we will configure them in Section 5.

Code: [Select]
/*----------------SECTION 6-----------------------------------------
 This section sets the timer which will update our controls.
---------------------------------------------------------------------*/
STARTTIMER main, 100, 42
run = 1
/*=============== END OF SECTION 6 ===========================*/

Section 6 is where we create a timer to be use to trigger updates to our controls.  The shown code indicate timer # 42 will be set to 1 tenth of a second intervals.  
We are also setting up our idle test by setting run to 1.

Code: [Select]
/*----------------SECTION 7--------------------------------------------
 This section is the idle loop for our test/example program.
-----------------------------------------------------------------------*/
WAITUNTIL run = 0
/*=============== END OF SECTION 7 ===========================*/

This is our idle loop where messages are being dispatched in the background by the OS.

Code: [Select]
/*----------------SECTION 8--------------------------------------------
 This section is where we do any cleanup and close our test/example program
-----------------------------------------------------------------------*/
STOPTIMER main, 42
CLOSEWINDOW main
END

/*=============== END OF SECTION 8 ==========================*/

In Section 8, we do our stand cleanup before shutdown once a closewindow event has occurred.

Code: [Select]
/*----------------SECTION 9---------------------------------------------
 This section contains the message handler for our test/example program..
-------------------------------------------------------------------------*/
SUB mainHandler(),INT
   SELECT @MESSAGE
CASE @IDCLOSEWINDOW
run = 0
       CASE @IDTIMER
SELECT @CODE
CASE 42
ENDSELECT
CASE @IDMENUPICK
SELECT @MENUNUM
CASE 100
run = 0
ENDSELECT
   ENDSELECT
   RETURN 0
ENDSUB
/*=============== END OF SECTION 9 ==========================*/
Section 9 is a standard windows message handler for our test/example program.
during development we will be adding code to the timer #42 section to update our controls.

CCT_lib.iwb

The CCT_lib file will contain code that actually defines and creates our control as we develop it.  Once we are through with development we will convert the file to a static  library file.

The following shows the code in the different parts of the skeleton.
Code: [Select]
/*======================================================
* CCT_lib.iwb
* Custom Control Tutorial Library Source File
*  PART 01
* Copyright (c)T.L. McCaughn 2011
*  This file may be freely shared
*=======================================================*/
This file also has a title block as previously discussed.  Notice that this one is also identified as Part 1.  The two files will appear as a set as we go through the different stages of development.

Code: [Select]
AUTODEFINE "OFF"     /* I always use this - personal preference */
$include "windowssdk.inc"  /* I always use this - personal preference */
$include "gdiplus.inc"     /* Needed in order to use the GDI+ library */

The AUTODEFINE and first $INCLUDE are the same as previously described. The $INCLUDE "gdiplus.inc" file is required since we will be using the OS's GDI+ library to draw our graphics for our control.

Code: [Select]
/*----------------SECTION 1------------------------------
 This section contains the required export declarations for our library
--------------------------------------------------------*/


/*=============== END OF SECTION 1 =====================*/
Section 1 will contain our EXPORT function declarations for each of the functions in our control library that a user can invoke.  Not all functions within our library will be callable by the user.  Some functions will be for internal use only.

Code: [Select]
/*----------------SECTION 2-----------------------------
 This section contains declarations needed for our library
 along with any needed initialization
---------------------------------------------------------*/

/*=============== END OF SECTION 2 ======================*/
Section 2 will contain any definitions and declarations that our control will need.

Code: [Select]
/*----------------SECTION 3-------------------------------
 This section contains the control's message handler
---------------------------------------------------------*/
SUB MyProc_CC(hWnd:UINT, uMsg:UINT, wParam:UINT, lParam:ANYTYPE),UINT

SELECT uMsg
CASE WM_CREATE

RETURN 0
      CASE WM_DESTROY

RETURN 0
      CASE WM_PAINT

RETURN 0
      CASE WM_ERASEBKGND

RETURN 0
      CASE WM_SETFOCUS

RETURN 0
      CASE WM_KILLFOCUS

RETURN 0
ENDSELECT
   RETURN(DefWindowProc(hWnd, uMsg, wParam, lParam))
ENDSUB
/*=============== END OF SECTION 3 =====================*/
Section 3 is the heart of our custom control; the message handler.  Notice that the passed parameters match our previous discussions about messages.  The OS messages that we will be writing code for are already identified.  We will be adding code to all of those.  In addition we will be adding some messages of our own creations along with their code.
Notice the RETURN just before the ENDSUB statement.  We had stated previously that messages we chose not to handle still had to be handle.  This return command passes any unhandled message on the the OS's default window handler.

Obviously, since this is the heart of the control, this handler routine will be rather large before we are through.

Code: [Select]
/*----------------SECTION 4------------------------------
 This section contains the routine used to register the control with the OS.
--------------------------------------------------------*/

/*=============== END OF SECTION 4 ======================*/
Section 4 is where we will place the code for registering our control with the operating system.

Code: [Select]
/*----------------SECTION 5-------------------------------
 This section contains the command used to create a control.
---------------------------------------------------------*/

/*=============== END OF SECTION 5 =====================*/
Section 5 will contain the code we will use to create an instance of our control.

Code: [Select]
/*----------------SECTION 6----------------------------
 This section contains the control's configuration commands
-------------------------------------------------------*/

/*=============== END OF SECTION 6 =================*/
Section 6 will contain the code we will use to configure our control.

Code: [Select]
/*----------------SECTION 7-----------------------------
 This section contains routines for updating the pointer positions of the control
--------------------------------------------------------*/

/*=============== END OF SECTION 7 ====================*/
Section 7 will contain the functions that are called by the timer routine in our test program. These functions will cause our control pointer to be updated.

Code: [Select]
/*----------------SECTION 8------------------------------
 This section contains routines that support the control's message handler
--------------------------------------------------------*/

/*=============== END OF SECTION 8 =====================*/
Section 8 will contain routines that support the message handler directly.

Code: [Select]
/*----------------SECTION 9---------------------------------
 This section contains routine for the control to talk to its parent
-----------------------------------------------------------*/

/*=============== END OF SECTION 9 =======================*/
Section 9 will contain the code that allows our control to send notifications to its parent window.

Code: [Select]
/*----------------SECTION 10--------------------------------
 This section contains any required utility routines
-----------------------------------------------------------/

/*=============== END OF SECTION 10 ======================*/
Section 10 will contain generic utility routines required by our control.

That concludes the overview of our skeleton files.  A copy of this could be set aside and used as the basis for any custom control the reader may want to attempt.

_____________________________

Coming Next - TBD
« Last Edit: August 18, 2011, 06:25:05 AM by LarryMc »
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library