Appcrash bei Kompilierung mit neuerem Purebasic
Appcrash bei Kompilierung mit neuerem Purebasic
Hallo, ich habe vor längerer Zeit ein kleines Programm zum schnellen Verlassen von Windows programmiert. Jetzt wollte ich es für einen älteren Rechner, auf dem Windows 7 32 bit läuft, geringfügig anpassen. Nach dem Kompilieren mit der aktuellen Purebasic-Version stürzte das Programm mit einem C0000005-Fehlercode ab. Nach langer vergeblicher Suche nach einem Fehler im Programm kam ich auf die Idee, ein Purebasic aus der Zeit der letztmaligen Kompilierung des Programms zu verwenden (habe ich verwahrt), weil die unangepasste Version problemlos funktionierte, und siehe da, es lief. Konkret: mit der Version 4.61 kompiliert läuft es, mit 5er-Versionen (5.11, 5,43 und 5.50) nicht. Hat jemand eine Erklärung dafür? Ich muss noch dazusagen, dass ich eher selten programmiere und die Purebasic-Entwicklung nicht intensiv verfolge.
Danke für jede Antwort.
Gerhard
Danke für jede Antwort.
Gerhard
Re: Appcrash bei Kompilierung mit neuerem Purebasic
Kannst du deinen Code hier posten? Sonst können wir das Problem nicht nachstellen und nachvollziehen.
Falls dein Code zu groß ist, dann versuche einen kleinen Beispielcode, mit dem du das Problem nachstellen kannst, zu schreiben.
Falls dein Code zu groß ist, dann versuche einen kleinen Beispielcode, mit dem du das Problem nachstellen kannst, zu schreiben.
Re: Appcrash bei Kompilierung mit neuerem Purebasic
Hallo, das ist der Code der Originalversion, die ebenfalls nach Kompilierung mit einer 5er Version auf dem Win7-32bit-PC abstürzt. Ich hoffe, dass der Code nicht zu lang und zu blöd ist.
Gruß
Gerhard
Gruß
Gerhard
Code: Alles auswählen
; WinExit
; schneller Ausstieg aus Windows
;- Version Constants
#FF_Name=" WinExit"
#FF_Version="4.1"
#FF_Date="01/13"
#FF_Delay=1000
;- Window Constants
;
Enumeration
#Window_0
#Window_1
EndEnumeration
;- Gadget Constants
Enumeration
; vom Hauptdialog
#Button_Ueber
#Image_0
#Text_0
#Button_Abmelden
#Button_Ausschalten
#Button_Ruhezustand
#Button_Energiesparmodus
#Button_Neustart
#Button_Abbruch
#CheckBox_Erzwingen
#CheckBox_temp
#CheckBox_save
EndEnumeration
Enumeration
; vom Unterdialog
#Text_1
EndEnumeration
;- Menu Constants
Enumeration
#Shortcut_0
#Shortcut_1
EndEnumeration
;- Fonts
Global FontID1
FontID1 = LoadFont(1, "Arial", 10, #PB_Font_Bold)
Global FontID2
FontID2 = LoadFont(2, "Arial", 10)
;- Image Plugins
;- Image Globals
Global Image0
;- Catch Images
Image0 = CatchImage(0, ?Image0)
;- Images
DataSection
Image0:
IncludeBinary "d:\ff\!purebasic\Winexit\winexit.ico"
EndDataSection
;- sonstige globale Variablen
Global schluss.b, inifile.s, tempdir.s
;- ExitWindowsEx uFlags-Konstanten
#EWX_LOGOFF = 0 ; Meldet sich neu am Netzwerk an
#EWX_SHUTDOWN = 1 ; Fährt den Computer herunter
#EWX_REBOOT = 2 ; Startet den Computer neu
#EWX_FORCE = 4 ; Beendet alle Programme ohne Aufforderung an den Benutzer
#EWX_POWEROFF = 8 ; Fährt den Computer herunter und schaltet ihn ab, wenn möglich
Procedure InfoDial()
Protected neuezeile.s=Chr(13)+Chr(10), zeile1.s, zeile2.s, zeile3.s, l_zeile1.b, l_zeile2.b, l_zeile3.b, max.b
zeile1=#FF_Name + " v" + #FF_Version
zeile2="(C) by FF " + #FF_Date
zeile3="written in PureBasic"
l_zeile1=Len(zeile1)
l_zeile2=Len(zeile2)
l_zeile3=Len(zeile3)
If l_zeile2 >= l_zeile1
max=l_zeile2
Else
max=l_zeile1
EndIf
If l_zeile3 >= max
max=l_zeile3
EndIf
zeile1=Space((max-l_zeile1)/2) + zeile1
zeile2=Space((max-l_zeile2)/2) + zeile2
zeile3=Space((max-l_zeile3)/2) + zeile3
MessageRequester("Info", zeile1 + neuezeile + zeile2 + neuezeile + zeile3)
EndProcedure
Procedure SubDial(openclose.b, action.b = 0)
Protected meldung.s
Select openclose
Case 1 ; open
Select action
Case 1
meldung="BenutzerIn wird abgemeldet..."
Case 2
meldung="Windows wird heruntergefahren..."
Case 3
meldung="Windows geht in den Ruhezustand..."
Case 4
meldung="Windows geht in den Energiesparmodus"
Case 5
meldung="Windows wird neu gestartet..."
Case 6
meldung="Leere das Temp-Verzeichnis..."
EndSelect
If OpenWindow(#Window_1, 386, 273, 276, 37, "WinExit", #PB_Window_TitleBar | #PB_Window_ScreenCentered )
TextGadget(#Text_1, 15, 10, 245, 20, meldung, #PB_Text_Center)
SetGadgetFont(#Text_1, FontID2)
EndIf
Case 2 ; close
CloseWindow(#Window_1)
EndSelect
EndProcedure
; nicht direkt aufrufbare API-Funktion SetSuspendState
; schaltet den Ruhezustand/Energiesparmodus ein
Procedure Suspend(Hibernate, ForceCritical=#False, DisableWakeEvent=#False)
Protected LibraryID
Protected Result = #False
LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
If LibraryID
Result = CallFunction(LibraryID, "SetSuspendState", Hibernate, ForceCritical, DisableWakeEvent)
CloseLibrary(LibraryID)
EndIf
ProcedureReturn Result
EndProcedure
; nicht direkt aufrufbare API-Funktion IsPwrSuspendAllowed
; testet, ob der Energiesparmodus zur Verfügung steht
Procedure SuspendAllowed()
Protected LibraryID
Protected Result = #False
LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
If LibraryID
Result = CallFunction(LibraryID, "IsPwrSuspendAllowed")
CloseLibrary(LibraryID)
EndIf
ProcedureReturn Result
EndProcedure
; nicht direkt aufrufbare API-Funktion IsPwrHibernateAllowed
; testet, ob der Ruhezustand zur Verfügung steht
Procedure HibernateAllowed()
Protected LibraryID
Protected Result = #False
LibraryID = OpenLibrary(#PB_Any, "powrprof.dll")
If LibraryID
Result = CallFunction(LibraryID, "IsPwrHibernateAllowed")
CloseLibrary(LibraryID)
EndIf
ProcedureReturn Result
EndProcedure
Procedure SetShutDownPrivileges()
Protected Privileges.TOKEN_PRIVILEGES
Protected htoken
OpenProcessToken_(GetCurrentProcess_(),40,@htoken)
Privileges\PrivilegeCount=1
Privileges\Privileges[0]\Attributes=#SE_PRIVILEGE_ENABLED
LookupPrivilegeValue_(0,"SeShutdownPrivilege",@Privileges\Privileges[0]\Luid)
AdjustTokenPrivileges_(htoken,0,@Privileges,0,0,0)
CloseHandle_(htoken)
EndProcedure
; Verzeichnis leeren (alle Dateien und Unterverzeichnisse löschen
Procedure.l FlushDir(what_dir.s)
Protected dir.l, name.s, fullpath.s
; Parameter übergeben?
If what_dir <> ""
; Verzeichnisuntersuchung beginnen
dir = ExamineDirectory(#PB_Any, what_dir, "")
; Verzeichnis kann untersucht werden
If dir
; Verzeichniseinträge durchgehen
While NextDirectoryEntry(dir)
; Namen des Eintrages ermitteln
name = DirectoryEntryName(dir)
; Punkteinträge übergehen
If name <> "." And name <> ".."
; kompletten Pfad zusammenbasteln
fullpath = what_dir + name
; es ist ein Verzeichnis
If DirectoryEntryType(dir) = #PB_DirectoryEntry_Directory
; löschen
DeleteDirectory(fullpath, "*.*", #PB_FileSystem_Recursive | #PB_FileSystem_Force)
; es ist eine Datei
Else
; Dateiattribute zurücksetzen und Datei löschen
SetFileAttributes(fullpath, #PB_FileSystem_Normal)
DeleteFile(fullpath)
EndIf
EndIf
Wend
; Verzeichnisuntersuchung beenden
FinishDirectory(dir)
EndIf
EndIf
EndProcedure
Procedure HandleInifile(startstop.b)
Select startstop
; Programmstart
Case 1
; Pfad zur ini-Datei vorhanden
If inifile <> ""
; es gibt schon eine ini-Datei
If FileSize(inifile) >= 0
; ini-Datei öffnen, Verarbeitung starten
OpenPreferences(inifile)
; es gibt die Gruppe 'winexit'
If PreferenceGroup("winexit")
; Stati der Gadgets setzen
SetGadgetState(#CheckBox_Erzwingen, ReadPreferenceInteger("erzw", 0))
SetGadgetState(#CheckBox_temp, ReadPreferenceInteger("tmp", 0))
SetGadgetState(#CheckBox_save, ReadPreferenceInteger("save", 0))
EndIf
; Verarbeitung beenden, ini-Datei schließen
ClosePreferences()
; es gibt noch keine ini-Datei
Else
; ini-Datei neu anlegen, Verarbeitung starten
CreatePreferences(inifile)
; Gruppe anlegen, Werte initialisieren
PreferenceGroup("winexit")
WritePreferenceInteger("erzw", 0)
WritePreferenceInteger("tmp", 0)
WritePreferenceInteger("save", 0)
; Verarbeitung beenden, ini-Datei schließen
ClosePreferences()
EndIf
EndIf
; Programmende
Case 2
; Einstellungen sollen gespeichert werden
If GetGadgetState(#CheckBox_save)
; ini-Datei öffnen, Verarbeitung starten
OpenPreferences(inifile)
; es gibt die Gruppe 'winexit'
If PreferenceGroup("winexit")
; Stati der Gadgets in ini-Datei schreiben
WritePreferenceInteger("erzw", GetGadgetState(#CheckBox_Erzwingen))
WritePreferenceInteger("tmp", GetGadgetState(#CheckBox_temp))
WritePreferenceInteger("save", GetGadgetState(#CheckBox_save))
EndIf
; Verarbeitung beenden, ini-Datei schließen
ClosePreferences()
EndIf
EndSelect
EndProcedure
Procedure MainDial()
If OpenWindow(#Window_0, 528, 279, 220, 318, "Windows verlassen...", #PB_Window_TitleBar | #PB_Window_ScreenCentered )
; Dialog aufbauen
ButtonGadget(#Button_Ueber, 190, 5, 20, 20, "...")
GadgetToolTip(#Button_Ueber, "Info zum Programm")
SetGadgetFont(#Button_Ueber, FontID1)
ImageGadget(#Image_0, 15, 10, 32, 32, Image0)
TextGadget(#Text_0, 55, 20, 125, 15, "...und zwar wie?", #PB_Text_Center)
SetGadgetFont(#Text_0, FontID1)
ButtonGadget(#Button_Abmelden, 10, 50, 200, 30, "Ab- und wieder anmelden")
GadgetToolTip(#Button_Abmelden, "Schnelles Ab- und wieder Anmelden")
SetGadgetFont(#Button_Abmelden, FontID2)
ButtonGadget(#Button_Ausschalten, 10, 85, 200, 30, "Herunterfahren / ausschalten", #PB_Button_Default)
GadgetToolTip(#Button_Ausschalten, "Fährt den PC herunter und schaltet ihn aus, wenn möglich")
SetGadgetFont(#Button_Ausschalten, FontID2)
ButtonGadget(#Button_Ruhezustand, 10, 120, 200, 30, "Ruhezustand")
GadgetToolTip(#Button_Ruhezustand, "Speichert die Sitzung auf der Festplatte und fährt den PC herunter")
SetGadgetFont(#Button_Ruhezustand, FontID2)
If HibernateAllowed() = #False
DisableGadget(#Button_Ruhezustand, 1)
EndIf
ButtonGadget(#Button_Energiesparmodus, 10, 155, 200, 30, "Energiesparmodus")
GadgetToolTip(#Button_Energiesparmodus, "Speichert die Sitzung im Arbeitsspeicher und schaltet Energiesparmodus ein")
SetGadgetFont(#Button_Energiesparmodus, FontID2)
If SuspendAllowed() = #False
DisableGadget(#Button_Energiesparmodus, 1)
EndIf
ButtonGadget(#Button_Neustart, 10, 190, 200, 30, "Neustart")
GadgetToolTip(#Button_Neustart, "Startet den PC neu")
SetGadgetFont(#Button_Neustart, FontID2)
ButtonGadget(#Button_Abbruch, 10, 225, 200, 30, "Abbruch")
SetGadgetFont(#Button_Abbruch, FontID2)
CheckBoxGadget(#CheckBox_Erzwingen, 10, 261, 200, 15, "Vorgang erzwingen (Vorsicht!)")
GadgetToolTip(#CheckBox_Erzwingen, "Bei den Optionen 1, 2 und 5 wird NICHT auf die Reaktion evtl. noch laufender Programme gewartet (Datenverlust möglich)")
SetGadgetFont(#CheckBox_Erzwingen, FontID2)
CheckBoxGadget(#CheckBox_temp, 10, 280, 200, 15, "Temp-Verzeichnis leeren")
GadgetToolTip(#CheckBox_temp, "Beim Herunterfahren/Neustart immer das Temp-Verzeichnis leeren")
SetGadgetFont(#CheckBox_temp, FontID2)
CheckBoxGadget(#CheckBox_save, 10, 299, 200, 15, "Einstellungen speichern")
GadgetToolTip(#CheckBox_save, "WinExit merkt sich die Einstellungen")
SetGadgetFont(#CheckBox_save, FontID2)
; Shortcuts für Default-Button und Abbruch hinzufügen
AddKeyboardShortcut(#Window_0, #PB_Shortcut_Return, #Shortcut_0)
AddKeyboardShortcut(#Window_0, #PB_Shortcut_Escape, #Shortcut_1)
; Flag für Aktionen beim Programmende
schluss = #False
; kompletter Pfad zur ini-Datei im Programmverzeichnis
inifile = GetPathPart(ProgramFilename()) + "winexit.ini"
; Startaktionen für die ini-Datei
HandleInifile(1)
; Temp-Verzeichnis ermitteln
tempdir = GetTemporaryDirectory()
; Ereignisschleife
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Menu
Select EventMenu()
Case #Shortcut_0
If GetGadgetState(#CheckBox_temp)
SubDial(1, 5)
FlushDir(tempdir)
SubDial(2)
EndIf
SetShutDownPrivileges()
SubDial(1, 2)
Delay(#FF_Delay)
SubDial(2)
If GetGadgetState(#CheckBox_Erzwingen)
ExitWindowsEx_(#EWX_POWEROFF | #EWX_FORCE, 0)
Else
ExitWindowsEx_(#EWX_POWEROFF, 0)
EndIf
schluss = #True
Case #Shortcut_1
End
EndSelect
ElseIf EventID = #PB_Event_Gadget
Select EventGadget()
Case #Button_Ueber
InfoDial()
Case #Button_Abmelden
SetShutDownPrivileges()
SubDial(1, 1)
Delay(#FF_Delay)
SubDial(2)
If GetGadgetState(#CheckBox_Erzwingen)
ExitWindowsEx_(#EWX_LOGOFF | #EWX_FORCE, 0)
Else
ExitWindowsEx_(#EWX_LOGOFF, 0)
EndIf
schluss = #True
Case #Button_Ausschalten
If GetGadgetState(#CheckBox_temp)
SubDial(1, 6)
FlushDir(tempdir)
SubDial(2)
EndIf
SetShutDownPrivileges()
SubDial(1, 2)
Delay(#FF_Delay)
SubDial(2)
If GetGadgetState(#CheckBox_Erzwingen)
ExitWindowsEx_(#EWX_POWEROFF | #EWX_FORCE, 0)
Else
ExitWindowsEx_(#EWX_POWEROFF, 0)
EndIf
schluss = #True
Case #Button_Ruhezustand
If GetGadgetState(#CheckBox_temp)
SubDial(1, 6)
FlushDir(tempdir)
SubDial(2)
EndIf
SetShutDownPrivileges()
SubDial(1, 3)
Delay(#FF_Delay)
SubDial(2)
If GetGadgetState(#CheckBox_Erzwingen)
Suspend(#True, #True, #False)
Else
Suspend(#True, #False, #False)
EndIf
schluss = #True
Case #Button_Energiesparmodus
If GetGadgetState(#CheckBox_temp)
SubDial(1, 6)
FlushDir(tempdir)
SubDial(2)
EndIf
SetShutDownPrivileges()
SubDial(1, 4)
Delay(#FF_Delay)
SubDial(2)
If GetGadgetState(#CheckBox_Erzwingen)
Suspend(#False, #True, #False)
Else
Suspend(#False, #False, #False)
EndIf
schluss = #True
Case #Button_Neustart
If GetGadgetState(#CheckBox_temp)
SubDial(1, 6)
FlushDir(tempdir)
SubDial(2)
EndIf
SetShutDownPrivileges()
SubDial(1, 5)
Delay(#FF_Delay)
SubDial(2)
If GetGadgetState(#CheckBox_Erzwingen)
ExitWindowsEx_(#EWX_REBOOT | #EWX_FORCE, 0)
Else
ExitWindowsEx_(#EWX_REBOOT, 0)
EndIf
schluss = #True
Case #Button_Abbruch
End
EndSelect
EndIf
If schluss
HandleInifile(2)
End
EndIf
Until EventID = #PB_Event_CloseWindow
EndIf
EndProcedure
MainDial()
End
; IDE Options = PureBasic 5.43 LTS (Windows - x86)
; CursorPosition = 61
; FirstLine = 57
; Folding = --
; UseIcon = winexit.ico
; Executable = WinExit.exe
; EnablePurifier
; IncludeVersionInfo
; VersionField0 = 4,1,0,0
; VersionField1 = 4,1,0,0
; VersionField2 = ff
; VersionField3 = WinExit
; VersionField4 = v4.1
; VersionField5 = 4.1
; VersionField6 = WinExit - schneller Ausstieg aus Windows
; VersionField7 = WinExit
; VersionField8 = %EXECUTABLE
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Appcrash bei Kompilierung mit neuerem Purebasic
Ich hab das Programm jetzt nicht getestet, aber der Aufruf "SetShutDownPrivileges()" gehört nicht in die Ereignisschleife
und sollte nur einmal (möglichst am Anfang) aufgerufen werden! Die Privilege bleiben für das ganze Programm erhalten!
und sollte nur einmal (möglichst am Anfang) aufgerufen werden! Die Privilege bleiben für das ganze Programm erhalten!
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Re: Appcrash bei Kompilierung mit neuerem Purebasic
Danke für den Hinweis. Ich werde es ausprobieren.
Gruß
Gerhard
Gruß
Gerhard
Re: Appcrash bei Kompilierung mit neuerem Purebasic
Ich habe es ausprobiert, also den Aufruf von SetShutDownPrivileges() vor die Ereignisschleife gesetzt. Ich hatte allerdings meine Zweifel, dass das was bewirken könnte, da die Funktion in der Ereignisschleife in der Regel ja auch nur einmal aufgerufen wird, je nachdem, welche Aktion gewählt wird. Aber nun hat sich überraschend herausgestellt, dass die Funktion selbst offenbar den Absturz auslöst. Als sie noch innerhalb der Ereignisschleife stand, fand der Absturz stets erst nach dem Anklicken einer Aktion statt. Jetzt stürzt das Programm sofort ab und schafft es nicht einmal mehr, den Dialog komplett aufzubauen. Das lässt m.E. nur diesen einen Schluss zu. Vielleicht findet ja jemand heraus, warum das mit 4.61 kompiliert funktioniert, aber mit 5.x nicht. Übrigens habe ich unter Windows 7 64 bit überhaupt nie Probleme gehabt. Danke für Eure Beteiligung.
Gerhard
Gerhard
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Appcrash bei Kompilierung mit neuerem Purebasic
Unter Windows 10 scheint es nicht mehr zu funktionieren, keinerlei Reaktion. Keine Ahnung was da geändert wurde.
So sieht die Funktion von mir aus, ich denke mal "Deine" ist dieselbe
ts-shutdown läßt grüssen
Code: Alles auswählen
Procedure EnableShutDown()
Protected Privileges.TOKEN_PRIVILEGES
Protected hToken.i
OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @hToken)
Privileges\PrivilegeCount = 1
Privileges\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
LookupPrivilegeValue_(0, "SeShutdownPrivilege", @Privileges\Privileges[0]\Luid)
AdjustTokenPrivileges_(hToken, 0, @Privileges, 0, 0, 0)
CloseHandle_(hToken)
EndProcedure
EnableShutDown()
ExitWindowsEx_(#EWX_REBOOT | #EWX_FORCE, 0)
ts-shutdown läßt grüssen
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Re: Appcrash bei Kompilierung mit neuerem Purebasic
PB reserviert für Privileges.TOKEN_PRIVILEGES nur 4 bytes!
Muss man also selber den Speicher erstellen.
Muss man also selber den Speicher erstellen.
Code: Alles auswählen
Procedure SetShutDownPrivileges()
Protected *Privileges.TOKEN_PRIVILEGES = AllocateMemory(8 + (1 * SizeOf(LUID_AND_ATTRIBUTES)))
Protected htoken
OpenProcessToken_(GetCurrentProcess_(),40,@htoken)
*Privileges\PrivilegeCount=1
*Privileges\Privileges[0]\Attributes=#SE_PRIVILEGE_ENABLED
LookupPrivilegeValue_(0,"SeShutdownPrivilege",@*Privileges\Privileges[0]\Luid)
AdjustTokenPrivileges_(htoken,0,*Privileges,0,0,0)
CloseHandle_(htoken)
FreeMemory(*Privileges)
EndProcedure
PureBasic 5.46 LTS (Windows x86/x64) | windows 10 x64 Oktober failure
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Appcrash bei Kompilierung mit neuerem Purebasic
@_JON_
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Re: Appcrash bei Kompilierung mit neuerem Purebasic
@_JON_
Den in der WinAPI Library bereitgestellten Code muss ich demnächst aktualisieren.
Den in der WinAPI Library bereitgestellten Code muss ich demnächst aktualisieren.