Einfacher Editor in OOP

Anfängerfragen zum Programmieren mit PureBasic.
es_91
Beiträge: 383
Registriert: 25.01.2011 04:48

Einfacher Editor in OOP

Beitrag von es_91 »

Hallo

Mittels der Anleitung von MK-Soft habe ich meinen funktionierenden Editor in OOP umgeschrieben. Er liest und schreibt eine Datei im temporären Verzeichnis namens "quickPAD.txt", sonst tut er nichts.

Leider zeigt das Programm in seiner jetzigen Form nur ein leeres Fenster an. Eigentlich müsste ein schwarzer Editor angezeigt werden. Kann mir das jemand ausdeutschen?

Code: Alles auswählen





declareModule  qui
	
	
	
	interFace iQui
		
		
		
		;{
		
		queryInterface  (  *riid,  
		                   *addr  )
		addRef  (  )
		release  (  )
		
		;}
		
		
		
	endInterFace
	
	
	
	structure sQui
		
		
		
		;{
		
		*vTable
		cntRef. i
		objMutex. i
		
		;}
		
		
		
	endStructure
	
	
	
	declare  new  (  )
	
	
	
	define  fl$  =  "quickPAD.txt"
	
	
	
endDeclareModule



module  qui
	
	
	
	declare  executing  (  *gadget  )
	
	
	
	declare.  b  loadFromTmpFile  (  *gadget  )
	
	
	
	declare.  q  open  (  )
	
	
	
	declare.  b  storeToTmpFile  (  *gadget  )
	
	
	
	procedure  addRef  (  *this.  sQui  )
		
		
		
		lockMutex  (  *this\  objMutex  )
		
		
		
		*this\  cntRef  +  1
		
		
		
		unlockMutex  (  *this\  objMutex  )
		
		
		
		procedureReturn  *this\  cntRef
		
		
		
	endProcedure
	
	
	
	procedure  queryInterface  (  *this.  sQui,  
	                              *riid,  
	                              *addr  )
		
		
		
		procedureReturn  2147500034
		
		
		
	endProcedure
	
	
	
	procedure  release  (  *this.  sQui  )
		
		
		
		protected  index,  cnt
		
		
		
		with  *this
				
			
			
			lockMutex  (  \  objMutex  )
			
			
			
			If  \  cntRef  =  0
				
				
				
				freeMutex  (  *this\  objMutex  )
				
				
				
				freeStructure  (  *this  )
				
				
				
				procedureReturn 0
				
				
				
			else
				
				
				
				\  cntRef - 1
				
				
				
			endIf
			
			
			
			unlockMutex  (  *this\  objMutex  )
			
			
			
			procedureReturn  \  cntRef
			
			
			
		endWith
		
		
		
	endProcedure
	
	
	
	procedure  executing  (  *ga_i  )
		
		
		
		repeat
			
			
			
		until  waitWindowEvent  (  )  =  #pb_event_closeWindow
		
		
		
		storeToTmpFile  (  *ga_i  )
		
		
		
	endProcedure
	
	
	
	procedure.  b  loadFromTmpFile  (  *ga_i  )
		
		
		
		define.  b  re_v
		
		
		
		define  *fi_i
		
		
		
		*fi_i  =  readFile  (  #pb_any,  
		                       getTemporaryDirectory  (  )  +  fl$  )
		
		
		
		if  *fi_i  and  
		    isFile  (  *fi_i  )  and  
		    isGadget  (  *ga_i  )  and  
		    gadgetType  (  *ga_i  )  =  #pb_gadgetType_editor
			
			
			
			repeat
				
				
				
				addGadgetItem  (  *ga_i,  
				                  -1,  
				                  readString  (  *fi_i  )  )
				
				
				
			until  eOF  (  *fi_i  )
			
			
			
			re_v  =  #true
			
			
			
		endIf
		
		
		
		if  *fi_i  and  
			isFile  (  *fi_i  )
			
			
			
			closeFile  (  *fi_i  )
			
			
			
		endIf
		
		
		
		procedureReturn  re_v
		
		
		
	endProcedure
	
	
	
	procedure  new  (  )
		
		
		
		protected  *object.  sQui
		
		
		
		*object  =  allocateStructure  (  sQui  )
		
		
		
		if  *object
			
			
			
			*object\  vTable  =  ?vTQui
			
			
			
			*object\  objMutex  =  createMutex  (  )
			
			
			
			*object\  cntRef  =  0
			
			
			
		endIf
		
		
		
		open  (  )
		
		
		
		procedureReturn  *object
		
		
		
	endProcedure
	
	
	
	procedure.  q  open  (  )
		
		
		
		define.  q  re_v
		
		
		
		define  *wi_i
		
		
		;{
		define.  w  wi_x  =  200
		define.  w  wi_y  =  150
		define.  w  wi_w  =  600
		define.  w  wi_h  =  400
		
		define.  q  wi_f  =  #pb_window_systemMenu
		
		define$  wi_t  =  "quickPAD"
		;}
		
		
		define  *g_e_i
		
		
		;{
		define.  w  g_e_x  =  0
		define.  w  g_e_y  =  0
		define.  w  g_e_x  =  wi_w
		define.  w  g_e_x  =  wi_h
		
		define.  q  g_e_f  =  #pb_editor_wordWrap
		;}
		
		
		*wi_i  =  openWindow  (  #pb_any,  
		                         wi_x,  
		                         wi_y,  
		                         wi_w,  
		                         wi_h,  
		                         wi_t,  
		                         wi_f  )
		
		
		
		setWindowColor  (  *wi_i,  
		                   #white  )
		
		
		
		*g_e_i  =  editorGadget  (  #pb_any,  
		                            g_e_x,  
		                            g_e_y,  
		                            g_e_w,  
		                            g_e_h,  
		                            g_e_f )
		
		
		
		setGadgetColor  (  *g_e_i,  
		                   #pb_gadget_frontColor,  
		                   #white  )
		
		
		
		setGadgetColor  (  *g_e_i,  
		                   #pb_gadget_backColor,  
		                   #black  )
		
		
		
		re_v  =  loadFromTmpFile  (  *g_e_i  )
		
		
		
		executing  (  *g_e_i  )
		
		
		
		procedureReturn  re_v
		
		
		
	endProcedure
	
	
	
	procedure.  b  storeToTmpFile  (  *ga_i  )
		
		
		
		define.  b  re_v
		
		
		
		define  *fi_i
		
		
		
		define.  q  co_i
		
		
		
		*fi_i  =  createFile  (  #pb_any,  
		                         getTemporaryDirectory  (  )  +  fl$  )
		
		
		
		if  *fi_i  and  
			isFile  (  *fi_i  )  and  
			isGadget  (  *ga_i  )  and  
			gadgetType  (  *ga_i  )  =  #pb_gadgetType_editor
			
			
			
			for  co_i  =  0  to  countGadgetItems  (  *ga_i  )
				
				
				
				if  co_i
					
					
					
					writeStringN  (  *fi_i,  
					                 #empty$  )
					
					
					
				endIf
				
				
				
				writeString  (  *fi_i,  
				                getGadgetItemText  (  *ga_i,  
				                                      co_i  )  )
				
				
				
			next
			
			
			
		endIf
		
		
		
		if  *fi_i  and  
			isFile  (  *fi_i  )
			
			
			
			closeFile  (  *fi_i  )
			
			
			
		endIf
		
		
		
		procedureReturn  re_v
		
		
		
	endProcedure
	
	
	
	dataSection
		
		
		
		vTQui:
		
		
		data.  i  @ queryInterface  ( )
		data.  i  @ addRef  ( )
		data.  i  @ release  ( )
		
		
		
	endDataSection
	
	
	
endModule



*qui  =  qui::new  (  )




Dem Finder des Fehler stelle ich gern das fertige Programm zur Verfügung. Es soll ein Text- und Bildbearbeiter werden.


Salut!
Benutzeravatar
HeX0R
Beiträge: 2960
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: Einfacher Editor in OOP

Beitrag von HeX0R »

Also bei dem Programmierstil wundert mich nicht, dass sich ein Fehler eingeschlichen hat.
Sowas hab ich ja noch überhaupt nicht gesehen, da wird's mir ja schwindlig beim durchschauen.
Dein Fehler ist hier:

Code: Alles auswählen

		Define.  w  g_e_x  =  0
		Define.  w  g_e_y  =  0
		Define.  w  g_e_x  =  wi_w
		Define.  w  g_e_y  =  wi_h
In Zukunft bin ich aber raus bei Codes von Dir, das ist mir zu anstrengend, sorry.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Einfacher Editor in OOP

Beitrag von STARGÅTE »

HeX0R hat geschrieben: 06.02.2024 21:40 Also bei dem Programmierstil wundert mich nicht, dass sich ein Fehler eingeschlichen hat.
Sowas hab ich ja noch überhaupt nicht gesehen, da wird's mir ja schwindlig beim durchschauen.
Ich auch nicht. Wie hast du es denn geschafft, dass selbst die PB-Befehle alle camelCase sind?
Und wieso sind da so viele Leerzeichen und -zeilen? Ist da irgendein Script drüber gelaufen, bevor es hier ins Forum kam?

Als Hinweis von mir noch:
Das durchmischen der verschiedenen Ganzzahltypen (.b, .w, .i, .q und den *pointer) solltest du dir abgewöhnen.
Auch wenn eine Prozedur vielleicht nur #True oder #False zurückgibt oder ein Wert immer kleiner als 32768 ist, macht es keinen Sinn hier statt .i (Integer) einen kleineren Typ wie .b oder .w zu verwenden, es macht das Programm nicht schneller, eher langsamer.
(Zumal ja loadFromTmpFile ein Byte zurück gibt, etwas weiter unten das Resultat dann aber in re_v.q geschrieben wird)
Das gleiche gilt für den größeren Typ .q (8 byte). Eine Quad wird nur in wenigen Ausnahmefällen tatsächlich benötigt, z.B. in der File-Library für die Datei-Schreibposition.
In allen anderen Fällen führt es wieder nur zur Verlangsamung des Codes, wenn dieser nicht unter 64 bit läuft.
Im Falle der For-Schleife, ist dieser unter x86 nicht mal kompilierbar, weil Quads hier nicht erlaubt sind.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Axolotl
Beiträge: 154
Registriert: 31.12.2008 16:34

Re: Einfacher Editor in OOP

Beitrag von Axolotl »

es_91 hat geschrieben: 06.02.2024 19:10 [schnipp / schnapp]

Dem Finder des Fehler stelle ich gern das fertige Programm zur Verfügung. Es soll ein Text- und Bildbearbeiter werden.

Salut!
Es sind noch mehr Fehler enthalten. Z.B. bleibt der Dateiname in den Proceduren unbekannt. Weil Define ein Shared innerhalb der Proceduren erfordert.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
es_91
Beiträge: 383
Registriert: 25.01.2011 04:48

Re: Einfacher Editor in OOP

Beitrag von es_91 »

Ich habe da bemerkt, dass sich dieser Fehler mit dem Editor auf eine Copy&Paste-Aktion berufen hat, sehr peinlich sowas.

Ja, zudem fehlt die share-Anbindung.

Hier nochmal der Code in funktionierender Form:

Code: Alles auswählen




declareModule  qui
	
	
	
	interFace iQui
		
		
		
		;{
		
		queryInterface  (  *riid,  
		                   *addr  )
		addRef  (  )
		release  (  )
		
		;}
		
		
		
	endInterFace
	
	
	
	structure sQui
		
		
		
		;{
		
		*vTable
		cntRef. i
		objMutex. i
		
		;}
		
		
		
	endStructure
	
	
	
	declare  new  (  )
	
	
	
	define$  fi_n  =  getTemporaryDirectory  (  )  +  
	                  "quickPAD.txt"
	
	
	
endDeclareModule



module  qui
	
	
	
	declare  executing  (  *gadget  )
	
	
	
	declare  loadFromTmpFile  (  *gadget  )
	
	
	
	declare  open  (  )
	
	
	
	declare  storeToTmpFile  (  *gadget  )
	
	
	
	procedure  addRef  (  *this.  sQui  )
		
		
		
		lockMutex  (  *this\  objMutex  )
		
		
		
		*this\  cntRef  +  1
		
		
		
		unlockMutex  (  *this\  objMutex  )
		
		
		
		procedureReturn  *this\  cntRef
		
		
		
	endProcedure
	
	
	
	procedure  queryInterface  (  *this.  sQui,  
	                              *riid,  
	                              *addr  )
		
		
		
		procedureReturn  2147500034
		
		
		
	endProcedure
	
	
	
	procedure  release  (  *this.  sQui  )
		
		
		
		protected  index,  cnt
		
		
		
		with  *this
				
			
			
			lockMutex  (  \  objMutex  )
			
			
			
			If  \  cntRef  =  0
				
				
				
				freeMutex  (  *this\  objMutex  )
				
				
				
				freeStructure  (  *this  )
				
				
				
				procedureReturn 0
				
				
				
			else
				
				
				
				\  cntRef - 1
				
				
				
			endIf
			
			
			
			unlockMutex  (  *this\  objMutex  )
			
			
			
			procedureReturn  \  cntRef
			
			
			
		endWith
		
		
		
	endProcedure
	
	
	
	procedure  executing  (  *ga_i  )
		
		
		
		repeat
			
			
			
		until  waitWindowEvent  (  )  =  #pb_event_closeWindow
		
		
		
		storeToTmpFile  (  *ga_i  )
		
		
		
	endProcedure
	
	
	
	procedure  loadFromTmpFile  (  *ga_i  )
		
		
		
		define  re_v
		
		
		
		define  *fi_i
		
		
		
		shared  fi_n
		
		
		
		*fi_i  =  readFile  (  #pb_any,  
		                       fi_n  )
		
		
		
		if  *fi_i  and  
		    isFile  (  *fi_i  )  and  
		    isGadget  (  *ga_i  )  and  
		    gadgetType  (  *ga_i  )  =  #pb_gadgetType_editor
			
			
			
			repeat
				
				
				
				addGadgetItem  (  *ga_i,  
				                  -1,  
				                  readString  (  *fi_i  )  )
				
				
				
			until  eOF  (  *fi_i  )
			
			
			
			re_v  =  #true
			
			
			
		endIf
		
		
		
		if  *fi_i  and  
			isFile  (  *fi_i  )
			
			
			
			closeFile  (  *fi_i  )
			
			
			
		endIf
		
		
		
		procedureReturn  re_v
		
		
		
	endProcedure
	
	
	
	procedure  new  (  )
		
		
		
		protected  *object.  sQui
		
		
		
		*object  =  allocateStructure  (  sQui  )
		
		
		
		if  *object
			
			
			
			*object\  vTable  =  ?vTQui
			
			
			
			*object\  objMutex  =  createMutex  (  )
			
			
			
			*object\  cntRef  =  0
			
			
			
		endIf
		
		
		
		open  (  )
		
		
		
		procedureReturn  *object
		
		
		
	endProcedure
	
	
	
	procedure  open  (  )
		
		
		
		define  re_v
		
		
		
		define  *wi_i
		
		
		;{
		define  wi_x  =  200
		define  wi_y  =  150
		define  wi_w  =  600
		define  wi_h  =  400
		
		define  wi_f  =  #pb_window_systemMenu
		
		define$  wi_t  =  "quickPAD"
		;}
		
		
		define  *g_e_i
		
		
		;{
		define  g_e_x  =  0
		define  g_e_y  =  0
		define  g_e_w  =  wi_w
		define  g_e_h  =  wi_h
		
		define  g_e_f  =  #pb_editor_wordWrap
		;}
		
		
		*wi_i  =  openWindow  (  #pb_any,  
		                         wi_x,  
		                         wi_y,  
		                         wi_w,  
		                         wi_h,  
		                         wi_t,  
		                         wi_f  )
		
		
		
		setWindowColor  (  *wi_i,  
		                   #white  )
		
		
		
		*g_e_i  =  editorGadget  (  #pb_any,  
		                            g_e_x,  
		                            g_e_y,  
		                            g_e_w,  
		                            g_e_h,  
		                            g_e_f )
		
		
		
		setGadgetColor  (  *g_e_i,  
		                   #pb_gadget_frontColor,  
		                   #white  )
		
		
		
		setGadgetColor  (  *g_e_i,  
		                   #pb_gadget_backColor,  
		                   #black  )
		
		
		
		re_v  =  loadFromTmpFile  (  *g_e_i  )
		
		
		
		executing  (  *g_e_i  )
		
		
		
		procedureReturn  re_v
		
		
		
	endProcedure
	
	
	
	procedure  storeToTmpFile  (  *ga_i  )
		
		
		
		define  re_v
		
		
		
		define  *fi_i
		
		
		
		define  co_i
		
		
		
		shared  fi_n
		
		
		
		*fi_i  =  createFile  (  #pb_any,  
		                         fi_n  )
		
		
		
		if  *fi_i  and  
			isFile  (  *fi_i  )  and  
			isGadget  (  *ga_i  )  and  
			gadgetType  (  *ga_i  )  =  #pb_gadgetType_editor
			
			
			
			for  co_i  =  0  to  countGadgetItems  (  *ga_i  )
				
				
				
				if  co_i
					
					
					
					writeStringN  (  *fi_i,  
					                 #empty$  )
					
					
					
				endIf
				
				
				
				writeString  (  *fi_i,  
				                getGadgetItemText  (  *ga_i,  
				                                      co_i  )  )
				
				
				
			next
			
			
			
		endIf
		
		
		
		if  *fi_i  and  
			isFile  (  *fi_i  )
			
			
			
			closeFile  (  *fi_i  )
			
			
			
		endIf
		
		
		
		procedureReturn  re_v
		
		
		
	endProcedure
	
	
	
	dataSection
		
		
		
		vTQui:
		
		
		data.  i  @ queryInterface  ( )
		data.  i  @ addRef  ( )
		data.  i  @ release  ( )
		
		
		
	endDataSection
	
	
	
endModule



*qui  =  qui::new  (  )



@STARGÅTE: Vielen Dank für Deine Hilfestellungen! Du hast natürlich Recht. Ich habe es, glaube ich, überall angepasst. ... Da ist kein Script drübergelaufen, ich code so. camelCase gefällt mir persönlich gut und die vielen Leerzeilen brauche ich wirklich, um nicht zu verrutschen (mit den Augen).

@HeX0R: Vielen Dank! Kein Problem, ich bin Dir dankbar dass Du den hauptsächlichen Fehler gefunden hast. Was für eine Blamage, da nutzte ich Strg+D und verlor die Übersicht. . .

Servus! :bounce:
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Einfacher Editor in OOP

Beitrag von NicTheQuick »

Puh, also da wird mir auch schwindlig, wenn der Code derartig unübersichtlich ist.
Ich akzeptiere das, wenn deine Augen nicht mehr gut sind und du die Zeilen anders nicht mehr auseinander halten kannst, aber sollte es nicht auch einfach reichen die Schrift im Editor größer zu machen?

Mit diesem Coding-Stil wirst du hier vermutlich nicht auf besonders viel Hilfestellung treffen, befürchte ich.
Zum Vergleich mal die Version, wie ich sie bevorzugen würde:

Code: Alles auswählen

DeclareModule qui
	Interface iQui
		queryInterface(*riid, *addr)
		addRef()
		release()
	EndInterface
	Structure sQui
		*vTable
		cntRef. i
		objMutex. i
	EndStructure
	Declare new()
	Define$ fi_n = GetTemporaryDirectory() + "quickPAD.txt"
EndDeclareModule

Module qui
	Declare executing(*gadget)
	Declare loadFromTmpFile(*gadget)
	Declare open()
	Declare storeToTmpFile(*gadget)
	
	Procedure addRef(*this.sQui)
		LockMutex(*this\objMutex)
		*this\cntRef + 1
		UnlockMutex(*this\objMutex)
		ProcedureReturn  *this\cntRef
	EndProcedure
	
	Procedure queryInterface(*this.sQui, *riid, *addr)
		ProcedureReturn 2147500034
	EndProcedure
	
	Procedure release(*this.sQui)
		Protected index, cnt
		With *this
			LockMutex(\objMutex)
			If \cntRef  =  0
				FreeMutex(*this\objMutex)
				FreeStructure(*this)
				ProcedureReturn 0
			Else
				\cntRef - 1
			EndIf
			UnlockMutex(*this\objMutex)
			ProcedureReturn  \cntRef
		EndWith
	EndProcedure
	
	Procedure executing(*ga_i)
		Repeat
		Until WaitWindowEvent() = #PB_Event_CloseWindow
		storeToTmpFile(*ga_i)
	EndProcedure
	
	Procedure loadFromTmpFile(*ga_i)
		Define re_v
		Define *fi_i
		Shared fi_n
		*fi_i = ReadFile(#PB_Any, fi_n)
		If (*fi_i And
		    IsFile(*fi_i) And
		    IsGadget(*ga_i) And
		    GadgetType(*ga_i) = #PB_GadgetType_Editor)
			Repeat
				AddGadgetItem(*ga_i, -1, ReadString(*fi_i))
			Until Eof(*fi_i)
			re_v  =  #True
		EndIf
		If *fi_i And IsFile(*fi_i)
			CloseFile(*fi_i)
		EndIf
		ProcedureReturn re_v
	EndProcedure
	
	Procedure new()
		Protected *object.sQui
		*object = AllocateStructure(sQui)
		If *object
			*object\vTable = ?vTQui
			*object\objMutex = CreateMutex()
			*object\cntRef = 0
		EndIf
		open()
		ProcedureReturn  *object
	EndProcedure
	
	Procedure open()
		Define re_v
		Define *wi_i
		;{
		Define wi_x = 200
		Define wi_y = 150
		Define wi_w = 600
		Define wi_h = 400
		Define wi_f = #PB_Window_SystemMenu
		Define$ wi_t = "quickPAD"
		;}
		Define *g_e_i
		;{
		Define g_e_x = 0
		Define g_e_y = 0
		Define g_e_w = wi_w
		Define g_e_h = wi_h
		Define g_e_f = #PB_Editor_WordWrap
		;}
		*wi_i = OpenWindow(#PB_Any, wi_x, wi_y, wi_w, wi_h, wi_t, wi_f)
		SetWindowColor(*wi_i, #White)
		*g_e_i = EditorGadget(#PB_Any, g_e_x, g_e_y, g_e_w, g_e_h, g_e_f)
		SetGadgetColor(*g_e_i, #PB_Gadget_FrontColor, #White)
		SetGadgetColor(*g_e_i, #PB_Gadget_BackColor, #Black)
		re_v = loadFromTmpFile(*g_e_i)
		executing(*g_e_i)
		ProcedureReturn re_v
	EndProcedure
	
	Procedure storeToTmpFile(*ga_i)
		Define re_v
		Define *fi_i
		Define co_i
		Shared fi_n
		*fi_i = CreateFile(#PB_Any, fi_n)
		If (*fi_i And
		    IsFile(*fi_i) And
		    IsGadget(*ga_i) And
		    GadgetType(*ga_i)  =  #PB_GadgetType_Editor)
			
			For co_i  =  0 To CountGadgetItems(*ga_i)
				If co_i
					WriteStringN(*fi_i, #Empty$)
				EndIf
				WriteString(*fi_i, GetGadgetItemText(*ga_i, co_i))
			Next
		EndIf
		
		If  *fi_i And  
		    IsFile(*fi_i)
			CloseFile(*fi_i)
		EndIf
		ProcedureReturn re_v
	EndProcedure
	
	DataSection
		vTQui:
		Data.i @queryInterface()
		Data.i @addRef()
		Data.i @release()
	EndDataSection
EndModule

*qui = qui::new()
Allerdings sind die ganzen Variablennamen auch nicht gut gewählt. Man kann am Variablennamen nicht erkennen, was z.B. `co_i` sein soll, oder `*ga_i` oder `g_e_f`. Also an dieser Stelle wäre noch ein Tipp von mir, dass du aussagekräftige Variablennamen nutzen solltest.
Und wieso sind deine Variablen eigentlich nicht camelCase, sondern in snake_case, wenn du es sonst überall aber camelCase bevorzugst?

Bezüglich der Architektur des Codes: Ich würde das Öffnen des Fensters und die Ereignisschleife aus `new()` entfernen. Objektorientierung zielt ja darauf ab, dass man mehrere Instanzen einer Objektklasse erstellen kann. Bei dir geht das aber nicht. Sobald man `qui::new()` aufruft, hängt das Programm in deinem Fenster fest. Man kann kein zweites mehr öffnen ohne den Code umzuschreiben.

Ich habe vor 10 Jahren mal ein Tutorial für etwas ähnliches gemacht, falls es dich interessiert. Da nutze ich auch Module, Interfaces, aber gebe auch die Möglichkeit beliebig viele dieser Fenster unabhängig zu erstellen: https://www.youtube.com/watch?v=eYrBLy13y2Q
Bild
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Einfacher Editor in OOP

Beitrag von mk-soft »

Da muss ich Nick recht geben.
Ausser die IUnknown (die man nur für COM Objekte braucht) sehe ich nicht ein Objekt zur Mehrfachverwendung.
Du musst alle Parameter, Id's und Properties in die Struktur legen.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Einfacher Editor in OOP

Beitrag von mk-soft »

Mal etwas zum knobeln ...

Mit einen kleinen Trick das Objekt auf ein Nothing Objekt umzuleiten, wenn dieser freigeben wird.

Update 2

Code: Alles auswählen

;-TOP

CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
  #S_OK = 0
  #S_FALSE = 1
CompilerEndIf

DeclareModule Common
  
  Enumeration CommonMenuItems 1001
    #MenuNew
    #MenuOpen
    #MenuSave
  EndEnumeration
  
  CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
    #S_OK = 0
    #S_FALSE = 1
  CompilerEndIf
  
EndDeclareModule

Module Common
EndModule

; ----

DeclareModule objEditNothing
  
  Interface iEdit
    Release()
    _NewFile()
    _OpenFile()
    _SaveFile()
  EndInterface
  
  Structure sEdit
    *vTable
  EndStructure
  
  Global Object.sEdit
  
EndDeclareModule

Module objEditNothing
  
  Object\vTable = ?vEdit
  
  ; Public
  
  Procedure Release(*this)
    Debug "Object not exists!"
    ProcedureReturn 0
  EndProcedure
  
  Procedure _NewFile(*this)
    Debug "Object not exists!"
    ProcedureReturn 0
  EndProcedure
  
  Procedure _OpenFile(*this)
    Debug "Object not exists!"
    ProcedureReturn 0
  EndProcedure
  
  Procedure _SaveFile(*this)
    Debug "Object not exists!"
    ProcedureReturn 0
  EndProcedure
  
  DataSection
    vEdit:
    Data.i @Release()
    Data.i @_NewFile()
    Data.i @_OpenFile()
    Data.i @_SaveFile()
  EndDataSection
     
EndModule

; ----

DeclareModule objEdit
  
  Interface iEdit
    Release()
    _NewFile()
    _OpenFile()
    _SaveFile()
  EndInterface
  
  Structure sEdit
    *vTable
    *Self.integer
    Window.i
    Editor.i
    Menu.i
    File.i
    FileName.s
    IsEdit.i
  EndStructure
  
  Declare New(FileName.s, *ppObject)
  
EndDeclareModule

Module objEdit
  
  UseModule Common
  
  ; Private
  
  #Title = "OOP-Editor - "
  
  Procedure DoWindowEvents()
    Protected *iObject.iEdit
    
    Select Event()
      Case #PB_Event_CloseWindow
        *iObject = GetWindowData(EventWindow())
        *iObject\Release()
        
      Case #PB_Event_Menu
        *iObject = GetWindowData(EventWindow())
        Select EventMenu()
          Case #MenuNew
            *iObject\_NewFile()
          Case #MenuOpen
            *iObject\_OpenFile()
          Case #MenuSave
            *iObject\_SaveFile()
        EndSelect
        
    EndSelect
  EndProcedure
        
  Procedure DoGadgetEvents()
    Protected *sObject.sEdit
    
    With *sObject
      Select Event()
        Case #PB_Event_Gadget
          *sObject = GetGadgetData(EventGadget())
          Select EventGadget()
            Case \Editor
              Select EventType()
                Case #PB_EventType_Change
                  If Not \IsEdit
                    \IsEdit = #True
                    SetWindowTitle(\Window, #Title + GetFilePart(\FileName) + "*")
                  EndIf
              EndSelect
          EndSelect
      EndSelect
    EndWith
  EndProcedure
  
  ; Private Methods
  
  Procedure _NewFile(*this.sEdit)
    With *this
      SetGadgetText(\Editor, "")
      \FileName = ""
      \IsEdit = #False
      SetWindowTitle(\Window, #Title + "New")
    EndWith
    ProcedureReturn 0
  EndProcedure
  
  Procedure _OpenFile(*this.sEdit)
    Protected filename.s
    
    With *this
      filename = OpenFileRequester("Open", "", "", 0)
      If filename
        \File = ReadFile(#PB_Any, FileName)
        If \File
          SetGadgetText(\Editor, ReadString(\File, #PB_File_IgnoreEOL))
          CloseFile(\File)
          \FileName = filename
          \IsEdit = #False
          SetWindowTitle(\Window, #Title + GetFilePart(\FileName))
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  Procedure _SaveFile(*this.sEdit)
    Protected filename.s
    With *this
      If \FileName = ""
        filename = SaveFileRequester("Save", "", "", 0)
      Else
        filename = \FileName
      EndIf
      If filename
        \File = CreateFile(#PB_Any, FileName)
        If \File
          WriteString(\File, GetGadgetText(\Editor))
          CloseFile(\File)
          \FileName = filename
          \IsEdit = #False
          SetWindowTitle(\Window, #Title + GetFilePart(\FileName))
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; Public
  
  Procedure Release(*this.sEdit)
    Protected filename.s
    With *this
      If IsWindow(\Window)
        If \IsEdit
          If \FileName = ""
            filename = SaveFileRequester("Save", "", "", 0)
          Else
            filename = \FileName
          EndIf
          If FileName
            \File = CreateFile(#PB_Any, \FileName)
            If \File
              WriteString(\File, GetGadgetText(\Editor))
              CloseFile(\File)
            EndIf
          EndIf
        EndIf
        CloseWindow(\Window)
      EndIf
      \Self\i = objEditNothing::Object
      FreeStructure(*this)
    EndWith
  EndProcedure
  
  Procedure New(FileName.s, *ppObject.Integer)
    Protected r1, *object.sEdit
    
    With *object
      *object = AllocateStructure(sEdit)
      If *object
        \vTable = ?vEdit
        \Self = *ppObject
        \Window = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 300, 200, #Title + GetFilePart(FileName), #PB_Window_SystemMenu)
        If \Window
          ; Menu
          \Menu = CreateMenu(#PB_Any, WindowID(\Window))
          MenuItem(#MenuNew, "New")
          MenuItem(#MenuOpen, "Open")
          MenuItem(#menuSave, "Save")
          ; Gadgets
          \Editor = EditorGadget(#PB_Any, 0, 0, 300, 200 - MenuHeight())
          ; Data
          \FileName = FileName
          \File = ReadFile(#PB_Any, \FileName)
          If \File
            SetGadgetText(\Editor, ReadString(\File, #PB_File_IgnoreEOL))
            CloseFile(\File)
          EndIf
          SetWindowData(\Window, *object)
          SetGadgetData(\Editor, *object)
          ; Bind Events
          BindEvent(#PB_Event_CloseWindow, @DoWindowEvents(), \Window)
          BindEvent(#PB_Event_Menu, @DoWindowEvents(), \Window)
          BindGadgetEvent(\Editor, @DoGadgetEvents())
          ; Result
          *ppObject\i = *object
          r1 = #S_OK
        Else
          ; Error Result
          FreeStructure(*object)
          *ppObject\i = objEditNothing::Object
          r1 = #S_FALSE
        EndIf
      EndIf
    EndWith
    ProcedureReturn r1
  EndProcedure
  
  DataSection
    vEdit:
    Data.i @Release()
    Data.i @_NewFile()
    Data.i @_OpenFile()
    Data.i @_SaveFile()
  EndDataSection
     
EndModule

; ----

;-Test

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, 50, 50, 600, 400, "Test Window", #WinStyle)
    
    Global *obj1.objEdit::iEdit
    Global *obj2.objEdit::iEdit
    Global *obj3.objEdit::iEdit
        
    filename.s = GetUserDirectory(#PB_Directory_Documents) + "Editor-001.txt"
    If objEdit::New(filename, @*obj1) = #S_OK
      Debug "Object 1 angelegt: " + Hex(*obj1)
    EndIf
    
    filename.s = GetUserDirectory(#PB_Directory_Documents) + "Editor-002.txt"
    If objEdit::New(filename, @*obj2) = #S_OK
      Debug "Object 2 angelegt: " + Hex(*obj2)
    EndIf
    
    filename.s = GetUserDirectory(#PB_Directory_Documents) + "Editor-003.txt"
    If objEdit::New(filename, @*obj3) = #S_OK
      Debug "Object 3 angelegt: " + Hex(*obj3)
    EndIf
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              *obj1\Release()
              *obj2\Release()
              *obj3\Release()
              Break
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Einfacher Editor in OOP

Beitrag von mk-soft »

Oder mit einen kleinen Object-Management ob das Object gibt

Update

Code: Alles auswählen

;-TOP

DeclareModule CommonObject
  
  Enumeration CommonMenuItems 1001
    #MenuNew
    #MenuOpen
    #MenuSave
  EndEnumeration
  
  Declare AddObject(*Object, vTable)
  Declare RemoveObject(*Object)
  Declare IsObject(*Object)
  
EndDeclareModule

Module CommonObject
  
  Structure sObject
    *vtable
  EndStructure
  
  Global NewMap Objects()
  
  Procedure AddObject(*Object, vTable)
    AddMapElement(Objects(), Str(*Object))
    Objects() = vTable
  EndProcedure
  
  Procedure RemoveObject(*Object)
    If FindMapElement(Objects(), Str(*Object))
      DeleteMapElement(Objects())
    EndIf
  EndProcedure
  
  Procedure IsObject(*Object.sObject)
    If FindMapElement(Objects(), Str(*Object))
      If *Object\vtable = Objects()
        ProcedureReturn #True
      EndIf
    EndIf
    ProcedureReturn #False
  EndProcedure
  
EndModule

Macro IsObject(Object)
  CommonObject::IsObject(Object)
EndMacro

; ----

DeclareModule objEditor
  
  Interface iEditor
    Release()
    _NewFile()
    _OpenFile()
    _SaveFile()
  EndInterface
  
  Structure sEditor
    *vTable
    Window.i
    Editor.i
    Menu.i
    File.i
    FileName.s
    IsEdit.i
  EndStructure
  
  Declare New(FileName.s)
  
EndDeclareModule

Module objEditor
  
  UseModule CommonObject
  
  ; Private
  
  #Title = "OOP-Editor - "
  
  Procedure DoWindowEvents()
    Protected *iObject.iEditor
    
    Select Event()
      Case #PB_Event_CloseWindow
        *iObject = GetWindowData(EventWindow())
        *iObject\Release()
        
      Case #PB_Event_Menu
        *iObject = GetWindowData(EventWindow())
        Select EventMenu()
          Case #MenuNew
            *iObject\_NewFile()
          Case #MenuOpen
            *iObject\_OpenFile()
          Case #MenuSave
            *iObject\_SaveFile()
        EndSelect
        
    EndSelect
  EndProcedure
  
  Procedure DoGadgetEvents()
    Protected *sObject.sEditor
    
    With *sObject
      *sObject = GetGadgetData(EventGadget())
      Select EventGadget()
        Case \Editor
          Select EventType()
            Case #PB_EventType_Change
              If Not \IsEdit
                \IsEdit = #True
                SetWindowTitle(\Window, #Title + GetFilePart(\FileName) + "*")
              EndIf
          EndSelect
      EndSelect
    EndWith
  EndProcedure
  
  ; Private Methods
  
  Procedure _NewFile(*this.sEditor)
    With *this
      SetGadgetText(\Editor, "")
      \FileName = ""
      \IsEdit = #False
      SetWindowTitle(\Window, #Title + "New")
    EndWith
    ProcedureReturn 0
  EndProcedure
  
  Procedure _OpenFile(*this.sEditor)
    Protected filename.s
    
    With *this
      filename = OpenFileRequester("Open", "", "", 0)
      If filename
        \File = ReadFile(#PB_Any, FileName)
        If \File
          SetGadgetText(\Editor, ReadString(\File, #PB_File_IgnoreEOL))
          CloseFile(\File)
          \FileName = filename
          \IsEdit = #False
          SetWindowTitle(\Window, #Title + GetFilePart(\FileName))
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  Procedure _SaveFile(*this.sEditor)
    Protected filename.s
    With *this
      If \FileName = ""
        filename = SaveFileRequester("Save", "", "", 0)
      Else
        filename = \FileName
      EndIf
      If filename
        \File = CreateFile(#PB_Any, FileName)
        If \File
          WriteString(\File, GetGadgetText(\Editor))
          CloseFile(\File)
          \FileName = filename
          \IsEdit = #False
          SetWindowTitle(\Window, #Title + GetFilePart(\FileName))
        EndIf
      EndIf
    EndWith
  EndProcedure
  
  ; Public
  
  Procedure Release(*this.sEditor)
    Protected filename.s
    With *this
      If \IsEdit
        If \FileName = ""
          filename = SaveFileRequester("Save", "", "", 0)
        Else
          filename = \FileName
        EndIf
        If FileName
          \File = CreateFile(#PB_Any, \FileName)
          If \File
            WriteString(\File, GetGadgetText(\Editor))
            CloseFile(\File)
          EndIf
        EndIf
      EndIf
      If IsWindow(\Window)
        CloseWindow(\Window)
      EndIf
      FreeStructure(*this)
      RemoveObject(*this)
    EndWith
  EndProcedure
  
  Procedure New(FileName.s)
    Protected *object.sEditor
    
    With *object
      *object = AllocateStructure(sEditor)
      If *object
        \vTable = ?vEdit
        \Window = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 300, 200, #Title + GetFilePart(FileName), #PB_Window_SystemMenu)
        If \Window
          ; Menu
          \Menu = CreateMenu(#PB_Any, WindowID(\Window))
          MenuItem(#MenuNew, "New")
          MenuItem(#MenuOpen, "Open")
          MenuItem(#menuSave, "Save")
          ; Gadgets
          \Editor = EditorGadget(#PB_Any, 0, 0, 300, 200 - MenuHeight())
          ; Data
          \FileName = FileName
          \File = ReadFile(#PB_Any, \FileName)
          If \File
            SetGadgetText(\Editor, ReadString(\File, #PB_File_IgnoreEOL))
            CloseFile(\File)
          EndIf
          SetWindowData(\Window, *object)
          SetGadgetData(\Editor, *object)
          ; Bind Events
          BindEvent(#PB_Event_CloseWindow, @DoWindowEvents(), \Window)
          BindEvent(#PB_Event_Menu, @DoWindowEvents(), \Window)
          BindGadgetEvent(\Editor, @DoGadgetEvents())
          AddObject(*object, ?vEdit)
        Else
          ; Error Result
          FreeStructure(*object)
          *object = 0
        EndIf
      EndIf
    EndWith
    ProcedureReturn *object
  EndProcedure
  
  DataSection
    vEdit:
    Data.i @Release()
    Data.i @_NewFile()
    Data.i @_OpenFile()
    Data.i @_SaveFile()
  EndDataSection
  
EndModule

; ----

;-Test

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, 50, 50, 600, 400, "Test Window", #WinStyle)
    
    Global *obj1.objEditor::iEditor
    Global *obj2.objEditor::iEditor
    Global *obj3.objEditor::iEditor
    
    filename.s = GetUserDirectory(#PB_Directory_Documents) + "Editor-001.txt"
    *obj1 = objEditor::New(filename)
    
    filename.s = GetUserDirectory(#PB_Directory_Documents) + "Editor-002.txt"
    *obj2 = objEditor::New(filename)
    
    filename.s = GetUserDirectory(#PB_Directory_Documents) + "Editor-003.txt"
    *obj3 = objEditor::New(filename)
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              If IsObject(*obj1)
                *obj1\Release()
              EndIf
              If IsObject(*obj2)
                *obj2\Release()
              EndIf
              If IsObject(*obj3)
                *obj3\Release()
              EndIf
              Break
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
es_91
Beiträge: 383
Registriert: 25.01.2011 04:48

Re: Einfacher Editor in OOP

Beitrag von es_91 »

Ich versuch auch gerade herauszufinden wie ich aus dem hier sinnlosen Objekt ein Sinnvolles machen könnte. Da die Anwendung nur ein Hauptfenster braucht ergibt das im Wesentlichen gar keinen Sinn.
Antworten