Minigui and OOP

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

Post Reply
User avatar
karweru
Posts: 220
Joined: Fri Aug 01, 2008 1:51 pm
DBs Used: DBF,mysql,mariadb,postgresql,sqlite,odbc
Contact:

Minigui and OOP

Post by karweru »

Dear Friends,

I have the following code that compiles with a syntax error. The idea here is to implement hmg in a oop version by creating classes to represent the various hmg controls. Does the semi-oop implemented in Hmg exclude programming harbour in a oop way or what could the problem be. Kindly assist.
#include "hmg.ch"
#include "hbclass.ch"

Function Main
local oWin:=tWindow():new(0,0,400,480,"myTest","MAIN")
oWin:onInitialize:={||("my Window Class works")}
oWin:create()

DEFINE MAIN MENU
POPUP "File"
ITEM "Test" ACTION {||"test finished"}
ITEM "Exit" ACTION {||oWin:release()}
END POPUP
END MENU

oWin:EndWindow()
oWin:activate()
Return

*----------------------------

CREATE CLASS tWindow

CLASSDATA WindowCount INIT 0

DATA WindowName,windowType

DATA Row,Col INIT 0
DATA width,Height INIT 800
DATA title
DATA noMinimize,noMaximize,noSize,noSysMenu,noCaption,noAutoRelease INIT .f.
DATA onInitialize,onRelease,onGotFocus,onLostFocus,onMaximize,onMinimize,onInteractiveClose INIT {||.t.}

METHOD createMainWindow()
METHOD createChildWindow()
METHOD createModalWindow()
METHOD createPanelWindow()

EXPORT:

METHOD init(nRow,nCol,nWidth,nHeight,cTitle,cWinType)
METHOD create()
METHOD endWindow()

METHOD center() INLINE doMethod(::windowName,"center")
MESSAGE centre() INLINE ::center()
METHOD Maximize() INLINE doMethod(::windowName,"maximize")
METHOD Minimize() INLINE doMethod(::windowName,"minimize")
METHOD Activate() INLINE doMethod(::windowName,"activate")
METHOD Restore() INLINE doMethod(::windowName,"restore")
METHOD close() INLINE doMethod(::windowName(),"release")

ENDCLASS

METHOD init(nRow,nCol,nWidth,nHeight,cTitle,cWinType) CLASS tWindow

::windowName:="win_"+lTrim(str(::windowCOunt++,3,0))

::windowType:=Upper(AllTrim(cWinType))

::row:=nRow
::col:=nCol
::width:=nWidth
::height:=nHeight
::title:=cTitle

return self

METHOD create() CLASS tWindow
if ::WindowType=="MAIN"
::createMainWindow()
elseif ::WindowType=="CHILD"
::createChildWindow()
elseif ::WindowType=="MODAL"
::createModalWindow()
elseif ::WindowType=="PANEL"
::createPanelWindow()
endif
return self

METHOD createMainWindow() CLASS tWindow
DEFINE WINDOW ::windowName WINDOWTYPE MAIN ROW ::row COL ::col WIDTH ::width HEIGHT ::height TITLE ::title ONINIT ::onInitialize
return self

METHOD createChildWindow() CLASS tWindow
return self

METHOD createModalWindow() CLASS tWindow
return self

METHOD createPanelWindow() CLASS tWindow
return self

METHOD endWindow() CLASS tWindow
END WINDOW
return self
Kind regards,
Gilbert.
User avatar
gfilatov
Posts: 1116
Joined: Fri Aug 01, 2008 5:42 am
Location: Ukraine
Contact:

Re: Minigui and OOP

Post by gfilatov »

Hello Gilbert,

You can not create OOP version in the such way 8-)

There is an outdated freeware MCL library by Luis Vasquez P. <luisvasquezcl@yahoo.com> for OOP implementation.

Please take a look for a small piece of code of aboved library:

Code: Select all

*************************************************************
*	MCL Minigui Class Library 
*
*	Copyright	2003 Luis Vasquez P. luisvasquezcl@yahoo.com
*	Mcl is a Class Library for Minigui
*************************************************************
* MINIGUI - Harbour Win32 GUI library source code
*
* Copyright 2002 Roberto Lopez <roblez@ciudad.com.ar>
* http://www.geocities.com/harbour_minigui/
*************************************************************
#include 'hbclass.ch'
#include 'common.ch'

#define WM_SYSCOMMAND	274
#define SC_CLOSE	61536
*--------------------------------------------------------------------
class twindow from TControlWin
	data	vWidth, vHeight, hWnd, nWnd
	data 	title, icon, notifyicon, notifytooltip
	data	main, nominimize, nomaximize, nosize, nosysmenu, nocaption, center,;
				NoShow, TopMost, child, Modal, NoAutoRelease, novscroll, nohscroll
	data 	binit, brelease, bmouseclick, bmousedrag, bmousemove, bonsize, bPaint,;
				bnotifyclick, bscrollup, bscrolldown, bscrollleft, bscrollright,;
				bhscrollbox, bvscrollbox, bGotfocus, blostfocus, bchange, bSize,;
				bOnMinimize, bOnMaximize, bInteractiveClose, brestore INIT { || .t. }
	data	MDI, mdichild, Parent				
	*- datas para ventana splitchild
	data GripperText, Focused, Cursor, Helpbutton
	data lStatusbar
	*- definicion de datos para el status bar
	Data 	oStatus, aStatus, aDate, aTime
	data       oMenu
	data 	aObject AS ARRAY READONLY

	VISIBLE:

	method New(row, col, width, height, title, main ) constructor
	method create()
	method addobject( o ) 			inline aadd( ::aObject, o )
	method Activate()	
	method cGetWidth()			inline GetWindowWidth( ::hWnd )	 
	method cGetheight()			inline GetWindowHeight( ::hWnd )
	method cGetCaption()		inline GetWindowText ( ::hWnd )
	method cSetCaption(x)		inline SetWindowText ( ::hWnd , x )
	method caption(x)				inline if( pcount() = 0, GetWindowText( ::hWnd ), SetWindowText(::hWnd, x ) )
	method cascade()				inline super:cascade()
	method cRow( xrow )			 		
	method cCol( xcol )
	method cWidth( xwidth )	
	method cHeight( xheight )
	method cGetWinColor(xColor)		inline if( pcount()>0, super:Backcolor := xColor, Super:Backcolor)
	method minimize()			inline _MinimizeWindow ( super:cname )
	method maximize()			inline _MaximizeWindow ( super:cname )
	method centerwindow() 			inline _CenterWindow ( super:cname )
	method restore()			inline _RestoreWindow ( super:cname )
	method cShow()				inline _ShowWindow ( super:cname )
	method cHide()				inline _HideWindow ( super:cname )
	method EndWindow()			inline if( ::lSplit, _EndWindow(), .t. )
	method OnInit()				inline Eval(::bInit)
	method OnRelease()			inline Eval(::bRelease)
	method OnMouseClick()			inline Eval(::bMouseClick)
	method OnMouseDrag()			inline Eval(::bMouseDrag)
	method OnMouseMove()			inline Eval(::bMouseMove)
	method OnSize()				inline Eval(::bSize)
	method OnPaint()			inline Eval(::bPaint)
	method OnScrollUp()			Inline Eval(::bScrollUp)
	method OnScrollDown()			inline Eval(::bscrolldown)
	method OnScrollleft()			inline Eval(::bscrollleft)
	method OnScrollRight()			inline Eval(::bscrollright)
	method OnHScrollBox()			inline Eval(::bhscrollbox)
	method OnVScrollBox()			inline Eval(::bvscrollbox)
	method OnGotfocus()			inline Eval(::bgotfocus)
	Method OnLostFocus()			inline Eval(::blostfocus)
	Method OnChange()			inline Eval(::bchange)
	Method OnMaximize()			inline Eval(::bOnMaximize )
	Method OnMinimimize()			inline Eval(::bOnMinimimize )
	Method OnInterActiveClose() 		Inline Eval( ::bInterActiveClose )
	Method Setfocus()			inline super:FormSetFocus( ::hWnd )
	Method Getfocus()			Inline _GetFocusedControl( ::cName )
	Method Refresh()			Inline RedrawWindow( ::hWnd )
	Method cGetControlIndex( cCtrlName )	
	Method Index( cCtrlName ) Inline ::cGetcontrolindex( cCtrlname )
	
	method property()
	Method DelControl(npos)
	*- Metodos para crear el statusbar
	Method AddItem( cMsg, bAction, nSize, cBitmap, cStyle, cToolTip )
	Method Date( bAction, nSize, cToolTip, cSeparator, cPad )
	Method Time( bAction, nSize, cToolTip )

	Method Setbrush( cImg, nStyle ) inline DrawPicture( ::hWnd, cImg, nStyle )

	Error Handler OnError( cMsg, nError )
	method end()

end class
*--------------------------------------------------------------------
method New(row, col, width,height,title,main) class twindow
*--------------------------------------------------------------------
	DEFAULT Row TO 0
	DEFAULT Col TO 0
  DEFAULT Width TO 500
	DEFAULT Height TO 400
  DEFAULT Title TO 'Default'
	DEFAULT Main TO .T.

	super:init('Win')
	super:row			= Row
	super:col			= Col
	super:width		= Width
	super:height	= height
	::Grippertext	=""
	::Focused			= .F.
	::title				= Title
	::icon				= ""
	::bSize				= { ||.t.}
	::mdi				  = .f.
	::mdichild		= .f.
	*-::main				= IF( PCOUNT() = 6, main, super:Ismain() )
	if( len( __aW ) = 0, ::Main := .t., ::Main := .f. )
	::Child				= IF( ::Main, .F., .T. )
	::novscroll		= .f.
	::nohscroll		= .f.
	::nominimize	= .F.
	::nomaximize	= .F.
	::nosize			= .F.
	::nosysmenu		= .F.
	::nocaption		= .F.
	::bRestore		= { || .t. }
	::NoShow			= .F.
	::TopMost			= .F.
	::center			= .F.
	::Modal				= .F.
	::NoAutoRelease=.F.
	::lStatusbar		= .f.
	::ostatus			= nil
	::astatus			= {}
	::adate				= {}
	::atime				= {}
	::omenu				= nil
	::FontSize		= 8
	::Cursor			= ""
	::Helpbutton	:= .f.
	::Parent := nil
	super:backcolor	:= { -1, -1, -1 }
	::aObject	:= {}
	super:NewWindow( Self )	
	::nWnd		:= super:hwnd()

return self
*--------------------------------------------------------------------
method create() class twindow
*--------------------------------------------------------------------
	local i := 1
	IF ::Modal
		::Main	= .f.
		::Child	= .f.
		::mdi = .f.
		::mdichild=.f.
	elseif ::mdi
		::child =.f.
		::modal = .f.
	elseif ::mdichild
		::main=.f.
		::child= .f.
		::mdi=.f.
		::modal = .f.
	Endif

	if ::Main .or. ::Child .or. ::mdi
		_DefineWindow( ;
		super:cname, ::title, super:col, super:row, ;
		super:width, super:height, ::nominimize, ;
		::nomaximize, ::nosize, ::nosysmenu, ::nocaption,.F., '',;
		::bInit, ::bRelease,;
		::bMouseDrag, ::bSize , ;
		::bMouseClick , ::bMouseMove, ;
		super:Backcolor, ::bPaint, ::noshow, ::topmost, ::main, ;
		::icon, ::child, super:Fontname, ;
		super:FontSize, ::NotifyIcon, ::NotifyTooltip , ;
		::bNotifyClick, ::bGotFocus, ;
		::bLostFocus, ::vHeight, ::vWidth, ;
		::bscrollleft , ::bscrollright , ;
		::bscrollup , ::bscrolldown , ;
		::bhScrollBox , ::bvScrollBox , ::Helpbutton,;
		::bOnMaximize, ::bOnMinimize, ::Cursor,;
		::NoAutoRelease, ::bInteractiveClose, ::brestore, ::mdi )
	
	elseif ::Mdichild
		_DefineChildMdiWindow ( ::parent, super:row , super:col , super:width,;
				super:height , ::nominimize, ::nomaximize, ;
				::nocaption, ::nohscroll, ::nohscroll, ::title , super:FontName, ;
				super:FontSize ,::bInit, ::bRelease, ::bMouseClick, ;
				::bGotFocus,::bLostFocus, ::bSize,;
				 ::bOnMaximize , ::bOnMinimize, ::focused , ::cursor )
				 				
	elseif ::Modal
 		_DefineModalWindow( ;	
		super:cname, ::title, super:col, super:row, ;
		super:width, super:height, "", ;
		::nosize, ::nosysmenu, ::nocaption,.F., '',;
		::bInit, ::bRelease,;
		::bMouseDrag, ::bSize , ;
		::bMouseClick , ::bMouseMove, ;
		super:Backcolor, ::bPaint, ;
		::icon, super:Fontname, ;
		super:FontSize, ::bGotFocus, ;
		::bLostFocus, ::vHeight, ::vWidth, ;
		::bscrollleft , ::bscrollright , ;
		::bscrollup , ::bscrolldown , ;
		::bhScrollBox , ::bvScrollBox , ;
		::Helpbutton, ::Cursor, ::NoShow,;
		::NoAutorelease, ::bInteractiveClose )		
	endif
	if ::lStatusbar
		if Len(::aStatus[1] ) > 0
			::ostatus = tstatusbar():new( Self )
			For i = 1 to len( ::astatus )
				::ostatus:additem( 	::astatus[i,1], ::astatus[i,2], ::astatus[i,3],;
														::astatus[i,4], ::astatus[i,5], ::astatus[i,6] )
			Next
			if len( ::aDate ) > 0
				::oStatus:date( ::adate[1], ::adate[2], ::adate[3],	::adate[4], ::adate[5] )
			endif	
			if len( ::aTime ) > 0
				::oStatus:time( ::atime[1], ::atime[2], ::atime[3] )
			endif	
		endif
	endif
	if ::mdichild
		_EndWindow()
	end		
return 
*--------------------------------------------------------------------
method cRow( xrow ) class twindow				
*--------------------------------------------------------------------

	if super:ControlActive
		if( pcount() > 0,	_SetWindowSizePos( super:cname, xrow ),;
											super:row	:= GetWindowRow( ::hWnd ) )

	endif

return super:row
*--------------------------------------------------------------------
method cCol( xcol ) class twindow
*--------------------------------------------------------------------

	if Super:ControlActive
		if( pcount() > 0,		_SetWindowSizePos( super:cname,,xcol),;
												super:col := GetWindowCol( ::hWnd ) )
	endif

return super:col
*--------------------------------------------------------------------
method cWidth( xwidth) class twindow
*--------------------------------------------------------------------

	if Super:ControlActive
		if( pcount() > 0,	_SetWindowSizePos( super:cname, , , xwidth ),;
											super:width	:= GetWindowWidth( ::hWnd ) )
	endif

return super:width
*--------------------------------------------------------------------
method cHeight( xheight ) class twindow
*--------------------------------------------------------------------

	if Super:ControlActive
		if( pcount() > 0,		_SetWindowSizePos( super:cname, , , , xheight ),;
											super:height	:= GetWindowWidth( ::hWnd ) )
	endif

return super:height
*--------------------------------------------------------------------
method Activate() class twindow
*--------------------------------------------------------------------

	LOCAL i := 1, nSplit := 0
	LOCAL lCerrarSplit := .f.
	LOCAL nControls := LEN( ::aObject )
	
	If ::Main
		_BeginWindowActive= .T.
		_ActiveFormName		= super:cname
	Endif

	super:ActiveControl()
	
	i := 1

	FOR i = 1 TO nControls
		::aObject[i]:Activate()
		if upper(::aObject[i]:cName) = 'SPLITBOX'
			nSplit := i
			lCerrarSplit := .t.
		Endif
	NEXT
	
	if lCerrarSplit
		::aObject[ nSplit ]:EndSplitbox()
	Endif
	
	_EndWindow()
	
	::hWnd	= GetFormHandle( super:cname )	
	
	if( ::center,_CenterWindow( super:cname ), NIL )
	_ActivateWindow({ super:cname })

return self
*--------------------------------------------------------------------
Method cGetControlIndex( cCtrlName ) Class TWindow
*--------------------------------------------------------------------
	local i := 1, npos := 0
	if pcount() > 0
		For i = 1 to len( ::aObject )
			if upper( cCtrlName ) == upper( ::aObject[ i ]:ControlName )
				npos := i
				exit
			endif
		Next	
	endif
Return nPos
*--------------------------------------------------------------------
Method end() class twindow
*--------------------------------------------------------------------
	Local i := 1, x

	Super:DelWindow( ::nWnd )
	if ::Main
		ReleaseAllWindows()
		Release All
	Else
		_ReleaseWindow( super:cname )
	Endif

Return nil

*--------------------------------------------------------------------
method property() class twindow
*--------------------------------------------------------------------
	local prop := 'super:cname, 	::title, super:col, super:row, ;
		super:width, super:height, ::nominimize, ;
		::nomaximize, ::nosize, ::nosysmenu, ::nocaption,;
		::bInit, ::bRelease,::bMouseDrag, ::bSize , ;
		::bMouseClick , ::bMouseMove, ;
		super:Backcolor, ::bPaint, ::noshow, ::topmost, ::main, ;
		::icon, ::child, super:Fontname, ;
		super:FontSize, ::NotifyIcon, ::NotifyTooltip , ;
		::bNotifyClick, ::bGotFocus, ;
		::bLostFocus, ::vHeight, ::vWidth, ;
		::bscrollleft , ::bscrollright , ;
		::bscrollup , ::bscrolldown , ;
		::bhScrollBox , ::bvScrollBox , ::Helpbutton,;
		::bOnMaximize, ::bOnMinimize, ::Cursor,;
		::NoAutoRelease, ::bInteractiveClose, ::lStatusbar'
return prop
*--------------------------------------------------------------------
Method OnError( cMsg ) Class TWindow
*--------------------------------------------------------------------
	LOCAL npos := 0, i := 1, nProceso := 0
	LOCAL xproc:= PROCNAME(), cObjectName := ""
	
	IF RAT('_', xproc ) != 0		
		nProceso = 1
		cObjectName	:= Upper( Subs( xproc, Rat('_', xproc )+1 ) )
	Elseif RAT(':', xproc ) != 0
		nProceso = 2
		cObjectName	:= Upper( Subs( xproc, Rat(':', xproc ) + 1 ) )
	Endif
	
	FOR i = 1 TO Len( ::aObject )
		IF Upper( ::aObject[i]:cName ) = cObjectName
			npos := i
			EXIT
		ENDIF
	NEXT
	if nProceso = 0
		msgstop('Error '+xproc,'Error')
		Exitprocess(0)
		Quit
		
	elseif nProceso = 2
		IF npos <> 0
			RETURN ::aObject[ npos ]
		ELSE
			Msgstop('Error '+cObjectName+' not exist','Error TWindow')
			ExitProcess(0)
			Quit
		ENDIF
	endif
RETURN NIL		

Method DelControl( npos ) Class TWindow

	Adel( ::aObject, npos )
	ASize( ::aObject, len( ::aObject )-1 )

Return nil
...
and sample of usage

Code: Select all

*- programa	: demo
*- funcion	: test button 
*- autor		: luis vasquez

#include 'mcl.ch'

procedure main
	local wnd, btn

	wnd	= twindow():new( ,, 300, 300, 'Test Class TButton')
	wnd:center	= true
	wnd:create()
		btn	= tbutton():new( 0,0, 80, 20, wnd, '&Close' )
		btn:baction	= { || if( msgyesno('Close this window','Confirm'), wnd:end(), .t. ) }
	wnd:activate()
return
IMHO The creation of such OOP library will required the knowledge of the low-level HMG internals from you :(
Kind Regards,
Grigory Filatov

"Everything should be made as simple as possible, but no simpler." Albert Einstein
User avatar
karweru
Posts: 220
Joined: Fri Aug 01, 2008 1:51 pm
DBs Used: DBF,mysql,mariadb,postgresql,sqlite,odbc
Contact:

Re: Minigui and OOP

Post by karweru »

Hi Grigory,

Thanks for your answer. To implement classes in Hmg, i've been directly calling _define* functions (just like in the Mcl library in your example), but due to the high rate of development of this library (thanks Roberto), I have to do alot of editing every time something changes. Besides, I don't think it is good to call internals. My thoughts were to use the alternate syntax, which IS WORKING for all other controls other that for a Window class, and my code is exactly as in my example. Maybe the translation of self (::) is the problem? I'm lost.

However, thanks for your time.
Kind regards,
Gilbert.
Post Reply