| Subject |
IDE halts for 1 minute when exiting app |
| From |
Paolo Baranzoni Esseduesoft <paolobaranzoni@aruba.it> |
| Date |
Tue, 31 Aug 2021 18:02:56 +0200 |
| Newsgroups |
dbase.getting-started |
| Attachment(s) |
GenericMDIApp.cc, setup.prg, start.prg, tutorial.mnu |
I'm trying to build an mdi app following the dBase tutorial.
But when i exit the app and go back to dBase IDE and try to open a file
in the source code editor (or design) then IDE halts for almost a minute
waiting for "i dont know what" and finally opens the source code editor.
I use dBase2019 on Windows10 pro 64bit.
Attached the four files (but they are almost the same as the tutorial)
Is there something wrong?
Thanks
Paolo B.
--
Questa e-mail รจ stata controllata per individuare virus con Avast antivirus.
https://www.avast.com/antivirus
| /*
GenericMDIApp.CC
From the dBASE Tutorial that was updated/maintained by
Michael Nuwer for years ...
Minor update, July 2014 by Geep Howell
(as noted) in the Close method, for
current versions of dBASE (9.x).
A simple custom class file that contains
a "generic" MDI application object. This
object, when used properly, is subclassed
and the subclass has the following:
set procedure to genericMDIApp.cc additive
class TestMDIApp of genericMDIApp()
this.FrameWinText = "Some Text for _app.framewin"
this.MenuClassName = "MenuClassname"
endclass
A startup program for this would assume that you
have a "SETUP" program, which opens any custom
control files necessary (and does whatever else
may be needed), instantiates the subclassed
MDI application object, and then starts it
with the 'start' method:
app = new TestMDIApp()
return ( app.open() )
*/
class GenericMDIApp
// This custom property should be overwritten
// in a subclass, or after instantiation, but
// before the Open() method is invoked:
this.FrameWinText = "Generic MDI application"
// The same goes for this custom property:
this.MenuClassName = "MyMainMenu"
// We assume here that every MDI app will have
// a SETUP.PRG
do setup
// Assign a property to _app.frameWin, which is
// a reference to this object: "this".
_app.framewin.app = this
function Open
// set a reference to the menu
private c
c = 'this.rootMenu = new '+this.MenuClassName+'(_app.framewin,"Root")'
&c.
// Make sure no forms are open
close forms
// Make sure we're not in "design mode"
set design off
// set the <Escape> key "off" but store the
// current setting:
this.OldEscape = set("ESCAPE")
set escape off
// Turn off the dBASE Plus shell, but
// leave the MDI frame window:
shell( false, true )
// Turn off the application's speedBar, statusBar, and tabBar
// however, for a true MDI app, you may actually want
// the tabBar turned on:
_app.speedbar := false
_app.statusBar := false
_app.tabBar := false
// Set the text property for the application's framewin
_app.framewin.oldText = _app.framewin.text
_app.framewin.text := this.FrameWinText
return
Function close
// close any forms that might have been left open
close forms
// set escape back to whatever it's previous
// state was:
cEscape = this.oldEscape
set escape &cEscape.
// set the shell back ...
shell( true, true )
// if we are in the "runtime" environment,
// we want to "quit" (otherwise the framewin will
// be left on screen)
if ( "runtime" $ lower( version(0) ) )
quit
else
// otherwise, let's reset some values:
with ( _app )
framewin.app := null
framewin.text := framewin.OldText
speedBar := true
statusBar := true
tabBar := true
endwith
// go back to design mode:
set design on
// close any open procedures
set procedure to
// release the menu
_app.framewin.root.release()
endif
return
endclass // don't forget this!
| /*
----------------------------------------------------------------------------
setup.prg
The setup program written for:
The dBASE Plus Tutorial: Developing An Application
January, 2017, Ken Mayer
Permission is granted to use this in your own applications, with the caveat
that credit be given appropriately.
This program makes sure the environment is normal, but then sets up the
application object (based on GenericMDIApp.cc), and more.
----------------------------------------------------------------------------
*/
// These always get me -- if the program
// crashes, and they usually do while developing --
// (due to programmer error), the speedBar, the
// statusBar, and the tabBar in the IDE is not available ...
// this just puts them back. The MDI application class turns
// them back off and on as needed ...
_app.speedbar := true
_app.statusBar := true
_app.tabBar := true
// this can also cause problems:
set design on
// Set procedures ...:
set procedure to start
// make sure the menu is available:
set procedure to tutorial.mnu
// custom controls used by the application
// add others as needed here:
| /*
START.PRG
Author: Ken Mayer
Date : January 13, 2017
Tutorial project START program
This program is used to start the TUTORIAL
application.
There is a reference to another .CC, which is
the genericMDIApp.CC file -- this contains
the generic application object, and below we
subclass it ...
The idea is that you have a lot of "things" that
you always do for any application that is
an MDI app. You create one object that handles
all of that, and then you subclass that for
the specifics for an application, as each is
at least slightly different.
*/
//update this for application version changes:
#define AppVersion "4.0" // Version 4 of this tutorial project
set talk off
// set the private directory for the BDE
// uses BDE (IDAPI) API Code below the TutorialApp
// definition -- this uses a default folder,
// no need to pass a value:
setPrivateDir()
// set up the application object:
local app
set procedure to GenericMDIApp.cc
app = new TutorialApp()
app.open()
return
/*
TutorialApp is a subclass of the "GenericMDIApp" contained
in the .cc file of the same name:
*/
class TutorialApp of GenericMDIApp
// set any specific code for the subclassed
// MDI application here - note this uses the AppVersion constant
// created above for the version number:
this.FrameWinText = "dBASE Plus Tutorial Project -- vers. " + AppVersion
// note this is not the file name -- the
// SETUP program must execute "set procedure ..." that
// will open the file "Tutorial.mnu" ... the class
// will be available from that point on. This is
// the classname of the menu:
this.MenuClassName = "TutorialMenu"
endclass
/*
Code that deals with setting the private folder for the BDE
to write _QSQLnnnn.dbf files, this is API code and a bit involved.
Provided by Wian in the dBASE newsgroups, but appears to have
been originally provided by Rick Miller.
*/
function setPrivateDir( cPath )
if not type("DbiSetPrivateDir") == "FP"
extern CUSHORT DbiSetPrivateDir(CSTRING) idapi32 from "DbiSetPrivateDir"
endif
Local cDir
if type("argVector(1)") == "C"
cDir = cPath
else
// when cDir == null, reset to default.
cDir = null
endif
return iif( DbiSetPrivateDir( cDir ) == 0, true, false )
| /*
----------------------------------------------------------------------------
tutorial.mnu
A basic menu, written for:
The dBASE Plus Tutorial: Developing An Application
January, 2017, Ken Mayer
Permission is granted to use this in your own applications, with the caveat
that credit be given appropriately.
----------------------------------------------------------------------------
*/
** END HEADER -- do not remove this line
//
// Generated on 01/13/2017
//
parameter formObj
new TUTORIALMENU(formObj, "root")
class TUTORIALMENU(formObj, name) of MENUBAR(formObj, name)
this.FILE = new MENU(this)
with (this.FILE)
text = "&File"
endwith
this.FILE.OPEN = new MENU(this.FILE)
with (this.FILE.OPEN)
text = "&Open"
endwith
this.FILE.OPEN.CUSTOMERS = new MENU(this.FILE.OPEN)
with (this.FILE.OPEN.CUSTOMERS)
text = "Customers"
endwith
this.FILE.OPEN.INVENTORY = new MENU(this.FILE.OPEN)
with (this.FILE.OPEN.INVENTORY)
text = "Inventory"
endwith
this.FILE.OPEN.SUPPLIER = new MENU(this.FILE.OPEN)
with (this.FILE.OPEN.SUPPLIER)
text = "Supplier"
endwith
this.FILE.OPEN.INVOICES = new MENU(this.FILE.OPEN)
with (this.FILE.OPEN.INVOICES)
text = "Invoices"
endwith
this.FILE.OPEN.LOOKUPS = new MENU(this.FILE.OPEN)
with (this.FILE.OPEN.LOOKUPS)
text = "Lookups"
endwith
this.FILE.OPEN.LOOKUPS.STATE = new MENU(this.FILE.OPEN.LOOKUPS)
with (this.FILE.OPEN.LOOKUPS.STATE)
text = "State"
endwith
this.FILE.OPEN.LOOKUPS.COUNTRY = new MENU(this.FILE.OPEN.LOOKUPS)
with (this.FILE.OPEN.LOOKUPS.COUNTRY)
text = "Country"
endwith
this.FILE.CLOSE = new MENU(this.FILE)
with (this.FILE.CLOSE)
onClick = class::CLOSE_ONCLICK
text = "&Close"
endwith
this.FILE.SEPARATOR1 = new MENU(this.FILE)
with (this.FILE.SEPARATOR1)
text = ""
separator = true
endwith
this.FILE.EXIT = new MENU(this.FILE)
with (this.FILE.EXIT)
onClick = class::EXIT_ONCLICK
text = "E&xit"
endwith
this.REPORTS = new MENU(this)
with (this.REPORTS)
text = "&Reports"
endwith
this.REPORTS.SUPPLIER = new MENU(this.REPORTS)
with (this.REPORTS.SUPPLIER)
text = "Supplier Information"
endwith
this.REPORTS.INVENTORY = new MENU(this.REPORTS)
with (this.REPORTS.INVENTORY)
text = "Inventory Summary"
endwith
this.REPORTS.STATEMENTS = new MENU(this.REPORTS)
with (this.REPORTS.STATEMENTS)
text = "Customer Statements"
endwith
this.REPORTS.SEPARATOR2 = new MENU(this.REPORTS)
with (this.REPORTS.SEPARATOR2)
text = ""
separator = true
endwith
this.REPORTS.LABELS = new MENU(this.REPORTS)
with (this.REPORTS.LABELS)
text = "Customer Address Labels"
endwith
this.WINDOW = new MENU(this)
with (this.WINDOW)
text = "&Window"
endwith
this.WINDOW.MENU10 = new MENU(this.WINDOW)
with (this.WINDOW.MENU10)
text = "&Cascade"
windowMenuItem = 1 // Cascade
endwith
this.WINDOW.MENU9 = new MENU(this.WINDOW)
with (this.WINDOW.MENU9)
text = "Tile &Vertically"
windowMenuItem = 3 // Tile Vertically
endwith
this.WINDOW.MENU8 = new MENU(this.WINDOW)
with (this.WINDOW.MENU8)
text = "&Tile Horizontally"
windowMenuItem = 2 // Tile Horizontally
endwith
this.WINDOW.MENU7 = new MENU(this.WINDOW)
with (this.WINDOW.MENU7)
text = "Arrange &Icons"
windowMenuItem = 4 // Arrange Icons
endwith
this.WINDOW.CLOSEALL = new MENU(this.WINDOW)
with (this.WINDOW.CLOSEALL)
onClick = {; close forms}
text = "Close &All"
windowMenuItem = 5 // Close All
endwith
this.HELP = new MENU(this)
with (this.HELP)
text = "&Help"
endwith
this.HELP.ABOUT = new MENU(this.HELP)
with (this.HELP.ABOUT)
text = "&About Tutorial"
endwith
this.windowMenu = this.window
function CLOSE_onClick()
// close current form if there is one
if type( "_app.framewin.currentForm" ) == "O"
_app.framewin.currentForm.close()
else
msgbox( "The currently active form cannot be closed "+;
"with this option.","Can't do it!", 64 )
endif
return
function EXIT_onClick()
return( _app.framewin.app.close() )
function OpenForm( oForm )
// set the top/left properties so the form isn't
// *right* on top of the current one ...
if type( "_app.framewin.currentForm" ) == "O"
oForm.top := _app.framewin.currentForm.top + 40
oForm.left := _app.framewin.currentForm.left + 40
else
oForm.top := 0
oForm.left := 10
endif
oForm.open()
oForm.setFocus()
return
endclass
|
|