ein einfacher Texteditor als Beispiel für PB4 (Vollversion).
Kommt mit einer API aus (Sendmessage) für die Funktionen Bearbeiten.
Update v1.01: Kommentare erweitert, kleine Programmanpassung
Update v1.02: Teilweise Menu´s sperren
Update v1.03: Procedure UpdateMenu()
Update v1.04: UpdateMenu() aufruf verbessert. Auf in WindowsCallback wenn Menu angewählt wird.
Update v1.05: Randeinstellung hinzugefügt. Kommentare erweitert (noch immer nicht fertig)
Update v1.06: Programparameter hinzugefügt. Textdateien verknüpfen jetzt möglich
Update v1.07: Repariert - Tastaturkürzel Strg-A (Alles Markieren) ging nicht; LimitText auf unbegrenzt gesetzt; Laden von ReadString() nach ReadData() umgestellt (Geschwindigkeit)
Code: Alles auswählen
;-TOP
; Kommentar : Einfacher Texteditor für PB4 Vollversion
; Author : mk-soft
; Datei : PBeditor.pb
; Version : v1.07
; Erstellt : 05.09.2006
; Geändert : 18.11.2006
; *****************************************************************************
;{ API SendMessage_(...)
;
; Ergebnis = SendMessage_(hwnd, uMsg, wParam, lParam)
;
; hwnd : Integer - Handle des Empfängers
; uMsg : Integer - Nummer der Meldung
; wParam : 16-Bit-Version: Integer - 16-Bit meldungsabhängige Informationen
; 32-Bit-Version: LongInt - 32-Bit meldungsabhängige Informationen
; lParam : Long oder Pointer - 32-Bit meldungsabhängige Informationen
;
; Ergebnis : Rückgabewert der Meldung
;
; Es wird eine Meldung an das Fenster bzw. Fensterobjekt mit dem Handle hwnd gesandt
; und gegebenenfalls eine Antwort zurückgemeldet.
;
; Verwendete Meldungen für das StringGadget
;
; WM_UNDO : Letzte Änderung rückgangig machen
; WM_CUT : Markierung ausschneiden und in der Zwischenablage ablegen
; WM_COPY : Markierung in der Zwischenablage ablegen
; WM_PASTE : Aus der Zwischenablage an der Cursorpostion einfügen
; EM_SETSEL : Textbereich markieren
; wParam - Startpostion
; lParam - Endpostion
; Bei wParm = 0 und lParm = -1 wird der gesamte Text markiert
; EM_SETMARGINS : Randeinstellungen für das Textbereich einstellen
; wParam - EC_LEFTMARGIN - Linken Rand in Pixel
; wParam - EC_RIGHTMARGIN - Rechtem Rand in Pixel
; lParam - MAKELONG(wLeft,wRight)
;}
; *****************************************************************************
;{ API Verwendete Konstanten für das StringGadget (WindowObjekt EditBox)
; Style = #ES_MULTILINE | #WS_VSCROLL | #WS_HSCROLL ; mit Oder verknüpft
; ES_MULTILINE : Mehrzeilig
; WM_VSCROLL : Vertikalen Scrollbalken hinzufügen
; WM_HSCROLL : Horizentalen Scrollbalken hinzufügen
;}
; *****************************************************************************
;- Konstanten
#ABOUT = "Einfacher TextEditor Version 1.0" +#LF$+#LF$ + "Author: mk-soft" + #LF$ + "Compiler: Purebasic v4.0"
;-- ID für Fenster
Enumeration
#Window
EndEnumeration
;-- ID für Menu
Enumeration
#Menu
EndEnumeration
;-- ID für Toolbar
Enumeration
#ToolBar
EndEnumeration
;-- ID´s für MenuItems
Enumeration
;--- Menu Datei
#Menu_Neu
#Menu_Oeffnen
#Menu_Speichern
#Menu_Speichern_als
#Menu_Beenden
#Menu_Zurueck
;--- Menu Bearbeiten
#Menu_Ausschneiden
#Menu_Kopieren
#Menu_Einfuegen
#Menu_Markieren
;--- Menu Hilfe
#Menu_Ueber
EndEnumeration
;-- ID für StatusBar
Enumeration
#StatusBar
EndEnumeration
;-- ID für Edit (Textfeld)
Enumeration
#Edit
EndEnumeration
; *****************************************************************************
; *****************************************************************************
;- Globale Variablen
Global Exit.l ; Programm ende
Global Titel.s ; Fenstertitel
Global Datei.s ; Aktuelle Datei
Global Speichern.l ; Speichern anfordern
Global Neu.l ; Neue Datei
; *****************************************************************************
;- Unterprogramme
Procedure.l MAKELONG(LowWord.l, HighWord.l)
;{ API Hilfsfunktion MAKELONG
; Mache Funktionen bei Sendmessage benötigen in den Parameter lParam zwei Word Werte.
; Diese müssen dann erst zusammengesetzt werden. Das HighWord 16 Bit nach Links schieben
; und das LowWord mit ODER anfügen. Das Ergebnis ist somit ein Longwert.
;}
result.l = HighWord << 16 | LowWord
ProcedureReturn result
EndProcedure
; *****************************************************************************
Procedure UpdateWindow()
;{ Procedure für Grössenänderung
; Je nach Einstellung des Destop kann die Höhe von den Menu, Toolbar und Statusleise variieren.
; Somit ist die Arbeitshöhe für das StringGadget nicht nur abhängig von der Fensterhöhe,
; sondern auch von der Desktop Einstellung und muss daher berechnet werden.
; Edithöhe = Fensterhöhe - Menuhöhe - Toolbarhöhe - Statusbarhöhe
;}
mn = MenuHeight()
tb = ToolBarHeight(#ToolBar)
sb = StatusBarHeight(#StatusBar)
dx = WindowWidth(#Window)
dy = WindowHeight(#Window) - mn - tb - sb
ResizeGadget(#Edit, 0, tb, dx, dy)
EndProcedure
; *****************************************************************************
Procedure UpdateMenu()
;{ Procedure für Aktuallisierung von Menu´s
; EM_GETSEL gibt den Start- und Endeposision von den selektierten Bereich zurück.
; Ist Ende grösser Start dann könnten die Menu´s Ausschneiden und Kopieren freigegeben werden
;
; WM_GETTEXTLENGHT gibt den länge des Textes zurück.
; Ist die Länge grösser Null dann kann das Menu Alles markieren freigegeben werden.
;
; EM_CANUNDO gibt zurück das Rückgängig möglich ist und somit das Menu Rückgängig
; freigegeben werden kann
;}
; Prüfen auf Markierung
SendMessage_(GadgetID(#Edit), #EM_GETSEL, @lpStart.l, @lpEnde.l)
If lpEnde > lpStart
DisableMenuItem(#Menu, #Menu_Ausschneiden, 0)
DisableMenuItem(#Menu, #Menu_Kopieren, 0)
Else
DisableMenuItem(#Menu, #Menu_Ausschneiden, 1)
DisableMenuItem(#Menu, #Menu_Kopieren, 1)
EndIf
; Prüfen Zeichen
textlen = SendMessage_(GadgetID(#Edit), #WM_GETTEXTLENGTH, 0, 0)
If textlen > 0
DisableMenuItem(#Menu, #Menu_Markieren, 0)
Else
DisableMenuItem(#Menu, #Menu_Markieren, 1)
EndIf
; Prüfen auf Rückgängig möglich
If SendMessage_(GadgetID(#Edit), #EM_CANUNDO, 0, 0)
DisableMenuItem(#Menu, #Menu_Zurueck, 0)
Else
DisableMenuItem(#Menu, #Menu_Zurueck, 1)
EndIf
EndProcedure
; *****************************************************************************
Procedure Datei_Speichern_als()
;{ Procedure für Datei speichern als
;
;}
Protected temp.s
; Dateiname erfragen
temp = SaveFileRequester("Datei Speichern als", Datei, "Text (*.txt)|*.txt|Alle Dateien|*.*", 0)
If temp = ""
ProcedureReturn 0
EndIf
; Extension automatisch anfügen
If GetExtensionPart(temp) = ""
If SelectedFilePattern() = 0
temp + ".txt"
EndIf
EndIf
; Datei prüfen
If FileSize(temp) >= 0
r1 = MessageRequester("Frage", "Datei " + Datei + " überschreiben?", #PB_MessageRequester_YesNo | #MB_ICONQUESTION)
If r1 = #PB_MessageRequester_No
ProcedureReturn 0
EndIf
EndIf
; Datei speichern
Datei = temp
If CreateFile(0, Datei)
temp = GetGadgetText(#Edit)
WriteString(0, temp)
CloseFile(0)
; Variablen aktuallisieren
Speichern = 0
Neu = 0
; Titel und Status aktuallisieren
Titel = "PB Editor - " + Datei
SetWindowTitle(#Window, Titel)
StatusBarText(#StatusBar, 0, "Gespeichert")
Else
MessageRequester("Fehler", "Datei konnte nicht gespeichert werden", #MB_ICONSTOP)
EndIf
EndProcedure
; *****************************************************************************
Procedure Datei_Speichern()
;{ Procedure für Speichern
;
;}
Protected temp.s
; Bei neuer Datei Speichern als aufrufen
If Neu
Datei_Speichern_als()
ProcedureReturn 0
EndIf
; Datei speichern
If CreateFile(0, Datei)
temp = GetGadgetText(#Edit)
WriteString(0, temp)
CloseFile(0)
; Variablen aktuallisieren
Speichern = 0
Neu = 0
; Titel und Status aktuallisieren
Titel = "PB Editor - " + Datei
SetWindowTitle(#Window, Titel)
StatusBarText(#StatusBar, 0, "Gespeichert")
Else
MessageRequester("Fehler", "Datei konnte nicht gespeichert werden", #MB_ICONSTOP)
EndIf
EndProcedure
; *****************************************************************************
Procedure Datei_Oeffnen()
;{ Procedure für Datei öffnen
;
;}
Protected temp.s
; Bei änderung Speichern aufrufen
If Speichern
r1 = MessageRequester("Frage", "Änderung speichern?", #PB_MessageRequester_YesNoCancel | #MB_ICONQUESTION)
If r1 = #PB_MessageRequester_Yes
Datei_Speichern()
EndIf
EndIf
If r1 = #PB_MessageRequester_Cancel
ProcedureReturn 0
EndIf
; Dateiname erfragen
temp = OpenFileRequester("Datei öffnen", "", "Text (*.txt)|*.txt|Alle Dateien (*.*)|*.*", 0)
If temp = ""
ProcedureReturn 0
EndIf
; Datei öffnen
Datei = temp
If OpenFile(0, Datei)
temp = ""
; Datei lesen bis zum ende
len = Lof(0)
temp = Space(len)
ReadData(0, @temp, len)
; Datei schliessen
CloseFile(0)
; Text in Editorfeld eintragen
SetGadgetText(#Edit, temp)
temp = ""
; Variablen aktuallisieren
Speichern = 0
Neu = 0
; Titel und Status aktuallisieren
Titel = "PB Editor - " + Datei
SetWindowTitle(#Window, Titel)
StatusBarText(#StatusBar, 0, "Geöffnet")
UpdateMenu()
Else
MessageRequester("Fehler", "Datei konnte nicht geöffnet werden", #MB_ICONSTOP)
EndIf
EndProcedure
; *****************************************************************************
Procedure Datei_Oeffnen_sofort(temp.s)
;{ Procedure für Datei öffnen bei Parameterübergabe
;
;}
Datei = temp
If OpenFile(0, Datei)
temp = ""
; Datei lesen bis zum ende
len = Lof(0)
temp = Space(len)
ReadData(0, @temp, len)
; Datei schliessen
CloseFile(0)
; Text in Editorfeld eintragen
SetGadgetText(#Edit, temp)
temp = ""
; Variablen aktuallisieren
Speichern = 0
Neu = 0
; Titel und Status aktuallisieren
Titel = "PB Editor - " + Datei
SetWindowTitle(#Window, Titel)
StatusBarText(#StatusBar, 0, "Geöffnet")
UpdateMenu()
Else
MessageRequester("Fehler", "Datei konnte nicht geöffnet werden", #MB_ICONSTOP)
EndIf
EndProcedure
; *****************************************************************************
Procedure Datei_Neu()
;{ Procedure für Neu
;
;}
; Bei änderung Speichern aufrufen
If Speichern
r1 = MessageRequester("Frage", "Änderung speichern?", #PB_MessageRequester_YesNoCancel | #MB_ICONQUESTION)
If r1 = #PB_MessageRequester_Yes
Datei_Speichern()
EndIf
EndIf
If r1 = #PB_MessageRequester_Cancel
ProcedureReturn 0
EndIf
; Editorfeld löschen
SetGadgetText(#Edit, "")
; Variablen aktuallisieren
Speichern = 0
Neu = 1
Datei = "Unbekannt.txt"
; Titel und Status aktuallisieren
Titel = "PB Editor - " + Datei
SetWindowTitle(#Window, Titel)
StatusBarText(#StatusBar, 0, "Neu")
EndProcedure
; *****************************************************************************
Procedure ProgrammEnde()
;{ Procedure bei Programm Ende
;
;}
; Bei änderung Speichern aufrufen
If Speichern
r1 = MessageRequester("Frage", "Änderung speichern?", #PB_MessageRequester_YesNoCancel | #MB_ICONQUESTION)
If r1 = #PB_MessageRequester_Yes
Datei_Speichern()
EndIf
EndIf
If r1 <> #PB_MessageRequester_Cancel
Exit = 1
EndIf
EndProcedure
; *****************************************************************************
Procedure WndProc(hWnd, uMsg, wParam, lParam)
;{ Callback Routine zur Bearbeitung von Meldungen
; Mit SetWindowCallback wird auf diese Procedure verlinkt.
; Hier werden weiter Meldungen von den Betriebssystem abgearbeitet die nicht von
; WindowEvent() oder WaitWindowEvent() weitergeleitet werden.
;
; Die Meldung WM_ENTERIDLE kommt wenn ein Menu oder ein Diaglogfenster angezeit wird.
; Zu diesen Zeitpunkt aktuallisieren wird dann die Menu´s ob sie freigegeben werden können.
;}
; Menu oder Dialog angezeigt
If uMsg = #WM_ENTERIDLE
UpdateMenu()
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;- Hauptprogramm **************************************************************
; Ersten Parameter auslesen (Dateiname bei aufruf bei "Öffnen mit")
para.s = ProgramParameter()
Neu = 1
Datei = "Unbekannt.txt"
Titel = "PB Editor - " + Datei
WinStyle = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_SizeGadget
;-- Fenster erstellen
If OpenWindow(#Window, 0, 0, 720, 480, Titel, WinStyle)
;--- Menu Erzeugen
If CreateMenu(#Menu, WindowID(#Window))
MenuTitle("&Datei")
MenuItem(#Menu_Neu, "&Neu" + #TAB$+ "Strg+N")
MenuItem(#Menu_Oeffnen, "&Öffnen" + #TAB$+ "Strg+O")
MenuItem(#Menu_Speichern, "&Speichern" + #TAB$+ "Strg+S")
MenuItem(#Menu_Speichern_als, "Speichern &als")
MenuBar()
MenuItem(#Menu_Beenden, "Be&enden")
MenuTitle("&Bearbeiten")
MenuItem(#Menu_Zurueck, "&Rückgängig" + #TAB$ + "Strg+Z")
MenuBar()
MenuItem(#Menu_Ausschneiden, "&Ausschneiden" + #TAB$ + "Strg+X")
MenuItem(#Menu_Kopieren, "&Kopieren" + #TAB$ + "Strg+C")
MenuItem(#Menu_Einfuegen, "&Einfügen" + #TAB$ + "Strg+V")
MenuItem(#Menu_Markieren, "Alles &markieren" + #TAB$ + "Strg+A")
MenuTitle("Hilfe")
MenuItem(#Menu_Ueber, "&Über")
;---> Menus sperren
DisableMenuItem(#Menu, #Menu_Zurueck, 1)
DisableMenuItem(#Menu, #Menu_Ausschneiden, 1)
DisableMenuItem(#Menu, #Menu_Kopieren, 1)
DisableMenuItem(#Menu, #Menu_Markieren, 1)
EndIf
;--- Toolbar erzeugen
If CreateToolBar(#ToolBar, WindowID(#Window))
ToolBarStandardButton(#Menu_Neu, #PB_ToolBarIcon_New)
ToolBarStandardButton(#Menu_Oeffnen, #PB_ToolBarIcon_Open)
ToolBarStandardButton(#Menu_Speichern, #PB_ToolBarIcon_Save)
ToolBarSeparator()
ToolBarStandardButton(#Menu_Zurueck, #PB_ToolBarIcon_Undo)
ToolBarSeparator()
ToolBarStandardButton(#Menu_Ausschneiden, #PB_ToolBarIcon_Cut)
ToolBarStandardButton(#Menu_Kopieren, #PB_ToolBarIcon_Copy)
ToolBarStandardButton(#Menu_Einfuegen, #PB_ToolBarIcon_Paste)
ToolBarToolTip(#ToolBar, #Menu_Neu, "Neu")
ToolBarToolTip(#ToolBar, #Menu_Oeffnen, "Öffnen")
ToolBarToolTip(#ToolBar, #Menu_Speichern, "Speichern")
ToolBarToolTip(#ToolBar, #Menu_Zurueck, "Rückgängig")
ToolBarToolTip(#ToolBar, #Menu_Ausschneiden, "Ausschneiden")
ToolBarToolTip(#ToolBar, #Menu_Kopieren, "Kopieren")
ToolBarToolTip(#ToolBar, #Menu_Einfuegen, "Einfügen")
EndIf
;--- Statusbar erzeugen
CreateStatusBar(#Statusbar, WindowID(#Window))
;--- Gadget erzeugen
If CreateGadgetList(WindowID(#Window))
Style = #ES_MULTILINE | #WS_VSCROLL | #WS_HSCROLL
StringGadget(#Edit, 0, 0, 0, 0, "", Style) ; Grösse und Position in der Procedure UpdateWindow()
; LimitText auf unbegrenzt setzen.
SendMessage_(GadgetID(#Edit), #EM_SETLIMITTEXT, -1, 0)
; Linken Rand einstellen
SendMessage_(GadgetID(#Edit),#EM_SETMARGINS,#EC_LEFTMARGIN,MAKELONG(4,0))
; Farben einstellen
SetGadgetColor(#Edit, #PB_Gadget_FrontColor, RGB(30, 40, 140))
SetGadgetColor(#Edit, #PB_Gadget_BackColor, RGB(254, 254, 220))
EndIf
;--- Tastenkürzel hinzufügen für Neu, Öffnen und Speichern
AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_N, #Menu_Neu)
AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_O, #Menu_Oeffnen)
AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_S, #Menu_Speichern)
AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_A, #Menu_Markieren)
;--- Callback Routine zur Bearbeitung von Meldungen weiterleiten
SetWindowCallback(@WndProc())
;--- Focus auf Edit setzen
SetActiveGadget(#Edit)
Exit = 0
If para
Datei_oeffnen_sofort(para)
EndIf
;--> Hauptschleife anfang
Repeat
; Warten auf Ereignis (Maus, Tastertur, etc)
event = WaitWindowEvent()
menu = EventMenu()
gadget = EventGadget()
type = EventType()
Select event
;--? Ein Menü wurde ausgewählt
Case #PB_Event_Menu
Select menu
Case #Menu_Beenden
ProgrammEnde()
Case #Menu_Neu
Datei_Neu()
SetActiveGadget(#Edit)
Case #Menu_Oeffnen
Datei_Oeffnen()
SetActiveGadget(#Edit)
Case #Menu_Speichern
Datei_Speichern()
SetActiveGadget(#Edit)
Case #Menu_Speichern_als
Datei_Speichern_als()
SetActiveGadget(#Edit)
Case #Menu_Zurueck
SendMessage_(GadgetID(#Edit), #WM_UNDO, 0, 0) ; API SendMessage_(hwnd, uMsg, wParam, lParam)
Case #Menu_Ausschneiden
SendMessage_(GadgetID(#Edit), #WM_CUT, 0, 0)
Speichern = 1
StatusBarText(#StatusBar, 0, "Geändert")
Case #Menu_Kopieren
SendMessage_(GadgetID(#Edit), #WM_COPY, 0, 0)
Case #Menu_Einfuegen
SendMessage_(GadgetID(#Edit), #WM_PASTE, 0, 0)
Speichern = 1
StatusBarText(#StatusBar, 0, "Geändert")
Case #Menu_Markieren
SendMessage_(GadgetID(#Edit), #EM_SETSEL, 0, -1)
Case #Menu_Ueber
MessageRequester("Info", #ABOUT)
EndSelect
;--? Ein Gadget wurde gedrückt
Case #PB_Event_Gadget
Select gadget
Case #Edit
Select type
Case #PB_EventType_Change
UpdateMenu()
If Speichern = 0
Speichern = 1
StatusBarText(#StatusBar, 0, "Geändert")
EndIf
EndSelect
EndSelect
;--? Das Schließgadget vom Fenster wurde gedrückt
Case #PB_Event_CloseWindow
ProgrammEnde()
;--? Das Fenster wurde in der Größe verändert
Case #PB_Event_SizeWindow
UpdateWindow()
EndSelect
Until Exit
;--< Hauptschleife ende
EndIf
;- Ende
End
FF
