////////////////////////////////////////////////////////////////////// // AKDialog.PRG // // AKDialog aus DATADLG.PRG // // Inhalt: // Klassen AKDialog und AKDialogMenu ////////////////////////////////////////////////////////////////////// // und ganz unten: DialogFF als "Dialog from File" // und : BlattFF als "Blatt from File" /////////////////////////////////// #include "Gra.ch" #include "Xbp.ch" #include "Dmlb.ch" #include "Common.ch" #include "Appevent.ch" #include "AKDialog.ch" #include "Dll.ch" /* 15.04.2008 16:02 ak neue Funktion zur Ermittellung der Gr”áen von Titlebar und Menubar aus Alaska_Downloads_PI\dbeditor\dialog.prg */ //**//**//**//**//**//**//**//**//**//**//**//**//**//**//**//**//**// // Defines used with the GetSystemMetrics()-API, see XbpGetSystemMetrics() #define SM_CXDLGFRAME 7 #define SM_CYDLGFRAME 8 #define SM_CYMENU 15 #define SM_CYCAPTION 4 /* Die Original-Methode: ***************************** METHOD XbpBrowseDialog:Resize(aSizeOld, aSizeNew) ***************************** * Resize the dialog object; this also adjusts the size of the embedded * components Local aSize :=::CurrentSize() Local aSizeDA :=::drawingArea:CurrentSize() Local nHeightTitlebar:=xbpGetSystemMetrics(SM_CYCAPTION) Local nHeightMenubar :=xbpGetSystemMetrics(SM_CYMENU) Local nWidthBorder :=xbpGetSystemMetrics(SM_CXDLGFRAME) Local nHeightBorder :=xbpGetSystemMetrics(SM_CYDLGFRAME) // resize dialog ::XbpDialog:Resize(aSizeOld, aSizeNew) // Compute space occupied by dialog's titlebar, border and menubar aSizeDA[1]:=aSize[1]-(nWidthBorder*2)-1 aSizeDA[2]:=aSize[2]-(nHeightTitlebar+nHeightMenubar+nHeightBorder*2) ::drawingArea:setSize({aSizeDA[1],aSizeDA[2]}) ::drawingArea:setPos({0,20}) ::drawingArea:resize:={ |mp1,mp2,obj| IIf(Len(obj:childList())>0,obj:childList()[1]:setSize(mp2),Nil) } // resize status bar ::oStatusBar:setSize({aSizeDA[1],20}) ::oStatusBar:setPos({0,0}) // resize infoline ::oInfoLine:setSize({aSizeDA[1]-16,16}) ::oInfoLine:setPos({5,2}) // resize resize icon ::oResizeIcon:setSize({16,16}) ::oResizeIcon:setPos({aSizeDA[1]-16,2}) ::oResizeIcon:setCaption(Chr(112)) Return Self */ ************************ Func XbpGetSystemMetrics(nValue) ************************ Return DllCall("USER32.DLL", DLL_STDCALL, "GetSystemMetrics", nValue) //**//**//**//**//**//**//**//**//**//**//**//**//**//**//**//**//**// /* * Klassendeklaration */ CLASS AKTabPage FROM XbpTabPage //, XbpDialog EXPORTED VAR Fenster VAR drawingArea // VAR minButton // VAR maxButton // VAR sysMenu // VAR titleBar METHOD INIT METHOD CREATE ENDCLASS METHOD AKTabPage:INIT( oParent, oOwner, aPos, ASize, aPP, lVisible ) // ::XbpDialog:INIT() ::XbpTabPage:INIT( oParent, oOwner, aPos, ASize, aPP, lVisible ) ::Fenster := XbpDialog():new( self, , {0,0}, {ASize[1],ASize[2]-15}, aPP, lVisible ) ::Fenster:minButton := .F. ::Fenster:maxButton := .F. ::Fenster:sysMenu := .F. ::Fenster:titleBar := .F. // ::Fenster:XbpDialog():CREATE() ::drawingarea := ::Fenster:drawingArea RETURN self METHOD AKTabPage:CREATE( oParent, oOwner, aPos, ASize, aPP, lVisible ) ::XbpTabPage:CREATE( oParent, oOwner, aPos, ASize, aPP, lVisible ) RETURN self CLASS AKDialog FROM XbpDialog, SCManager PROTECTED: VAR appendMode // Wird ein neuer Datensatz angelegt? VAR editControls // XBPs, die Daten „ndern VAR appendControls // XBPs, die nur bei APPEND // aktiv sind VAR keyControls // Liste von XBPs fr Tastaturnavigation VAR keyboardBlock // Codeblock fr xbeP_Keyboard Ereignisse EXPORTED: VAR area READONLY // aktueller Arbeitsbereich VAR newTitle // Codeblock um Titel zu „ndern VAR contextMenu // Kontextmen fr Datendialog VAR windowMenu // Dynamisches Fenstermen // im Anwendungsfenster VAR currentControl // Aktuelles Edit Control VAR seekOrder // Daten fr die Suche im VAR seekExpr // SeekDialog VAR seekFields VAR seekTitle VAR cFont VAR aData1 VAR aData2 // 15.04.2008 17:46 fr XbpDialog:resize(): VAR nHeightTitlebar // H”he der Titlebar VAR nHeightMenubar // H”he der Menubar VAR nWidthBorder // Breite des linken/rechten Rands VAR nHeightBorder // Breite des unteren Rands VAR oLabel // das Label auf der Titelzeile VAR oIconBar // die IconLeiste unterhalb der MenuBar 27.06.2008 22:00 VAR oToolBar // die DA der ToolLeiste unterhalb der IconBar 24.10.2008 09:43 VAR oStatusBar // die DA der TextLeiste am unteren Rand des Fensters 24.10.2008 09:43 VAR rtfMle //+27.09.2008 14:11 VAR oHelp //+06.10.2008 12:16 zur Aufnahme des Help-Thread-Objektes METHOD init // Lebenszyklus METHOD create METHOD configure METHOD destroy METHOD addEditControl // XBP fr Edit registrieren METHOD addAppendControl // XBP fr Append registrieren METHOD addKeyControl // XBP fr Keyboard handling registrieren METHOD notify // Nachricht von DBO verarbeiten METHOD readData // Daten einlesen METHOD validateAll // Daten validieren METHOD writeData // Daten schreiben METHOD isIndexUnique // Indexwert prfen METHOD setDisplayFocus // Dialog hat Fokus bekommen METHOD keyHandler // Tastatursteuerung fr Edit controls METHOD StrukturErweiterung // Erweitert die Struktur von Dateien // 1.1.2005 METHOD resize // 07.04.2008 15:14 wenn Gr”áe des Fensters ver„ndert, dann... METHOD AddLabel // Label rechts oben auf die Titelzeile METHOD AddIconBar // Leiste unterhalb der MenuBar 27.06.2008 22:00 ENDCLASS // 15.04.2008 17:38 aus dbeditor\dialog.prg (Zitat siehe oben) METHOD AKDialog:resize( aSizeOld, aSizeNew ) //METHOD XbpBrowseDialog:Resize(aSizeOld, aSizeNew) ***************************** * Resize the dialog object; this also adjusts the size of the embedded components //Local aSize :=::CurrentSize() //Local aSizeDA :=::drawingArea:CurrentSize() //Local nHeightTitlebar:=xbpGetSystemMetrics(SM_CYCAPTION) //Local nHeightMenubar :=xbpGetSystemMetrics(SM_CYMENU) //Local nWidthBorder :=xbpGetSystemMetrics(SM_CXDLGFRAME) //Local nHeightBorder :=xbpGetSystemMetrics(SM_CYDLGFRAME) /* Function XbpGetSystemMetrics() siehe oben */ ::nHeightTitlebar:=xbpGetSystemMetrics(SM_CYCAPTION) ::nHeightMenubar :=xbpGetSystemMetrics(SM_CYMENU) ::nWidthBorder :=xbpGetSystemMetrics(SM_CXDLGFRAME) ::nHeightBorder :=xbpGetSystemMetrics(SM_CYDLGFRAME) // resize dialog ::XbpDialog:Resize(aSizeOld, aSizeNew) RETURN self /* * Datendialog initialisieren */ METHOD AKDialog:init( oParent, oOwner , ; aPos , aSize , ; aPParam, lVisible ) LOCAL aPSize LOCAL nBSb DEFAULT lVisible TO .T., ; oParent TO SetAppWindow() aPParam := IIf( Empty(aPParam), {}, aPParam ) nBSb := AppDesktop():currentSize()[1] IF cBfont != NIL .AND. Val(cBfont)>5 //24.03.2008 15:28 cFont := Trim(cBfont) //24.03.2008 15:28 ELSEIF nBSb > 1200 cFont := "12.Arial" ELSEIF nBSb > 1000 cFont := "10.Arial" ELSEIF nBSb >750 cFont := "8.Arial" ELSE cFont := "7.Arial" ENDIF AAdd ( aPParam, { XBP_PP_COMPOUNDNAME, cFont } ) /* * Ohne Angabe einer Position wird das Fenster zentriert angezeigt */ IF aPos == NIL aPSize := oParent:currentSize() ASize := {100,100} aPos := { (aPSize[1] - aSize[1]) / 2, ; (aPSize[2] - aSize[2]) / 2 } ENDIF ::XbpDialog:INIT( oParent, oOwner, ; aPos , aSize , ; aPParam, lVisible ) ::XbpDialog:taskList := .T. ::minsize := {400,300} //06.04.2008 17:53 ::movewithOwner := .F. //07.04.2008 20:36 // //06.04.2008 20:33 einstellbar, damit Fenster-Gr”áe variabel/flexibel IF cSerieBM != "F" ::border := XBPDLG_RAISEDBORDERTHIN_FIXED // 21.04.2007 18:38 Die Wirkung muss beobachtet werden: // damit die Fenster nicht immer per 'X' geschlossen werden oder minimiert werden: ::sysmenu := .F. //21.04.2007 18:31 hebt Min+Max-Button/X/System-Men auf !! // // ::minButton := .T. // ::maxButton := .T. //???wieso wirkt das nicht?: ::XbpDialog:minButton := .F. // -->Bei einem MDI Client Fenster wird der Pushbutton zum Minimieren des Fensters immer angezeigt, // es sei denn, :titleBar ist auf .F. (falsch) gesetzt. ENDIF ::aData1 := {} ::aData2 := {} ::area := 0 ::editControls := {} ::appendControls := {} ::keyControls := {} ::keyboardBlock := {|nKey,x,obj| ::keyHandler( nKey, obj ) } ::appendMode := .F. ::newTitle := {|obj| obj:getTitle() } RETURN self /* * Systemresourcen anfordern * und AKDialog im aktuellen Arbeitsbereich registrieren */ METHOD AKDialog:create( oParent, oOwner , ; aPos , aSize , ; aPParam, lVisible ) ::xbpDialog:create( oParent, oOwner , ; aPos , aSize , ; aPParam, lVisible ) ::appendMode := Eof() ::area := Select() ::close := {|mp1,mp2,obj| obj:destroy() } DbRegisterClient( self ) /*15.04.2008 17:44 */ ::nHeightTitlebar:=xbpGetSystemMetrics(SM_CYCAPTION) ::nHeightMenubar :=xbpGetSystemMetrics(SM_CYMENU) ::nWidthBorder :=xbpGetSystemMetrics(SM_CXDLGFRAME) ::nHeightBorder :=xbpGetSystemMetrics(SM_CYDLGFRAME) //+24.10.2008 09:21: damit der HelpThread das betreffende Fenster findet (auch Ersatz fr aThrdFenster??) ThreadObject():cargo := self RETURN self /* * Systemresourcen konfigurieren * und Dialog ggf. in neuem Arbeitsbereich registrieren */ METHOD AKDialog:configure( oParent, oOwner , ; aPos , aSize , ; aPParam, lVisible ) LOCAL lRegister := (::area <> Select()) ::xbpDialog:configure( oParent, oOwner , ; aPos , aSize , ; aPParam, lVisible ) IF lRegister (::area)->( DbDeRegisterClient( self ) ) ENDIF ::area := Select() ::appendMode := Eof() IF lRegister DbRegisterClient( self ) ENDIF //+22.12.2010 14:36 fr Resize-Vorg„nge: ::editControls := {} ::appendControls := {} ::keyControls := {} RETURN self /* * Systemresourcen freigeben und AKDialog entregistrieren */ METHOD AKDialog:destroy() /* * Aufruf ignorieren wenn das Fenster schon im INIT Status ist. */ IF ::Status() == XBP_STAT_INIT RETURN self ENDIF // ::writeData() // wird schon an anderer Stelle gemacht (zB: Button:activate ::hide() // (::Area)->( DbCloseArea() ) //// /* //// * Eintrag im Fenstermen l”schen //// */ //// IF ! Empty( ::windowMenu ) //// ::windowMenu:delItem( self ) // //// ::windowMenu := NIL //// ENDIF //// //// /* //// * Referenzen auf den AKDialog und das Kontextmen l”schen //// */ //// IF ! Empty( ::contextMenu ) //// ::contextMenu:cargo := NIL //// ::contextMenu := NIL //// ENDIF IF Used() //+28.10.2009 22:04 DbDeRegisterClient( self ) ENDIF /* * Systemresourcen freigeben und Instanzvariablen * auf die Werte im Zustand :init() zurcksetzen */ ::xbpDialog:destroy() ::Area := 0 ::appendMode := .F. ::editControls := {} ::appendControls := {} ::newTitle := {|obj| obj:getTitle() } RETURN self /* * Notify Methode: * - Vor Bewegen des Satzzeigers, Daten schreiben * - Nach Bewegen des Satzzeigers, Daten neu einlesen */ METHOD AKDialog:notify( nEvent, mp1, mp2 ) IF nEvent <> xbeDBO_Notify RETURN self // ** RETURN ** ENDIF DbSuspendNotifications() DO CASE CASE mp1 == DBO_MOVE_PROLOG // Satzzeiger wird bewegt ::writeData() CASE mp1 == DBO_MOVE_DONE .OR. ; // Skip ist beendet mp1 == DBO_GOBOTTOM .OR. ; mp1 == DBO_GOTOP ::readData() //// DO CASE //// CASE Empty( ::contextMenu ) //// CASE Eof() // Eintr„ge im Kontextmen //// ::contextMenu:disableBottom() // verfgbar machen oder //// ::contextMenu:disableEof() // sperren, je nachdem //// CASE mp1 == DBO_GOBOTTOM // wo der Satzzeiger sich //// ::contextMenu:enableAll() // befindet. //// ::contextMenu:disableBottom() //// CASE mp1 == DBO_GOTOP //// ::contextMenu:enableAll() //// ::contextMenu:disableTop() //// OTHERWISE //// ::contextMenu:enableAll() //// ENDCASE //// //// DO CASE //// CASE Eof() // Eintr„ge im Bearbeiten-Men //// WinMenu():editMenu:disableBottom() // des Fensters sperren //// WinMenu():editMenu:disableEof() // oder verfgbar machen //// CASE mp1 == DBO_GOBOTTOM // je nachdem, wo sich //// WinMenu():editMenu:enableAll() // der Satzzeiger befindet //// WinMenu():editMenu:disableBottom() //// CASE mp1 == DBO_GOTOP //// WinMenu():editMenu:enableAll() //// WinMenu():editMenu:disableTop() //// OTHERWISE //// WinMenu():editMenu:enableAll() //// ENDCASE ENDCASE DbResetNotifications() RETURN self /* * EditControl an Liste anfgen */ METHOD AKDialog:addEditControl( oXbp ) IF ValType( oXbp ) = "O" // dieses IF von ak am 31.12.02 IF AScan( ::editControls, oXbp ) == 0 AAdd( ::editControls, oXbp ) ::addKeyControl( oXbp ) ENDIF ELSE AAdd( ::editControls, oXbp ) ENDIF RETURN self /* * AppendControl an Liste anfgen */ METHOD AKDialog:addAppendControl( oXbp ) IF AScan( ::appendControls, oXbp ) == 0 AAdd( ::appendControls, oXbp ) ::addKeyControl( oXbp ) ENDIF RETURN self /* * XBP an Liste fr die Tastatursteuerung anfgen. Jeder XBP bekommt * den gleichen :keyBoard Codeblock. Er wird nach dem Ereignis * xbeP_Keyboard ausgewertet und ruft einen benutzerdefinierten * Tastatur-Handler */ METHOD AKDialog:addKeyControl( oXbp ) IF AScan( ::keyControls, oXbp ) == 0 AAdd( ::keyControls, oXbp ) oXbp:keyBoard := ::keyboardBlock ENDIF RETURN self /* * Fenster hat den Fokus bekommen. * Workarea ausw„hlen, Eintrag im Fenstermen markieren und Fokus * auf das aktuelle Edit Control setzen */ METHOD AKDialog:setDisplayFocus DbSelectArea( ::area ) IF ::windowMenu <> NIL ::windowMenu:checkItem( self ) ENDIF IF ::currentControl <> NIL SetAppFocus( ::currentControl ) ENDIF RETURN self //////****************************************************************************** //////* Die ueberladene Keyboard Methode muss die Methode the SCManager Basisklasse //////* rufen um die ShortCuts zu bearbeiten //////****************************************************************************** //////METHOD AKDialog:Keyboard( nKey ) ////// ////// LOCAL lHandled := FALSE ////// ////// lHandled := ::HandleShortCut( nKey ) ////// IF ! lHandled ////// RETURN ::xbpDialog:keyBoard( nKey ) ////// ENDIF ////// //////RETURN self /* * Benutzerdefinierte Tastaturverarbeitung */ METHOD AKDialog:keyHandler( nKey, oXbp ) LOCAL i:=AScan( ::keyControls, oXbp ) //** SCManager: LOCAL lHandled := ::HandleShortCut( nKey ) IF ! lHandled DO CASE CASE i == 0 CASE oXbp:isDerivedFrom( "XbpMLE" ) .OR. oXbp:isDerivedFrom( "XbpListbox" ) // Return, PageUp, PageDown werden zum Editieren von MLE und Listbox // verwendet. In dem Fall werden die Tasten hier ignoriert. CASE nKey == xbeK_RETURN IF ++i > Len( ::keyControls ) i := 1 ENDIF DO WHILE ! ::keyControls[i]:isenabled() i ++ ENDDO SetAppFocus( ::keyControls[i] ) ////// CASE nKey == xbeK_PGDN ////// IF ! Eof() ////// SKIP ////// IF Eof() ////// DbSuspendNotifications() ////// SKIP -1 // Append-Situation vermeiden ////// DbResetNotifications() ////// DbGobottom() // Notification ausl”sen ////// ENDIF ////// ENDIF ////// ////// CASE nKey == xbeK_PGUP ////// IF ! Bof() ////// SKIP -1 ////// ENDIF ////// ENDCASE ENDIF RETURN self /* * Datensatz lesen und Daten in EditControls einlesen */ METHOD AKDialog:readData() LOCAL i, imax := Len( ::editControls ) FOR i:=1 TO imax // Daten aus Datei in ::editControls[i]:setData() // XBPs bertragen NEXT Eval( ::newTitle, self ) // Neuer Fenstertitel IF Eof() // XBPs aktivieren oder IF ! ::appendMode // deaktivieren, die nur imax := Len( ::appendControls ) // bei APPEND zug„nglich FOR i:=1 TO imax // sein drfen ::appendControls[i]:enable() // Eof() ist erreicht NEXT // XBPs entsperren ENDIF ::appendMode := .T. ELSEIF ::appendMode // Satzzeiger wurde von imax := Len( ::appendControls ) // Eof() auf existierenden FOR i:=1 TO imax // Datensatz bewegt. ::appendControls[i]:disable() // XBPs wieder sperren NEXT ::appendMode := .F. ENDIF RETURN /* * Daten der EditControls in eine Datei schreiben */ METHOD AKDialog:writeData() LOCAL i, imax LOCAL lLocked := .F. , ; // Ist Satzsperre gesetzt? lAppend := .F. , ; // Ist Datensatz neu? aChanged := {} , ; // XBPs mit ge„nderten Daten nOldArea := Select() // Aktueller Bereich dbSelectArea( ::area ) IF Eof() // Neuen Datensatz anlegen //// IF ::validateAll() // Daten vor Append validieren ////// IF ConfirmBox( self, "Soll ein Datensatz angefgt werden?", ; ////// "Dateiende erreicht", ; ////// XBPMB_YESNO, ; ////// XBPMB_QUESTION ) == XBPMB_RET_YES //// APPEND BLANK //// lAppend := .T. //// aChanged := ::editControls // Alle XBPs k”nnen ge„ndert sein //// lLocked := ! NetErr() // Automatische Sperre ////// ELSE ////// DbSelectArea( nOldArea ) // keinen neuen Datensatz schreiben ////// RETURN .F. // *** ZURšCK *** ////// ENDIF //// ELSE //// MsgBox("Ungltige Daten") // Keine ungltigen Daten DbSelectArea( nOldArea ) // in neuen Datensatz schreiben RETURN .F. // *** ZURšCK *** //// ENDIF ELSE imax := Len( ::editControls ) // Feststellen, welche Daten FOR i:=1 TO imax // ge„ndert wurden IF ::editControls[i]:changed AAdd( aChanged, ::editControls[i] ) ENDIF NEXT IF Empty( aChanged ) // Keine Žnderung -> DbSelectArea( nOldArea ) // keine Satzsperre n”tig RETURN .T. // *** ZURšCK *** // ELSEIF ConfirmBox( oCB, "Žnderungen speichern?", ; // "Datensatz wurde ge„ndert.", ; // XBPMB_YESNO, ; // XBPMB_QUESTION ) = XBPMB_RET_NO // DbSelectArea( nOldArea ) // keine Satzsperre n”tig // RETURN .F. // *** ZURšCK *** ENDIF lLocked := DbRLock( Recno() ) // Datensatz sperren ENDIF IF ! lLocked MsgBox( "Datensatz ist zur Zeit gesperrt" ) DbSelectArea( nOldArea ) // keine Satzsperre m”glich RETURN .F. // *** ZURšCK *** ENDIF imax := Len( aChanged ) // Schreibzugriff nur fr DbSuspendNotifications() //+20.12.2010 21:38 mal zum Test FOR i:=1 TO imax // ge„nderte Daten IF ! lAppend // erforderlich IF ! aChanged[i]:validate() aChanged[i]:undo() // ungltige Daten ! LOOP // Original wiederherstellen ENDIF // und n„chsten XBP validieren ENDIF IIf( !DbLocked(), DbRLock(), ) //+17.01.2010 10:14 vorsichtshalber, manchmal notiz-Fehler aChanged[i]:getData() // Daten aus XBP holen und // // IIf(i==1 .AND. Alias()!="tl",TransLog(,,aChanged[i]:editbuffer()),) //29.04.2007 19:03 // NEXT // in Datei schreiben DbCommit() // Datenpuffer wegschreiben DbRUnlock( Recno() ) // Sperre aufheben // Dialogelemente nach Append IF ::appendMode // wieder sperren imax := Len( ::appendControls ) FOR i:=1 TO imax ::appendControls[i]:disable() NEXT ::appendMode := .F. IF ! Empty( ::contextMenu ) ::contextMenu:disableBottom() ::contextMenu:enableEof() ENDIF //// WinMenu():editMenu:disableBottom() //// WinMenu():editMenu:enableEof() ENDIF DbResumeNotifications() //+20.12.2010 21:38 mal zum Test DbSelectArea( nOldArea ) RETURN .T. /* * Daten aus allen EditControls validieren * Wird bei APPEND gebraucht bevor ein neuer Datensatz angefgt wird */ METHOD AKDialog:validateAll() LOCAL i := 0, imax := Len( ::editControls ) LOCAL lValid := .T. DO WHILE ++i <= imax .AND. lValid lValid := ::editControls[i]:validate() ENDDO RETURN lValid /* * Prfen, ob ein Indexeintrag noch nicht vorhanden ist */ METHOD AKDialog:isIndexUnique( nOrder, xIndexValue ) LOCAL nOldOrder := OrdNumber() LOCAL nRecno := Recno() LOCAL lUnique := .T. DEFAULT nOrder TO nOldOrder //22.06.2008 17:07 IF !Empty( xIndexValue ) DbSuspendNotifications() // Keine Nachricht vom DBO // an self bei DbSeek() !!! OrdSetFocus( nOrder ) SatzDelete() // damit er sich nicht selber findet lUnique := .NOT. DbSeek( xIndexValue ) OrdSetFocus( nOldOrder ) DbGoTo( nRecno ) SatzRecall() // damit er wieder da ist DbResetNotifications() ENDIF RETURN lUnique // neue Felder in einer Datei anfgen: METHOD AKDialog:StrukturErweiterung( cDatei, aNeuFeld, nA ) LOCAL nOldArea := SELECT(), i, aFeld cDatei := cDatver + cDatei SELECT (nA) DbUseArea( , , cDatei ) // Datei ”ffnen COPY TO (cDatei+"k") // Sicherungskopie COPY TO temp // Daten zwischenspeichern DbCopyExtStruct( "Struct" ) // Struktur bertragen DbUseArea( , , "Struct" ) // strukturerweiterte Datei FOR i := 1 TO Len(aNeuFeld) aFeld := aNeuFeld[i] DbAppend() // ”ffnen und neue FIELD->Field_Name := aFeld[1] // Felddefinition eintragen FIELD->Field_Type := aFeld[2] FIELD->Field_Len := aFeld[3] FIELD->Field_Dec := aFeld[4] NEXT DbCloseArea() //// // Sicherungskopie fr //// IF FILE(cDatver+"Temp.dbf") //// COPY FILE ( cDatei+".dbf" ) TO ( cDatver+"Temp.dbf" ) // - DBF-Datei //// COPY FILE ( cDatei+".dbt" ) TO ( cDatver+"Temp.dbt" ) // - Memo-Datei //// ELSE //// FRename( cDatei+".dbf", cDatver+"Temp.dbf" ) // - DBF-Datei //// Frename( cDatei+".dbt", cDatver+"Temp.dbt" ) // - Memo-Datei //// ENDIF DbCreateFrom( cDatei,, "Struct" ) // Neue Datei erzeugen DbUseArea( , , cDatei ) // Datei ”ffnen DbImport( cDatver+"Temp" ) // Datens„tze aus Sicherungskopie bernehmen DbCloseArea() //// // Dateien umbenennen //// IF FILE(cDatei+".bkf") //// COPY FILE ( cDatver+"Temp.dbf" ) TO ( cDatei+".bkf" ) // - DBF-Datei //// COPY FILE ( cDatver+"Temp.dbt" ) TO ( cDatei+".bkt" ) // - Memo-Datei //// ELSE //// FRename( cDatver+"Temp.dbf", cDatei+".bkf" ) // - DBF-Datei //// FRename( cDatver+"Temp.dbt", cDatei+".bkt" ) // - Memo-Datei //// ENDIF FErase( "Struct.dbf" ) // Strukturerweiterte Datei l”schen SELECT (nOldArea) RETURN self /* 15.04.2008 22:52 Label rechts oben mit Verstorbenennamen und Auftragsnummer: */ // This method adds a button onto the titlebar. // Note : The button itself is a XbpDialog without any frame with // an XbpPushButton on its drawingArea in the same // size, filling the DA completly. METHOD AKDialog:AddLabel( cCaption ) // aufrufen, wenn Parameter gesetzt (f08[5]?) LOCAL aPos := {::currentsize()[1]-130*nH,::currentsize()[2]-::nHeightTitlebar} LOCAL aSize := { 100*nH, ::nHeightTitlebar } LOCAL oDlg // the dialog created without border, titlebar or anything. ::oLabel := XbpDialog():new( AppDesktop(), self, aPos, aSize ) ::oLabel:movewithOwner := .T. ::oLabel:Border := XBPDLG_NO_BORDER ::oLabel:Titlebar := .F. ::oLabel:minButton := .F. ::oLabel:maxButton := .F. ::oLabel:create() // the PushButton, in the size of the dialog. ::oLabel:cargo := XbpStatic():new( oDlg:drawingarea , , { 0, 0}, ; oDlg:CurrentSize()) ::oLabel:cargo:autosize := .F. // ::oLabel:cargo:PointerFocus := .F. ::oLabel:cargo:caption := cCaption ::oLabel:cargo:Create() // add the dialog to the array that stores each user defined // button of the titlebar. // AAdd( ::aDlg4Buttons, oDlg ) RETURN( self ) // ::nHeightTitlebar:=xbpGetSystemMetrics(SM_CYCAPTION) // ::nHeightMenubar :=xbpGetSystemMetrics(SM_CYMENU) // ::nWidthBorder :=xbpGetSystemMetrics(SM_CXDLGFRAME) // ::nHeightBorder :=xbpGetSystemMetrics(SM_CYDLGFRAME) METHOD AKDialog:AddIconBar( ) // aufrufen, wenn Parameter gesetzt (f08[5]?) LOCAL aPos := {::currentpos()[1]+::nWidthBorder, ; ::currentpos()[2]+::currentsize()[2]-::nHeightTitlebar-::nHeightMenubar - ; Min(::nHeightMenubar,::nHeightMenubar*nV)} LOCAL aSize := { ::currentsize()[1]-::nWidthBorder*2, Min(::nHeightMenubar,::nHeightMenubar*nV) } // LOCAL oDlg // the dialog created without border, titlebar or anything. ::oIconBar := XbpDialog():new( AppDesktop(), self, aPos, aSize ) ::oIconBar:movewithOwner := .T. ::oIconBar:Border := XBPDLG_NO_BORDER ::oIconBar:Titlebar := .F. ::oIconBar:minButton := .F. ::oIconBar:maxButton := .F. ::oIconBar:create() ::oIconBar:drawingArea:setColorBG( XBPSYSCLR_BACKGROUND ) ////// // the PushButton, in the size of the dialog. ////// ::oIconBar:cargo := XbpStatic():new( ::oDlg:drawingarea , , { 0, 0}, ; ////// oDlg:CurrentSize()) ////// ::oIconBar:cargo:autosize := .F. //////// ::oLabel:cargo:PointerFocus := .F. ////// ::oIconBar:cargo:caption := cCaption ////// ::oIconBar:cargo:Create() ////// ////// // add the dialog to the array that stores each user defined ////// // button of the titlebar. //////// AAdd( ::aDlg4Buttons, oDlg ) RETURN( self ) //******************************************************************************** #include "Gra.ch" #include "Xbp.ch" #include "Appevent.ch" #include "Appedit.ch" #include "Appbrow.ch" #include "Font.ch" #include "dmlb.ch" #include "Common.ch" PROCEDURE RunWin(oOwner, cProc, aWinSize, aWinPos, cTitle, optP1,optP2,optP3,optP4,optP5) LOCAL oDosWin LOCAL oOldWin LOCAL oOldFocus := SetAppFocus() LOCAL nOldArea := SELECT(), nRec := RecNo() LOCAL aSizeDesktop, aPos (nOldArea)->(DbSuspendNotifications()) ////// aSizeDesktop := AppDesktop():currentSize() ////// #define DEF_FONTHEIGHT aSizeDesktop[2]/28 ////// #define DEF_FONTWIDTH aSizeDesktop[1]/80 ////// #define DEF_ROWS 25 ////// #define DEF_COLS 80 ////// aPos := { (aSizeDesktop[1]-(DEF_COLS * DEF_FONTWIDTH)) /2, ; ////// (aSizeDesktop[2]-(DEF_ROWS * DEF_FONTHEIGHT)) /2 } ////// aWinSize := { DEF_COLS, DEF_ROWS } ////// aWinPos := aPos oDosWin := XbpCrt():New(AppDeskTop(),oOwner:cargo,aWinPos,aWinSize[2],aWinSize[1],cTitle,.f. ) IF aWinPos[1] = 0 .AND. aWinPos[2] = 0 ScreenCenter(oDosWin,.t.) ENDIF ////// oDosWin:FontWidth := DEF_FONTWIDTH ////// oDosWin:FontHeight := DEF_FONTHEIGHT ////// oDosWin:FontName := "8.Arial" oDosWin:Create() oDosWin:SetModalState(XBP_DISP_APPMODAL) oOldWin := SetAppWindow(oDosWin) oDosWin:Show() SET COLOR TO "GR+/B,W+/R,,,N/W" oDosWin:Close := {||PostAppEvent(xbeK_PGDN)} SetAppFocus(oDosWin) SetCursor(1) &cProc(optP1,optP2,optP3,optP4,optP5) oDosWin:Hide() oDosWin:SetModalState(XBP_DISP_MODELESS) SetAppWindow(oOldWin) oDosWin:Destroy() set charset to oem if oOldFocus <> NIL SetAppFocus(oOldFocus) ENDIF SELECT &nOldArea GO nRec (nOldArea)->(DbResumeNotifications()) RETURN //+09.03.2010 18:14 //+ damit die ConfirmBox immer ontop bleibt: FUNCTION ConfirmBoxNeu(oOwner, cMessage, cTitle, nButtons, nStyle, nStartButton) LOCAL x, oAppWin := SetAppWindow(oOwner) x := ConfirmBox(oOwner, cMessage, cTitle, nButtons, nStyle, nStartButton) SetAppWindow(oAppWin) RETURN x