HOWTO extend a class using inheritance

Moderator: Rathinagiri

Post Reply
Ricci
Posts: 255
Joined: Thu Nov 19, 2009 2:23 pm

HOWTO extend a class using inheritance

Post by Ricci » Sun Nov 27, 2011 8:04 pm

As I described in this example ( viewtopic.php?f=32&t=2121 ) HMG4 is based on full OOP and it is not difficult to use this for your own extensions without touching the source code.

A simple example: Let us extend the bitmap class so it will react on a double click.
Usually we define a simple click to call a function in BITMAP:

Code: Select all

#include "hmg.ch"
#include "hbqtgui.ch"

FUNCTION Main()

	LOCAL oForm1

	HbQt_ErrorSys()

   DEFINE MAINWINDOW oForm1
				ROW  10
				COL  10
				WIDTH	300
				HEIGHT 200
				FONT "ARIAL"; SIZE 09

		DEFINE IMAGE oBitmap
					ROW 10; COL 10
					WIDTH 200; HEIGHT  200
					PICTURE "mypicture.png"
					ONCLICK { || msginfo( "Click" ) }
		END IMAGE

	END Window

	ACTIVATE WINDOW oForm1

RETURN Nil
Using ONDBLCLICK instead of ONCLICK will not work because the BITMAP class didn´t know about the double click.

Let´s extend the BITMAP class:

1. We define the new CLASS MYIMAGE based on IMAGE:

Code: Select all

CLASS MYIMAGE FROM BITMAP
   
ENDCLASS
2. Now we add the method for the doubleclick. To make it easy for us we look through the source codes and find classes that still react on double click. We take the code from them:

Code: Select all

CLASS MYIMAGE FROM BITMAP
   
   METHOD OnDblClick                      SETGET
	
ENDCLASS

METHOD OnDblClick( bValue ) CLASS MYIMAGE

   IF PCOUNT() == 0
      RETURN ::bOnDblClick
   ELSEIF PCOUNT() == 1
      IF hb_IsBlock( bValue ) == .T.
         ::bOnDblClick := bValue
         ::oQtObject:connect( QEvent_MouseButtonDblClick, bValue )
      ELSEIF hb_IsNil( bValue ) == .T.
         ::bOnDblClick := NIL
         ::oQtObject:disconnect( QEvent_MouseButtonDblClick )
      ENDIF
   ENDIF

RETURN Self
Because we use CLASS commands we need to include "hbclass.ch" !

3. We change our program code to define a MYIMAGE instead of IMAGE:

Code: Select all

		DEFINE MYIMAGE oBitmap
					ROW 10; COL 10
					WIDTH 200; HEIGHT  200
					PICTURE "mypicture.png"
					ONDBLCLICK { || msginfo( "Click" ) }
		END MYIMAGE
4. We now get a compiler error, because the preprocessor didn´t find "DEFINE MYIMAGE" in HMG.CH.
Since we are using oneliners in our define, we only have to change the translate command for the first line. We search for the translate commands of IMAGE in HMG.CH, copy the lines, put them into the head of our program and change IMAGE TO MYIMAGE (we don´t need to understand the rest of #xcommand ;) ):

Code: Select all

#xcommand DEFINE MYIMAGE <tagreference>[ <dummy1: OF, PARENT> <oParent> ] [ TOVAR <varname> ] => ;
With Object [<varname> :=] MYIMAGE():New( <"tagreference">[, <oParent> ] )
#xcommand END MYIMAGE => End With
That´s it. Here is the whole program, the image will now react on double click instead of a click.
And the best thing is that we didn´t change anything of the source codes so any update will not influence our work.

Code: Select all

#include "hmg.ch"
#include "hbqtgui.ch"
#include "hbclass.ch"

#xcommand DEFINE MYIMAGE <tagreference>[ <dummy1: OF, PARENT> <oParent> ] [ TOVAR <varname> ] => ;
With Object [<varname> :=] MYIMAGE():New( <"tagreference">[, <oParent> ] )
#xcommand END MYIMAGE => End With

FUNCTION Main()

	LOCAL oForm1

	HbQt_ErrorSys()

   DEFINE MAINWINDOW oForm1
				ROW  10
				COL  10
				WIDTH	300
				HEIGHT 200
				FONT "ARIAL"; SIZE 09

		DEFINE MYIMAGE oBitmap
					ROW 10; COL 10
					WIDTH 200; HEIGHT  200
					PICTURE "mypicture.png"
					ONDBLCLICK { || msginfo( "Click" ) }
		END IMAGE

	END Window

	ACTIVATE WINDOW oForm1

RETURN Nil

//-------------------------------------------------------------------------------------------------------------------------------

/*==============================================================================
   MYIMAGE class
==============================================================================*/
CLASS MYIMAGE FROM BITMAP
   
// Methods
   METHOD OnDblClick                      SETGET
	
ENDCLASS

/*..............................................................................
   OnDblClick
..............................................................................*/
METHOD OnDblClick( bValue ) CLASS MYIMAGE

   IF PCOUNT() == 0
      RETURN ::bOnDblClick
   ELSEIF PCOUNT() == 1
      IF hb_IsBlock( bValue ) == .T.
         ::bOnDblClick := bValue
         ::oQtObject:connect( QEvent_MouseButtonDblClick, bValue )
      ELSEIF hb_IsNil( bValue ) == .T.
         ::bOnDblClick := NIL
         ::oQtObject:disconnect( QEvent_MouseButtonDblClick )
      ENDIF
   ENDIF

RETURN Self
Ricci

mrduck
Posts: 497
Joined: Fri Sep 10, 2010 5:22 pm

Post by mrduck » Sun Nov 27, 2011 8:37 pm

Great post Ricci,
it's exactly one of the reasons HMG4 is so powerfull !

Ricci wrote: 4. We now get a compiler error, because the preprocessor didn´t find "DEFINE MYIMAGE" in HMG.CH.
Since we are using oneliners in our define, we only have to change the translate command for the first line. We search for the translate commands of IMAGE in HMG.CH, copy the lines, put them into the head of our program and change IMAGE TO MYIMAGE (we don´t need to understand the rest of #xcommand ;) ):

Code: Select all

#xcommand DEFINE MYIMAGE <tagreference>[ <dummy1: OF, PARENT> <oParent> ] [ TOVAR <varname> ] => ;
With Object [<varname> :=] MYIMAGE():New( <"tagreference">[, <oParent> ] )
#xcommand END MYIMAGE => End With
So if you use pure oop syntax, you don't ever need to create the xcommands !

And the best thing is that we didn´t change anything of the source codes so any update will not influence our work.
Exactly, pure inheritance at work !

Please keep up with these posts... I'd like one on the pop-up graph... :-)

User avatar
danielmaximiliano
Posts: 2136
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Has thanked: 154 times
Been thanked: 23 times
Contact:

Post by danielmaximiliano » Mon Nov 28, 2011 12:29 am

Hola Ricci:

English term or phrase: clear as day
Spanish translation : más claro que el agua (por todo el mundo)
Spanish Argentina : más claro hechale agua.

Gracias por compartir / thanks for sharing
*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`.HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. : +54901169026142
Telegram Name : DaNiElMaXiMiLiAnO

User avatar
Rathinagiri
Posts: 5263
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Has thanked: 169 times
Been thanked: 172 times
Contact:

Post by Rathinagiri » Mon Nov 28, 2011 3:47 am

Nice explanation Ricci. Thanks a lot.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.

Ricci
Posts: 255
Joined: Thu Nov 19, 2009 2:23 pm

Post by Ricci » Mon Nov 28, 2011 9:41 am

mrduck wrote: So if you use pure oop syntax, you don't ever need to create the xcommands !
I know, but HMG code is more readable. :D

mrduck
Posts: 497
Joined: Fri Sep 10, 2010 5:22 pm

Post by mrduck » Mon Nov 28, 2011 9:42 am

I was saying this to all the readers, not you... I know that you and Luigi know... ;-)
Ricci wrote:
mrduck wrote: So if you use pure oop syntax, you don't ever need to create the xcommands !
I know, but HMG code is more readable. :D

Post Reply