Das Verfahren beruht auf der Fähigkeit der neuen PowerShell, direkt im Eingabeprompt zu rechnen. Es wird also mit RunProgram() einfach der Eingabe-String an die PowerShell übergeben. Die PowerShell ist in Windows 7 eingebaut (sogar in Verson 1 und 2). Ab XP kann sie kostenlos nachgerüstet werden (Version 1 ?). Von Administratoren wird die PowerShell aber gerne für den Normal-Nutzer eingeschränkt. Aber auf dem Rechner zuhause sollte es gehen.
Das Programm beeped zweimal. Das erste mal, wenn die PowerShell aufgerufen wird, und das zweite mal, wenn es von der PowerShell wieder zurückkommt. Bei mir dauert es etwa 1 Sekunde, bis das Ergebnis da ist.
Zunächst das Include-File 'CalculatorFeld.pbi':
Code: Alles auswählen
;***********************************************************************************************************************
;* Dieses Modul enthält den eigentlichen Kalkulations-Aufruf. *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Entwickelt für PureBasic 4.5 von: Jürgen Priess (09.2010) *
;***********************************************************************************************************************
EnableExplicit
Procedure.s DoCalculation(Ausdruck.s="")
;***********************************************************************************************************************
;* Der Rechen-Ausdruck wird berechnet, indem er der Windows PowerShell übergeben wird. Diese ist ab Windows 7 bereits *
;* im Betriebssystem integriert. Nutzer von XP und Vista können die PowerShell (Version 1 ?) kostenlos nachrüsten. In *
;* Windows 7 sind beide Versionen vorhanden - hier wird aber nur die Version 1 genutzt. *
;* ------------------------------------------------------------------------------------------------------------------- *
;* Den String, der die Program-Variable initialisiert, wurde so aus dem Eigenschaftsfenster der PowerShell übernommen. *
;* Gegebenenfalls muß 'powershell.exe' gesucht werden und der vollständige Pfad angepaßt werden. *
;***********************************************************************************************************************
Protected ProgramId.l = 0
Protected Program.s = "%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe" ;gegebenenfalls anpassen
Protected SystemRoot.s = GetEnvironmentVariable("SystemRoot")
Protected Result.s = ""
Protected Flags.l = #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide
Protected I.l = 0
Protected Zeichen.s = ""
Ausdruck = Trim(Ausdruck) ;führende und nachfolgende Leerzeichen entfernen
;Ausdruck auf ungültige Zeichen hin untersuchen (es soll nicht 'dir *.*' eingegeben werden können)
For I = 1 To Len(Ausdruck)
Zeichen = Mid(Ausdruck,I,1)
If 0 = FindString(" ()*+-./0123456789Ee",Zeichen,1)
MessageRequester("Problem!","Zeichen '" + Zeichen + "' ist nicht erlaubt!")
ProcedureReturn Result
EndIf
Next I
If 0 < Len(Ausdruck) ;nur wenn noch was drinsteht wird gerechnet
Beep_(880,200)
Program = ReplaceString(Program,"%SystemRoot%",SystemRoot,#PB_String_NoCase) ;ersetzen des SystemRoot-Verzeichnisses
ProgramId = RunProgram(Program,Ausdruck,"",Flags) ;Aufruf der PowerShell
If ProgramId
While ProgramRunning(ProgramId)
If AvailableProgramOutput(ProgramId)
Result + ReadProgramString(ProgramId)
EndIf
Wend
If 0 < ProgramExitCode(ProgramId)
MessageRequester("Problem!",Result)
Result = ""
EndIf
CloseProgram(ProgramId)
Result = ReplaceString(Result,",",".") ;Dezimalzahlen werden mit kommer ausgegeben, aber nur mit Punkt akzeptiert
Else
MessageRequester("Problem!","Die PowerShell wurde nicht gefunden.")
EndIf
Beep_(1760,200)
EndIf
ProcedureReturn Result
EndProcedure
Code: Alles auswählen
;***********************************************************************************************************************
;* Dieses Modul enthält den im wesentlichen die vom PureBasic-Designer erzeugten Gadget-Definitionen. *
;* ------------------------------------------------------------------------------------------------------------------- *
;* PureBasic Visual Designer v3.95 build 1485 (PB4Code) *
;***********************************************************************************************************************
;- Window Constants
Enumeration
#CalculatorFeld
EndEnumeration
;- Gadget Constants
Enumeration
#Ausdruck
#Rechne
EndEnumeration
Procedure Open_CalculatorFeld()
If OpenWindow(#CalculatorFeld, 20, 20, 600, 20, "CalculatorFeld", #PB_Window_SystemMenu | #PB_Window_TitleBar )
StringGadget(#Ausdruck, 0, 0, 530, 20, "")
ButtonGadget(#Rechne, 530, 0, 70, 20, "&Rechne")
EndIf
EndProcedure
Code: Alles auswählen
;***********************************************************************************************************************
;* Dieses Modul enthält im wesentlichen die vom PureBasic-Designer erzeugte Event-Schleife. *
;* ------------------------------------------------------------------------------------------------------------------- *
;* PureBasic Visual Designer v3.95 build 1485 (PB4Code) *
;***********************************************************************************************************************
EnableExplicit
IncludeFile "Designer.pb"
IncludeFile "CalculatorFeld.pbi"
Global Event.l = 0
Global WindowID.l = 0
Global GadgetID.l = 0
Global EventType.l = 0
Open_CalculatorFeld()
AddKeyboardShortcut(#CalculatorFeld,#PB_Shortcut_Return,#VK_RETURN)
AddKeyboardShortcut(#CalculatorFeld,#PB_Shortcut_Escape,#VK_ESCAPE)
SetActiveGadget(#Ausdruck)
Repeat ; Start of the event loop
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadget() ; Is it a gadget event?
EventType = EventType() ; The event type
;You can place code here, and use the result as parameters for the procedures
If Event = #PB_Event_Gadget
If GadgetID = #Rechne
SetGadgetText(#Ausdruck,DoCalculation(GetGadgetText(#Ausdruck)))
SetActiveGadget(#Ausdruck)
EndIf
EndIf
Select EventMenu()
Case #VK_RETURN
SetGadgetText(#Ausdruck,DoCalculation(GetGadgetText(#Ausdruck)))
SetActiveGadget(#Ausdruck)
Case #VK_ESCAPE
Break
EndSelect
Until Event = #PB_Event_CloseWindow ; End of the event loop
RemoveKeyboardShortcut(#CalculatorFeld,#PB_Shortcut_All)
End
PS: Sollte jemand in das Calculator-Feld "1 + 2 * 3" eingeben, so wird als Ergebnis 7 ausgewiesen, weil hier mathematisch korrekt Punktrechnung vor Strichrechnung berücksichtigt wird. Den Windows-Taschenrechner kann man seit je her in einer kaufmännischen (Standard) und einer technisch-wissenschaftlichen Darstellung anzeigen. Der kaufmännische Taschenrechner bekommt immer schon bei obiger Eingabe 9 heraus, weil er erst "1 + 2" berechnet und dann das Ergebnis mit 3 multipliziert. Der technisch-wissenschaftliche Taschenrechner liefert das Ergebnis 7 (verrückt was?). Das gilt auch für real existierende Taschenrechner. Die billigen liefern bei der Rechnung meist 9, die teuren 7. Da kann man sich furchtbar vertun ...
PS: Das Calculator-Eingabefeld bekommt sogar bei Rechnungen wie "(1/3)*3" wieder 1 heraus. Eine Situation, wo einige Taschenrechner nur "0.99999999999" herausbekommen, weil die Genauigkeit der Zahlendarstellung intern begrenzt ist (bei allen Rechnern). 'Bessere' Rechner können aber damit umgehen.