Clipper 97 goes Xbase++ goes MDI ?
Moderator: Moderatoren
Clipper 97 goes Xbase++ goes MDI ?
Hallo an alle, ich grüße Euch
Habe früher Programme in clipper 97 geschrieben ( Privat ) -- habe danach Xbase++ verwendet um die Programme auf Windows XP zu portieren -- mit minimalen Änderungen, d.h. so wenig zu ändern wie möglich - keine GUI - hauptsache es läuft
Jetzt habe ich ein Problem:
Adressverwaltung und Terminplanung soll in 2 Fenstern gleichzeitig ablaufen !
Habe Xbase 1.82 + Tools und express++ zur Verfügung !
Anwedung läuft bereits unter xbase++ aber in reinem clipper code compiliert mit minimaler Anpassung !!!
Möchte jetzt praktisch wissen - wir groß der Aufwand ist damit gleichzeitig die Adressen und die Terminplanung in 2 Windows Fenstern aufrufbar und gleichzeitig verwendbar ist - hoffe ich habe mich verständlich ausgedrückt.
Wie fange ich überhaupt an ?
Was muß ich ändern ? --> wenn es geht so wenig wie möglich
mfg klaus
Habe früher Programme in clipper 97 geschrieben ( Privat ) -- habe danach Xbase++ verwendet um die Programme auf Windows XP zu portieren -- mit minimalen Änderungen, d.h. so wenig zu ändern wie möglich - keine GUI - hauptsache es läuft
Jetzt habe ich ein Problem:
Adressverwaltung und Terminplanung soll in 2 Fenstern gleichzeitig ablaufen !
Habe Xbase 1.82 + Tools und express++ zur Verfügung !
Anwedung läuft bereits unter xbase++ aber in reinem clipper code compiliert mit minimaler Anpassung !!!
Möchte jetzt praktisch wissen - wir groß der Aufwand ist damit gleichzeitig die Adressen und die Terminplanung in 2 Windows Fenstern aufrufbar und gleichzeitig verwendbar ist - hoffe ich habe mich verständlich ausgedrückt.
Wie fange ich überhaupt an ?
Was muß ich ändern ? --> wenn es geht so wenig wie möglich
mfg klaus
- Wolfgang Ciriack
- Der Entwickler von "Deep Thought"
- Beiträge: 2950
- Registriert: Sa, 24. Sep 2005 9:37
- Wohnort: Berlin
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 34 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hallo Klaus,
wenn dein Programm netzwerkfähig ist, warum dann nicht einfach das Programm 2x starten ?
wenn dein Programm netzwerkfähig ist, warum dann nicht einfach das Programm 2x starten ?
Viele Grüße
Wolfgang
Wolfgang
Re: Clipper 97 goes Xbase++ goes MDI ?
Das habe ich mir auch schon gedacht -
es ist aber nicht netzwerkfähig ! wobei das wohl für meine Bedürfnisse die beste Lösung wäre
.... im moment steht im SOURCE ja " set exclusive on " sonst würde xbase ja bei jedem ändern bzw anfügen mit
einer Fehlermeldung aussteigen ...
gibt es eine möglichst einfache Möglichkeit das ganze netzwerktauchlich zu machen ...
habe da auch mal was von der DATA-Komponente DBFDBE gelesen und dem Modus DBF_Autolock
wie müßte ich meinen Clipper Source verändern um diese Funktion zu nutzen ?
Source für Datenbankaufruf ... etc.
mfg klaus
es ist aber nicht netzwerkfähig ! wobei das wohl für meine Bedürfnisse die beste Lösung wäre
.... im moment steht im SOURCE ja " set exclusive on " sonst würde xbase ja bei jedem ändern bzw anfügen mit
einer Fehlermeldung aussteigen ...
gibt es eine möglichst einfache Möglichkeit das ganze netzwerktauchlich zu machen ...
habe da auch mal was von der DATA-Komponente DBFDBE gelesen und dem Modus DBF_Autolock
wie müßte ich meinen Clipper Source verändern um diese Funktion zu nutzen ?
Source für Datenbankaufruf ... etc.
mfg klaus
- Manfred
- Foren-Administrator
- Beiträge: 21248
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 211 Mal
- Danksagung erhalten: 71 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
Hi Klaus,
es stellt sich jetzt die alte Gretchenfrage: "Was hast Du noch alles vor unter oder mit Xbase++ zu machen?" Soll es bei diesem Projekt bleiben, oder willst Du mehr machen?
Hier wurde schon ausgiebig im Forum über das Thema diskutiert. Wenn Du vor hast mehr zu machen, dann freunde Dich mit dem Gedanken an, alles neu und unter GUI zu machen und dann gleichzeitig auch netzwerktauglich. Mehrmals öffnen ist auch Netzwerk. Alles andere ist nur vergebene Liebesmühe außer Du willst viel lernen. (Glaube es mir, ich habe auch viel Erfahrung auf dem Gebiet gesammelt in den letzten Jahren. )
Wenn es allerdings bei diesem Projekt bleiben soll, dann wirst Du wohl stricken müssen, bis es ungefähr so paßt. Also mit Neterr() usw.
Wie sieht es mit OOP aus? Vielleicht baust Du Dir Klassen, die dann für weitere Projekte alle Arbeiten einfach übernehmen?
Möglichkeiten gibt es einige, Du mußt Dir aussuchen, was für Dich am besten geeignet ist.
es stellt sich jetzt die alte Gretchenfrage: "Was hast Du noch alles vor unter oder mit Xbase++ zu machen?" Soll es bei diesem Projekt bleiben, oder willst Du mehr machen?
Hier wurde schon ausgiebig im Forum über das Thema diskutiert. Wenn Du vor hast mehr zu machen, dann freunde Dich mit dem Gedanken an, alles neu und unter GUI zu machen und dann gleichzeitig auch netzwerktauglich. Mehrmals öffnen ist auch Netzwerk. Alles andere ist nur vergebene Liebesmühe außer Du willst viel lernen. (Glaube es mir, ich habe auch viel Erfahrung auf dem Gebiet gesammelt in den letzten Jahren. )
Wenn es allerdings bei diesem Projekt bleiben soll, dann wirst Du wohl stricken müssen, bis es ungefähr so paßt. Also mit Neterr() usw.
Wie sieht es mit OOP aus? Vielleicht baust Du Dir Klassen, die dann für weitere Projekte alle Arbeiten einfach übernehmen?
Möglichkeiten gibt es einige, Du mußt Dir aussuchen, was für Dich am besten geeignet ist.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
du meinst sicherlich Summer 87KlausXXL hat geschrieben:Habe früher Programme in clipper 97
Die 3PP Libs haben damit nichts zu tunKlausXXL hat geschrieben:Adressverwaltung und Terminplanung soll in 2 Fenstern gleichzeitig ablaufen !
Habe Xbase 1.82 + Tools und express++ zur Verfügung !
und da gibt es mit S87 eine Menge Probleme z.b. mit Variabeln die ja alle Private/Public sind.KlausXXL hat geschrieben:Möchte jetzt praktisch wissen - wir groß der Aufwand ist damit gleichzeitig die Adressen und die Terminplanung in 2 Windows Fenstern aufrufbar und gleichzeitig verwendbar ist - hoffe ich habe mich verständlich ausgedrückt.
Wie fange ich überhaupt an ?
Was muß ich ändern ? --> wenn es geht so wenig wie möglich
Wolfgang schlug ja schon vor das Programm 2x zu starten.
Ich würde sogar noch weiter gehen und sagen "zerlege" es in 2 separate Programme,
wobei später "gemeinsame" Teile in eine Lib/DLL kommen.
Alle Tools die ich damals ausprobiert habe sind nur "Hilfsmittel" um die Stellen zu finden wo eine Modifikation notwendig ist.KlausXXL hat geschrieben:.... im moment steht im SOURCE ja " set exclusive on " sonst würde xbase ja bei jedem ändern bzw anfügen mit einer Fehlermeldung aussteigen ...
gibt es eine möglichst einfache Möglichkeit das ganze netzwerktauchlich zu machen ...
Das selbe Ergebniss bekommst du auch mit Try & Error wenn du " set exclusive OFF " nimmst und einfach die Fehlermeldung liest.
Dabei solltest du dann VX20 IDE benutzen dann hast du Editor/Compile/Debug alles zusammen
Frage : solle es noch mit Cl*pper arbeiten ?KlausXXL hat geschrieben: habe da auch mal was von der DATA-Komponente DBFDBE gelesen und dem Modus DBF_Autolock
wie müßte ich meinen Clipper Source verändern um diese Funktion zu nutzen ?
Der DBFDBE (DATA-Komponente) DBF_AUTOLOCK Modus ist nicht Cl*pper compatible und erfordert die Modifizierung der DBF.
Auf das Problem "lost Update" wird ja hingewiesen, also zusätzliche Arbeiten evtl. notwendig.
aber zurück zu deiner Frage "wie mache ich es Netzwerkfähig" :
1.) " set exclusive OFF "
2.) suche die Stellen wo du eine DBF "öffnest".
Code: Alles auswählen
statt
USE KUNDEN
wird jetzt
IF NET_USE("KUNDEN")
ELSE
ENDIF
Ich öffne in NET_USE dann auch die "passenden" INDEX Datei dazu
3.) suche die Stellen mit REPLACE
Code: Alles auswählen
statt
REPLACE a->KDNR WITH cKDNR
wird jetzt
IF NET_RLOCK()
REPLACE KUNDEN->KDNR WITH cKDNR
UNLOCK // wieder freigeben !
ENDIF
Code: Alles auswählen
statt
APPEND BLANK
wird jetzt
APPEND BLANK
IF NETERR()
// Fehler aufgetreten
ENDIF
gruss by OHR
Jimmy
Jimmy
Re: Clipper 97 goes Xbase++ goes MDI ?
OK erstmal DANKE an alle für die schnelle Hilfe ...
werde die einfache Lösung von Auge_Ohr verwenden ...
So habe bis jetzt folgendes gemacht:
habe die Adressverwaltung herausgelößt und als eigenes EXE File compiliert ... Umstellung für Netzbetrieb ist auch fertig
starte diese aus meinem Terminplanerprogramm mit RunShell("","adresse.exe",.T.)
funktioniert soweit
Frage: gibt es eine Möglichkeit wenn ich den Terminplaner beende --> automatisch vorher das geöffnete Adressprogramm automatisch vorher mit zu beenden.
Im Moment bin ich an der Anpassung des Terminplaners --> ist leider ne menge such und tipparbeit
mfg Klaus
werde die einfache Lösung von Auge_Ohr verwenden ...
So habe bis jetzt folgendes gemacht:
habe die Adressverwaltung herausgelößt und als eigenes EXE File compiliert ... Umstellung für Netzbetrieb ist auch fertig
starte diese aus meinem Terminplanerprogramm mit RunShell("","adresse.exe",.T.)
funktioniert soweit
Frage: gibt es eine Möglichkeit wenn ich den Terminplaner beende --> automatisch vorher das geöffnete Adressprogramm automatisch vorher mit zu beenden.
Im Moment bin ich an der Anpassung des Terminplaners --> ist leider ne menge such und tipparbeit
mfg Klaus
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
JaKlausXXL hat geschrieben:Frage: gibt es eine Möglichkeit wenn ich den Terminplaner beende --> automatisch vorher das geöffnete Adressprogramm automatisch vorher mit zu beenden.
Code: Alles auswählen
Text in der Titelzeile der "Fenster"
CloseIt( { "Nachricht lesen", ;
"Nachricht schreiben", ;
"Nachrichten Eingang", ;
"Nachrichten gesendet" } )
**********************************************
#include "DLL.CH"
#define WM_CLOSE 0x0010
#define WM_QUIT 0x0012
DLLFUNCTION SendMessageA( nHwnd, nCmd, wParam, lParam) USING STDCALL FROM USER32.DLL
FUNCTION CloseIt( aNaam )
LOCAL i, nMax := LEN( aNaam )
FOR i = 1 TO nMax
CloseNow( aNaam[ i ] )
NEXT
RETURN NIL
FUNCTION CloseNow( cNaam )
LOCAL oDlg
LOCAL aTasklist
LOCAL aSize := { 0, 0 }
LOCAL aPos := { 0, 0 }
LOCAL lRunnin := .F.
LOCAL i
LOCAL nHwnd, cWind
oDlg := XbpDialog() :new( AppDesktop(),, aPos, aSize,, .F. )
oDlg:clipSiblings := .T.
oDlg:drawingArea:ClipChildren := .T.
oDlg:create()
SETAPPFOCUS( oDlg )
aTasklist := GetTaskList( oDlg:gethWnd( ) )
FOR i = 1 TO LEN( aTasklist )
cWind := TRIM( UPPER( SUBSTR( aTasklist[ i ], 9 ) ) )
cWind := SUBSTR( cWind, 1, LEN( cWind ) - 1 )
IF cWind == TRIM( UPPER( cNaam ) )
lRunnin := .T.
nHwnd := VAL( LEFT( aTasklist[ i ], 8 ) )
SendMessageA( nHwnd, WM_CLOSE, 0, 0 )
RETURN lRunnin
ENDIF
NEXT
RETURN lRunnin
FUNCTION gettasklist( hWnd )
LOCAL aList := {}
LOCAL cWindowName
LOCAL nVisible
DO WHILE hWnd != 0
cWindowname := SPACE( 100 )
IF ( getwindowtexta( hWnd, @cWindowName, LEN( cWindowName ) ) <> 0 )
nVisible := IsWindowVisible( hWnd )
IF nVisible == 1
AADD( aList, STR( hWnd, 8 ) + cWindowname )
ENDIF
ENDIF
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
ENDDO
RETURN aList
FUNCTION GetWindow( hWnd, uCmd )
LOCAL nDll := DllLoad( "USER32.DLL" )
LOCAL xRet := DllCall( nDll, DLL_STDCALL, "GetWindow", hWnd, uCmd )
DllUnLoad( nDll )
RETURN xRet
FUNCTION GetWindowTextA( hWnd, lPstring, nMax )
LOCAL nDll := DllLoad( "USER32.DLL" )
LOCAL xRet := DllCall( nDll, DLL_STDCALL, "GetWindowTextA", hWnd, @lPstring, nMax )
DllUnLoad( nDll )
RETURN xRet
FUNCTION IsWindowVisible( hWnd )
LOCAL nDll := DllLoad( "USER32.DLL" )
LOCAL xRet := DllCall( nDll, DLL_STDCALL, "IsWindowVisible", hWnd )
DllUnLoad( nDll )
RETURN xRet
gruss by OHR
Jimmy
Jimmy
Re: Clipper 97 goes Xbase++ goes MDI ?
Danke .. werde dies mal versuchen zu verstehen und dann testen
...
hätte da noch was ...
Compilire mein Programm im GUI Mode damit ich setmode (43, 120) verwenden kann
Wie kann ich beim Start die Position des Fensters auf dem Desktop auf dauer festlegen ?
mfg Klaus
...
hätte da noch was ...
Compilire mein Programm im GUI Mode damit ich setmode (43, 120) verwenden kann
Wie kann ich beim Start die Position des Fensters auf dem Desktop auf dauer festlegen ?
mfg Klaus
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1931
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hi Klaus,
ich habe es mir etwas vereinfacht um nicht immer wieder Dialogerstellung zu kopieren, habe ich mir eine Funktion gebaut, diese wird nur aufgerufen.
Hier der aufruf
Es wird übergeben 1. Position des Dialoges, 2. Dimension des Dialoges, 3. Titel, 4. Hinweis zur internen Farbgestaltung
Hier der Dialogerstellung:
Vielleicht hilft es dir weiter.
- Wie Manfred schon geschrieben hat. Den Weg bin ich auch gegangen - Wenn du deinen kompletten Programme auf xbase und mit neuer Maskengestaltung arbeiten möchtest (deine Kunden auch) wirst du um den Weg GUI - NICHT vorbeikommen. Ich habe mich dabei auch von "alten Zöpfen" befreit.
ich habe es mir etwas vereinfacht um nicht immer wieder Dialogerstellung zu kopieren, habe ich mir eine Funktion gebaut, diese wird nur aufgerufen.
Hier der aufruf
Code: Alles auswählen
oDlg:=DialogErzeugen({100,100},{600,400},"Verkaufsprogramm","UP")
Hier der Dialogerstellung:
Code: Alles auswählen
#include "Gra.ch"
#include "Xbp.ch"
#include "Appevent.ch"
#include "Font.ch"
#include "Inkey.ch"
Function DialogErzeugen(aPos,aDim,cTitel,Prg,cString)
Local nEvent, mp1, mp2, lFarbe:=.t., oDlg, drawingArea, aFarbe:={}, cHeimat:=""
aRueck:=FarbAbfrage(Prg)
aFarbe:=aRueck[1]
oDlg := XbpDialog():new( AppDesktop(), , aPos, aDim, , .F.)
oDlg:taskList := .T.
oDlg:title := cTitel
oDlg:maxsize:=aDim
oDlg:Minsize:=aDim
oDlg:create()
CenterControl(oDlg)
// Abfrage für 16-Bit
If File("sprinter.bat") .and. cString <> "e"
use Sysconf New
cHeimat:=alltrim(Sysconf->Heimat)
Close Sysconf
FileDelete("*.cdx")
Index(oDlg,.t.,cHeimat)
EndIf
drawingArea := oDlg:drawingArea
drawingArea:setFontCompoundName( "9.Arial")
If aRueck[2]=.f. .and. !empty(aFarbe)
If aFarbe[1] >0 .or. aFarbe[2] >0 .or. aFarbe[3] >0
drawingArea:setColorBG( GraMakeRGBColor(aFarbe ) )
EndIf
EndIf
oDlg:show()
SetAppFocus(oDlg)
Return oDlg
- Wie Manfred schon geschrieben hat. Den Weg bin ich auch gegangen - Wenn du deinen kompletten Programme auf xbase und mit neuer Maskengestaltung arbeiten möchtest (deine Kunden auch) wirst du um den Weg GUI - NICHT vorbeikommen. Ich habe mich dabei auch von "alten Zöpfen" befreit.
Re: Clipper 97 goes Xbase++ goes MDI ?
Performance Problem ???
Mein Test Notebook: XP + Intel Pentium M 1,5GHz + 512 Arbeitsspeicher
da laufen Fenster: 1xTerminplaner + 3xAdresse ohne 'Probleme
auf Benutzer PC: XP + AMD X2 BE2400 + 3GB Arbeitsspeicher
da laufen Fenster: 1xTerminplaner + 2xAdresse da fängt es schon an - wie soll ich es sagen - zu hackeln ,
d.h. keine flüssige Bedienung der Fenster mehr !?!?!?!?!?!?!
WIE KANN DAS SEIN -- da der Benutzer PC wesentlich mehr Leistung und Arbeitsspeicher hat !!!"
jemand ne IDEE ?
mfg Klaus
Mein Test Notebook: XP + Intel Pentium M 1,5GHz + 512 Arbeitsspeicher
da laufen Fenster: 1xTerminplaner + 3xAdresse ohne 'Probleme
auf Benutzer PC: XP + AMD X2 BE2400 + 3GB Arbeitsspeicher
da laufen Fenster: 1xTerminplaner + 2xAdresse da fängt es schon an - wie soll ich es sagen - zu hackeln ,
d.h. keine flüssige Bedienung der Fenster mehr !?!?!?!?!?!?!
WIE KANN DAS SEIN -- da der Benutzer PC wesentlich mehr Leistung und Arbeitsspeicher hat !!!"
jemand ne IDEE ?
mfg Klaus
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hallo, Klaus.
Mit eXpress++ hast Du eigentlich das Mittel der Wahl zur Verfügung, um aus einer alten Clipper-Anwendung innerhalb kürzester Zeit eine MDI-fähige GUI-App zu machen. Nach der Umstellung der Datenbankzugriffe auf nichtexclusive Nutzung (Lock/Unlock) solltest Du allerdings NICHT, wie hier empfohlen wurde, Deine Module als EXEn getrennt starten, sondern mit Multithreading arbeiten. Das ist in Xbase++ sehr simpel. PUBLIC-Variablen sind in allen Threads sichtbar, aber Workareas sind gekapselt. Deshalb kann man Programmteile relativ problemlos mehrfach aufrufen, ohne dass sie sich "beißen" - vorausgesetzt, das ganze ist netzwerkfähig. Wichtig dafür ist, dass Deine eXpress++-Dialoge (bist Du damit schon durch?) NICHT modal erzeugt werden, jedenfalls diejenigen, die mehrfach aufgerufen werden können.
Wenn Du Dein Hauptmodul/-menü bereits mit eXpress++ erzeugst, müssen die Aufrufcodeblöcke für die mehrfach zu startenden Module einfach dieserart geändert werden (ACTION-Codeblöcke von MENUITEMS oder DCPUSHBUTTONS):
Aus "{||MeinTerminkalender()}" wird:
Damit liefe "MeinTerminKalender" in einem neuen Thread, der mit dem RETURN am Ende dieses Moduls automatisch beendet wird. Wenn "MeinTerminKalender" nicht-modal wäre, könnte der Anwender ins Hauptmenü "rüberklicken" und das Modul beliebig oft abermals aufrufen. Aliase und Workareas können mehrfach verwendet werden, da sie im Thread gekapselt sind. Nur bei exclusiven Datenbankzugriffen muss man aufpassen - das crasht so nämlich. Und alle Variablen, die nicht PUBLIC sind, sind in Threads nicht sichtbar. Hier sind möglicherweise noch Vorarbeiten nötig.
Mit eXpress++ hast Du eigentlich das Mittel der Wahl zur Verfügung, um aus einer alten Clipper-Anwendung innerhalb kürzester Zeit eine MDI-fähige GUI-App zu machen. Nach der Umstellung der Datenbankzugriffe auf nichtexclusive Nutzung (Lock/Unlock) solltest Du allerdings NICHT, wie hier empfohlen wurde, Deine Module als EXEn getrennt starten, sondern mit Multithreading arbeiten. Das ist in Xbase++ sehr simpel. PUBLIC-Variablen sind in allen Threads sichtbar, aber Workareas sind gekapselt. Deshalb kann man Programmteile relativ problemlos mehrfach aufrufen, ohne dass sie sich "beißen" - vorausgesetzt, das ganze ist netzwerkfähig. Wichtig dafür ist, dass Deine eXpress++-Dialoge (bist Du damit schon durch?) NICHT modal erzeugt werden, jedenfalls diejenigen, die mehrfach aufgerufen werden können.
Wenn Du Dein Hauptmodul/-menü bereits mit eXpress++ erzeugst, müssen die Aufrufcodeblöcke für die mehrfach zu startenden Module einfach dieserart geändert werden (ACTION-Codeblöcke von MENUITEMS oder DCPUSHBUTTONS):
Aus "{||MeinTerminkalender()}" wird:
Code: Alles auswählen
{|o|o:=thread():new(),o:start({||MeinTerminKalender()})}
Herzlich,
Tom
Tom
-
- UDF-Programmierer
- Beiträge: 92
- Registriert: Di, 19. Dez 2006 19:37
- Wohnort: Düsseldorf
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hallo Klaus,
ich habe das auch so wie Tom programmiert. {|o|o:=thread():new(),o:start({||.... usw. .
Die Netzwerkroutinen konnte ich mit leichten Modifikationen aus meinen alten
Clipper-Quellen übernehmen.
Ich benutze auch eXpress++ .
Das ist einfach genial. Das ist in keiner anderen Programmiersprache so einfach möglich.
Auf diese Art konnte ich schnell und preisgünstig eine Anwendung auf Windows umstellen.
Ich würde allerdings raten, im Thread möglichst keine Public-Variable anzulegen.
Ich benutze hier gegen alle Empfehlungen neben Local- auch Privat-Variable (ist einfach bequemer),
diese werden nach Beendigung des Prozesses gelöscht.
Funktioniert schon seit Jahren ohne Probleme.
Gruß
Jürgen
ich habe das auch so wie Tom programmiert. {|o|o:=thread():new(),o:start({||.... usw. .
Die Netzwerkroutinen konnte ich mit leichten Modifikationen aus meinen alten
Clipper-Quellen übernehmen.
Ich benutze auch eXpress++ .
Das ist einfach genial. Das ist in keiner anderen Programmiersprache so einfach möglich.
Auf diese Art konnte ich schnell und preisgünstig eine Anwendung auf Windows umstellen.
Ich würde allerdings raten, im Thread möglichst keine Public-Variable anzulegen.
Ich benutze hier gegen alle Empfehlungen neben Local- auch Privat-Variable (ist einfach bequemer),
diese werden nach Beendigung des Prozesses gelöscht.
Funktioniert schon seit Jahren ohne Probleme.
Gruß
Jürgen
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
nun ich wollte bei meiner Antwort nicht gleich mit DLL und Threads anfangen für jemanden der von S87 kommt ...... wobei später "gemeinsame" Teile in eine Lib/DLL kommen.
Was die Variablen angeht : PRIVATE sind doch auch nicht Thread "safe", oder ?
also unbedingt mit /w compilieren und die angemahnten Variabel deklarieren.
hm ... S87 Code ... verwendest du INKEY() ... evtl mit 0 ? nimmm 0.1 !!!Performance Problem ???
auch andere Stellen wo Cl*pper "wartet" müssen für Xbase++ modifiziert werden.
starte doch mal den Taskmanager und dann deine S87 vs. Xbase++ Version.
Wenn die Xbase++ Version > 10% braucht sind bestimmt noch "Cl*pper wait-state" in deinem Source vorhanden.
einfach "beobachten" wo die CPU % "ansteigen" ... nimm VX20.EXE als Debugger und mit F8 STEP um die genaue Stelle zu lokalisieren.
Was macht der Code :... werde dies mal versuchen zu verstehen und dann testen
nun du gibt, als Array, die "Namen" der "Fenster" an welche geschlossen werden sollen.
Die "Namen" sind nun die "Titel" der "Fenster" wie du sie auch im Taskmanager sehen kannst.
Der Code holt mit GetTaskList() die Namen aus dem Taskmanager und vergleicht mit IF cWind == TRIM( UPPER( cNaam ) ) ob du es als Element angegeben hast.
Per SendMessageA( nHwnd, WM_CLOSE, 0, 0 ) wird nun an das "Fenster" der WM_CLOSE Event gesendet.
Wenn du keinen :Close Codeblock hast verwende WM_QUIT
gruss by OHR
Jimmy
Jimmy
- Rolf Ramacher
- Der Entwickler von "Deep Thought"
- Beiträge: 1931
- Registriert: Do, 09. Nov 2006 10:33
- Wohnort: Bergheim
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hi,
ich nutze auch wie Jürgen fast ausschließlich Local Variablen, damit diese auch nur in der Function bekannt sind. Privat nutze ich ganz selten - Public gar nicht mehr, da ja jede .exe im eigenen Thread arbeitet.
ich nutze auch wie Jürgen fast ausschließlich Local Variablen, damit diese auch nur in der Function bekannt sind. Privat nutze ich ganz selten - Public gar nicht mehr, da ja jede .exe im eigenen Thread arbeitet.
Re: Clipper 97 goes Xbase++ goes MDI ?
Vielen DANK erstmal für eure Bemühungen und Erklärungen !
Letzter stand:
Werde jetzt erstmal alles auf 3 exe Files ändern
---> express verwende ich ausschließlich im Moment für Druckausgaben --- ich weiß bei dem funktionsumfang gehöre ich dafür gesteinigt ..
Ich habe im Moment probleme mit folgendem code:
...
cdatumn1:=space(8)
clear gets
@35,4 say "VON :" get cdatumn1 picture "99.99.99"
read
...
flock()
aktuell:=ctod(cdatumn1)
? aktuell
wait("")
replace twoche with left(cdow(aktuell),2) <--- fehler
unlock
Fehler bei: twoche
Fehlermeldung: Base/8027
unkown symbol for database field
mfg Klaus
Letzter stand:
Werde jetzt erstmal alles auf 3 exe Files ändern
---> express verwende ich ausschließlich im Moment für Druckausgaben --- ich weiß bei dem funktionsumfang gehöre ich dafür gesteinigt ..
Ich habe im Moment probleme mit folgendem code:
...
cdatumn1:=space(8)
clear gets
@35,4 say "VON :" get cdatumn1 picture "99.99.99"
read
...
flock()
aktuell:=ctod(cdatumn1)
? aktuell
wait("")
replace twoche with left(cdow(aktuell),2) <--- fehler
unlock
Fehler bei: twoche
Fehlermeldung: Base/8027
unkown symbol for database field
mfg Klaus
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hallo, Klaus.
Welchen Datentyp hat "TWOCHE"?
Am Rande: Warum initialisierst Du "cdatumn1" als String? Datumsfelder (dDatumn1 := Date() oder dDatumn1 := CtoD(" . . ")) werden bei GETs automatisch formatiert (PICTURE ist überflüssig), darüberhinaus reagieren die GETs auf SET DATE- und SET CENTURY-Einstellungen automatisch - und die Eingabe wird validiert (falsche Datumseingaben sind nicht möglich).
Welchen Datentyp hat "TWOCHE"?
Am Rande: Warum initialisierst Du "cdatumn1" als String? Datumsfelder (dDatumn1 := Date() oder dDatumn1 := CtoD(" . . ")) werden bei GETs automatisch formatiert (PICTURE ist überflüssig), darüberhinaus reagieren die GETs auf SET DATE- und SET CENTURY-Einstellungen automatisch - und die Eingabe wird validiert (falsche Datumseingaben sind nicht möglich).
Herzlich,
Tom
Tom
Re: Clipper 97 goes Xbase++ goes MDI ?
twoche ist in der Datenbank: twoche --> Character 2Tom hat geschrieben: Welchen Datentyp hat "TWOCHE"?
da sollte dann drinstehen : Mo , Di, Mi , Do , Fr ... Wochentag abgekürzt
mfg Klaus
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hallo, Klaus.
Die Datenbank ist nicht selektiert:
8027 - [BASE] - ???
Associated with: "65:Unknown symbol for database field"
Caused by: Accessing of a database FIELD that does not exist in the
currently selected workarea. Use Alias->FieldName instead.
(Aus der XppErrors.chm von Andreas Gehrs-Pahl.)
Die Datenbank ist nicht selektiert:
8027 - [BASE] - ???
Associated with: "65:Unknown symbol for database field"
Caused by: Accessing of a database FIELD that does not exist in the
currently selected workarea. Use Alias->FieldName instead.
(Aus der XppErrors.chm von Andreas Gehrs-Pahl.)
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
Ich habe ja schon ewig nicht mehr mit S87 gearbeitet, aber viele haben damals noch mit dBase III+ gearbeitet und S87 lediglich als Compiler verwendet.Tom hat geschrieben:Hallo, Klaus.
Welchen Datentyp hat "TWOCHE"?
Am Rande: Warum initialisierst Du "cdatumn1" als String?
Wenn ich mich nicht irre gab es aber "damals" das "Problem" beim dBase III Datum ... die meisten (auch ich) haben dann XX.XX.XX statt 99.99.99 verwendet.
Dies ist übrigens, wenn man noch ein 2-stelliges Jahr hat, auch das "2K Problem" gewesen das man dann vom Type "C" auf Type "D" umgestellt hat, aber für andere Sachen wieder auf Type "C" zurück konvertieren musste.
AnmerkungenKlausXXL hat geschrieben: flock()
aktuell:=ctod(cdatumn1)
? aktuell
wait("")
replace twoche with left(cdow(aktuell),2) <--- fehler
unlock
flock() : warum ? ist schon eine DBF geöffnet ? Was ist der Rückgabe Wert ?
wait() : hoffentlich "nur" hier als "Demo" ... ? siehe mal im Taskmanager nach CPU % beim "Wait"
replace twoche : auf welchem SELECT bist du ? man sollte möglich immer einen ALIAS verwenden
left(cdow(aktuell),2) : du speicherst doch eh das Datum, oder ?
gruss by OHR
Jimmy
Jimmy
Re: Clipper 97 goes Xbase++ goes MDI ?
Tom hatte natürlich recht ... falscher select bereich ... war alles so verschachtelt, daß ich es nach mehrmaligem durchsehen ... übersehen habe . Danke TomTom hat geschrieben:Die Datenbank ist nicht selektiert:
...
ach ja die wait() kommen natürlich wieder raus ... habe ich mir nur so angewöhnt um zu sehen wenn irgendwo ein Fehler ist
mfg.
ach ja was ist eigentlich die einfachste Möglickeit einen bestehenden Termin zu KOPIEREN , d.h. alle daten des Datensatzes zu Übernehmen außer Terminnr und Datum des Termins
z.B.
terminnr, datum des Satz muß geändert werden
alles ander nur kopiert werden: adresse,Tel, etc
mfg Klaus
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Hallo, Klaus.
Die Funktion "Scatter()" liest alle Felder eines Datensatzes in ein Array, "Gather()" ist die Gegenfunktion, die zurückschreibt. Damit kann man sehr leicht kopieren, aber zum Beispiel auch die Daten für Anzeigemasken sammeln. Nach dem "Gather()" auf dem neuen Datensatz musst Du lediglich die veränderten Daten (Terminnummer, Datum) "nachschieben".
Also:
Die Funktion "Scatter()" liest alle Felder eines Datensatzes in ein Array, "Gather()" ist die Gegenfunktion, die zurückschreibt. Damit kann man sehr leicht kopieren, aber zum Beispiel auch die Daten für Anzeigemasken sammeln. Nach dem "Gather()" auf dem neuen Datensatz musst Du lediglich die veränderten Daten (Terminnummer, Datum) "nachschieben".
Also:
Code: Alles auswählen
* auf dem zu kopierenden Datensatz
a := Scatter()
DbAppend()
Gather(a)
TerminNr := NeueTerminNr()
* use
DbUnlock()
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
Der Tip von Tom bezieht sich eher auf XbpSLE, den beim GET hätten wir als Array ja die GETlist().KlausXXL hat geschrieben:ach ja was ist eigentlich die einfachste Möglickeit einen bestehenden Termin zu KOPIEREN , d.h. alle daten des Datensatzes zu Übernehmen außer Terminnr und Datum des Termins
Diese sollte immer als LOCAL GETlist := {} deklariert werden.
In "reinem" Cl*pper Code könnte es so aussehen:
Code: Alles auswählen
LOCAL i, iMAX
LOCAL aKopie := {}
// Anzahl FELDer
iMax := FCOUNT()
// Werte in ein Array einlesen
FOR i := 1 TO iMax
AADD(aKopie, FIELDGET(i) )
NEXT
// Datensatz anhängen
APPEND BLANK
IF NETERR()
// ERROR
ELSE
// Array Element in die DBF schreiben
FOR i := 1 TO iMax
FIELDPUT(i, aKopie[i] )
NEXT
ENDIF
gruss by OHR
Jimmy
Jimmy
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Clipper 97 goes Xbase++ goes MDI ?
Scatter() und Gather() sind zwar nicht explizit dokumentiert, funktionieren aber auch ganz ohne Xbparts.Der Tip von Tom bezieht sich eher auf XbpSLE
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: Clipper 97 goes Xbase++ goes MDI ?
Ja stimmt ja siehe c:\ALASKA\XPPW32\SOURCE\SYS\Blocks.prgTom hat geschrieben:Scatter() und Gather() sind zwar nicht explizit dokumentiert, funktionieren aber auch ganz ohne Xbparts.
... ich hatte nur :setdata() / :getdata() im Kopf und dazu braucht man ja einen :datalink und den hat ja das XbpSLE ...
ok wieder was gelernt.
gruss by OHR
Jimmy
Jimmy
Re: Clipper 97 goes Xbase++ goes MDI ?
gibt es eine sichere Möglichkeit sicherzustellen, daß ein Datensatz - der gerade neu angelegt wurde
in der Datenbank abgespeichert ist -- auch wenn kurze Zeit später das Programm mit einer Fehlermeldung
aussteigt ?
sozusagen nach
append blank
...
replace Feld1 with xyz
etc.
und
replace KundNr with Kundnr +1
....
* JETZT ALLES IN DATENBANKEN ABSPEICHERN *
Hintergrund --- wenn xbase durch Fehlermeldung aussteigt sind zu 90% die zuletzt eingegebenen DATEN weg ...
und was noch schlimmer ist eine Kundennummer bzw Terminnummer wird nicht mit +1 abgelegt ,
so daß beim erneuten Start des Programms eine doppelte Terminnummer neu angelegt wird ... was die
ganzen Daten dureinander bringt ....
mfg Klaus
in der Datenbank abgespeichert ist -- auch wenn kurze Zeit später das Programm mit einer Fehlermeldung
aussteigt ?
sozusagen nach
append blank
...
replace Feld1 with xyz
etc.
und
replace KundNr with Kundnr +1
....
* JETZT ALLES IN DATENBANKEN ABSPEICHERN *
Hintergrund --- wenn xbase durch Fehlermeldung aussteigt sind zu 90% die zuletzt eingegebenen DATEN weg ...
und was noch schlimmer ist eine Kundennummer bzw Terminnummer wird nicht mit +1 abgelegt ,
so daß beim erneuten Start des Programms eine doppelte Terminnummer neu angelegt wird ... was die
ganzen Daten dureinander bringt ....
mfg Klaus