Page 1 of 1

Minigui and OOP

Posted: Thu Apr 29, 2010 10:52 am
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

Re: Minigui and OOP

Posted: Thu Apr 29, 2010 11:57 am
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 :(

Re: Minigui and OOP

Posted: Thu Apr 29, 2010 12:26 pm
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.