2009-09-19   Paradox 11 - Build 410 - Internal 10.1

This document contains descriptions of some errors in the Paradox help files. It covers both cases where the help files are incorrect, and cases where the behaviour maybe should have been mentioned in the help files.

This document contains information about some undocumented methods and procedures. Be careful when using these methods. They are undocumented and unsupported.

This file is a complement to my buglist.

My basic source of information for this document is the Corel Paradox newsgroups.

The list has been compiled by:
Bertil Isberg, Statistics Sweden
office e-mail: bertil.isberg AT scb DOT se
home e-mail: bertil.isberg AT bredband DOT net


My current configuration:
Paradox: Help | About dialog: 11.00.410
BDE Administrator: Object | Version Information - Idapi32.dll: 5.2.0.2.
My Computer - Properties: Win XP Media Center Edition Version 2002 SP 2

Note: the items are not sorted by the id.




Table of contents



Interactive

105 ActiveX objects sendToBack() / bringToFront()
223 BDE MS SQL Server
653 BDE Administrator Auto ODBC
132 BDE Administrator MinBufsize and MaxBufsize
78 BDE Administrator SharedMemLocation - Win2000
682 Chart XAxisName property
85 Chart Marker size
92 Chart Logarithmic Scale
683 Chart YAxisName property
21 Chart LeftWall Pattern on a 3D chart
256 Command line Specifying a startfile
119 DataModel SQL files
154 Experts Objects created by the object experts
260 Export QuattroPro 9, .QPW format
89 Field - Combo When the list does not fit in the form
107 Field object Property Font.Size
100 Field object Property NextTabStop
561 Field object Format property
273 Field object LineSpacing property
274 Field object Alignment property
217 Field object Fit Width property
159 Field object Formatting a timestamp field
108 Form Publish to Html
216 Form / Report Version Compatibilty
24 Form / Report Version Compatibilty
45 Form / Report Changing Style Sheet in a form
292 Form design Tab order and multirecord objects
692 Graphic Magnification property
140 Graphic Aquire Image
234 Import Spreadsheet ranges
239 Import Importing dates from Excel
80 Import Fixed length import
243 Installation SpellChecker
242 Installation AliasManager and .cfg files
244 Installation PageSetup. Paper size in inches.
251 Keyboard shortcuts CTRL+SPACEBAR
86 List object DataSource property
133 Local SQL Update table containing memo field
165 Local SQL Updating formatted memo
185 Local SQL Live Query View
267 Locate dialog Advanced pattern match
75 Locate dialog Using Wildcards
97 Nationalized Windows Format - Date
103 Nationalized Windows ProjectViewer
153 Nationalized Windows Installation
98 Open Table dialog Remote databases
245 ProjectViewer Refresh of object lists
36 Query Table with 255 columns
161 Query Live Query View
192 Query Setting: Table Update Handling
28 Query Selecting two tables
72 Query Translating a Qbe to Sql
642 Query Specifying a selection
71 Query Translating a Qbe to Sql
649 Query Timestamp and time columns
138 Remote SQL Sybase: CT Library - temporary tables
258 Report Summary scope on single-table reports
91 Report Table Frame - Detach Header
663 Report Margins.Right
33 Report PublishAs Html
186 Report Defining Group bands
285 Restructure Memo and formatted memo fields
293 Statusbar Customizing statusbar
417 Table Copy to remote database
687 Table add
420 Table Column names
270 Table Referential integrity
276 Table Editing a table
694 Table Language drivers for Paradox tables
180 Table Hyperlink
669 Table Password
49 Table Structure dialog Changing a Secondary index.
93 Table Structure dialog Picture Validity check
35 Table Structure dialog dBase table
95 TableRepair Referential integrity
10 TableRepair Password
645 Text object Property HotKeyTarget
106 Text object Property Font.Size
236 Toolbar Text formatting toolbar
176 Toolbar Text formatting toolbar
275 Toolbar Customizing toolbars
146 Visual Database Designer General


ObjectPAL

212 actionEvent type ActionSelectCommand constants
474 actionEvent type ActionEditCommands constants
673 actionEvent type ActionEditCommands constants
423 actionEvent type actionClass() example
32 ActiveX - VCR Programming the buttons
667 ActiveX - WebServer nCookies property
131 ActiveX - WebServer Active property
162 ActiveX objects VCR and WebServer
623 addinForm type isMaximized()
424 anyType type view() example
189 anyType type blank()
188 anyType type isBlank()
300 anyType type trace() proc
304 Application type setIcon() method
652 Array type Maximum size of an array
177 Basic syntax Assigning strings to field & textobjects
627 Basic syntax Referencing content of fieldobjects
87 Basic syntax Values returned from a custom method
169 Basic syntax Object self
20 Basic syntax Naming objects in a form
254 Basic syntax Data types of properties
122 Basic syntax PXDLITE.INI
305 Binary type clipboardEnum() method
426 Binary type writeToClipBoard() example
429 Binary type writeToFile() example
428 Binary type size() example
691 built-in event methods newValue() event
681 Chart object YAxisName property
680 Chart object XAxisName property
184 Constants PrinterSizes constants
412 Constants PrintPreview constants
515 Currency type currency()
430 Currency type currency() example
232 Database type open()
432 Database type getMaxRows() example
306 Database type enumCapabilities() method
431 Database type beginTransaction() example
433 Database type setMaxRows()
677 Database type isTable()
60 Database type isTable()
313 dataTransfer type loadFromParadox() method
434 dataTransfer type appendAsciiVar()
81 dataTransfer type Fixed length import
701 dataTransfer type getDestType() example
316 dataTransfer type setUI() method
315 dataTransfer type setSourceFixedFieldInfo() method
314 dataTransfer type setSourceFieldInfo() method
261 dataTransfer type QuattroPro 9, .QPW format
233 dataTransfer type setSourceRange()
312 dataTransfer type isParadoxImport() method
311 dataTransfer type guessSourceType() method
238 dataTransfer type Importing dates from Excel
310 dataTransfer type getSourceFieldInfo() method
309 dataTransfer type enumSourceFieldInfo() method
308 dataTransfer type enumQAInfo() method
700 dataTransfer type getDestCharset()
441 dataTransfer type transferData() example
689 dataTransfer type setProblems()
435 dataTransfer type dlgImport() example
149 dataTransfer type setSource()
170 dataTransfer type setSourceStartRow()
436 dataTransfer type setSource()
437 dataTransfer type getDestDelimitedFields() example
438 dataTransfer type setSource()
439 dataTransfer type getSourceRange()
442 Date type date() example
317 Date type date() proc
511 Date type date()
443 Date type dateVal() example
512 Datetime type datetime()
658 Datetime type dow()
659 Datetime type doword()
449 Datetime type hour() example
135 Debugger Tracer
123 dynArray type Overview
451 errorEvent type reason() example
452 errorEvent type setReason() example
112 Event type eventInfo.setErrorCode()
453 Event type setErrorCode() example
592 Examples General issues
96 Field - ListBox Number of items in a listbox
6 Field object Property Scroll
289 Field object BlankRecord property
129 fileSystem type totalDiskSpaceEx()
455 fileSystem type findFirst() example
414 fileSystem type General information
128 fileSystem type freeDiskSpaceEx()
118 fileSystem type deleteDir()
282 fileSystem type freeDiskSpace()
43 fileSystem type getFileAccessRights()
55 fileSystem type totalDiskSpaceEx() example
462 fileSystem type isValidDir() example
461 fileSystem type isValidFile() example
456 fileSystem type findNext() example
693 fileSystem type enumFileList()
457 fileSystem type getDir() example
458 fileSystem type getDir()
459 fileSystem type setDir()
460 fileSystem type isDir() example
283 fileSystem type totalDiskSpace()
469 fileSystem type setWorkingDir() examples
467 fileSystem type setPrivDir() examples
466 fileSystem type windowsSystemDir() example
465 fileSystem type windowsDir() example
464 fileSystem type setPrivDir()
196 fileSystem type totalDiskSpaceEx()
291 Form type bringToTop()
99 Form type isMaximized()
679 Form type dmAddTable()
471 Form type dmGet() example
116 Form type Property DesktopForm
318 Form type isDelivered() method
319 Form type setIcon() method
478 Form type writeText()
477 Form type isMaximized() example
476 Form type getSelectedObjects() example
475 Form type stringListRefresh() example
472 Form type dmGetProperty() example
470 Form type attach() example
183 Form type formCaller()
644 Form type getProtoProperty()
422 Form type show()
650 Form type formCaller()
160 Graphic type writeToFile()
158 Graphic type writeToFile() creating jpg
668 Graphic type readFromFile()
661 Graphic type readFromClipboard()
141 Graphic type readFromFile()
207 keyEvent type isAltKeyDown()
206 keyEvent type isControlKeyDown()
480 keyEvent type isFromUi() example
481 keyEvent type setShiftKeyDown() example
482 keyEvent type setAltKeyDown() example
479 keyEvent type setControlKeyDown() example
621 Keywords switch example
284 Keywords Uses
109 Keywords scan keyword
79 Keywords try - onFail
622 Keywords quitloop example
641 Keywords Uses
82 Keywords for - loop
44 Keywords Const
483 Library type close() example
320 Library type isDelivered() method
297 List object DataSource property
502 longint type isBitSet() example
144 longInt type Assigning a hex constant
321 longInt type hiWord() method
322 longInt type loWord() method
610 Mail type getAttachment() example
611 Mail type getAttachmentCount() example
614 Mail type getSender() example
323 Mail type addDataDlg() method
612 Mail type getMessage() example
613 Mail type getMessageType() example
615 Mail type getSubject() example
485 Memo type memo() example
487 Memo type writeToClipboard() example
286 Memo type Using sizeEx() on a memo variable
676 Memo type Memo type
488 Menu type All examples
489 Menu type setMenuChoiceAttributeById() example
248 Menu type Example on building menus
102 Menu type setMenuChoiceAttribute()
101 Menu type setMenuChoiceAttributeById()
247 Menu type menuChecked
155 Menu type setMenuChoiceAttribute() example
156 Menu type setMenuChoiceAttributeById()
674 menuEvent type menuCommand constants
491 menuEvent type isFromUi() example
490 menuEvent type id() example
130 menuEvent type Builtin menuconstants
330 mouseEvent type setAltKeyDown() method
492 mouseEvent type isLeftDown() example
329 mouseEvent type isAltKeyDown() method
493 mouseEvent type isMiddleDown() example
494 mouseEvent type isRightDown() example
495 mouseEvent type setMousePosition() example
262 mouseEvent type setInside() example
350 MSWindow type maximize() method
351 MSWindow type minimize() method
349 MSWindow type isVisible() method
348 MSWindow type isMinimized() method
347 MSWindow type isMaximized() method
352 MSWindow type setPosition() method
353 MSWindow type setText() method
355 MSWindow type show() method
356 MSWindow type windowHandle() method
354 MSWindow type setTitle() method
336 MSWindow type bnInfo() method
345 MSWindow type hide() method
344 MSWindow type getTitle() method
343 MSWindow type getText() method
342 MSWindow type getPosition() method
341 MSWindow type enumWindowNames() method
339 MSWindow type enumProperties() method
338 MSWindow type cbInfo() method
337 MSWindow type bringToTop() method
346 MSWindow type isIconic() method
331 MSWindow type attach() method
288 MultiRecord object BlankRecord property
104 Nationalized Windows Menu Window
413 Notebook object CurrentPage property
139 Number type number type
357 Number type number() proc
514 Number type number()
137 ObjectPAL Editor Global Search
214 ObjectPAL Editor Object Listbox
94 ObjectPAL QuickLookup BrowserOption constants
620 oleAuto type unregisterControl() example
619 oleAuto type openObjectTypeinfo() example
618 oleAuto type openTypeInfo() example
117 oleAuto type invoke()
703 Page object size property
208 popupMenu type show()
240 popupMenu type addText()
698 Query type checkField()
65 Query type removeTable() example
290 Query type Keywords in a query variable
88 Query type CheckPlus - CheckDescending
197 Query type getAnswerName()
190 Query type setQueryRestartOptions()
699 Query type insertTable()
672 Query type executeQbe()
547 Query type getTableId() example
548 Query type insertTable() example
550 Query type readFromString() example
551 Query type removeCriteria()
552 Query type removeCriteria() example
47 Query type setAnswerFieldOrder()
358 Query type dump() method
359 Query type enumFieldStruct() method
46 Query type Tilde variable
23 Query type setLanguageDriver()
179 Report type moveToPage()
690 Report type print() example
498 Report type load() example
361 Report type isDelivered() method
496 Report type enumUiObjectNames() example
362 Report type isPrintPreview() method
249 Report type reportPrintInfo variables
363 Report type printPreview() method
664 Report type Property Margins.Right
365 Script type isDelivered() method
500 Script type create() example
419 Session type getAliasProperty()
418 Session type enumAliasLoginInfo()
366 Session type convertFieldInfo() method
14 Session type addAlias()
299 Session type removePassword()
501 Session type saveProjectAliases() example
634 Sql type executeSql()
215 Sql type writeSql()
191 Sql type setQueryRestartOptions()
503 Sql type setQueryRestartOptions() example
505 Sql type readFromString() example
163 Sql type createAuxTables()
120 Sql type executeSql()
506 statusEvent type statusValue() example
508 String type Virtual key codes
507 String type chr() example
705 String type searchEx()
643 String type chr()
704 String type search()
702 String type advMatch()
509 String type chrToKeyName()
510 String type format() example
626 String type upper()
706 String type format()
296 String type readFromClipboard()
373 String type soundEx() method
372 String type reverse() method
371 String type readFromFile() method
370 String type isURL() method
369 String type isEmailAddress() method
368 String type flipCase() method
367 String type breakApart() method
374 String type writeToFile() method
266 String type advMatch()
58 String type isEmpty()
171 String type string() procedure
115 String type match()
90 String type advMatch()
376 Stringlist type isEmpty() method
377 Stringlist type view() method
375 Stringlist type isAssigned() method
516 Stringlist type attach() example
697 System type execute()
41 System type fileBrowserEx()
157 System type runExpert()
151 System type tracerWrite()
655 System type fileBrowserEx()
241 System type sound()
656 System type fail()
237 System type sysInfo()
148 System type readEnvironmentString()
175 System type sendKeys()
530 System type searchRegistry()
121 System type setRegistryValue()
670 System type printerSetOptions()
126 System type fileBrowserEx()
127 System type fileBrowser()
662 System type errorshow()
147 System type isTableCorrupt()
535 System type sound() example
534 System type setRegistryValue() example
533 System type sendKeysActionId() example
532 System type sendKeys() example
531 System type searchRegistry() example
517 System type enumFonts() example
529 System type readProfileString()
528 System type readEnvironmentString() example
527 System type printerGetInfo() example
526 System type getRegistryValue() example
525 System type formatSetDateDefault() example
524 System type formatGetSpec() example
523 System type errorLog() example
522 System type errorCode() example
521 System type enumRegistryValueNames() example
520 System type enumRegistryKeys() example
519 System type enumPrinterForms()
684 System type enumDesktopWindowNames()
398 System type recorderStart() proc
390 System type printerGetType() proc
391 System type projectViewerIsRestricted() proc
392 System type projectViewerRefresh() proc
393 System type projectViewerRestrict() proc
394 System type projectViewerUnRestrict() proc
395 System type recorderContinue() proc
396 System type recorderFlush() proc
397 System type recorderPause() proc
389 System type printerGetPaperSizes() proc
399 System type recorderStop() proc
400 System type resetCompileInformation() proc
401 System type sendKeysFromFile() proc
402 System type sendKeysSpeed() proc
403 System type setNewShell() proc
404 System type setRegistryValue() proc
405 System type SQLupdates() proc
406 System type startUpTime() proc
187 System type enumPapersources()
181 System type fileBrowserEx()
381 System type enumFontStyles() proc
625 System type setGlobal() and global()
281 System type errorMessage()
34 System type enumPrinters()
378 System type addKeys() proc
379 System type compilerTimeInfo() proc
380 System type enumFontSizes() proc
388 System type printerGetLayout() proc
383 System type getRegistryValue() proc
384 System type isAltKeyDown() proc
385 System type isControlKeyDown() proc
386 System type isShiftKeyDown() proc
382 System type errorIsTrapOnWarnings() proc
387 System type openSQLEditor() proc
671 Table type create keyword
225 Table type enumSecStruct()
210 Table type restructure()
675 Table type Language drivers for Paradox tables
209 Table type restructure()
202 Table type nRecords()
167 Table type restructure()
168 Table type protect()
219 Table type cCount()
624 Table type create keyword
182 Table type create keyword
647 Table type isEmpty()
211 Table type restructure()
538 Table type createIndex() example
280 Table type empty()
57 Table type rename() example
59 Table type isTable()
15 Table type compact()
415 Table type copy() to remote database
252 Table type restructure()
407 Table type addRefInt() method
69 Table type setRange()
536 Table type copy() example
537 Table type create keyword example
37 Table type add()
277 Table type restructure()
539 Table type enumSecStruct() example
540 Table type isShared()
541 Table type setReadOnly() example
542 Table type sort keyword example
543 Table type subtract() example
409 Table type addValCheck() method
685 Table type add()
287 TableFrame object BlankRecord property
136 TableFrame object Property CurrentColumn
194 tableView type TVHeading object
193 tableView type TVData object
497 tableView type wait()
201 tCursor type nRecords()
3 tCursor type isEmpty()
74 tCursor type attach(tcursor)
67 tCursor type cMax()
172 tCursor type locate()
54 tCursor type add()
646 tCursor type isEmpty()
164 tCursor type locateNext()
63 tCursor type qLocate()
68 tCursor type setRange()
657 tCursor type update()
665 tCursor type locate()
73 tCursor type add()
686 tCursor type add()
84 tCursor type forceRefresh()
77 tCursor type locatePattern()
416 tCursor type copy() to remote database
560 tCursor type getIndexName() example
565 tCursor type home() example
553 tCursor type atFirst() example
554 tCursor type atLast() example
555 tCursor type copyToArray() example
556 tCursor type createIndex() example
557 tCursor type enumRefintStruct() example
558 tCursor type fieldUnits2() example
559 tCursor type getGenFilter() example
226 tCursor type enumSecStruct()
562 tCursor type insertBeforeRecord() example
563 tCursor type insertAfterRecord() example
564 tCursor type insertRecord() example
571 tCursor type type() example
570 tCursor type setRange()
569 tCursor type locatePrior() example
568 tCursor type isValid() example
567 tCursor type isShared()
566 tCursor type isInMemoryTcursor() example
279 tCursor type empty()
268 tCursor type locatePattern()
218 tCursor type cCount()
228 tCursor type cancelEdit()
111 textStream type writeString()
688 textStream type readLine()
450 Time type time() example
513 Time type time()
695 Toolbar type disabling toolbar buttons
265 Toolbar type Bitmap constants
545 Toolbar type setPosition()
546 Toolbar type getPosition()
544 Toolbar type setPosition() example
198 Tutorial Wrong directory mentioned
142 Twain type aquire()
271 uiObject type LineSpacing property
76 uiObject type locatePattern()
411 uiObject type setOCXWantKeys() method
499 uiObject type create()
227 uiObject type getRgb()
272 uiObject type Alignment property
56 uiObject type cancelEdit()
70 uiObject type setRange()
269 uiObject type locatePattern()
666 uiObject type locate()
696 uiObject type bringToFront()
124 uiObject type switchIndex()
221 uiObject type attach()
83 uiObject type setGenFilter()
220 uiObject type setPosition()
114 uiObject type enumFieldNames()
593 uiObject type menuAction() example
605 uiObject type setTimer() example
200 uiObject type nRecords()
588 uiObject type getHtmlTemplate() example
589 uiObject type locateNextPattern() example
590 uiObject type locatePriorPattern() example
591 uiObject type lockRecord() example
609 uiObject type view() example
608 uiObject type recordStatus() example
607 uiObject type priorRecord() example
606 uiObject type postRecord() example
195 uiObject type insertAfterRecord()
604 uiObject type setPosition() example
603 uiObject type postAction() example
602 uiObject type sendToBack() example
601 uiObject type nRecords() example
600 uiObject type nextRecord() example
599 uiObject type lockStatus() example
598 uiObject type moveToRecord() example
597 uiObject type moveToRecNo() example
596 uiObject type mouseRightUp() example
595 uiObject type mouseRightDown() example
594 uiObject type mouseRightDouble() example
173 uiObject type locate()
572 uiObject type atFirst() example
648 uiObject type isEmpty()
573 uiObject type atLast() example
574 uiObject type bringToFront() example
576 uiObject type cancelEdit() example
577 uiObject type copyToArray() example
578 uiObject type deleteRecord() example
579 uiObject type edit() example
587 uiObject type enumSource() example
580 uiObject type end() example
178 uiObject type attach()
581 uiObject type getRange() example
582 uiObject type insertBeforeRecord() example
583 uiObject type insertRecord() example
584 uiObject type isEmpty() example
585 uiObject type getPosition() example
586 uiObject type killTimer() example


Runtime

264 Files required Objects created by experts
660 Installation Silent installation
152 Nationalized Windows Installation
295 ProjectViewer ProjectViewer
125 TableRepair Files required
263 Unavailable features PublishAs



Interactive

Interactive---ActiveX objects

105 sendToBack() / bringToFront()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

If you place a progressbar (or any other Paradox ActiveX object) directly below a native Paradox Combo field, the Combo field drop down list gets covered by the ActiveX.

ActiveX objects are always in front.

WorkAround:
Use the Visible property to hide/show the object.

To index

Interactive---BDE

223 MS SQL Server
Buglist Id: Last tested in version: First seen in version:
10.0 P37.0 W95 P4

MS SQL Server can be configured to use Windows authentication or SQL authentication. The native MSSQL driver uses SQL Authentication by default unless the settings described below is applied as shown:

We need to blank out the default user name that is set in the BDE Administrator application for the native driver "MSSQL". It was set to "MYNAME" which would be sent to the database which would mess up the Windows Authentication process. By blanking this out, and not sending any user name or password at all when connecting, this seems to tell SQL Server to use Windows Authentication - and everything works!

As we discovered on another machine, it would not work unless the SQL client was set to use "Named Pipes" instead of "TCP/IP" in the SQL Server Client Network Utility. Then it used Windows authentication when supplied with a blank user name and password. If TCP/IP was used, it would still try to connect using a blank user name and password and would not use Windows Authentication.

Reported by: "David Petrie"
Date: 26 april 2006

My comment:
It's on the Alias tab in the Client Network utility, you have to change the Network library setting to Named Pipes.
 
My preferred solution is to use the SQL Server Odbc driver to connect to a MS SQL Server configured for Windows authentication.

To index

Interactive---BDE Administrator

78 SharedMemLocation - Win2000
Buglist Id: Last tested in version: First seen in version:
9.0 P49.0 P4

On Win2000, set SharedMemLocation in Bde Admin to 5BDE to make it possible to run two instances of Paradox 9.

Otherwise you'll get an error:
Could not initialize BDE: Shared memory conflict.


From: Liz
Date: Sun, 01 Sep 2002

On WinXP, according to Bill Todd on the BDE group, try setting SharedMemSize to 4096 and SharedMemLocation to 6BDE.


From: Lance Leonard
Date: 19 November 2002

Extract from http://bdesupport.com/errors.htm

Other values that may also help solve this issue on NT or Windows 2000 are: 1000, 7000, and 7F00. If none of these values resolve the issue, you may try 2000, 3000, 4000, etc. or any values in between the specified ranges below for each operating system:

     Windows 95/98: SHAREDMEMLOCATION = 9000 to FFFF
     Windows NT/2000: SHAREDMEMLOCATION = 1000 to 7F00



From: Bill Todd
Date: 22 March 2005
Try reducing the SharedMemSize to 2048 and then try different SHAREDMEMLOCATION.

To index

132 MinBufsize and MaxBufsize
Buglist Id: Last tested in version: First seen in version:
10.0 P21.0

The default values for MinBufsize and MaxBufsize have been too low ever since Paradox 1 for Windows. Increase them to at least 2048 and 16384, to prevent GPV errors when working in Paradox.

To index

653 Auto ODBC
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

BDE Administrator's help files says:
< Quote >
Setting AUTO ODBC to TRUE is no longer recommended because of the Virtual configuration mode setting. For more information, see Options dialog box.
< /Quote >

When Auto ODBC is False, the virtual aliases created by the BDE are not seen by Alias Manager in Paradox, even though those aliases are shown in BDE Administrator. With Auto ODBC=TRUE, BDE will create aliases seen by Paradox with the same name as the ODBC datasource.

To index

Interactive---Chart

682 XAxisName property
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95

To index

683 YAxisName property
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95

To index

85 Marker size
Buglist Id: Last tested in version: First seen in version:
PX002911 Build 233

In a XY chart, the series (lines) has a property Marker.Size. Even though you specify a size, the markers in the chart are sized in relation to the resulting number of x-value observations in the chart. To see the marker at all, you have to increase the Weight when the number of observation increases.

To index

92 Logarithmic Scale
Buglist Id: Last tested in version: First seen in version:
11 Build 233

If you set Y-Axis properties: Scale: Autoscale and Logarithmic the grid lines disappear. Uncheck Autoscale and select proper values for Y-axis - Scale: Low Value and High Value to get the grid lines.

To index

21 LeftWall Pattern on a 3D chart
Buglist Id: Last tested in version: First seen in version:
PX028911 Build 2337.0 W95

The pattern you set for the left wall of a 3D graph is ignored (in design, preview, and print)

To index

Interactive---Command line

256 Specifying a startfile
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

If you specify a startfile on the command line used to launch Paradox, ProjectViewer won't open, and neither will objects left open on the Paradox desktop when Paradox was closed down, be reopened.

Example:
C:\Program Files\WPO11\Programs\PDXWIN32.EXE -p c:\data\pdoxpriv\P7 -o c:\data\bde32cfg\idapiascii.cfg -w c:\data\pdoxapps\dodsorsaker applkonstant.fsl

To index

Interactive---DataModel

119 SQL files
Buglist Id: Last tested in version: First seen in version:
10.09.0 P4

Not all SQL files will be accepted for use in a DataModel. Especially, if you try to select the SQL file from another directory than the working directory.

Reported by: Carolyn Wendover
I also tried building the report fresh with my SQL file in the other directory. I can see the file when I am in the data model builder, but it will not let me select it. The only way I got it to work was to have the SQL file in my work directory. I do not want that in my production version since it can get overwritten by another user.

Explanation:
The SQL file has to be created based on an alias. If you don't actively specify an alias, you get :work:, and then you cannot use it from a different working directory.

Open the SQL file in the SQL editor. The title of the window should say: :Sample:Px0306. If it says :WORK:Px0306, it has be used from the directory where it was created.


Reported by: LARRY DIGIOVANNI
Date: 11 April 2005
SQL files based on non standard databases cannot be selected for use in the data model at all.

Tested in all 32 bit versions of Paradox with BDE 5.2.

To index

Interactive---Experts

154 Objects created by the object experts
Buglist Id: Last tested in version: First seen in version:
10.0 P2

PARADOX RUNTIME ISSUE

Objects created by the object experts may contain code referencing files in Experts directories, eg Memo field with popup edit window.

When using these experts to create objects to be used in Paradox Runtime, you have to change the code so it doesn't contain a reference to expertsDir() and maybe you have to copy the referenced form to your application.

To index

Interactive---Export

260 QuattroPro 9, .QPW format
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

Exporting to QP9 was never implemented in Paradox 9, something about too many problems parsing the data so it was pulled to allow releasing the product.

Reported by: Steve - Corel
Date: 10 October 2000


Neither Paradox 10 or 11 allows export to QuattroPro 9 - QPW format. Only the the QuattroPro 7-9 - WB3 format is supported in export.

To index

Interactive---Field - Combo

89 When the list does not fit in the form
Buglist Id: Last tested in version: First seen in version:
11 Build 2331.0

A drop down list have the bad habit of showing the drop down list as a part of the form , so that if the form is too small to contain all the list, the list is clipped to the border of the form.

To index

Interactive---Field object

100 Property NextTabStop
Buglist Id: Last tested in version: First seen in version:
10.0

When you, in Design mode, using ObjectExplorer, specify the property NexTabStop for a field in a tableframe to a field outside the frame, it is only applied to the first record in the table frame. To make it work for all records in the frame, you'll need ObjectPAL code.

To index

159 Formatting a timestamp field
Buglist Id: Last tested in version: First seen in version:
10.0 P210.0 P2

SUMMARY
If a timestamp field has a format with a different dateorder than the BDE setting for date, entering an incomplete timestamp value, the date will be formatted according to the BDE setting for date, and not according to the format specified for the field.


SETUP:
Table with a timestamp.
BDE setting for timestamp : YYYY-MM-DD hh:mm:ss
BDE Setting for date: YYYY-MM-DD

Format for field:
Dateorder: %D-%M-%Y
%D, %H:%M:%S

In the field, enter a value 01-02-03, which should be Feb 1 2003, and leave the field. You'll get Feb 3, 2001.

Enter a value 01-02-2003, and you can't leave the field.

Enter a value 2003-02-01, and you'll get Feb 1, 2003.

To index

107 Property Font.Size
Buglist Id: Last tested in version: First seen in version:
11 Build 233

To index

273 LineSpacing property
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

To index

274 Alignment property
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

To index

217 Fit Width property
Buglist Id: Last tested in version: First seen in version:
PX033010.0 P35.0

According to help files
< Quote >
You can instruct Paradox to expand objects in a report horizontally to show all of their contents when you run the report. Right-click an object in a Report Design window and choose Properties. Enable the Fit Width check box on the Run Time property page.
The result depends on the type of object.
< /Quote >

In the text that follows, nothing is said on OLE objects. It looks like OLE objects ignore FitWidth, and only relies on Magnification.

To index

561 Format property
Buglist Id: Last tested in version: First seen in version:
11 Build 300

When using formats DBDate, DBNumeric, DBTimestamp, and DBTime as formats in your forms and reports, the format defined is the one you as developer have in your Bde Administrator. This format will be saved with the form/report and applied when form/report is opened by the user.

If the users BDE settings are different than yours, Paradox will create new formats named DBDate1,DBNumeric1, and so on for representing the formats you defined.

When using the Windows formats Windows Short Date, Windows #, Windows $, Windows Time, and Win.DateStamp, your settings are not saved. The format is retrieved from the user's Windows configuration.


Help Topics - index - Formats

To index

Interactive---Form

108 Publish to Html
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0

Running a form, File | Publish To Html is no longer available, but the Help files still contains references to the feature.

< Quote >
1 With a form open, click File Publish to HTML.
2 Type a filename in the File name box.
3 Choose .HTM from the Save as type list box.
4 Click Save.

Paradox saves an HTML version of your form that can be viewed by a Web browser. The Corel Web Servers are case-sensitive, so make sure you note the exact filename used when saving documents for future reference.

 Notes

· Paradox automatically adds FORM METHOD and ACTION tags to any form published to HTML. By default, the FORM METHOD tag is set to POST and the ACTION is set to the Paradox form object's noise name (for example, #Form1). To set these properties yourself, change the HTMLMethod property or the HTMLAction property of the form using the Object Explorer.
· Paradox also adds a Submit button to static forms published to HTML. For the Submit button to work with the Corel Web Server Control, you must add code to trap the POST action in the OnPostRequest event.
< /Quote >

Since Paradox 10, only tables and reports can be published to Html.

To index

Interactive---Form / Report

24 Version Compatibilty
Buglist Id: Last tested in version: First seen in version:
PX031410.0 P29.0

-You can open forms created in Paradox 10 with a P10 style sheet in P9 without getting an error, but OTOH you cannot open them at all in previous versions.


-When converting forms with even the simplest code from Paradox 9 to an earlier version (8 or 7), you can get a message "Can not interpret file. It could be corrupt" in an error box that will not go away when you press OK. This happens when you use Paradox menus after an object has been selected in the form.

WorkAround:
Open form in Design mode. First thing you do, is to change the style sheet to one from P7 or P8.


-When designing for use in multiple versions, always use stylesheet from oldest version.


-Paradox 10 SP2:
Forms, Reports and Datamodels created in earlier versions can be opened and saved in Paradox 10, then re-opened in earlier versions (unless features from Paradox 10 are used).

To index

45 Changing Style Sheet in a form
Buglist Id: Last tested in version: First seen in version:
PX050411 Build 2335.04

Changing a form's style sheet doesn't dirty the form, e.g. DesignModified doesn't get set to TRUE.

Reported by: Lance Leonard
Subject: Paradox misbehaving...
Date: 24 March 2000

To index

216 Version Compatibilty
Buglist Id: Last tested in version: First seen in version:
PX062511 Build 23310.0 P2

SUMMARY:
Opening and then closing a form with Notebook object designed in a Paradox 9 or a previous version will give a message that the form is changed when being closed in P10 or later versions.


SETUP:
1. Start Paradox 8.
1.1 Open/New/Blank Form.
1.2 Put Notebook object on it.
1.3 Close and save the form as "nbForm.fsl".
1.4 Close Paradox 8
2. Copy "nbForm.fsl" to Paradox 10 :WORK:.
3. Open Paradox 10.
3.1 Open "nbForm.fsl".
3.2 Close the form.

Result:
Question "You have made changes... Do you want to save it?" appears.

Notes:
1. I haven't noticed problem while using other design objects.
2. Same problem I can recreate using P9 originated nbForm too.


Reported by:
From: Ivica Kolar


MY COMMENT:
DesignModified property is set to True when form is opened in design mode.

To index

Interactive---Form design

292 Tab order and multirecord objects
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

In a form with more than one table, the Design layout screen will allow you to select how the tables are to be shown. If master table is shown as multirecord object, the setting Nested is made available.

With nested objects, the detail table is placed inside the record object of the master mro, and the tab button will move between master and detail table.

With unnested obejcts, the detail table is placed outside of the master mro. Tab button will move inside the mro.

When creating the objects manually, you can choose to place the detail table in the mro itself as opposed to the record object. In this case the tab button will not leave the master table.

To index

Interactive---Graphic

692 Magnification property
Buglist Id: Last tested in version: First seen in version:
11 Build 41010.0

If you have two graphic images with the same size but with different resolutions, (dpi value) when inserted into a Paradox graphic object, the image with the higher resolution will be smaller than the other image.


I used Corel PhotoHouse to create two jpg files, one with 150 dpi and one with 68 dpi. Viewed at 100 % they have the same size, but viewed with zoom factor 1:1, the 150 dpi jpg is much smaller than the 68 dpi jpg. Paradox takes the size of the jpg with zoom factor 1:1.

According to the PhotoHouse help files:
"Zoom (100%) Displays the most accurate representation of the active image. Zoom 100% matches pixels in the image with screen pixels in the display.

Zoom 1:1 Displays the active image at its actual physical size"

Opening the two jpgs in Kodak Imaging, and selecting the Zoom "Natural Size" (translated from Swedish), I see the same effects as in Paradox. The 150 dpi jpg is smaller than the 68 dpi. Natural size represents a zoom factor 64% for 150 dpi and 141.5% for 68 dpi.

Help files explain it this way (translated from Swedish)
Natural size will adjust the picture so it is shown with its actual size, 1 cm in the picture is 1 cm on the screen.

Reported by: Bertil Isberg
Date: 20 September 2005

To index

140 Aquire Image
Buglist Id: Last tested in version: First seen in version:
10.0 P210.0

Paradox does not support 32 bit images, regardless if they are scanned in, or imported from files. With other topics such as graphics handling, 24bit scanned images can be saved to disk as .gif, .jpg to keep the filesize down.

...

Paradox is not capable of acquire 32bit graphic images to graphic objects or graphic field objects. If a 32bit image is acquired to one of these objects, the image will appear slanted or distorted. 32bit images can be acquired to a file successfully. In general, applications should not acquire images greater than 24bits to adhere to the limitations of Paradox.


REPORTED BY:
Paul Cronk

To index

Interactive---Import

80 Fixed length import
Buglist Id: Last tested in version: First seen in version:
PX041610.07.0 W95

If you do a fixed length import from a file with NULL characters in it (ASCII 00), you get an error of "Corrupt file - other than header" and the resulting table is blank.

To index

234 Spreadsheet ranges
Buglist Id: Last tested in version: First seen in version:
10.0 P39.0 P4

To index

239 Importing dates from Excel
Buglist Id: Last tested in version: First seen in version:
PX063911 Build 233

To index

Interactive---Installation

242 AliasManager and .cfg files
Buglist Id: Last tested in version: First seen in version:
PX068410.0 P310.0 P3

Paradox 10 in WPO2002 SP3
Win2000, Win95B

PROBLEM:
.cfg file has to be a registered extension

DESCRIPTION:
When saving the changes made in AliasManager, the cfg file will get an .ini extension. Idapi32.cfg will be saved as Idapi32.cfg.ini, and it won't be the file loaded next time Paradox is launched.

Problem is caused by .cfg not being registered in HKEY_CLASSES_ROOT. When registering it, the problem disappears.

[HKEY_CLASSES_ROOT\.cfg]
@="cfg file"
is enough

Paradox code to do it:

setRegistryValue( ".CFG", "", "cfg file", RegKeyClassesRoot )

This has been verified in Paradox 10 with WPO2002 SP3 installed running on Win2000 and Win95B.

P9 SP4 works without .cfg being registered.

To index

243 SpellChecker
Buglist Id: Last tested in version: First seen in version:
PX068110.0 P310.0 P3

Paradox 10 WPO2002 SP3

PROBLEM:
SpellChecker looks for an incorrect Registry key after installation of SP3.

[HKEY_LOCAL_MACHINE\SOFTWARE\AppMan\10\IAYG\Components\WTEnglish_Folder2\WordPerfect Office 2002 Professional::10]
"InstallDest"="C:\\Program Files\\Corel"


DESCRIPTION:
Open any table with an Alpha column. Move to that column. Enter edit mode. Select Tools | SpellChecker.


Reported by: Jack E. Wasserstein, DDS
Date: 21 September 2002

Verified by: Martin Ferwerda
Yep, broken for me also after sp3 on WinME.


WORKAROUND:
Add InstallDest to the registry key below

[HKEY_LOCAL_MACHINE\SOFTWARE\AppMan\10\IAYG\Components\WTEnglish_Folder2\WordPerfect Office 2002 Professional::10]
"InstallDest"="C:\\Program Files\\Corel"

Here's code to do it from inside Paradox

var
   st string
endvar

st=getRegistryValue( "Software\\Corel\\Appman\\10\\IAYG\\Components\\WTEnglish_Folder2\\WordPerfect Office 2002 Professional::10",
"InstallDest", RegKeyLocalMachine )
setRegistryValue( "Software\\Appman\\10\\IAYG\\Components\\WTEnglish_Folder2\\WordPerfect Office 2002 Professional::10",
"InstallDest", st, RegKeyLocalMachine )


For an OEM version of WP office the key is:
[HKEY_LOCAL_MACHINE\SOFTWARE\AppMan\10\IAYG\Components\WTEnglish_Folder2\WordPerfect Office 2002 OEM::10]

To index

244 PageSetup. Paper size in inches.
Buglist Id: Last tested in version: First seen in version:
PX061010.0 P210.0

Paradox 10, 11
Win2000

PaperSize is reported in inch even though ControlPanel - Measurement System is set to Metric.

Win2000 US version and Swedish version with Regional options set to Swedish.
Not in Win95B Swedish version.

Problem disappears when Registry setting PreferredLanguage is changed to SV
[HKEY_LOCAL_MACHINE\SOFTWARE\COREL\WordPerfect Suite\11]
"PreferredLanguage"="EN"

Change for appropriate version of the office suite.

To index

Interactive---Keyboard shortcuts

251 CTRL+SPACEBAR
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

When Ctrl+Spacebar doesn't invoke the Table Lookup dialog.


If you have installed Internet Explorer 4 with desktop enhancements on Win NT, the key combination Ctrl-Spacebar is no longer valid. Choose the command from the menu. If it works, this was the problem.

Reported by: Daniel Betschart
Subject: V9 Table Lookup Fails
Date: 21 February 2000


The "INTERNAT.EXE" International keyboard switcher took over the CTRL-SPACE key combo...
Reported by: Kasey Chang
Subject: NT Bug
Date: 4 April 2000

To index

Interactive---List object

86 DataSource property
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

Specifying the DataSource property for a list object in ObjectExplorer, by setting Table.ColumnName, the value does not stick. This is as designed. The value is used for a one time loading of the list, but it will not read the table every time the form is opened.

To index

Interactive---Local SQL

133 Update table containing memo field
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

Updating a table containing memo field using local SQL Update statement does not work as expected.

a) SQL Property setting "Generate auxiliary tables" interferes with the number of records updated

b) update tablename
set memo="value"
does not work.

WorkAround:
add where clause
where 1=1

c) update tablename
set memo="value"
where id < value
will run forever.
The upper boundary has to be closed like <=value.
This applies also when a range like
where id>value1 and id < value2
is used.


d) See also bug Px0386

e) See also WadId 165 on Formatted memo


SETUP:
Create a table Px0386c

id - I *
m1 - M 1
m2 - M 1
f1 - f 1

Add 20 records with id=1-20. Leave the memo fields blank. They will be updated in the examples.

Run a local sql. Generate auxiliary tables should be checked in the SQL properties dialog.

You have to reassign values to M1 and M2 now and then to be able to see the result.


1)
update px0386c
set m1="abc"
Only 16 records are updated.

2)
update px0386c
set m2="def"
where id>0
Only 16 records are updated

3)
update px0386c
set m1="bcd"
where 1=1
only 16 records is updated

Change the SQL properties to Fast query. Use this setting from now on.
1) still only 16 records
2) all records are updated.
3) all records are updated.



4)
update px0386c
set m1=m2
where id>0 and id<21
will run forever

5)
update px0386c
set m1=m2
where id<21
will run forever

6)
update px0386c
set m1=m2
where id<=20
is Ok

7)
update px0386c
set m1=m2
where id>=1 and id<=20
is Ok

8)
update px0386c
set m1=m2
where id between 1 and 20
is Ok

9)
update px0386c
set m1="zzz"
 where id in(1,2,3,4,5,6,7,8,
 9,10,11,12,13,14,15,16,17,18,19,20)
is Ok.

10)
This one is logged (Px0386)
update px0386c
set id=id
will wipe out data from memo columns for some records. Record 9 and later.


When running this from ObjectPAL, there is no sqlHandle.createAuxtables(No) for sql type. You can achieve this by adding a comment to the Sql statement like this

sqlHandle=Sql

/*
AuxTables: False
*/
Here goes you ordinary SQL statement
endSql

Problems have been verified by: Ivica Kolar

To index

165 Updating formatted memo
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

Updating a table containing formatted memo field using local SQL Update statement does not work. The table will be corrupted so you can't enter values in the formatted memo field using a table view.


SETUP:
Create a table Px0386c

id - I *
m1 - M 1
m2 - M 1
f1 - f 1

Add 20 records with id=1-20. Leave the memo fields blank. They will be updated in the examples.

Run a local sql. Check Fast Queries in the SQL properties dialog.

update px0386c
set f1="abc"
where 1=1
does not work.
You cannot update a formatted memo at all using Local SQL.

Result is corrupted table.
Entering Memo view on f1 field in table view gives:
"Error writing file. Record not tagged."

Problem has been verified by: Ivica Kolar

To index

185 Live Query View
Buglist Id: Last tested in version: First seen in version:
11 Build 233

According to the Paradox 10 Help files, Live Queries (SQL) , you should be able to create a Live Query View when the SQL statement contains an ORDER BY clause:

Single-table queries or views can be updated provided that

· there are no UNION, INTERSECT, or MINUS operations
· there is no DISTINCT keyword in the SELECT statement
· everything in the SELECT clause is a simple column reference or a calculated field, and no aggregation is allowed
· there is no GROUP BY or HAVING clause
· there are no sub queries that reference the table in the FROM clause and no correlated sub queries
· any ORDER BY clause can be satisfied with an index


I have not been able to create an live query view when there is an ORDER BY clause. My guess is that the last condition should have been: any ORDER BY clause is replaced by using an index for changing the sort order.


Reported by: Father Robert Bower
Date: July 22 2002

To index

Interactive---Locate dialog

75 Using Wildcards
Buglist Id: Last tested in version: First seen in version:
PX005310.05.04

There are problems when using the Locate dialog to find values that contains space or special characters like +, that can be used in Advanced Pattern Match.

Say you have a field that contains the value (inside the quotes) "aa + bb" and you want to do a locate pattern to find the value.

Try aa.. , aa .. , aa +.. , aa + b..

Add a \ before the + char and check the Advanced pattern match in the Locate dialog.

To index

267 Advanced pattern match
Buglist Id: Last tested in version: First seen in version:
11 Build 2334.5

To index

Interactive---Nationalized Windows

97 Format - Date
Buglist Id: Last tested in version: First seen in version:
10.0

This applies only to nationalized versions of Windows.

When selecting the date format Windows Long, there is a setting Case for the name of the Month. It has three choices: Mixed Case, Upper, Lower . The specification MixedCase is related to the Windows Standard, which in USA is Mixed Case, but in Sweden is lower case. You won't get Jan but jan.

To index

103 ProjectViewer
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

The Property menu for Paradox objects in ProjectViewer contains a menuitem SendTo (in Swedish = SkickaTill) with no functionality at all. The menuitem shouldn't be there. In a US version of Windows, it does not occur.

To index

153 Installation
Buglist Id: Last tested in version: First seen in version:
10.0 P2

Install: P10 does not follow Win98 localization.
Installing P10 to Win98 with CentralEuropean setup, DefaultFont/Script value is Western by default.
Steps:
1. Prepare clean Win98 setup for CentralEuropean area, Croatia for example.
2. Install and run Paradox 10.
3. Use Tools/Settings/Preferences and check Script value of Default font option.
Script is, by default, Western i.e. not CentralEuropean.

Workaround: User have to manualy correct Script value.


REPORTED BY: Ivica Kolar
Date: 10 March 2002

To index

Interactive---Open Table dialog

98 Remote databases
Buglist Id: Last tested in version: First seen in version:
PX002310.01.0

You can select multiple local tables in the Table | Open dialog. You can only select one from a remote database.

To index

Interactive---ProjectViewer

245 Refresh of object lists
Buglist Id: Last tested in version: First seen in version:
PX066611 Build 233

With Working directory on a network drive, saving a new form, it won't show up in ProjectViewer until Current directory is changed.

Changing the RefreshRate under Tools | Settings | Preferences from default value = 60 to 3, will cause ProjectViewer to refresh the object list almost instantly.

This happens when running Paradox on Win2000, and the file server is a Win2000 server.


Originally reported by: Wayne Sheppard
Subject: Paradox 10 project viewer
Date: 26 July 2001

To index

Interactive---Query

192 Setting: Table Update Handling
Buglist Id: Last tested in version: First seen in version:
10.0 P2

To index

71 Translating a Qbe to Sql
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

If you translate a QBE file to a SQL statement with the SHOW SQL button, the columnlist after SELECT seems to have a max limit of size. With 8-10 characters in each column name, I manage to get 92-93 columnames in the list. An estimated max length seems to 1026 characters give or take a few.

To index

72 Translating a Qbe to Sql
Buglist Id: Last tested in version: First seen in version:
PX020011 Build 2337.0 W95

When a QBE with a "NOT value" criteria is translated to SQL, you get Column<>value. The QBE condition will select blank values, but the SQL condition won't. To get the same result in SQL as in QBE, you have to change the code to NOT(Column=value).

To index

28 Selecting two tables
Buglist Id: Last tested in version: First seen in version:
PX036211 Build 2337.0 W95

When you create a new Query and select two tables from an alias to be included in the query, the alias will be resolved into a directory name. When selecting one table, the alias will be saved into the QBE file.

To index

36 Table with 255 columns
Buglist Id: Last tested in version: First seen in version:
PX046011 Build 2335.04

A Paradox table with 255 columns can be created and viewed, but you cannot create a query based on the table.

To index

161 Live Query View
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

The help files says on Live query view - QBE
< Quote >
The selection conditions you specify in the query must be capable of being expressed as a filter. This means the following query structures are not allowed:
....
Use of the ".." wildcard operator before selection conditions. Use of the .. wildcard operator after a selection condition is allowed, as in the example Canada.., and produces a case-insensitive answer set.
< /Quote >

But, with a trailing wildcard like in Canada.. , you won't get a live query view, only a query view with read-only fields.

The corresponding query translated to SQL will create a Live query view.

To index

649 Timestamp and time columns
Buglist Id: Last tested in version: First seen in version:
11 Build 3025.04

The following is from a Paradox TechInfo (slightly edited by Bertil Isberg)

Q: How do I query a time or timestamp field from the query editor?

A: To query a time or timestamp field, you must enter the time in military time (24 hours) and include seconds. In a timestamp field, the date must be entered before the time with a space in between the date and the time. This is true regardless of your settings in the BDE Administrator. Date should be formatted as DBDate format. Below are a number of examples where DBDate format is yyyy-mm-dd.

     1. Query all records where the time field value is exactly 1:30 in the afternoon.

          Query

          Table | TimeField |
                | Check 13:30:00 |

          EndQuery

     2. Query all records where the timestamp field value is exactly 2:22 in the afternoon on July 10, 1995.

          Query

          Table | TimeStampField |
                | Check 1995-07-10 14:22:00 |

          EndQuery

          Note that if times or timestamps are entered from ObjectPAL, internally the field will include milliseconds, so queries that match exact values are almost certain to fail because there is no way to enter milliseconds in a query.

     3. Query all records where the time field value was entered anytime in the 1 o'clock hour.

          Query

          Table | TimeField |
                | Check >=13:00:00, <14:00:00 |

          EndQuery

     4. Query all records where the timestamp field value was entered on July 10, 1995.

          Query

          Table | TimeStampField |
                | Check >=1995-07-10, <1995-07-11 |

          EndQuery

     5. Query all records where the timestamp field value was entered in July of any year.

          Query

          Table | TimeStampField |
                | Check ..-07-.. |

          EndQuery

          Please note that when you use wildcard characters as shown above, the month value you type in must match the date settings you have in the IDAPI32.CFG. If LEADINGZEROM is set to FALSE, the following query would return a result if you have data entered with a month of July in the timestamp field. However, if LEADINGZEROM is set to TRUE, the following query will not return a result if you have data entered with a month of July.

     6. Query all records where the timestamp field value is anytime today or before today.

          Query

          Table | TimeStampField |
                | Check
          EndQuery

          Note that today in a timestamp field means 12:00:00 AM today.

To index

642 Specifying a selection
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Even though almost all examples is showing selection conditions specified unqouted, you should get accustomed with quoting string values. Do NOT try to select AS400 or OR12 or NO23. Quote the strings like "AS400", "OR12", and "NO23". A selection AS400 won't select the string AS400, but rather all values and the resulting column will be named 400. OR12 and NO23 will cause syntax errors. Expression must be followed by an example element defined in a SET.

A selection condition consisting of a reserved word followed by digits will cause problems when used unquoted in a query.

To index

Interactive---Remote SQL

138 Sybase: CT Library - temporary tables
Buglist Id: Last tested in version: First seen in version:
PX017910.07.0 W95

Sybase System 10 on a Windows NT.

Connecting from Paradox 7 for Win95 - patch 4 and Delphi 2.01 through BDE 3.50 and SqlLink 3.50. Using the CT-library connection.

SQL statement:

select Komkod
into #diffbnp
from dbo.nlivrest
where Ar=1991

gives an peGeneralSQL error both in Paradox 7 for Win95 patch 4 and Delphi 2.01 SQL Explorer.

#diffbnp is a Sybase temporary table.


BDE: 13059 $33 $3
ct_cursor(CLOSE): user api layer: external error: A cursor must be opened before this command type can be initialized.
Server error: 171


Both a 32 DB-library and an 32 ODBC driver connection run without problems.

16 bit CT library creates an error when tested with Paradox 5.
16 bit DB library is Ok.


WORKAROUND:
Source: BDEFAQ

SELECT INTO statment returning error "ct_cursor(CLOSE); user api layer: external error: A cursor must be opened before this command type can be intialized." What is wrong and how do I get around the problem?

Answer:
The Sybase CTLIB client will always parse a passthrough sql statement wheather or not we (Delphi, BDE, SQL Links, etc.) issue an 'open' or 'exec'. If a SELECT is found to be the FIRST word, it (Sybase CTLIB) will try to create a cursor hence the error message. There is a workaround. Place a comment in front of the SQL text like so:
CHANGE
select * into #temptable from oldtable
TO
/**/select * into #temptable from oldtable

To index

Interactive---Report

91 Table Frame - Detach Header
Buglist Id: Last tested in version: First seen in version:
11 Build 233

When you detach the header from a table frame in a report, and the frame contains a calc field, the Fit Width property for that column won't stick. It is changed when report is run and when the report is opened in design mode again the property is changed to False.

To index

186 Defining Group bands
Buglist Id: Last tested in version: First seen in version:
11 Build 233

When defining multiple group bands in a report and you want to to use ranges for one of the group bands, only the inner group can have a range. This is not mentioned in the help files.

To index

33 PublishAs Html
Buglist Id: Last tested in version: First seen in version:
PX038110.08.0 P1

Filters are ignored when a report is published as Html.

Calculated fields does not work.

Other stuff that are not supported (for whatever reason): The BC/AD Era part of dates, formatting info on formatted memo fields, OLE, binary and bytes fields, line, elipse, OLE, ActiveX, charts, and crosstab objects.

The name of the html file saved, cannot contain spaces.

Publish As ... spreadsheet as QuattroPro, Excel, and Lotus, works best from a tabular report. If report contains group bands, you'll get a spreadsheet tab for each group. (not for Excel)

WorkAround:
As a workaround for the filter problem, you can use a query to select the records and base the report on the answertable (or the query)

To index

258 Summary scope on single-table reports
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0 P4

Help file says
< Quote >
When you place summaries in a single-table report, location affects the scope as follows:

·Corresponding band headers and footers calculate to the same value. This means you can place a summary in either the report header or report footer and get the same result. Likewise, a calculation in either the page header or page footer yields the same result.
·In a table frame, the scope of the calculation is over records in the table (if it is a detail table, the scope is all records in the detail set).
·In a report band (either the header or the footer area), the scope of the calculation is all values contained by the report band - all records for the table.

·In the page band (either the header or the footer area), the scope of the calculation is all values contained by the page band - all records on the page.
·In a group band (either the header or the footer area), the scope of the calculation is all values contained by the group band - all records for the group.
< /Quote >

The meaning of 'Contained by' is not obvious.

If a record is split on two pages, Last will not give you the last value on the page, but the value of the last record completed on the page. First is the first record on a page even if it is continued from a previous page.

Note: In Paradox 7.32 SP4, Last is the last record even when it is continued on next page, but First is the first record started on the page.

To index

663 Margins.Right
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

You cannot change the Margins.Right property for a report in ObjectExplorer. The value will be revoked as soon as you leave the setting.

The only way to change the right margin interactively is through the PageSetup dialog.

To index

Interactive---Restructure

285 Memo and formatted memo fields
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Changing the datatype for a column from Memo to Formatted memo will cause problems with the contents of column. Afterwards all records are considered to be not blank when selecting records using QBE or SQL.

If you have to change the datatype for a memo, add a new column with datatype formatted memo.
Use ObjectPAL to copy the contents of the memo field to the formatted memo field. Code shown below.
Drop the memo column.
Rebuild the table.

var
   tc tcursor
   m memo
endvar

tc.open("fmproblem")
tc.edit()
scan tc:
   m=tc."memofld"
   tc.fmemofld=m
   tc.unlockrecord()
endScan
tc,endEdit()
tc.close()


Originally reported by: "Ian Espie"
Date: 20 August 2003

To index

Interactive---Statusbar

293 Customizing statusbar
Buglist Id: Last tested in version: First seen in version:
11 Build 3009.0 P4

Statusbar contains two parts, the first line - statusbar - and the second line - the applicationbar or the document/task switcher. With ObjectPAL, you can hide and show the second line by using the method showApplicationBar(yes/no).

When customizing the statusbar, the document switcher is not one of the items shown as part of the statusbar. If you remove it by dragging it off the statusbar, you can get it back by right clicking the statusbar, selecting Reset statusbar.

You can move the document switcher to the statusbar as described below:
Right click on the status bar and select "Customize".
Then drag the document switcher from the bottom line of the status bar to the top line.
Next drag the other items off the top line of the status bar (Or leave on if you want).
Next, right click on the status bar again and select "Size | One Line". The original task switcher line will disappear (along with the NUM | SCROLL | INSERT) and leave the task switcher line all by itself.

Originally reported by: Greg Johnson
Date: 21 July 1999


Warning:
When I tested having document switcher on the first and only line of the statusbar in Paradox 9 , and 11, Reset Statusbar produced lots of GPVs and Runtime Error 216. See Buglist PX0722.

To index

Interactive---Table

417 Copy to remote database
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

To index

420 Column names
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Even though column names beginning with a digit is allowed in tables, and in QBE, Local SQL requires such column names to be quoted. Otherwise you'll get an error: Invalid use of keyword.

Nothing is said at all in the help files on column names beginning with a digit.

Example that works:

INSERT
INTO DI0420 (DI0420."3digcode")
VALUES ('123')

You can not use a correlation name in this case.


Originally reported by: "Dave James"
Date: 3 November 2003

To index

669 Password
Buglist Id: Last tested in version: First seen in version:
11 Build 3021.0

Help topic: Restructure Paradox Table dialog box covers passwords. Nothing is said which characters that can be used in a password. My recommendation is to use characters lower than Ascii 128 as those characters are independent on the system language driver. A password containing characters in the range 128-254 is not guaranteed to work with a different system language driver than the one used when password was created.

To index

687 add
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

When you add data from a local table to a non Paradox table, the update parameter does not work. You'll get a message: Cannot Update dBASE or Server tables. Do you wish to just append records?

See also: see ObjectPAL - Table type - add(). WadId 685.

To index

694 Language drivers for Paradox tables
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

The list of available drivers does not contain the US default, 'ascii' ANSI which has the internal name DBWINUS0

To index

270 Referential integrity
Buglist Id: Last tested in version: First seen in version:
Bde 5.0Bde 3.0

BDE Limitation - Referential Integrity:
The length of a string identifying the full path to the tables using referential integrity is 81 characters. If the tables using referential integrity have a length of more than 81 characters, you will get an error message: "Invalid file name" and the referential integrity link will fail.

To index

276 Editing a table
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

If you copy a _column_ of text, enter an empty Paradox _9_ table view of a table with two alpha fields, in edit mode, and then paste, it creates one record for each line of text, in whichever of the two fields you were in when you pasted. This does not work in Paradox 8 - you get a single record with the first line of text only. In Paradox 9, if you copy TWO columns of text (comma delimited, two fields per line), and paste it in as above, the text gets pasted into whichever of the two fields yoo were in; it does not paste it into the two separate fields. (My comment 2000-06: Tab-separated is Ok, but not comma-separated.)

In version 9, if you highlight two columns of another Paradox table, copy, and paste into a two column table, it pastes the data into two columns - the one you're in when you paste and the next to the right; if there aren't enough columns to the right it fails with a message to that effect.

Reported by: Steve Caple
Subject: Paste New Records?
Date: 10 July 1999

To index

180 Hyperlink
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

Help files says:

< Quote >
To insert a hyperlink in a field

Type the URL in an alpha field.
< /Quote >


But if the URL e g is paradoxtips.free.fr the hyperlink won't work. You have to add the protocol http://paradoxtips.free.fr

Same problem arises if an email address contains a dot before the @ character, e g bertil.isberg@nospamscb.se is not accepted, but mailto://bertil.isberg@nospamscb.se is.

To index

Interactive---Table Structure dialog

35 dBase table
Buglist Id: Last tested in version: First seen in version:
PX045911 Build 2339.0

When I try to restructure or do an Info-structure on a Dbase for Windows table using Paradox 9, I get the following error message:
The maximum number of fields for this table has been reached, no more can be added.

The table does have more than 255 fields, but Dbase can handle that. I do the restructure in Paradox 8 just fine.

Reported by: Mark Anderson
Subject: Error when restructuring Dbase IV table
Date: 29 November 1999

To index

49 Changing a Secondary index.
Buglist Id: Last tested in version: First seen in version:
PX054411 Build 2339.0 P4

If you have a table with an existing compound secondary index, you can change order of the columns in the index using the Up and Down arrow in the Restructure dialog - Secondary index tab, but the change is not saved when you press the Save button.

To save changes of the order of the columns in a compound secondary index, you have to remove a field and add it back.

Reported by:
From: Mark Bannister
Subject: Re: How difficult can Paradox be?
Date: 13 November 2000

To index

93 Picture Validity check
Buglist Id: Last tested in version: First seen in version:
10.0

ChangeTo queries and SQL Update statements ignore a Picture validity checks specified in the table.

The Picture validity check will only prevent illegal values while editing records one by one through a table, a form or ObjectPAL code (tcursor), not while using set oriented updates.

WorkAround:
Use a lookup table instead.

To index

Interactive---TableRepair

95 Referential integrity
Buglist Id: Last tested in version: First seen in version:
PX015510.01.0

When a master table in a RI relation is repaired, the copy of the table still contains references to the child tables. You cannot remove those references inside Paradox, only by deleting the Val file. As a consequence, the copy of the master table can not be deleted inside Paradox unless you first delete the VAL file.

To index

10 Password
Buglist Id: Last tested in version: First seen in version:
PX016410.07.0 W95

Rebuilding a table with Table Repair strips auxilary passwords.

To index

Interactive---Text object

106 Property Font.Size
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

You can not specify a Font size larger than 72. In P7, you could use ObjectExplorer to get larger sizes.

To index

645 Property HotKeyTarget
Buglist Id: Last tested in version: First seen in version:
11 Build 30210.0

Text objects got a new property HotkeyTarget in P10. The property is used by Paradox to create hotkeys for objects. You define a hotkeycharacter by adding the & character in front of the letter you want to be the hotkey. HotkeyTarget property is defined by Paradox when the object is placed on the form but won't have any effect until the hotkeycharacter is entered in the text.

Help files does not mention that the hotkey functionality ignores the TabStop property. Focus will be moved to an object even though TabStop is unchecked.

To index

Interactive---Toolbar

176 Text formatting toolbar
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT9.0 P3 RT

Text formatting toolbar is not available in Paradox Runtime. The missing feature is not mentioned in the Paradox Runtime Developers Help.

Neither can you activate the toolbar using
winPostMessage(app.windowhandle(),winGetMessageID("WM_COMMAND"),7903,0)

To index

275 Customizing toolbars
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

Below are two methods to customize toolbars interactively described. Both methods can be used without being in Customize toolbar mode entered by the Customize button in the View | Toolbars dialog.

1)
To add a separator: Hold down the Alt key while you Drag a toolbar button a little to the left or right. This requires a little training but really is very easy.

Reported by: Michael Juul Hansen
Date: 3 September 1999


2)
User can easily move/copy any button between toolbars in v9. More below:

* To move a button from one toolbar to another, simply depress the Alt key and drag the icon from one toolbar to another
* To copy a button from one toolbar to another, simply depress the Ctrl + Alt keys and drag the icon from one toolbar to another

Reported by: Ken Wong - Corel
Subject: Toolbar and other UI suggestions
Date: 27 October 1998

To index

236 Text formatting toolbar
Buglist Id: Last tested in version: First seen in version:
PX058311 Build 23310.0

Text formatting toolbar seems to have been restricted to be used only in design mode in Paradox 10. In previous versions, the toolbar could be used when editing formatting memo fields.

To index

Interactive---Visual Database Designer

146 General
Buglist Id: Last tested in version: First seen in version:
9.0 P39.0 P3

When adding tables to the Visual Database Designer just the first 100 was added and no message that the rest was not. I'm using Paradox 9 SP3.


REPORTED BY: Stefan Bodingh
Subject: Looking for... DM and VDD Feedback
Date: 6 May 2000

To index

ObjectPAL

ObjectPAL---actionEvent type

212 ActionSelectCommand constants
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

The descriptions of how some of the constants are invoked are incorrect
< Quote >
SelectBottomLeft SmallInt In Memo View, it selects from the current position to the beginning of the last line in the display region. This constant is invoked by SHIFT + CTRL + PAGEUP.

SelectTopRight SmallInt In Field View or Memo View, it selects from the current position to the end of the top line of the screen; otherwise, it selects from the current position to the top right field. This constant is invoked by SHIFT + CTRL + PAGEDOWN.
< /Quote >

SHIFT+CONTROL+PAGEUP is SelectTopLeft
SHIFT+CONTROL+PAGEDOWN is SelectBottomRight


Where to find this:
Index: Action constants - Action constants - then in the text "Action Select commands"

To index

673 ActionEditCommands constants
Buglist Id: Last tested in version: First seen in version:
11 Build 30211 Build 302

ObjectPAL help files does not mention the constant EditPropertySheet, with which you can bring up the Property sheet for a field object.

Example: A button with TabStop unchecked.
fld.postAction(EditPropertySheet)

Reported by: Liz
Date: 16 July 2001

To index

423 actionClass() example
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

Example says:
< Quote >
The following example uses actionClass to prevent the user from making any changes to a field object.
< /Quote >

This is not true. The code will not prevent data from being entered in the field, but changes can't be restored except for by using Edit - Undo.

To prevent data from being entered, make the field ReadOnly.

To index

474 ActionEditCommands constants
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to help file:
< Quote >
EditEnterFieldView SmallInt Enters Field View for the current field (allowing arrow keys to move around within the field). Begins by moving the current position to the end of field and unhighlighting it. This constant is invoked by F2, View, Field View, or the Field View button.
< /Quote >

When the field has WordWrap checked, EditEnterFieldView begins by moving the cursor to the beginning of the field.

To index

ObjectPAL---ActiveX - VCR

32 Programming the buttons
Buglist Id: Last tested in version: First seen in version:
PX037911 Build 2339.0 P1

The focus is lost when using the VCR buttons. I don't know which record is active. You have to add code to move to the record/tableFrame object.

To index

ObjectPAL---ActiveX - WebServer

131 Active property
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0 P4

From: Tom Krieg
Subject: Corel CWS OCX problem
Date: 10 November 2001
It seems from my brief and far from comprehensive testing that a method in the OCX (doShutDown) doesn't get fired at all.


From: Liz
Date: 11 November 2001
Check the pdxinet.hlp file for doShutDown - it's only supposed to fire when you set Active to false or when you use ToggleActive - not when the form closes.


From: Tom Krieg
Date: 11 November 2001
Thanks, I've done just that and you are correct, however, from the help file:

Properties --> Active.

"Switches the Corel Web Server Control off and on. The server toggles Active when you change the form from Run mode to Design mode."

I assumed this was also the case when you close the form. NEITHER is true, active is not toggled off when you change mode or when the form closes, so if you want to perform any code in doShutDown, you have to explicitly toggle active before the form closes. Just another error in the help files, it seems.

To index

667 nCookies property
Buglist Id: Last tested in version: First seen in version:
11 Build 3028.0

Only problem with cookies and the CWS is that anytime you access the nCookies property, the session ends and the ocx returns a 404 without executing the rest of the code... I haven't dug deep enough into the other cookie functions, but I think they may be broken, too. :-(

By: "Dan Alder (Corel)"
Date: 29 March 2001

To index

ObjectPAL---ActiveX objects

162 VCR and WebServer
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT

PARADOX RUNTIME

If you are using the VCR object or the WebServer object from the ActiveX toolbar in an application distributed with Paradox Runtime, you have to take care of the registration of the two OCX files, VCR.ocx and WebSrv.ocx.

You can do it with code as shown below.

Example based on the VCR control.....

Assume winDirectory is the windows system directory (where the control is copied to for registration) and myDirectory is the source location of the control to install and register.

switch
   case RegisterMyControls(winDirectory,myDirectory,"VCR.OCX","VCR.VcrCtrl.1") = False :
      ....your error handling
endSwitch

method RegisterMyControls(var winDirectory String,
                                            var myDirectory String,
                                            controlName String,
                                            controlProgID String) Logical
var
   myOLE OleAuto
endVar
   try myOLE.open(controlProgID)
      myOLE.close()
      return True
   onFail
      errorClear()
      if not fs.FindFirst(winDirectory + controlName) then
         fs.copy(myDirectory + controlName,winDirectory + controlName)
      endIf
      if registerControl(winDirectory + controlName) = False then
         msgStop("Error","Could not register " + controlName + "!")
         return False
      else
         return True
      endIf
   endTry
endMethod

CODE SUPPLIED BY: Rick Kelly
Date: March 19 2002

To index

ObjectPAL---addinForm type

623 isMaximized()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

When used from a form, addinForm.isMaximized() seems to return False unless addinForm is maximized by addinForm.maximize().

To index

ObjectPAL---anyType type

424 view() example
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

The example named Beginner:

After adding Orders to the form as a tableFrame, rename fieldname Ship_Via to ShipVia.


The example named Advanced:
< Quote >
The following example uses a view dialog box to prompt you for a date. If you enter a valid date, the code displays the day of the week for that date; otherwise, an error message is displayed.
< /Quote >

An invalid date will cause a statusbar warning already in the view() statement. To catch the error, try statement has to be moved and an errorTrapOnWarnings(Yes) added. Correct code is:

method pushButton(var eventInfo Event)
var
  theDate AnyType
  fullDays Array[7] String
endvar

fullDays[1] = "Sunday"
fullDays[2] = "Monday"
fullDays[3] = "Tuesday"
fullDays[4] = "Wednesday"
fullDays[5] = "Thursday"
fullDays[6] = "Friday"
fullDays[7] = "Saturday"

 ; initialize theDay variable
theDate = today()
 ; now show today's date in a dialog and prompt the user to enter a new date
errorTrapOnWarnings(yes) ; This line added
try ; try move to here
theDate.view("Enter a Date")

 ; it's possible the user could enter an invalid date (like "Saturday")
 ; so this try..fail block attempts to convert theDate to a Date with
 ; dateVal() and if successful, displays the day of the week that
 ; theDate falls on

   msgInfo("Day of the week", String(theDate) + " falls on a\n" +
             fullDays[dowOrd(dateVal(theDate))])
onfail
  msgStop("Error!", theDate + " is not a valid date.")
endtry
errorTrapOnWarnings(No) ; This line added to restore errorTrapOnWarnings

endMethod

To index

188 isBlank()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

Information on this topic is found in Object PAL index on the keyword "isBlank method". Keyword "isBlank" shows the isBlank() syntax.


if variable.isBlank()
and
if variable=blank()
is not always the same.


Use isBlank() in if statements, use blank() in assignments.

Let's look at an example:

tcursor.cmax() is used to retrieve the max value from a column in a table. The column contains no values, so cmax() returns a blank value if the setting Treat Blank as Zeroes is unchecked.

var
   tc tcursor
   liHold longint
endvar
tc.open(":Buggar:Testing\\isblank")
liHold = tc.cmax("IntegerColumn")

; Now if liHold.isBlank() and if liHold=blank() both returns True

liHold=liHold+1

; Now liHold.isBlank() returns True, but liHold=blank() returns False, even though the value seems to be blank.

liHold.view()

When BlankAsZero(Yes) is specified, assigning typecasted blank values will assign False to a logical variable and 0 to a smallint variable. Those values will also be used in a if variable=blank(), which means that a False value is blank.

 
REPORTED BY: Mark Bannister
Subject: stupid ISblank()
Date: 5 September 2002

To index

189 blank()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

To index

300 trace() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
trace(const ar Array[] AnyType)

trace(const dn DynArray[] AnyType)

trace(const rec Record)

trace(const value AnyType)


Outputs information on the variables to the debugger's log window.


Useful if you're running Paradox under a debugger:
(Note, we're not talking about the ObjectPAL debugger, we're talking about a C++ type debugger).


Reported by: David Berg, Paradox Development
Date: 1996

To index

ObjectPAL---Application type

304 setIcon() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setIcon(const fileName String, const index LongInt) Logical

Same as setIcon(fileName) except allows an icon other than the first one to be chosen.


Reported by: David Berg, Paradox Development
Date: 1996

To index

ObjectPAL---Array type

652 Maximum size of an array
Buglist Id: Last tested in version: First seen in version:
11 Build 3029.0

There is a max size for an array. You cannot allocate an array with a size larger than 64K.

The following OPAL code will show you the limit:

var
 liIndex LongInt
 arAny Array[] String
endVar
 try
  for liIndex from 1 to 1000000
   arAny.addLast("")
  endFor
 onFail
  msgInfo(liIndex,errorMessage())
 endTry

The onFail is invariably tripped on the 645,120th pass thru the for/endFor loop (P9/P10) and the size of the string inserted does not seem to be relevant. The limit is much higher for other data types like SmallInt/LongInt.

Fortunately, a DynArray Type does not have the same limitations.


Reported by: "Rick Kelly"
Date: 8 April 2004

To index

ObjectPAL---Basic syntax

627 Referencing content of fieldobjects
Buglist Id: Last tested in version: First seen in version:
PX044611 Build 3007.0 W95 P4

When your code references the content of a fieldobject, you should typecast the value of the fieldobject. It's not necessary all the time, but look at this:

A form contains two fields, fldCreate and fldLikeThis. The fields are used to enter two tablenames. The name of the table to create and the name of a table which structure you want to use.

var
   tbl table
endvar

errorTrapOnWarnings(Yes)
try
  tbl= create fldCreate
    like fldLikeThis
    endCreate
onFail
  errorShow()
endTry
errorTrapOnWarnings(No)

Whatever you enter in fldCreate, you will get an error: An error was triggered in a Create operation. 'field content' is not a valid table name.

Code should be

try
  tbl= create string(fldCreate'value) ; value property is not necessary
             like string(fldLikeThis'value) ; value property is not necessary
         endCreate
onFail
  errorShow()
endTry

To index

254 Data types of properties
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

Help file says
< Quote >
You can also assign properties using a property constant in a quoted string, or by assigning the value of a constant to a variable. For example, all of the following statements are valid:

var
theProp AnyType
endVar

thatBox.Frame.Style = ShadowFrame ; uses a constant
thatBox.Frame.Style = "ShadowFrame" ; uses a constant as a quoted string
theProp = ShadowFrame
thatBox.Frame.Style = theProp ; uses a variable assigned to a constant
< /Quote >

What is not mentioned is:

When you retrieve a property and assign it to a string variable, the value returned can be the integer value converted to a string or the property's constant name. What you get depends on the assignment itself.

var
  st string
  ui uiobject
endvar

ui.attach("MyField") ; MyField is a field object in the form

st=ui'DisplayType; evaluates to "5"
st.view()
st=string(ui'DisplayType); evaluates to "LabeledField"
st.view()

When you explicitly cast the property as a string, you'll get the name. When you let Paradox convert it, you'll get the value.


Reported by: "Vladimir Menkin"
Date: 24 June 2003

To index

177 Assigning strings to field & textobjects
Buglist Id: Last tested in version: First seen in version:
10.0 P210.0 P2

If you are assigning large strings to a field or a textobject in a form, you should cast the right side of the assignment as a memo, otherwise you can get a GPV.

fldView is an undefined field

fldView'value=fill(" ",8084)
fldView'value=string(fldView'value)+chr(13)+fill("-",87)

The second line will cause a GPV when executed. If first line is changed to 8083 characters, the GPV won't occur.


Solution is to cast the values to memo before assigning them, like this:

fldView'value=memo(fill(" ",8084))
fldView'value=memo(string(fldView'value)+chr(13)+fill("-",87))


Reported by: Greg
Date: Thu, 02 May 2002

To index

169 Object self
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

The definition of object self is not as correct as it could be in the help files.


Definition:
self is the user interface object containing the most recently called _method_.

Notice:
The use of user interface object. It is always an object in a form.

Read the definition as:
When a method in a library is called from a form, self refers to the user interface object in the form containing the method that called the library method.
 
When self is used within a proc, self will be the object containing the method that called the proc. This can be another object than the one containing the proc.

When self is used in a builtin method/event or a custom method in a form, it refers to the object containing the code. This is the standard definition.

 
Comments:
Other uses of self, is not recommended. It should not be used within an builtin method/event in a library or script. In this case, self refers to the library/script.

Neither should it be used, in a method called from an event/builtin method in the library/script.


NOTES:
Defintion is created by Jim Kocis. The rest of the text is mine. Possible changes to the definition after Paradox 5 is not studied.

To index

122 PXDLITE.INI
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

According to the help files, you can add custom menuitems using PXDLITE key in Registry

< Quote >
You can add menu commands to the File, Tools, and Help menus and the File, Open submenu using the corresponding keys within PXDLITE. Inside a key, you place values corresponding to the menu command you want to add.

......Lines removed

The key for the File menu is File, the Tools menu is Tools, and the Help menu is Help. The key for the File, New submenu is New and the key for the File, Open submenu is Open.
< /Quote >

In the File menu, New and Open works, but not File itself.

This doesnot work:
setRegistryValue("Software\\Corel\\Paradox\\9.0\\PxdLite\\File",
"M&yItem",
   "D:\\data\\Buggar\\Buglist.fsl",
regKeyCurrentUser)

This works as documented:
setRegistryValue("Software\\Corel\\Paradox\\9.0\\PxdLite\\New",
"MyItem&2",
   "D:\\data\\Buggar\\Buglist.fsl",
regKeyCurrentUser)


The help files also forgets to mention the SEPARATOR value. You can add a new separator to the menu using a key with a data value of "SEPARATOR" (case sensitive)

To index

20 Naming objects in a form
Buglist Id: Last tested in version: First seen in version:
PX028410.07.0 W95

Attempting to perform a descending sort when there is a variable or object named "D" in the form generates a syntax error: Identifier expected.

WorkAround:
Rename all variables or objects named D.

To index

87 Values returned from a custom method
Buglist Id: Last tested in version: First seen in version:
PX046311 Build 233

A blank value returned from a method will when referenced in the calling method be translated in accordance with Treat Blank As Zero setting.

If I make a date variable blank its value is quite literally a blank as seen in the Watches window. However, as control returns to the calling method, the returned value changes to "00/00/0000", and then fails the if daDateVar.isBlank() test

The value changes in the assignment statement, dDateVar=dMyMethod()

To index

ObjectPAL---Binary type

305 clipboardEnum() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
ClipboardEnum(var formatNames Array[] String) SmallInt

Synonym for EnumClipBoardFormats (no new functionality).


Reported by: David Berg, Paradox Development
Date: 1996

Example:
method pushButton(var eventInfo Event)
var
   arstFormatNames Array[] String
   si smallint
   b binary
endvar
si=b.ClipboardEnum(arstFormatNames)
si.view()
arstFormatNames.view()

endMethod

To index

426 writeToClipBoard() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example is using the clipboard format "Native", which is not explained. Could it be something left over from Windows 3.x ? To make the code work, I changed the "Native" format to "Borland Form Object". My change requires a native Paradox object like a button to have been copied to clipboard.

Furthermore, the code in the examples does not handle a false return correctly. A return statement has to be added.

Below is the changed example code:

The following code is attached to btnStoreClip.

method pushButton(var eventInfo Event)
   var
      b Binary
   endVar

   if not b.readFromClipboard("Borland Form Object") then ; FORMAT CHANGED
      msgInfo("Instructions", "First copy something to Clipboard.")
      return; LINE ADDED
   endIf

   b.writeToFile("Native.clp")
endmethod


The following code is attached to btnRetrieveClip.

method pushButton(var eventInfo Event)
   var
      b Binary
   endVar

   if not b.readFromFile("Native.clp") then
      beep()
      message("File does not exist")
      return ; LINE ADDED
   endIf

   b.writeToClipBoard("Native")
endMethod

To index

428 size() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example contains code to test free diskspace on drive B, but drive B is not used for writing the file.
< Quote >
    if freeSpace > binVar.size() then ; if there's room on B:
       binVar.writeToFile(soundsTC.SoundName) ; write binVar to file
    else ; else the file won't fit on B:
      msgStop("Stop", "The disk in drive B: is full.")
      return
    endIf
< /Quote >

should be:

    if freeSpace > binVar.size() then ; if there's room on B:
       binVar.writeToFile("B:\\"+soundsTC.SoundName) ; write binVar to file ; LINE CHANGED
    else ; else the file won't fit on B:
      msgStop("Stop", "The disk in drive B: is full.")
      return
    endIf

Note:
The description of the table Sounds used contains a typo.
< Quote >
Assume that SOUNDS.DB is a Paradox table with the following structure: SoundName, A32; SoundData, and B.
< /Quote >

The end of the sentence contains an AND that shouln't be there.
should be:
Assume that SOUNDS.DB is a Paradox table with the following structure: SoundName, A32; SoundData, B.

Same typo exists in ReadFromFile example.

To index

429 writeToFile() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

ObjectPAL---built-in event methods

691 newValue() event
Buglist Id: Last tested in version: First seen in version:
11 Build 41010.0

The help files does not mention that there is a case when newValue() event is not triggered when an item in a listbox is selected.



If a list field has no item selected after having been initialized, newValue() is not guaranteed to trigger on the user's first attempt to click an item.
When there is no item selected in the list, list.selection=0. If a user moves to the list, using the mouse, and makes an selection, and mouse is moved slightly between mousedown and mouseup, newValue() event is not triggered. Studying the events, following sequence occurs normally:
 
list mousedown
list mouseup
field newvalue
list mouseclick
field mouseclick

but if mouse is moved between mousedown and mouseup, the sequence looks like this

list mousedown
list mouseup
list mouseclick
field mouseclick

This behaviour seems to occur only when list.selection=0.

Possible workaround:
Add this code to field object's arrive event
var
   ui uiobject
endvar
ui.attach(self.first)
ui.action(MoveDown)

or this to the list object's arrive event
self.action(MoveDown)

BY: BERTIL ISBERG and ANDY FOX
Date: 1 September 2005

To index

ObjectPAL---Chart object

680 XAxisName property
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95

Help file says
< Quote >
This property determines the field being used as the x-axis, and is read-only. This property applies only to chart objects.
< /Quote >

Trying to retrieve the value will return a blank string. Trying to set the value using Object Explorer, the value does not stick. It becomes a blank value as soon as the property is changed. Behaviour has changed in Paradox 9 and later versions. In Paradox 7, the value could be set.

If a form contains linked tables, e g Orders and Customer, with Orders as master table, you can set XAXisName using Object Explorer or ObjectPAL, as long as you specify a field from the master table. Even though ObjectExplorer shows a blank value for the property, the value is set. In Paradox 7, you would get "Value can not be set" if a column from Customer was specified.

Setting the property to a column in the detail table, using ObjectPAL, will cause an error
An error occurred when setting the property named 'XAxisName' of the object named '<>' of type 'Graph' followed by error "Invalid table."

The value has to be on the form [:ALIAS:Table.Column] where table must not include .db extension

To index

681 YAxisName property
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95

To index

ObjectPAL---Constants

412 PrintPreview constants
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

PrintPreview constants
printPreviewEnter, printPreviewExit
- enters or exits print preview mode.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
See ObjectPAL - Report type - method printPreview() - WADID 363

To index

184 PrinterSizes constants
Buglist Id: Last tested in version: First seen in version:
11 Build 233

The help files says:
< Quote >
Constant Data type Description

prn10x14 LongInt 10 by 14 inches
prn11x17 LongInt 11 by 17 inches
prnA3 LongInt A3 297 x 420 mm
prnA4 LongInt A4 210 x 297 mm
prnA4Small LongInt A4 Small 210 x 297 mm
prnA5 LongInt A5 148 x 210 mm
prnB4 LongInt B4 250 x 354
prnB5 LongInt B5 182 x 257 mm
prnCustom LongInt Custom paper size
< /Quote >

When prnCustom is used in ObjectPAL, you'll get a syntax error: Error: Unknown identifier.

To index

ObjectPAL---Currency type

430 currency() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 1 - Performing a simple calculation
see ObjectPAL - Examples - General Issues - WADID 592 - Issue 3: Regional settings


Example 2 - Performing more than one calculation

Running the code, I get the opposite result. The number calculation will display .484791 and the currency calculation will show .484790

To index

515 currency()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

The help files does not mention that since Paradox 7 for Win95/NT, the default format to use when casting a string as a currency, is the Windows Number (sic!) format specified in Control Panel applet Regional Options. You can specify another format using formatSetNumberDefault(). In previous versions, the default format was the format used in the examples.

To index

ObjectPAL---Database type

431 beginTransaction() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example can be seen as a model for using different transaction handling methods. The custom methods that is to handle the editing of the tables are not included. But even when used as a model there are some issues with the code.

errorShow() is used to show a message, but when catching a false return from transactionActive(), commitTransaction() and rollbackTransaction(), I'm not sure there is an error message. Better to use msgStop() or msgInfo() in these cases.

transactionActive() does not work correctly with local tables, and should only be used with remote tables.

To index

432 getMaxRows() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example showed
< Quote >
var
   myQBE Query
endvar
if getMaxRows() < 1000 then
   setMaxRows(1000)
endif
myQBE = Query
         Customer |Customer No |Name |
                     | Check |A.. |
endQuery
< /Quote >

is not correct. Both getMaxRows() and setMaxRows() requires a databasehandle.

Example should have been:
var
   myQBE Query
   dbHandle database
endvar
dbHandle.open(":MyDb:")
if dbHandle.getMaxRows() < 1000 then
   dbHandle.setMaxRows(1000)
endif
myQBE = Query
         Customer |Customer No |Name |
                     | Check |A.. |
endQuery

executeQbe(dbHandle, myQbe)


See more comments on setMaxRows()

To index

433 setMaxRows()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Help files says
< Quote >
 Notes
The maximum specified with the setMaxRows method can exceed that specified by the MAX ROWS BDE configuration option.

If no setMaxRows method is issued or if the maxRows argument is set to -1, Paradox imposes no limit on rows. If present, the BDE MAX ROWS limit is imposed.
< /Quote >

The last sentence "If present, the BDE MAX ROWS limit is imposed." is hard to understand. It looks like setMaxRows() has no effect at all for existing aliases. Maybe it can used for an alias created in the current session.

Summary:
setMaxRows() does not have any effect at all on the sql statements and QBE statements executed when an existing alias is used. And it cannot be used with local databases. It will cause an error "Database not opened".


SETUP:
a)
Code used in the examples slightly modified

var
myQBE Query
myDatabase Database
endvar
myDatabase.open("WORK")

if mydatabase.getmaxrows()<1000 then
; I have removed the else clause here, so maxRows will be set to 1000 when < 1000
; else
   mydatabase.setmaxrows(1000)
endif
myQBE = Query
         Customer |Customer No |Name |
                       | Check |A.. |
endQuery
executeQbe(mydatabase, myQbe)
myDatabase.close()

The code gives an error on setMaxRows(): Database not opened.

It cannot be used on local tables.

b)
Tested on a remote database, setMaxRows() can be used, but has no effect on the QBE or SQL executed. The only effect of setMaxRows() is that the value set by setMaxRows() will be retrieved by getMaxRows().

When running a query or a sql statement, the MAX ROWS value specified for the database in BDE Administrator is used. No matter whether it is blank, 0, -1 or anything else.

c)
SetAliasProperty["MAX ROWS"] can be used to change the MAX ROWS.

To index

677 isTable()
Buglist Id: Last tested in version: First seen in version:
PX002111 Build 4107.0 W95

isTable() should not be applied on any file, but only on tables. When applied on the secondary index file tablename.Xnn, Paradox will cause an Unexpected: General Protection Violation error.

To index

60 isTable()
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

To index

306 enumCapabilities() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
enumCapabilities(const TblCap_TblName String, const FldCap_TblName String) Logical

enumCapabilities(const TblCap_TblName String, const FldCap_TblName String, const IndxCap_TblName) Logical


Creates two tables. One has information on the overall table capabilities the attached database has, the other is capabilities by field type. Capabilities include types of fields, indexing, security, validity checks allowed, etc.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   db database
endvar

db.open(":WORK:")
db.enumCapabilities("TblCapTblName.db", "FldCapTblName.db", "IndxCapTblName.db")
db.close()

COMMENTS 2003-12
It's similar to enumDriverCapabilities()

To index

232 open()
Buglist Id: Last tested in version: First seen in version:
10.0 P35.04

You cannot open a database based on a project alias in a named session .

With code like
var
  ses session
  db database
endvar
ses.open("somesession")
ses.addprojectalias("ABC","Standard","c:\\temp")
db.open("ABC",ses)

db.open() will fail. ABC is not known in the default session.

But when code is like
ses.open("somesession")
addprojectalias("ABC","Standard","c:\\temp")
db.open("ABC",ses)

db.open() will not fail, but return false. The alias is known in default session, but not in session "somesession".


If you create and save a project alias, such an alias will not be seen in a named session.
ses.open("somesession")
ses.enumaliasNames(":WORK:aliases")
will only show the public aliases.

To be known in a named session, a projectalias has to be explicitly created in that session (ses.addProjectAlias()), but then, as shown above, it can't be used to open a database.


When projectalias is not known in default session, db.open() will cause an error
When projectalias is not known in the second session, db.open() will return false.
When alias is not known in default session, db.open() will return false

So you can't use a projectalias when opening a database in a different session.

Originally reported by: "Vladimir Menkin"
Date: 3 April 2003

To index

ObjectPAL---dataTransfer type

233 setSourceRange()
Buglist Id: Last tested in version: First seen in version:
10.0 P39.0 P4

Help files says:
< Quote >
setSourceRange specifies a sub range of the spreadsheet to import. The value specified by setSourceRange can be a named range, a page name, or an explicit range in QPW or Excel format.
< /Quote >

Example shows:
   ;Set the range to import from the spreadsheet.
   ;Either named range or specified range (ie. Page1:A1..Page3:AB10)
   dt.setSourceRange("myRange")


Using a named range in an Excel workbook does not work. When the workbook contains more than one tab and the range is specified for one of the tabs, Paradox will show the range as the complete workbook.

Range defined as
=Blad1!$A$2:$C$5
will be shown as
A:A1..B:F5
by Paradox - getSourceRange()

Interactively, selecting < Spreadsheet A > and entering MyRange will be translated to A:A1..A:C5.
Changing it manually to A:A2..A:C5 will create a correct result

Same problem occurs when there is only one tab. The range shown by Paradox starts at A1.

Using the tabnames, other than A, B, C... will cause an error Invalid cell range.

The only valid range specification when importing Excel spreadsheets seems to be the form B:A6..B:H6100. When sourcetype dtExcel5 is specified, you won't get the range on that format. So avoid using sourceType dtExcel5 in setSource().

NOTE 2:
When header rows does not match the columns to be imported, some of the columns in the range specified may be excluded from the import.

Example:
A B C D
xxx xxx
xxx xxx
12 13 14 15

Even though you have specified columns A through D, column D could be missing in the resulting table.

To index

238 Importing dates from Excel
Buglist Id: Last tested in version: First seen in version:
PX063911 Build 23310.0 P2

An Excel column to be imported as Date has to be formatted as Date (as opposed to General text) in Excel.

To index

261 QuattroPro 9, .QPW format
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

see Interactive - Export - QuattroPro 9, .QPW format, WadId 260.

Furthermore, there is no dataTransfer filetype constant for QuattroPro 9 - QPW format.

To index

308 enumQAInfo() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
enumQAInfo(transferData DynArray[] Anytype)

Use this undocumented DataTransfer method to find out information about how we (tried to) transfer your data.


Reported by: David Berg, Paradox Development
Date: 1996

Example
method pushButton(var eventInfo Event)
var
   daratQAInfo DynArray[] Anytype
   dt datatransfer
endvar

dt.setSource("Customer.xls")
dt.setDest("Cust.db")
dt.enumQAInfo(daratQAInfo)
daratQAInfo.view()
endMethod

To index

309 enumSourceFieldInfo() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
enumSourceFieldInfo([const maxRows LongInt, const flags LongInt])

For ASCII text files?

Dt.enumSourceFieldInfo() scans the current source file and records the structure of the source file (use getSourceFieldInfo to read it). This function works with ASCII Variable and Fixed input, and tables. However, the results for ASCII Fixed file structure aren't reliable. (The Import Expert uses this function to guess at the structure of delimited text files.) maxRows allows you to limit the number of lines processed. Setting flags to 1 turns off the structure guessing for fixed format ASCII and just guesses field types (set the structure via setSourceFixedFieldInfo).


Reported by: David Berg, Paradox Development
Date: 1996

Example:
method pushButton(var eventInfo Event)
var
   liMaxRows LongInt
   liFlags LongInt
   dt datatransfer
   arstnames Array[] String
   arsttypes Array[] String
   arlilen Array[] LongInt
   arlidp Array[] LongInt
   arlistartPos Array[] LongInt
endvar

liMaxrows=40
liFlags=0
dt.setSource("Customer.txt",dtASCIIVar)
dt.setDest("Cust.db")
dt.enumSourceFieldInfo(liMaxRows,liFlags)

dt.getSourceFieldInfo(arstnames, arsttypes, arlilen, arlidp, arlistartPos)

arstNames.view()
arstTypes.view()
arlilen.view()
arlidp.view()
arlistartpos.view()

endMethod

To index

310 getSourceFieldInfo() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
getSourceFieldInfo(var names Array[] String, var types Array[] String, var len Array[] LongInt, var dp Array[] LongInt, [var startPos Array[] LongInt])

For ASCII text files ?

Call dt.getSourceFieldInfo after calling Dt.enumSourceFieldInfo(). The Names array gets a list of field names (either read from the first line of the delimited text file, or "Field1, Field2, ...". Types is the field type. Len is the size of the field, and dp is the maximum number of decimal places encountered.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
method pushButton(var eventInfo Event)
var
   liMaxRows LongInt
   liFlags LongInt
   dt datatransfer
   arstnames Array[] String
   arsttypes Array[] String
   arlilen Array[] LongInt
   arlidp Array[] LongInt
   arlistartPos Array[] LongInt
endvar

liMaxrows=40
liFlags=0
dt.setSource("Customer.txt",dtASCIIVar)
dt.setDest("Cust.db")
dt.enumSourceFieldInfo(liMaxRows,liFlags)

dt.getSourceFieldInfo(arstnames, arsttypes, arlilen, arlidp, arlistartPos)

arstNames.view()
arstTypes.view()
arlilen.view()
arlidp.view()
arlistartpos.view()

endMethod

To index

311 guessSourceType() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
guessSourceType()

For ASCII text files:

Calling dt.guessSourceType() will scan the current source file (must be a text file, use dt.SetSource) and will set the source type to dtASCIIFixed or dtASCIIVar as appropriate. If the file is delimited, it will also guess at the delimiters and separators, and drop them into the dt variable. This function is largely obsolete since SetSource does this anyway when called with dtAuto as the file type.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
method pushButton(var eventInfo Event)
var
   dt datatransfer
   daratQAInfo DynArray[] Anytype
endvar

dt.setSource("Customer.txt")
dt.setDest("Cust.db")
dt.guessSourceType()

dt.enumQAInfo(daratQAInfo)
daratQAInfo.view()
endMethod

To index

312 isParadoxImport() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
isParadoxImport() Logical

If you were to replace our Import/Export UI (or the Text Import Expert) with your own, you'd first need to call loadFromParadox() to see if you were called from the Import menu or directly (via someone running your form). If you were called from Paradox, then this also fills in the DataTransfer object with everything we know about the requested Import/Export so far. The isParadoxImport() function tells you whether the user selected an Import or an Export.


Reported by: David Berg, Paradox Development
Date: 1996

To index

313 loadFromParadox() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
loadFromParadox() Logical

If you were to replace our Import/Export UI (or the Text Import Expert) with your own, you'd first need to call loadFromParadox() to see if you were called from the Import menu or directly (via someone running your form). If you were called from Paradox, then this also fills in the DataTransfer object with everything we know about the requested Import/Export so far. The isParadoxImport() function tells you whether the user selected an Import or an Export.


Reported by: David Berg, Paradox Development
Date: 1996

To index

314 setSourceFieldInfo() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
setSourceFieldInfo(const names Array[] String, const types Array[] String, const len Array[] LongInt, const dp Array[] LongInt, [const startPos Array[] LongInt])

For ASCII text files ?

Anything you set with this function you can read back with dt.getSourceFieldInfo - oh boy! In the future, this may do something meaningful.


Reported by: David Berg, Paradox Development
Date: 1996

COMMENT
I get an error: "Could not allocate memory" when using this method.

To index

315 setSourceFixedFieldInfo() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setSourceFixedFieldInfo(const startPos Array[] LongInt, const len Array[] LongInt)

For ASCII text files ?

Call dt.setSourceFixedFieldInfo with the structure of a fixed format ASCII text file (column starts and lengths), then call Dt.enumSourceFieldInfo() to determine the data type for each column, and read the results with dt.getSourceFieldInfo.


Reported by: David Berg, Paradox Development
Date: 1996

To index

316 setUI() method
Buglist Id: Last tested in version: First seen in version:
7.0 W95 P4

Undocumented.

Syntax:
setUI(const flags LongInt)

Call dt.setUI(-1) to make the subsequent dt.TransferData() function display all the status and warning messages (just as if you were performing your Import or Export from the UI). The other options are:


Value Meaning
0 Don't show ANY UI (ObjPAL default)
3 Show the Progress Dialog (with Cancel Button)
4 Confirm file overwrites
8 Display Status Line Messages
16 Display Informational/Warning Dialogs (e.g. too many rows)
32 Control the Cursor (Show an hourglass, restore to an arrow)
64 Ask for Passwords when necessary
255 Show ALL the above (same as -1)


Reported by: David Berg, Paradox Development
Date: 1996

To index

81 Fixed length import
Buglist Id: Last tested in version: First seen in version:
PX041610.07.0 W95

see Interactive - Import-Fixed Length import: WadId: 80

Using ObjectPAL import, you may get a different errormessage.

To index

170 setSourceStartRow()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

The method setSourceStartRow() is not documented in the help files even though the textimport expert is using it in the script created by the expert.

The method is mentioned in the ObjectPAL Quick Lookup under dataTransfer type.

To index

149 setSource()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0

Help files does not show dataTransfer.setSource(). Only the twain type setSource(). dataTransfer setSource() is available only under dataTransfer type.


To see this:
Open ObjectPALReference help files, Index tab
Enter setSource and you'll get setSource examples and setSource method.
Select setSource method, and you'll get Overview: setSource method and setSource Example.
Select Overview: setSource method, and you'll get the twain type setSource().

To index

689 setProblems()
Buglist Id: Last tested in version: First seen in version:
11 Build 41011 Build 410

Help file does not mention which records are written to Problems table. When appending a delimited text file to an existing table, alpha variables are truncated and not written to Problems.

Reported by: "Steve Caple"
Date: 13 July 2005

To index

700 getDestCharset()
Buglist Id: Last tested in version: First seen in version:
11 Build 410

Description refers to wrong method, getSourceCharset() instead of getDestCharset().

To index

701 getDestType() example
Buglist Id: Last tested in version: First seen in version:
11 Build 410

The last part of the example, Export to text, is not correct.
< Quote >
Export to text
var
   dt DataTransfer
endVar
dt.setSource ( "ANSWER.db" )
msgInfo("Info", "the current dest type is " + string(dt.getDestType()))
dt.SetDest ( "NEWFILE.TXT" )
dt.setDestSeparator ( ";" )
dt.transferData ( )
< /Quote >
Should be dt.SetDest("NEWFILE.TXT", dtAsciivar)

To index

434 appendAsciiVar()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Nothing is said on the defaults for a delimited ascii file when being imported without the options
[ , const separator String, const delimiter String, const allFieldsDelimited Logical, const ANSI Logical ] ) Logical

They are described in the importAsciiVar() method.

The following table displays the default settings for optional arguments:
< Quote >
separator , (comma)
delimiter " (double quote) text fields only
ANSI False
< /Quote >

To index

435 dlgImport() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example says:
< Quote >
The target table name defaults to the name of the source file, with a .DB extension.
< /Quote >

When not specified, the target table name defaults to .db only.

To index

436 setSource()
Buglist Id: Last tested in version: First seen in version:
11 Build 3009.0

In Paradox 9 and later versions, the name of the file to be imported with TransferData() has to contain a path. If no path is specified, Paradox programs directory is searched for the file, but not the working directory.

Always use:
getAliasPath(":YourAlias:")+"\\"+"YourFileName" when specifying the file.

To index

437 getDestDelimitedFields() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example does not use the method!!

Replace
    dt.setDestDelimitedFields(DTDelimJustText)
with

   if dt.getDestDelimitedFields() = dtDelimAllFields then
      dt.setDestDelimitedFields(DTDelimJustText)
   endif

To index

438 setSource()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Importing Excel spreadsheets can require a cell range specified.

Example:
var
   dt DataTransfer
endVar

dt.setSource ( getAliasPath(":WORK:")+"\\ORDERS3.XLS")
dt.setDest ( getAliasPath(":WORK:")+"\\ZNEWFILE.DB" )
dt.setSourceFieldNamesFromFirst(True)
dt.transferData ( )

can give an error Invalid Cell Range.

By adding a
dt.getSourceRange()
before dt.transferData(), the import may work.

When sourcetype dtExcel5 is specified, you won't get the range on a format accepted by transferData(). So avoid using sourceType dtExcel5 in setSource().

To index

439 getSourceRange()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to the help files
< Quote >
Retrieves the range set by setSourceRange.
< /Quote >

For Excel spreadsheets, the range has to be on the form A:A1..A:X45. Named ranges set with setSourceRange() are ignored.

To index

441 transferData() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The last example does not work unless newfile.txt already exist with correct filetype format Fixed or Var.
< Quote >
var
   dt DataTransfer

endVar
dt.setSource ( "ORDERS.DB" )
dt.SetDest ( "NEWFILE.TXT" )

dt.setDestSeparator ( ";" )
dt.transferData ( )
< /Quote >

A TXT file has to be specified with dataTransferFileType, dtAsciiVar in this case. It can be set in setDest() or with setDestType(). Even a getDestType() after setDestSeparator() may work.

If the text file does not exist, dt.getDestType() will return 14 before setDestSeparator() is specified.
If the file exist, the existing file will be analyzed.

To index

ObjectPAL---Date type

442 date() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

443 dateVal() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

511 date()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Help file says
< Quote >
In ObjectPAL, you can represent Date values in either month/day/year, day-month-year, or day.month.year format. Dates must be explicitly declared. For example, the following code assigns the date December 21 1997 to d.

var
  d Date
endVar
d = date("12/21/1997")

If you omit the quotes around the Date value ObjectPAL divides the values.
....
Date values are formatted by the formatSetDateDefault method (System type), or by ObjectPAL formatting statements. See the formatSetDateDefault method for more information.
< /Quote >

The help files does not mention that since Paradox 7 for Win95/NT, the default format to use when casting a string as a date, is the Windows Short date format specified in Control Panel applet Regional Options. You can specify another format using formatSetDateDefault(). In previous versions, the default format was the format used in the examples.

To index

317 date() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
date(dateString String, formatSpec String) Date

Converts the passed string to a date, using the provided format specification. This allows working with formatted data. For example, Date("12-Jan-96") causes an error unless it happens to match your current date format, but Date("12-Jan-96","DM3O(%D-%M-%Y") returns the date 1/12/96, because we've told Paradox the format we expect to see.


Example:

var
   d date
endvar

; My default date format is Y-M-D
d=date("12/28/1997", "DO(%M/%D/%Y)")
d.view()


Reported by: David Berg, Paradox Development
Date: 1996

To index

ObjectPAL---Datetime type

512 datetime()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

The help files does not mention that since Paradox 7 for Win95/NT, the default format to use when casting a string as a datetime, is the Windows time format and Windows Short date format specified in Control Panel applet Regional Options. The two are separated by a space. You can specify another format using formatSetDateTimeDefault(). In previous versions, the default format was the format used in the examples.

To index

658 dow()
Buglist Id: Last tested in version: First seen in version:
PX060211 Build 302

dow() does not work for B.C years 2 or higher.

Furthermore the dow() function generates a GPV with P8, P9, P10 for dates with B.C. years 2 or higher on Win 9x versions of Windows. Interestingly, it works for year = -1.

Problem described is related to BDE 5.x. dow() does work on bde 4.51

Reported by: Rick Kelly [infoATnospam.crooit.com]
9 September 2001

To index

659 doword()
Buglist Id: Last tested in version: First seen in version:
PX060211 Build 302

doword() does not works for B.C years 2 or higher.
doword() generates an error: Overflow. The source data is numerically too large (positive or negative) to store in the destination.

Reported by: Rick Kelly [infoATnospam.crooit.com]
9 September 2001

To index

449 hour() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

ObjectPAL---Debugger

135 Tracer
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0 P3

This is what the help files says on the Tracer's Show Code menuitem
< Quote >
Show Code lets you control whether each line of code is listed in the Tracer as it executes. With Show Code turned off, tracer output consists only of messages output from tracerWrite statements and any event methods checked in the Select Built-in Methods For Tracing dialog box.
< /Quote >

A requirement for ShowCode to work, is that Program | Compile With Debug is checked.


Reported by:
From: Elmar von Muralt
Subject: Tracer not showing code
Date: den 28 November 2001

To index

ObjectPAL---dynArray type

123 Overview
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95

Nothing is said at all in the help files on what happens if you try to reference an non-existing element in a dynArray. It looks like any reference to a non existing element in the dynArray with other methods than contains, will create the element, but without assigning a value to it.

Thread 1)
From: Vladimir Menkin
Date: 23 September 2001

I guess the effect described below may be considered as a bug (P9):

var
 darst dynarray[] string
 st string
endvar
try
 st=darst["test"]
onfail
errorclear()
endtry
darst.view()

The line
 st=darst["test"]
creates an element in the dynarray darst with the index "test" and N/A as a value.


Reply by: Bertil Isberg

I wouldn't consider this a bug, but rather a WAD.

try this
if darst["test"].isAssigned() then
else
    darst.view()
endif

As soon as you reference a non existing element in the dynArray with other methods than contains, the element is created.

If an element in a dynarray is unassigned, you will get an error when assigning the dynarray to another dynarray.
Example: darst1=darst2 requires all elements in darst2 to have values assigned.


Thread 2)
From: mark bannister
Date: 27 January 2003

Should this trip an error?
var
   darst dynarray[] string
endvar
errorTraponwarnings(yes)
darst["frogs"] = iif(darst.contains("frogs"),darst["frogs"]+"E","somethingelse")
--this line gives an error: You have tried to use an unassigned variable.


Reply by: Bertil Isberg

There are problems when using not existing dynarray elements on the right side in an assignment.

This code works
if darst.contains("frogs") then
 darst["frogs"]=darst["frogs"]+"E"
else
   darst["frogs"]="A"
endif

And this:

darst["frogs"] =
iif(darst.contains("frogs") and darst["frogs"].isAssigned(),darst["frogs"]+"E","somethingelse")

Note this is accepted and works Ok:
darst["frogs2"] = iif(darst.contains("frogs"),darst["frogs"]+"E","somethingelse")

So your problem is based on darst["frogs"] being on both sides. To be able to assign a value to darst["frogs"], Paradox creates the element. so iif darst.contains("frogs") will be true, and the iif statement tries to return darst["frogs"]+"E". As darst["frogs"] is unassigned, you will get an error.

To index

ObjectPAL---errorEvent type

451 reason() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example could have contained code to trigger an error

Put this code in a pushButton event of a pushButton object
var
tc tcursor
endvar

tc.open("Non existing table")

To index

452 setReason() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

ObjectPAL---Event type

453 setErrorCode() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

112 eventInfo.setErrorCode()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

The help files says
< Quote >
Use setErrorCode with eventInfo to specify the status of an event. For example:

method canArrive(var eventInfo MoveEvent)
 eventInfo.setErrorCode(CanNotArrive) ; CanNotArrive is an ObjectPAL constant
endMethod

By attaching this method to a field, you can prevent a user from moving the pointer into the field. The constant CanNotArrive has been assigned a nonzero value by ObjectPAL, and any nonzero error value blocks this method's built-in code from executing.
< /Quote >

As used in the example, the builtin error constant CanNotArrive will work as expected. But if you want to prevent arrive on a container like a tableFrame or a record object in a tableFrame, the builtin constant will create an unexpected behaviour.

This is the code in the canArrive event for a tableframe bound to Orders table, which is the detail table in a form, where Customer is the master table. (Messages in the code below are irrelevant)

if isEdit() and
   eventInfo.reason() = UserMove then

  switch
  case Balance_Due=0:
    msgInfo("Message", "Zero earnings, no input lines")
    eventInfo.setErrorCode(CanNotArrive)

  case Balance_Due<>Amount_Paid:
    msgInfo("Message","Totals match, cannot edit")
    eventInfo.setErrorCode(CanNotArrive)
  endSwitch

endif

A background: You can only arrive to an object with TabStop property =True. In a tableFrame there is no other objects than field objects with this property, so Paradox will, on the usermove, try to find a field object in the tableframe where arrive is allowed. The errorconstant CanNotArrive is part of this functionality.

Paradox will handle the builtin constant CanNotArrive as if the arrive were prevented for the default (first column or last departed from) field object, and will try to find another field where arrive is allowed. The code will execute for each column and each row in the table frame.

If you instead specify error constant UserError or UserError+custom constant, Paradox won't try to find another field.

Maybe, the example shown, is the only case where builtin constants will create an unexpected behaviour. I haven't bothered to test them all as there are thousands of them.

Conclusion: Don't use the builtin error constants in eventInfo.setErrorCode() as some of them will invoke a certain behaviour in Paradox. UserError (or UserError + custom constant if you want to be able to separate the handling of them) is enough to prevent the default behaviour of an event.

To index

ObjectPAL---Examples

592 General issues
Buglist Id: Last tested in version: First seen in version:
11 Build 300

GENERAL ISSUE 1: thisForm is not declared and not assigned

Form level var window
var
   thisForm form
endvar


Form level open event
method open(var eventInfo Event)
if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form
else
   ;// This code executes only for the form
   doDefault
   thisForm.attach()
endIf
endMethod


GENERAL ISSUE 2: Buttons with TabStop checked

All examples are probably created with buttons having TabStop unchecked. In some examples, visual effects of moving to a record, disappears if the button has TabStop. In other examples, the code does not work as expected, e g wrong record is edited.


Uncheck TabStop for the button.


GENERAL ISSUE 3: Windows regional settings

All examples where numbers, dates, and times are converted from string to number, currency, date, datetime, and time are based on how Paradox work in versions prior to Paradox 7 for Win95 and NT. Since that version, strings should be entered
-with decimalseparator from Windows regional setting when casted as number and currency. Neither thousand separator nor currency symbol should be used.
-with yy mm dd order from Windows regional settings when casted as date. Any separator can be used.
-with the 24 hour format from Windows regional settings when casted as time. Any separator can be used.
-with the 24 hour format for time and with the datepart order from Windows regional settings, time first followed by a blank separator and the date when casted as datetime.

To index

ObjectPAL---Field - ListBox

96 Number of items in a listbox
Buglist Id: Last tested in version: First seen in version:
10.09.0

Maximum number of items in a listbox has increased from 2500 to a limit defined by the amount of memory you have on your PC, but you have to use a scan loop to fill the list. DataSource property is still limited by the old maximum value.

To index

ObjectPAL---Field object

6 Property Scroll
Buglist Id: Last tested in version: First seen in version:
PX010311 Build 2335.0

The property Scroll is always (0,0) for a field. Looks like it does not work for fields, but only for textobjects.

To index

289 BlankRecord property
Buglist Id: Last tested in version: First seen in version:
11 Build 3005.04

To index

ObjectPAL---fileSystem type

414 General information
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

Help file says
< Quote >
FileSystem variables provide access to and information about disk files, drives, and directories. They provide a handle, a variable you can use in ObjectPAL statements to work with a directory or a file.
< /Quote >

Nothing is said on support for Universal Naming Convention - UNC, but at least some of the methods do not support UNC.

To index

455 findFirst() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example is using errorshow() when msgStop() or msgInfo() should be used.
< Quote >
; >>INVALID PATTERN CAUSES AN ERROR!! <<
if fs.findFirst("c:\\WordPerfect Office 11\\Paradox\\") then
   message("This message never displays.")
else
   errorShow("Invalid pattern: c:\\WordPerfect Office 11\\Paradox\\")
endIf
< /Quote >

findFirst() won't fail when the pattern is invalid. It will return false, and no error is shown. Replace errorShow() with msgStop(). Or use fail() instead of errorShow().

To index

456 findNext() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

In example 2 - Using a file specification as an argument, files in a directory are presented in popupmenu, and the file selected is to be opened with Notepad.

< Quote >
while fs.findNext("c:\\WordPerfect Office 11\\Paradox\\*.txt")
   p.addText(fs.name())
endWhile

choice = p.show() ; show the pop-up menu
if not choice.isBlank() then ; if user selected a file
   execute("Notepad.exe " + choice) ; edit the file in Notepad
endif
< /Quote >

Change the code to this:
fs.setdir("c:\\WordPerfect Office 11\\Paradox\\") ; THIS LINE ADDED
while fs.findNext("*.txt")
   p.addText(fs.name())
endWhile

choice = p.show() ; show the pop-up menu
if not choice.isBlank() then ; if user selected a file
   execute("Notepad.exe " + choice) ; edit the file in Notepad
endif

To index

457 getDir() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The path specified in fs.SetDir() in the example used should contain trailing backslashes
< Quote >
var
   fs FileSystem
   st String
endVar

   st = "c:\\WordPerfect Office 11\\Paradox\\myforms"

   if fs.getDir() <> st then
      fs.setDir(st)
   endIf
< /Quote >

should be

   st = "c:\\WordPerfect Office 11\\Paradox\\myforms\\"


To see the effects of missing trailing backslashes, test the example under ObjectPAL - fileSystem type - findNext() - WadId 456.

Note: getDir() will always return the path without trailing backslashes.

To index

458 getDir()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

getDir() will always return the path without trailing backslashes.

To index

459 setDir()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

460 isDir() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example is using isDir() to find out if a directory exists, and if it does, fs.setDir() is used to set the directory as default for fileSystem variable.

< Quote >
newDir = "C:\\WordPerfect Office 11\\Paradox\\diveplan"
if isDir(newDir) then
   fs.setDir(newDir)
   msgInfo("Current directory", fs.getDir())
else
   msgStop(newDir, "Directory does not exist.")
endIf
< /Quote >

newDir = "C:\\WordPerfect Office 11\\Paradox\\diveplan\\" ; CHANGE THIS LINE

The directory name should have trailing backslashes when used in fs.setDir().

To see the effects of missing trailing backslashes, test the example under ObjectPAL - fileSystem type - findNext() - WadId 456.

To index

461 isValidFile() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The copy() method as used in the example does not accept all extensions.

< Quote >
proc copyNewFile( origFileName String )
var
   newFile string
endVar

newFile.view()

if isValidFile( newFile ) then
   copy( origFileName, newFile )
else
   msgInfo( "Error", "This is not a valid filename" )
endif

endProc
< /Quote >

NOTE: No fileSystem handle on the copy() statement. It works for some extension. I guess this is the table type copy() procedure. I tested with extension .abc on the target file, and I got an error.

As this is the fileSystem copy() method, code should be

proc copyNewFile( origFileName String )
var
   newFile string
   fs fileSystem
endVar

newFile.view()

if isValidFile( newFile ) then
   fs.copy( origFileName, newFile ) ; LINE CHANGED
else
   msgInfo( "Error", "This is not a valid filename" )
endif

Now the extension .abc can be used on the target.

To index

462 isValidDir() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example refers to the isValidFile() example, but that one does not contain the use of isValidDir().


Here's an example based on the isValidFile() example

; Note origFileName contains a file in the working directory. Nothing but the filename is specified.
; The file is copied to a different directory, specified with no trailing backslash.
; Proc is called as copyNewFile("Customer.txt")

proc copyNewFile( origFileName String )
var
   newDir string
   fs fileSystem
endVar

newDir.view("Enter target folder." )

if isValidDir( newDir ) then
   fs.copy( origFileName, newDir+"\\"+origfilename )
else
   msgInfo( "Error", "This is not a valid directory name" )
endif
endProc

To index

464 setPrivDir()
Buglist Id: Last tested in version: First seen in version:
PX059311 Build 30010.0

Help file says
< Quote >
Paradox closes all of its open windows and frees all locks before setting the private directory. Therefore, setPrivDir does not take effect until all ObjectPAL code has finished executing. You can keep a form open by adding code to its built-in menuAction method to trap for the MenuChangingPriv menu command (see the example for details). If you do so, save any documents that need saving before changing the working directory. setPrivDir returns True if successful; otherwise, it returns False.

ObjectPAL provides the following MenuCommands constants for handling changes to the private directory:

Constant Description

MenuFilePrivateDir Issued when the user chooses Tools, Settings, Preferences, Database, Private Directory from the Paradox menu. Trap for this constant to prevent the user from changing the private directory.
MenuChangingPriv Issued just before the private directory changes. Trap for this constant to keep a form open when changing the private directory.
MenuChangedPriv Issued just after the private directory changes. Trap for this constant to find out when the private directory has changed.
< /Quote >

The behaviour described is changed in Paradox 10.

Paradox does not close open windows. Save any documents that need saving before changing private directory. Such forms will prevent private directory from being changed.

MenuFilePrivateDir Issued when setPrivDir() is executed. It has never been triggered by changing the Tools, Settings, Preferences, Database, Private Directory from the Paradox menu.
MenuChangingPriv Is never issued in Paradox 10 and later versions.
MenuChangedPriv As described above.

Note: You cannot change private directory when tables are open.


COMMENT:
The help file was changed in P11 Build 302, but two issues remains.

< Quote >
MenuFilePrivateDir Issued when setPrivDir() is executed. Trap for this constant to prevent the user from changing the private directory.
MenuChangingPriv Is never issued in Paradox 10 and later.
MenuChangedPriv Is never issued in Paradox 10 and later.

ObjectPAL also provides the constant MenuFileWorkingDir, issued when the user clicks Tools, Settings, Preferences, Database, Working Directory.

Note: You cannot change the private directory when tables are open.
< /Quote >

MenuChangedPriv Issued just after the private directory changes. Trap for this constant to find out when the private directory has changed.

MenuFileWorkingDir is only issued by File - Working Directory. There is no such setting as Working Directory under Tools, Settings, Preferences, Database, Working Directory.

To index

465 windowsDir() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example does not work
< Quote >
var
   fs FileSystem
   fileName, destName String
endVar

fileName = "\\win.ini"

fs.setDrive("B")
if fs.findFirst(fileName) then
   destName = windowsDir() + fileName
   fs.copy(fileName, destName)
endIf
< /Quote >

Use this instead

var
   fs FileSystem
   fileName, destName String
endVar

fileName = "win.ini" ; LINE CHANGED

fs.setDir("B:\\") ; LINE CHANGED
if fs.findFirst(fileName) then
   destName = windowsDir() +"\\"+ fileName ; LINE CHANGED
   fs.copy(fileName, destName)
endIf

To index

466 windowsSystemDir() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example does not work
< Quote >
var
   fs FileSystem
   fileName, destName String
endVar

fileName = "\\special.drv"

fs.setDrive("B")
if fs.findFirst(fileName) then
   destName = windowsSystemDir() + fileName
   fs.copy(fileName, destName)
endIf
< /Quote >


Use this code instead
var
   fs FileSystem
   fileName, destName String
endVar

fileName = "special.drv" ; LINE CHANGED

fs.setDir("B:\\") ; LINE CHANGED
if fs.findFirst(fileName) then
   destName = windowsSystemDir() +"\\"+ fileName ; LINE CHANGED
   fs.copy(fileName, destName)
endIf

To index

467 setPrivDir() examples
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 1 - Using a menu choice to set the private directory

The example shown is not relevant any longer (Paradox 10 and later versions).

Here's a modified example

The following example changes the private directory and the resulting menu commands generated by Paradox. When you issue a menuAction(MenuFilePrivateDir), the code calls disableDefault to block the default behavior. This prevents Paradox from displaying the Set Private Directory dialog box and then tests the value of a Logical variable okToChangePriv (declared and assigned elsewhere). If okToChangePriv is True, the code calls setPrivDir to set the private directory (:PRIV:) behind the scenes.

The code responds to the MenuChangedPriv menu command, issued by Paradox just after it changes the private directory.

Code in a form's menuAction event

method menuAction(var eventInfo MenuEvent)

; In a real app you'd declare and assign this variable elsewhere.

okToChangePriv = True
if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form

   switch
      case eventInfo.id() = MenuFilePrivateDir :
         disableDefault ; Block the default behavior.
         if okToChangePriv then
            setPrivDir("c:\\pdx\\mine") ; Set :PRIV: to hard-coded path.
         else
            return
         endIf

      case eventInfo.id() = MenuChangedPriv :
         ; You may want to take some action after changing :PRIV:.
         ; This example just displays the new path.
         message(privDir())
         sleep(1000)

      otherwise : doDefault
   endSwitch
else
   ;// This code executes only for the form
endif
endMethod


The code below is used in a button or any suitable event.
self.menuAction(MenuFilePrivateDir)

or in a menu as a menuconstant MenuFilePrivateDir bound to the menuchoice


Example 2 - Using a form's open method

The following example uses the open and the menuAction methods of a form to set the private directory before the form opens. In the form's built-in open method, setPrivDir changes the private directory to the same directory as the form.

The following code is attached to the form's built-in open method:

;frm1 :: open
method open(var eventInfo Event)
   var
      f Form
      dynPath DynArray[] String
   endVar

   if eventInfo.isPreFilter() then
      ; This code executes for each object on the form:
      f.attach()
      splitFullFileName(f.getFileName(), dynPath)
      setPrivDir(dynPath["Drive"] + dynPath["Path"])
   else
      ; This code executes only for the form:
   endIf
endMethod

To index

469 setWorkingDir() examples
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 1 - Using a menu command to set the working directory

The initial text describing the example is better changed to:

The following example uses a menu command to change the working directory, and the resulting menu commands. When you click File - Working Directory, the code calls ........

To index

693 enumFileList()
Buglist Id: Last tested in version: First seen in version:
11 Build 41011 Build 410

Help files says
< Quote >
enumFileList lists information about files that match the criteria specified in fileSpec. If fileSpec is *.*, the array or table includes records for the current directory (.) and the parent directory (..).
< /Quote >

Nothing is said on the file specification, so you should assume it works like a file specification on the command prompt. * and ? can be used. If your filenames don't conform to the 8.3 notation, watch out for extension selections when wildcard * is used.

An example:
dir scb?.jpg
will find scb2.jpg

dir scb*.jpg
will find scb2.jpg, scbcolor.jpg, as well as scb2.jpg8

But
dir cust*.db
won't find customer.dbf, only customer.db

Reported by: "Robert Molyneux"
Date: 30 November 2005

To index

43 getFileAccessRights()
Buglist Id: Last tested in version: First seen in version:
PX049911 Build 2337.0 W95

If the filename specified in getFileAccessRights() is incorrect, you'll get an error saying "You have tried to use an unassigned variable".

To index

55 totalDiskSpaceEx() example
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

Example in the help files is using wrong method

< Quote >
var
   L longint
   FS filesystem
endvar

L = FS.totalDiskSpace("C")
msginfo("Total Disk Space", "Drive C is " + string(L) + " Kilobytes.")
endMethod
< /Quote >

To index

128 freeDiskSpaceEx()
Buglist Id: Last tested in version: First seen in version:
10.0 P28.0

Methods FreeDiskSpaceEx() and TotalDiskSpaceEx() may return incorrect result for disks larger than 2GB depending on the version of Windows used. Problem does not occur in Win2000.

From: Ivica Kolar
Subject: LongInt limitation, DriveSpace
Date: 10 November 2001

Use this script:
method run(var eventInfo Event)
var
    fs filesystem
endvar

;To do this test correctly you shoud have more than 2GB free on disk C.
    msgInfo(fs.freeDiskSpace("C")/1024, fs.freeDiskSpaceEx("C")) ;T1

;To do this test correctly you should have C partition bigger than 2GB.
    msgInfo(fs.totalDiskSpace("C")/1024, fs.totalDiskSpaceEx("C")) ;T2

endMethod

My results with PC1: P9.00.883/Win98:
    T1: ignored, free space < 2GB
    T2: shows 2096832 instead of 4104564

My results with PC2: P10.0.0.663/Win98:
    T1: shows 2096832 instead of something like 14059008
    T2: shows 2096832 instead of something like 19926880

I have not 64bit hexa calculator handy so I can not make exact calculations.


From: Ivica Kolar
Date: 10 November 2001

Regarding API...

API emulation of totalDiskSpaceEX(), freeDiskSpaceEX() follows (just written):

Uses KERNEL32
{
BOOL GetDiskFreeSpace(

  LPCTSTR lpRootPathName, // address of root path
  LPDWORD lpSectorsPerCluster, // address of sectors per cluster
  LPDWORD lpBytesPerSector, // address of bytes per sector
  LPDWORD lpNumberOfFreeClusters, // address of number of free clusters
  LPDWORD lpTotalNumberOfClusters // address of total number of clusters
 );
}

     GetDiskFreeSpace( sRootPathName CPTR,
           liSectorsPerCluster CPTR,
           liBytesPerSector CPTR,
           liNumberOfFreeClusters CPTR,
           liTotalNumberOfClusters CPTR )CWORD [STDCALL "GetDiskFreeSpaceA"]

     GetLastError() CLONG
endUses

method run(var eventInfo Event)
var
     sRootPathName String
     liSectorsPerCluster,
     liBytesPerSector,
     liNumberOfFreeClusters,
     liTotalNumberOfClusters LongInt
     siBool SmallInt
     liError LongInt
     liKBPC LongInt
     dar DynArray[] AnyType
endvar

     sRootPathName = "C:\\"
     siBool = GetDiskFreeSpace( sRootPathName, liSectorsPerCluster,
            liBytesPerSector, liNumberOfFreeClusters, liTotalNumberOfClusters )

     if siBool = 0 then
          liError = GetLastError()
          msgInfo("API ERROR", liError )
     else
          dar["1 #SectorsPerCluster"] = liSectorsPerCluster
          dar["2 #BytesPerSector"] = liBytesPerSector
          dar["3 #FreeClusters"] = liNumberOfFreeClusters
          dar["4 #TotalClusters"] = liTotalNumberOfClusters
          liKBPC = (liSectorsPerCluster * liBytesPerSector) /1024
          dar["5 #KB PerCluster"] = liKBPC
          dar["6 FreeSpace [KB]"] = liNumberOfFreeClusters * liKBPC
          dar["7 TotalSpace [KB]"] = liTotalNumberOfClusters * liKBPC
          dar.view("I got it! ")
     endif
endMethod

Unfortunatelly, seems that Paradox methods uses GetDiskFreeSpace() too.
I mean, above emulation also returns wrong information.
What is wrong is:
          dar["3 #FreeClusters"] = liNumberOfFreeClusters
          dar["4 #TotalClusters"] = liTotalNumberOfClusters

Both values are 16 bits!


From: Ivica Kolar
Date: 10 November 2001


My results so far - OS is Win98,
What returns invalid value when space is > 2GB:
    1. freeDiskSpaceEx() and totalDiskSpaceEx(), (checked with P8/9/10)
    2. API emulation using GetDiskFreeSpace(), (checked with P8/9/10)
    3. Paradox10 Menu: Help/AboutParadox/SystemInfo: item "Available space on drive C"
        Note: This value is same as in 1 & 2 for freeDiskSpace.
    4. WordPerfect & other WPO components,
        Menu: Help/About.../SystemInfo: item "Available space on drive C"
        Note: This value strongly differs from one obtained in 3.

What returns proper value:
    Windows itself (properties...), DOS (Chkdsk...)...


From: Ivica Kolar
Date: 11 November 2001

A few more notes...

{
The GetDiskFreeSpace API is used in Windows 95 and Windows NT 3.x.
The GetDiskFreeSpaceEx is only available under Windows NT 4.0 or later, or Windows 95 OSR2 or later...

So what we have to is:
     Try to use GetDiskFreeSpaceEx.
     If above fails we need to use GetDiskFreeSpace.
}

Uses KERNEL32

 GetDiskFreeSpaceExA( sRootPathName CPTR,
       llUserBytes CPTR,
       llTotalBytes CPTR ,
       llFreeBytes CPTR )CWORD

 GetLastError() CLONG
 MoveMemory( lpDst CPTR, lpSrc CPTR , liSze CLONG) [STDCALL
"RtlMoveMemory"]

endUses

method run(var eventInfo Event)
var
     sRootPathName String
     llUserBytes, llFreeBytes, llTotalBytes Number
     llFreeBytesL, llFreeBytesH,
     llTotalBytesL,llTotalBytesH LongInt

     liSize LongInt
     siBool SmallInt
     liError LongInt
     dar DynArray[] AnyType
endvar

     sRootPathName = "C:\\"
     siBool = GetDiskFreeSpaceExA( sRootPathName, llUserBytes, llTotalBytes, llFreeBytes )

     if siBool = 0 then
          liError = GetLastError()
;W95 or NT3.x: GetDiskFreeSpaceExA not available!
        ;use GetDiskFreeSpace here
 else

      llFreeBytesL = 0
      llFreeBytesH = 0
      llTotalBytesL = 0
      llTotalBytesH = 0

      liSize = 4
;Get Low 32 bit part
      MoveMemory(llTotalBytesL, llTotalBytes, liSize )
      MoveMemory(llFreeBytesL, llFreeBytes, liSize )

;Get High 32 bit part
;The problem is here: We can not do pointer arithmetic in Paradox!
;And we can not access High 32bit part of 64 bit integer!
; MoveMemory(llFreeBytesH, llFreeBytes+4, liSize )
; MoveMemory(llTotalBytesH, llTotalBytes+4, liSize )

  dar["1 #FreeBytesH"] = llFreeBytesH
  dar["1 #FreeBytesL"] = llFreeBytesL
  dar["2 #TotalBytesH"] = llTotalBytesH
  dar["2 #TotalBytesL"] = llTotalBytesL
  dar.view("")
 endif

endMethod

To index

129 totalDiskSpaceEx()
Buglist Id: Last tested in version: First seen in version:
10.0 P2

To index

118 deleteDir()
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

FileSystem type has examples on fs.delete() and fs.deleteDir(), but on Win NT , and Win2000, you may get into problems when combining fs.delete() and fs.deleteDir().

Here's how to delete a directory after the files have been deleted.

Example 1)

var
   fs filesystem
   stFile string
   si smallInt
   arFiles array[] string
endvar

fs.setDir("C:\\DATA\\CHRISTINAJ\\")
fs.enumFileList( "*.*", arFiles )
for si from 1 to arFiles.size()
    stFile="C:\\DATA\\CHRISTINAJ\\"+arFiles[si]
    if fs.findFirst(stFile) then
        fs.delete(stFile)
    else
        msgInfo(stFile, "File not found.")
    endIf
endfor

; Files are deleted. Now delete the directory

fs.unAssign() ; NOTE This is necessary
if not fs.deleteDir("C:\\DATA\\CHRISTINAJ" ) then
    ;This message displays all the time
     msgStop( "Error", "Dir can not be deleted" )
endif


Example 2)
var
   fs filesystem
   stFile string
   si smallInt
   arFiles array[] string
endvar

fs.setDir("C:\\DATA\\CHRISTINAJ\\")
if fs.findFirst("*.*") then
    message(fs.name())
    fs.delete(fs.name())
    while fs.findNext()
        message(fs.name())
        fs.delete(fs.name())
    endWhile
else
    msgInfo("*.*", "File not found.")
endIf

; NOTE No fs.unAssign() needed

if not fs.deleteDir("C:\\DATA\\CHRISTINAJ" ) then
    msgStop( "Error", "Dir can not be deleted" )
endif

To index

282 freeDiskSpace()
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

Method is replaced by freeDiskSpaceEx(). As it returns number of bytes as a longint, it can't handle disks with more than 2Gb free space.

To index

283 totalDiskSpace()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

Method is replaced by totalDiskSpaceEx(). As it returns number of bytes as a longint, it can't handle disks larger than 2Gb.

To index

196 totalDiskSpaceEx()
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

If you haven't inserted a floppy in the floppy drive, the method will return -1 in Paradox for Win95, instead of 0 as in Paradox for Win 3.1x

To index

ObjectPAL---Form type

318 isDelivered() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isDelivered() Logical

tests to determine if the form is delivered. This check is performed internally, not by the extension of the filename.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
method pushButton(var eventInfo Event)
var
   f form
endvar

f.open("MyForm")
msgInfo(f.isDelivered(),"")
endMethod

COMMENTS:
Using a fsl file renamed to fdl, isDelivered() reported True.

To index

319 setIcon() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setIcon(const fileName String, const index LongInt) Logical

Same as setIcon(fileName) except allows an icon other than the first one to be chosen


Reported by: David Berg, Paradox Development
Date: 1996

To index

116 Property DesktopForm
Buglist Id: Last tested in version: First seen in version:
11 Build 233

The description of the DesktopForm property from the help files:
< Quote >
DesktopForm is a read-write property of form objects which enables the application to have a background form available to handle menu events when no other forms are active on the Desktop. Only one form on the Desktop should have this property set at any time. This property takes effect only when there are no other MDI child windows on the Desktop. In this case, menu events are sent to this form (by way of its menuAction event method).
< /Quote >

There is nothing said of key events.

If the menu contains menu shortcuts like Ctrl+P, Ctrl+C, there is no way to handle those shortcuts in a hidden desktopform.

To index

183 formCaller()
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

Example of formCaller() method is very basic. The method is used in a pushButton event to show the title of the calling form. A more realistic example would have covered how to get formCaller() to work when you want to change the appearance of the form when the form is called from another form.

This note should have been in the help files: To get formCaller() to work during the opening process of a form, you have to issue an postAction() to the form from the calling form between the frm.open() and frm.wait() statements.


Example:
You want to change the labeltext on a button depending on how the form is opened. When called, labeltext should be Return. When opened on its own, it should say Close.

Give the button a name, btnClose.
Give it a custom method uSetLabeltext(const stText string)
self'labeltext=stText

In button's open event
uSetLabeltext("Close")

In form level action event, write this code:
var
   fCaller form
endvar
if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form

else
   ;// This code executes only for the form
   if eventInfo.id()=UserAction+1 then
      if formCaller(fCaller) then ; try to get a handle to the calling form
         btnClose.uSetLabeltext("Return")
      endif
    endif
endIf

And eventually in the calling form, you have to post an action to the called form. Moving the postAction to the called form's open event, won't work. It has to be sent from the calling form.

var
   f form
endvar

f.open(":Buggar:Wad\\formCaller2")
f.postAction(UserAction+1)
f.wait()
f.close()


BACKGROUND
REPLY BY: Brian Bushay
FormCaller only works while the WAIT() is in effect. You can not use it in the open(), arrive() or setFocus() methods of a form because these take place before the wait() begins. One way around this is to use postAction to generate a user defined action just before the wait()

frm.active.postAction(UserAction+1)
frm.wait()

Then in the called form's action method trap for the userAction and use formCaller()

To index

99 isMaximized()
Buglist Id: Last tested in version: First seen in version:
PX018211 Build 2337.0 W95

Retrieving the maximized state of a form with isMaximized() in removeFocus() event does not return the expected value when you move from a form to another form. By the time removeFocus() is called, the form is no longer maximized. Only if you are moving between forms and dialogboxes is value returned in a proper way.


WorkAround:
You can catch the menuactions MenuControlMaximize, MenuControlMinimize and MenuControlRestore to get the information whether the form is maximized or not.

To index

644 getProtoProperty()
Buglist Id: Last tested in version: First seen in version:
11 Build 3005.04

According to help files
< Quote >
getProtoProperty ( const objectType SmallInt, propertyName String ) AnyType

Description

getProtoProperty returns the value of the property specified in propertyName of the prototype object specified in objectType. To specify objectType, use one of the UIObjectTypes constants. If called as a method, getProtoProperty operates on prototype objects in the style sheet of the specified form. If called as a procedure, getProtoProperty uses the style sheet of the current form.
< /Quote >

The help file does not mention the properties that can be retrieved this way. Some properties that belongs to objects existing on the toolbar, will cause a Unexpected: General Protection Violation error, when referenced in GetProtoProperty().

Example

msgInfo(getProtoProperty (TextTool, "AvgCharSize"), "")

I have tested all properties retrieved by enumUiClasses() and categorized as PropertyObjects together with TextTool and FieldTool. None of those causes a GPV, but a couple creates an error. AvgCharSize is not one of the properties mentioned in the table created.


Reported by: "FGM"
Subject: Possible bug in getProtoProperty
Date: 28 April 2004

To index

650 formCaller()
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

According to the help files:
< Quote >
formCaller assigns the handle of the current form's calling form to caller, if the form is waiting. If the current form was not opened by another form, and the form that opened the current form is not waiting for the current form, the method returns False and caller is unassigned.
< /Quote >

formCaller can also tell you if a script was opened by a script or run directly.

method run(var eventInfo Event)

var
  f Form
  stCallerName string
endVar
message("Called script is executing...")
if formCaller(f) then ; try to get a handle to the calling script
  stCallerName = f.getFileName() ; get the script's name
  msgInfo("FYI", "I was called by: \n" + stCallerName)
else
  msgInfo("FYI", "I was NOT called")
endif
formReturn()

endMethod

This script can be called by another script:
method run(var eventInfo Event)
var
  scr Script
endVar
scr.load(":BUGGAR:Wad\\Di0650CalledScript")
scr.run()
scr.close()
endMethod

Conclusion: For formCaller() a script behaves like a form waited upon.


Reported by: "Tony McGuire"
Date: 2 August 2004

To index

679 dmAddTable()
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95

The help file says
< Quote >
Adds a table to a form's data model.

Syntax

dmAddTable ( const tableName String ) Logical
< /Quote >

It does not have to be a table. It can just as well be a QBE file.

To index

470 attach() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

In the second example, the code in attachToSite button does not behave as described.
< Quote >
The following code is attached to the pushButton method for attachToSites:

; attachToSites::pushButton
method pushButton(var eventInfo Event)
var
   sitesForm Form
endVar

; Attach to Sitenote by its title (Notes).
; Note that this won't work: sitesForm.attach("Sitenote")
if not sitesForm.attach("Notes") then
      errorShow()
      return
endIf

; cycle through sizes
sitesForm.minimize() ; minimize the form
sleep(2000) ; pause
sitesForm.maximize() ; maximize the form
sleep(2000) ; pause
sitesForm.show() ; restore to original size
endMethod
< /Quote >

sitesForm.show() won't restore the maximized form.

To index

471 dmGet() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

472 dmGetProperty() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Explanation to the example:

Create the UpdateProperties() as a custom method at form level.

Call it from a pushButton with code like

Customer.UpdateProperties()
or
Orders.UpdateProperties()

To index

475 stringListRefresh() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

There is no example. Maybe because stringListRefresh() seems to be unnecessary. It is automatically refreshed when stringlistfilename property is changed.


method pushButton(var eventInfo Event)
var
f form
   st string
endvar

f.attach()
f'stringlistfilename="SW_Names.pxr"
f.stringListRefresh()
endMethod

To index

476 getSelectedObjects() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

When running the example code, make sure the default size for a new form is large enough to hold the three boxes. If not, the boxes can't be created and the code will give an Unassigned variable error.

To index

477 isMaximized() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example contains code to restore a maximized form, but form.show() won't restore a maximized form.

To index

478 writeText()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to the help file:
< Quote >
This method will be removed in a future version of Paradox. It is recommended that you use the publishTo method instead.
< /Quote >

The method works in Paradox 9, but not in Paradox 10 and later versions. It may cause Unexpected Generel Protection Violation errors. Especially when applied to a form variable as shown in the example code.

To index

291 bringToTop()
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0 P3

According to the help files
< Quote >
If a hide statement has made a form invisible, bringToTop makes it visible again.
< /Quote >

The statement is correct, but there's more to say.

When a form is opened hidden, you have to restore the form in a correct way to prevent effects on the toolbars shown in your application.

var
 f form
endvar

f.open(":BUGGAR:Wad\\Px0350c", WinstyleDefault+WinstyleHidden)
f.show()
f.bringtotop()
close()

is the correct way to make the Property toolbar enter the correct state - Run form, instead of state - Empty desktop. With f.bringtotop() and f.show() in the opposite order, the opened form will get a property toolbar as Empty desktop.

This effect may be seen only when the forms have StandardMenu property set to False.

Even though help files says bringTotop() makes a hidden form visible, use it after a show() when necessary to bring the form to top.

To index

422 show()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to the help files
< Quote >
show makes a hidden form visible. show also restores a minimized window. show doesn't make a form the top window; use bringToTop to make a form the top layer and give it focus.
< /Quote >

But what about a maximized form? How do you restore a maximized form? In Paradox7, show() would restore a maximized form, but not in Paradox9 and later versions.

You have to use Windows API

Uses "USER32"
ShowWindow(windowHandle CLONG,windowState CLONG)
endUses

Const
    SW_RESTORE=longint(9)
endConst

and this executing code
var
 liHandle longint
endvar

liHandle=windowhandle()
showWindow(lihandle, SW_RESTORE)

or you can use an undocumented MSWindow type method show()

var
msw MSWindow
endvar

msw.attach(windowHandle())
msw.show()

or you can use

var
  f form
endvar
f.attach(TargetForm)
winsendmessage(f.windowhandle(),winGetMessageId("WM_SYSCOMMAND"),61728 ,0)

To index

ObjectPAL---Graphic type

668 readFromFile()
Buglist Id: Last tested in version: First seen in version:
11 Build 30210.0 RT

PARADOX RUNTIME

SUMMARY:
You cannot read all tif files with graphic.readfromfile() in Paradox Runtime.

According to the help files on Paradox Runtime, some graphic filters are not available:
< Quote >
 Graphics filters (.cdr, .cpt, .wpg, .cmx, .png, .pcd, .wmf, and .emf)
< /Quote >

.tif is not mentioned.

Reading some .tif files in full Paradox following Paradox files are accessed:

C:\Program\Corel\Paradox\Programs\PFIT110.DLL
C:\Program\Corel\Paradox\Programs\WStr11.dll
C:\Program\Corel\Paradox\Programs\Convert\GraphicsImport110.dll ** Does not exist in Runtime
C:\Documents and Settings\scbcbis\Application Data\Corel\WordPerfect Office 11\User Config\CdrConv.ini
C:\Program\Corel\Paradox\Programs\CDRCONV.EXE ** Does not exist in Runtime
C:\Program\Corel\Paradox\Programs\CRLPPD110.dll ** Does not exist in Runtime
C:\PROGRAM\COREL\PARADOX\PROGRAMS\PDXVWR32.DLL ** Does not exist in Runtime

Originally reported by: "Alec Scaresbrook"
Date: 24 December 2004

To index

661 readFromClipboard()
Buglist Id: Last tested in version: First seen in version:
11 Build 3029.0

Most RTL methods will fail when errorTrapOnWarnings(Yes) is set and the method returns a False value. readFromClipboard() does not.

Not testing the return value from readFromClipboard() may cause an error "You have tried to use an unassigned variable. A variable must be assigned a value before you can use it." later on.

To index

158 writeToFile() creating jpg
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT

PARADOX RUNTIME

SUMMARY:
You cannot create jpg file with graphic.writetofile("filename",graphicJPEG) in Paradox Runtime.

According to the help files on Paradox Runtime, some graphic filters are not available:
< Quote >
 Graphics filters (.cdr, .cpt, .wpg, .cmx, .png, .pcd, .wmf, and .emf)
< /Quote >

jpg is not mentioned.

There's a jpg import filter in Paradox 10 Runtime, but no export filter. That should have been in the docs.

To index

160 writeToFile()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0

According to the help files the syntax is

graphic.writeToFile ( const fileName String [, const FileType smallint ] [, var options dynArray[] anytype ])

but the dynarray is not described at all.


EXAMPLE and DESCRIPTION OF dynarray elements:

There are only options for graphicJPEG:

var
    g graphic
    dynOptions dynArray [] anytype
endVar

dynOptions["compression"] = 25 ; can be 1 to 255
dynOptions["smoothing"] = 25 ; can be 1 to 255
dynOptions["encodingMethod"] = "none" ; can be "none", "progressive", or "optimized"
dynOptions["subFormat"] = "standard" ; can be "standard" or "optional"

g = graphicField.value
g.writeToFile("myfile.jpg", graphicJPEG, dynOptions)


REPORTED BY: Dan Alder (Corel)
Date: 8 May 2001


When this syntax has been tested in Paradox 10, the destination file has always the same size.

Reported by:
Fabio Spaggiari
Date: 10 April 2002


Verified by:
Bertil Isberg

To index

141 readFromFile()
Buglist Id: Last tested in version: First seen in version:
10.0 P2

To index

ObjectPAL---keyEvent type

206 isControlKeyDown()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P2

Key Event has methods isControlKeyDown() and isAltKeyDown().

For both methods the help files says:
< Quote >
Reports whether CTRL (ALT) was held down during a KeyEvent.
< /Quote >
This is not the complete description. Both of them will also report whether AltGr was held down during the keyEvent.

To catch only Ctrl+E, and not AltGr+E, the code should look like

if eventInfo.isControlKeyDown() and
   eventInfo.isAltKeyDown()=false and
   eventInfo.vChar() = "E" then
       msginfo("CTRL E only" ,"")
       ; do something
endif

When AltGr is pressed, both isControlKeyDown() and isAltKeyDown() is true.

To index

207 isAltKeyDown()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P2

To index

479 setControlKeyDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 1- thisForm

Wrong method, eventInfo.vChar(), is used to catch the "C". eventInfo.char() should be used.

Correct code:
method keyPhysical(var eventInfo KeyEvent)

if eventInfo.isPreFilter() then
  ; code here executes for each object in form
  if eventInfo.isControlKeyDown() and ; if user presses CTRL + C
    eventInfo.char() = "C" then ; THIS LINE CHANGED
    disableDefault ; block normal processing
    ; alternate color of boxOne between red and blue
    boxOne.color = iif(boxOne.color = Red, Blue, Red)
  endif
else
  ; code here executes just for form itself
endif
endMethod

To index

480 isFromUi() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

481 setShiftKeyDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

482 setAltKeyDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

ObjectPAL---Keywords

621 switch example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Code contains a typo
< Quote >
for i from 1 to sz-1 step 1
   for j from 1 to sz-i step 1
      if a[j] <> a[j+1] then
         a.exchange(j, j+1)
      endIf
   endFor
endFor
< /Quote >

The line
     if a[j] <> a[j+1] then
should be
     if a[j] > a[j+1] then
or
     if a[j] < a[j+1] then
depending on which sort order you prefer. Ascending or descending

To index

622 quitloop example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Syntax error in code
< Quote >
var
   myArray Array[12]
   notAssigned Logical
endVar
< /Quote >

should be
   myArray Array[12] string ; or anything else

To index

641 Uses
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0 P4

In Paradox 10 SP4 and higher version numbers ( P11 SP1), watch out for references to WinAPI functions and other functions in externals DLLS and EXEs

Specifying the stdcall calling convention which works fine in P7 SP4 and P9 SP4 will cause GPV on exit or earlier in P10 SP4.

Uses "kernel32.dll"
GetComputerName(lpBuffer cptr, nSize cptr) cLong [stdcall "GetComputerNameA"]
endUses
Uses "advapi32.dll"
GetUserName(lpBuffer cptr, nSize cptr) cLong [stdcall "GetUserNameA"]
endUses

The code is calling GetComputerName() and GetUserName().

Change the Uses clause to
Uses "kernel32.dll"
GetComputerNameA(lpBuffer cptr, nSize cptr) cLong
endUses
Uses "advapi32.dll"
GetUserNameA(lpBuffer cptr, nSize cptr) cLong
endUses

and call GetComputerNameA() and GetUserNameA() instead.

To index

284 Uses
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

You can use an alias when specifying where a DLL or EXE file is stored.

Uses :Alias:MyDLL
   whatever()
endUses

Reported by: Dan Alder (Corel)
Date: 10 May 2000

New in Paradox 9, but not mentioned in the help files.

MY COMMENTS:
Date: 31 August 2005

I tested with SHELL32.DLL and created an alias pointing to C:\WINNT\SYSTEM32.

Uses ":MYWIN32:SHELL32"

ShellExecuteA(hwnd cLong,
   lpOperation cptr,
   lpFile cptr,
   lpParameters cptr,
   lpDirectory cptr,
   nShowCmd cLong) cLong

endUses

With this setup, I got an error saying "This form references external procedures or DLLs which could not be found" followed by "Could not find DLL, :MYWIN32:SHEL32.DLL, referenced in the USES statement. You cannot call methods from this DLL."

When I copied this DLL to an alias :BUGGAR: and ran a form with a subdirectory to :BUGGAR: as working directory, I could use an alias specification.

Uses ":BUGGAR:SHELL32"

With Filemon, I can verify it's the SHELL32.DLL from my alias that is loaded.

With Filemon, I can also see that when the alias MYWIN32 is referenced, I get a "Sharing violation" when the DLL is to be loaded. It looks like the alias specification makes Paradox try to load a new instance of SHELL32.DLL instead of using the instance already loaded by Windows.

So, you can use an alias to specify where the DLL or EXE is, but there are certain exceptions.

To index

109 scan keyword
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.0

Syntax for scan:

scan tcVar [ for booleanExpression ] :
      Statements
endScan

The tcVar cannot be an element in an array of tcursors.

The statement
Scan artc[1] :

where artc is declared as
artc array[] tcursor

will cause an Error: Syntax error.


Workaround:

Use a while loop
while not artc[1].eot()

or
use tc.attach(artc[1])
and
scan tc:

To index

82 for - loop
Buglist Id: Last tested in version: First seen in version:
PX042311 Build 2331.0

If the variables used for start and stop in a for loop are unassigned , you'll get an infinite loop.

To index

79 try - onFail
Buglist Id: Last tested in version: First seen in version:
PX037011 Build 2339.0

A return statement or a loop statement inside the onFail clause will bring up the errormessage.

Workaround:
use errorClear() before return / loop

To index

44 Const
Buglist Id: Last tested in version: First seen in version:
PX050110.07.0 W95 P4

Typecasting string to date in a Const window doesn't accept the Windows Short date format.

Example:

in a method I can use:
dateVariable=date("2000-12-31")

but in a Const window it is not accepted.
ctdMydate=date("2000-12-31").

ctMydate=date("12/31/2000") is accepted.

To index

ObjectPAL---Library type

320 isDelivered() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isDelivered() Logical

tests to determine if the library is delivered. This check is performed internally, not by the extension of the filename.


Reported by: Paul Cronk - Corel
Date: 5 april 2000

Example:
var
   l library
endvar

l.open("PX0672")
msgInfo(l.isDelivered(),"")

COMMENTS:
Using a lsl file renamed to ldl, isDelivered() reported True.

To index

483 close() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example forgets to mention that usage of explicitly named methods in a library requires a USES block.


Add this code to a USES block in the button or any of its containers

Uses ObjectPAL

"tools.lsl"
"kit.lsl"

endUses

To index

ObjectPAL---List object

297 DataSource property
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

According to the help files
< Quote >
In any method of a list object,
self.datasource="[:alias:table.fieldname]"
will fill the listbox with the specified table values.
< /Quote >

But ":ALIAS:tablename.columnname" is enough

To index

ObjectPAL---longint type

502 isBitSet() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Both examples are using smallint.isBitSet() instead of longInt.isBitSet().

To index

ObjectPAL---longInt type

321 hiWord() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Undocumented.

Syntax:
hiWord(const value LongInt) LongInt

Returns the high order word (the most significant 16 bits). For example, hiWord(200000) returns 3. Equivalent to dividing the number by 65,536.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
method pushButton(var eventInfo Event)
var
   li, liHi longint
endvar

li=longInt(6400)*6400
li.view()

liHi=li.hiword() ; 625
liHi.view()

endMethod

To index

322 loWord() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Undocumented.

Syntax:
loWord(const value LongInt) LongInt

Returns the low order word (the least significant 16 bits). For example, hiWord(200000) returns 3392. Equivalent to the number modulo 65,536.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
method pushButton(var eventInfo Event)
var
   li, liLow longint
endvar

li=longInt(6400)*6400
li.view()

liLow=li.loword() ; 0
liLow.view()

endMethod

To index

144 Assigning a hex constant
Buglist Id: Last tested in version: First seen in version:
10.0 P29.0

If the longint hexadecimal constant has 1 in the most significant bit (which means negative integer), Paradox takes only 4 the least significant hexadecimal digits and treats them as signed *smallint*. the four most significant digits are ignored in this case.
Example:

var
 i longint
endvar
i=0x80000001;evaluates to 1
i=0xFFFF0001;evaluates to 1
i=0x8000FFFF;evaluates to -1
i=0x8534FFFF;evaluates to -1


REPORTED BY: Vladimir Menkin
Subject: Bug with hexadecimals
Date: 4 February 2002


COMMENTS:
From: Bertil Isberg

Isn't this a case where the method fromHex() is to be used?

Reading help files on hexadecimal numbers, there are two topics, fromHex() and toHex().

method fromHex() returns the value you expect.

Example:
i=fromHex("0x80000001");evaluates to -2147483647

To index

ObjectPAL---Mail type

323 addDataDlg() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
addDataDlg(const tableName String, const moniker String, const dataFormat SmallInt)

addDataDlg(const tc TCursor, const moniker String, const dataFormat SmallInt)

To index

610 getAttachment() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get a complete example, add this code after endvar

   m.addAddress("JDOE")
   m.addAddress("SSMITH", MailAddrCC)
   m.setSubject("Final sales numbers")
   m.setMessage("The final sales numbers are attached")
   m.addAttachment("SALES.TXT")

To index

611 getAttachmentCount() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get a complete example, add this code after endvar

   m.addAddress("JDOE")
   m.addAddress("SSMITH", MailAddrCC)
   m.setSubject("Final sales numbers")
   m.setMessage("The final sales numbers are attached")

To index

612 getMessage() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get a complete example, add this code after endvar

   m.addAddress("JDOE")
   m.addAddress("SSMITH", MailAddrCC)
   m.setSubject("Final sales numbers")
   m.setMessage("The final sales numbers are attached")
   m.addAttachment("SALES.TXT")

To index

613 getMessageType() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get a complete example, add this code after endvar

   m.addAddress("JDOE")
   m.addAddress("SSMITH", MailAddrCC)
   m.setSubject("Final sales numbers")
   m.setMessage("The final sales numbers are attached")
   m.addAttachment("SALES.TXT")
   m.setMessageType("IPM.URGENT")

To index

614 getSender() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get a complete example, add code from readMessage() and get this example

method pushButton(var eventInfo Event)

var
   msg,
   replyMsg Mail
   sender,
   fullAddress String
;endVar
;var
   inboxIds Array [] String
   i LongInt
endVar

; Code form readMessage
msg.enumInbox( inboxIds, True)
for i from 1 to inboxIds.size()
  msg.readMessage(inboxIds[i])
; End Add code
  msg.getSender(sender,fullAddress) ; supplies sender info

  replyMsg.addAddress(fullAddress) ; add sender to reply
  replyMsg.setSubject(msg.getSubject()+" - Reply") ; set reply message
                                                 ; subject to original
                                                  ; subject plus "reply"
  replyMsg.sendDlg() ; open the send dialog to
                                                  ; let user type contents
  ; for the reply message
; Code from readMessage
endFor
; end Add

endMethod

To index

615 getSubject() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get a complete example, add this code after endvar

   m.addAddress("JDOE")
   m.addAddress("SSMITH", MailAddrCC)
   m.setSubject("Final sales numbers")
   m.setMessage("The final sales numbers are attached")
   m.addAttachment("SALES.TXT")

To index

ObjectPAL---Memo type

676 Memo type
Buglist Id: Last tested in version: First seen in version:
11 Build 4109.0

The help mentions what happens when assigning a memo type variable to a string or a memo type variable,
< Quote >
If you assign a memo field to a String variable, you get only the memo text without any formatting. If you assign a memo field to a Memo variable, you get the text and the formatting.
< /Quote >
but nothing is said on assignments to a field bound to a formatted memo column.

When assigning a memo variable to such a field with formattedMemo'value=memoVariable, you have to move off the field first. If the field is active, the formatting is lost. dmput("MyTable", "formattedmemo", memoVariable) is an alternate solution, which does not require the field to be inactive. A third solution is using clipboard.and action(EditPaste). the code would then look like:
memoVariable.writetoclipboard()
formattedMemo.moveto()
;active.action(EditEnterMemoView)
; active.action(MoveEnd)
; Use EditEnterMemo View and MoveEnd, if you want to append the pasted text after the existing
; Use only EditEnterMemoView if you want to insert the pasted text before the existing text
;active.action(selectSelectAll)
; Use SelectSelectAll, if you want to replace existing text with the pasted text
active.action(editPaste)

To index

286 Using sizeEx() on a memo variable
Buglist Id: Last tested in version: First seen in version:
11 Build 3009.0 P4

In the help files, nothing is said on using size() and sizeEx() on memo variables. In most cases, sizeEx() gives the correct result, but there are cases when low ascii characters are involved, where the size of the memo is not the same as the size of string with the same contents.


var
   st2,st1 string
   m memo
endvar

st1="ABCDEFGHIJKLMNOPQRSTUVWXYZ"+chr(26)
st2=string(st1)
msginfo(st1,st2.size()) ;==> gives size = 27
m=memo(st1)
msginfo(m,m.sizeEx()) ;===> gives = 0

st1="AB"+chr(13)+"CD"
st2=string(st1)
msginfo(st1,st2.size()) ;==> gives size=5
m=memo(st1)
msginfo(m,m.sizeEx()) ;===> gives 6


st1="AB"+chr(5)+"CD"
st2=string(st1)
msginfo(st1,st2.size()) ;==> gives size = 5
m=memo(st1)
msginfo(m,m.sizeEx()) ;===> gives 4

Reported by: "Michel Claveau"
Date: 23 August 2003

To index

485 memo() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to the text in the example:
< Quote >
When cast as a Memo, memoObject displays all formatting information.
< /Quote >

Font, font color, font size and font style is not displayed.

When
    memoObject.value = tc."MemoData"
the formatting is displayed, though.

To index

487 writeToClipboard() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

In the example, the btnReadFromClipboard code is missing a tc.edit()

Code should be
   ; Open table to hold memos
   tcMemo.open("mymemos.db")
   tcMemo.edit() ; THIS LINE ADDED
   if vrMemo.readFromClipboard() then
      ; Add a record to the table and insert the value
      tcMemo.insertRecord()

To index

ObjectPAL---Menu type

488 All examples
Buglist Id: Last tested in version: First seen in version:
11 Build 300

When the examples are run from design mode, the toolbar buttons indicates Edit mode, but statusbar says View mode.

This happens in Paradox 9 SP4 and later versions, but not in Paradox 7 patch 4.

To index

489 setMenuChoiceAttributeById() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The code in menuAction is missing +UserMenu

method menuAction(var eventInfo MenuEvent)

var
  menuItem SmallInt
endVar

if eventInfo.isPreFilter() then
  ;code here executes for each object in form

  menuItem = eventInfo.id()
  switch
    case menuItem = InsMenu +UserMenu: ; LINE CHANGED
      active.action(DataInsertRecord) ; insert new record
    case menuItem = DelMenu +UserMenu: ; LINE CHANGED
      active.action(DataDeleteRecord) ; delete active record
    case menuItem = UndoMenu +UserMenu: ; LINE CHANGED
      active.action(DataCancelRecord) ; revert record to original state
      setMenuChoiceAttributeById(UserMenu+UndoMenu, MenuDisabled + MenuGrayed) ; LINE CHANGED
  endswitch

else
  ;code here executes just for form itself
endif

endMethod

To index

247 menuChecked
Buglist Id: Last tested in version: First seen in version:
PX035011 Build 2339.0

MenuChoiceAttribute MenuChecked should not be combined with MenuEnabled. Toggling between MenuChecked and MenuNotChecked

To index

248 Example on building menus
Buglist Id: Last tested in version: First seen in version:
PX035011 Build 2337.0 W95 P4

Here's an example on how to build and change menuchoice attributes for a form. Multiple instances of the form can be open and the menus should keep their own settings in each instance when switching between the forms.

Create a blank form with a pushButton. Set labeltext to Disable.

In form's var window

var
   ; Global variables for keeping the menuchoice attributes
   siAttribAttributes,
   siAttribPasswords smallint
endvar

A custom method, uBuildMenu(), defined at form level

method uBuildMenu()
var
  p1, p2, p3 PopUpMenu
  m1 Menu
endVar

p1.addText("Passwords", MenuChecked , UserMenu+1) ; add items to p1 popup
siAttribPasswords=MenuChecked
p1.addText("Attributes...", MenuEnabled, UserMenu+2)
siAttribAttributes=MenuEnabled
p2.addText("Basic...",MenuEnabled, UserMenu+3) ; add items to p2 popup
p2.addText("Scientific...", MenuEnabled, UserMenu+4)

p1.addPopUp("Calculator", p2) ; add another item to p1 popup,
                              ; and display p2 popup when the
                              ; item is selected

p3.addText("About...", MenuEnabled, UserMenu+5) ; add an item to 3rd popup

m1.addPopUp("Utilities", p1) ; add item to menu bar,
                              ; and drop-down p1 when selected
m1.addPopUp("Help", p3) ; add item to menu bar,
                              ; and drop-down p3 when selected
m1.show() ; show the menu bar (not PopUpMenu)

endMethod


Form level menuaction to handle the menuactions.
Only menuitem Utilites | Passwords has an action, checking and unchecking the menuitem itself.
Menuitem Utilites | Attributes.., will be disabled by the pushbutton.

method menuAction(var eventInfo MenuEvent)
var
siAttrib smallInt
endvar
if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form

else
   ;// This code executes only for the form

  if eventInfo.id()=MenuInit then
     setMenuChoiceAttributeById(UserMenu+1, siAttribPasswords )
     setMenuChoiceAttributeById(UserMenu+2, siAttribAttributes )

  endif

  if eventInfo.id()=UserMenu+1 then
      siAttrib = getMenuChoiceAttributeById(UserMenu+1)
      if hasMenuChoiceAttribute(siAttrib, MenuChecked) then
         siAttribPasswords=MenuNotChecked
      else
         siAttribPasswords=MenuChecked
      endif
  endif

endIf

endMethod


Form level open and action contains call to build the menu when form is opened.
method open(var eventInfo Event)

if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form

else
   ;// This code executes only for the form
   doDefault
   self.postAction(UserAction+1)
endIf

endMethod


method action(var eventInfo ActionEvent)

if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form

else
   ;// This code executes only for the form
   if eventInfo.id()=UserAction+1 then
      uBuildMenu()
   endif
endIf

endMethod


Code in the pushButton's pushButton event to disable menuchoice Attributes...

method pushButton(var eventInfo Event)
   siAttribAttributes=MenuDisabled+MenuGrayed
endMethod

To index

155 setMenuChoiceAttribute() example
Buglist Id: Last tested in version: First seen in version:
PX064910.0 P2 RT

PARADOX RUNTIME issue
The example on setMenuChoiceAttribute() where menu is built in form's open event and the menuchoice attribute menuDisabled+menuGrayed is used, will not work in Paradox Runtime. Example should show where the code should be placed, eg in menuAction event when eventInfo.id()=MenuBuild is triggered.

To index

156 setMenuChoiceAttributeById()
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT

To index

101 setMenuChoiceAttributeById()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

In a multi form application where the user can switch between forms, setMenuChoiceAttributeById() and setMenuChoiceAttribute() has to be specified in menuAction event, when catching the event with eventInfo.id()=MenuInit. When specified elsewhere, the attribute won't stick when the user moves to another form and return back.

To index

102 setMenuChoiceAttribute()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

To index

ObjectPAL---menuEvent type

130 Builtin menuconstants
Buglist Id: Last tested in version: First seen in version:
PX051810.0 P25.0

Some of the builtin menuconstants, e g MenuXXXXOpen, like MenuFormOpen, requires a menu "wake up" before used from ObjectPAL. If you start your form from Windows Desktop when launching Paradox, these menuconstants don't work as first selection in the menus. This is an old behaviour in Paradox. In Paradox 10 SP2, Paradox will lock up when such a menuchoice is selected. In P8 and P9, the behaviour was even worse.

The "wake up" code is sendkeys("%%"). This is the same as two keypresses on the Alt button. You can add this line of code to the start script of your application as one of the last thing you do before opening the main form.

To index

490 id() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example 1 - Using a form's built-in menuAction method - says:
< Quote >
The following example attaches code to a form's built-in menuAction method. When the user selects Close from the System menu, attempts to toggle to a design window, or chooses File, Exit, the method asks the user to confirm whether or not to leave the form.
< /Quote >

But only a menuaction(MenuFileExit) issued from inside the form will be caught by the code.
(Paradox 9 SP4 and later versions.)

To index

491 isFromUi() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example1 - Checking for a Delete menu action

Code is using disableDefault to prevent MenuRecordDelete. It's ok as shown due to the use of isFromUi() in the code, but eventInfo.setErrorCode(UserError) should rather be used.

A menuAction(MenuRecordDelete) sent any other way will return TRUE even when record is not deleted when disableDefault is used to prevent an (menu)action to be carried out.


This is how the code should be:
method menuAction(var eventInfo MenuEvent)

if eventInfo.isPreFilter() then
      ; This code executes for each object on the form:

else
      ; This code executes only for the form:

   if eventInfo.id() = MenuRecordDelete and
      eventInfo.isFromUI()
       then
      if msgQuestion("Delete record?",
         "Delete this record?") <> "Yes" then

         eventInfo.setErrorcode(userError)
         return
      endIf
   endIf
endif

endMethod

To index

674 menuCommand constants
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

There is a menuCommand constant MenuWindowTile. It works as a Window Tile Side-by-Side. To get Window Tile Top and Bottom, there is an undocumented and unnamed constant with value 30675.

Reported by: Vladimir Menkin
Date: 22 August 2000

To index

ObjectPAL---mouseEvent type

492 isLeftDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Maybe the code works but is very hard to make anything with the text selected by moving the mouse with left mouse button pressed. The right mouse button can be used to e g cut the selected text.

Look at the setLeftDown() example instead.

To index

493 isMiddleDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

494 isRightDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

see ObjectPAL - menuEvent type - isLeftDown() example - WadId 492

Look at the setRightDown() example instead.

To index

495 setMousePosition() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example requires the mouseRightUp() event to contain code. If blank, the example causes a syntax error.

To index

262 setInside() example
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

The example for setInside() method in Paradox 7-9 is not very easy to understand
< Quote >
In the following example, the mouseUp method for sendAnEvent uses setInside to change the eventInfo variable and then sends the event to buttonOne.

; sendAnEvent::mouseUp
method mouseUp(var eventInfo MouseEvent)
eventInfo.setInside(Yes)
buttonOne.mouseUp(eventInfo)
endMethod

< /Quote >

After having discussed this with Corel, the text was changed in Paradox 10, but it is still not correct. I don't know what happened when we tested this event in Paradox9 and 10.

< Quote >
In the following example, the mouseUp method for sendAnEvent uses setInside to change the eventInfo variable and then sends the event to buttonOne.
Place the following code in the mouseUp event of the form:

; form::mouseUp
method mouseUp(var eventInfo MouseEvent)
eventInfo.setInside(Yes)
eventInfo.setInside(No)
buttonOne.mouseUp(eventInfo)
endMethod


Place the following code in the mouseUp event of buttonOne

; buttonOne::mouseUp
method mouseUp(var eventInfo MouseEvent)
msginfo (eventinfo.isinside(),"")
endMethod
< /Quote >

Here's how the example should have been

create a button and name it sendAnEvent. Add code from Paradox 9 help files to it.
method mouseUp(var eventInfo MouseEvent)
eventInfo.setInside(Yes)
buttonOne.mouseUp(eventInfo)
endMethod


create a button and name it buttonOne. Add code below to its mouseUp() event:

msginfo (eventinfo.isinside(), self'name)

Run the form. Click button named sendAnEvent. Now buttonOne's mouseUp() is executing.

To index

329 isAltKeyDown() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isAltKeyDown() Logical

tests to see if the alt key has been depressed in a mouse event.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


COMMENT:
Works when setAltKeyDown() is used. It does not recognize the keyboard ALT key.

Example:
see ObjectPAL- MouseEvent - setAltKeyDown() WADID: 328

To index

330 setAltKeyDown() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
setAltKeyDown()

sets the alt key into a depressed state for the event.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example - variation on setConotrolKeyDown

The following example creates a MouseEvent and sets ALT to Yes. The event is then sent to the mouseUp built-in event method for a field called lcField. This method is attached to the pushButton method for a button named sendALT:

; sendALT::pushButton
method pushButton(var eventInfo Event)
var
  ALTMsEvent MouseEvent ; declare the event
endVar

ALTMsEvent.setControlKeyDown(Yes) ; set the Control key
lcField.mouseUp(ALTMsEvent) ; send the event
endMethod

The following code is attached to the mouseUp method for lcField. This method checks whether ALT is pressed when the mouse is clicked. If so, the value in the field is changed to all lowercase.

; lcField::mouseUp
method mouseUp(var eventInfo MouseEvent)
if eventInfo.isAltKeyDown() then ; check for Alt key
  self.Value = lower(self.Value) ; change to lowercase
endif
endMethod

To index

ObjectPAL---MSWindow type

331 attach() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
attach() Logical

Attaches to the window with focus (typically this will be the currently running ObjectPAL form since UIObjects don't have Window Handles).

attach(handle LongInt) Logical

Attaches to the window with the specified window handle. Use Form::windowHandle, Form::windowClientHandle, Application::windowHandle, or Application::windowClientHandle to get Paradox's window handles.

attach(name String) Logical

Attaches to the window with the specified name (title). It can only used for application titles, and not for form titles.

attach(win MSWindow) Logical

Attaches to the window specified by the win variable.

attach(win MSWindow, id AnyType) Logical

Attaches to the child window with the specified id. The win variable must refer to a dialog that contains a control with the specified id.


Example Nov 2003

var
msw msWindow
endvar

msw.attach(windowHandle())
msw.setTitle("MSWindow class test")

Example Jan 2004
var
    msw MSWINDOW
    f form
endvar

f.attach("Form titlel")
msw.attach(f.windowhandle())
msw.maximize()
sleep(500)
msw.show()


var
    msw MSWINDOW
endvar

if not msw.attach("Inbox - Microsoft Outlook")
    errorshow()
endif
msw.maximize()
message("Maximized")
sleep(1000)
msw.show()
message("Restored")


Reported by: David Berg, Paradox Development
Date: 1996

To index

336 bnInfo() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
bnInfo(DynArray dyn)

Identical to EnumProperties; however, it always treats the window as a button.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
msw msWindow
darat dynarray[] anytype
endvar

msw.attach()
msw.bninfo(darat)
darat.view()

To index

337 bringToTop() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
bringToTop() Logical

Change the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

To index

338 cbInfo() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
cbInfo(DynArray dyn)

Identical to EnumProperties; however, it always treats the window as a combo box.


Reported by: David Berg, Paradox Development
Date: 1996


Example:
var
msw msWindow
darat dynarray[] anytype
endvar

msw.attach()
msw.cbinfo(darat)
darat.view()

To index

339 enumProperties() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
enumProperties(var properties DynArray anytype)

enumProperties(const tblName string)

These functions create a list of information known about the window (and it's children???). The information enumerated depends on the type of the window and includes things like:

All Windows Class, Child Id, Focus, Parent, Instance, Text, Text Length, Handle, Position, Size
Edit Controls Count, First Visible Line, Modified, Selection Start, Selection End, Lines
Buttons Checked, Grayed, Highlighted
Combo Boxes Count, First Visible Line, Modified, Selection Start, Selection End, Drop List Showing, Items
List Boxes Count, Selected Count, Top Item, MultiSelect, List Items, Selected Items
Scroll Bars Position, Max, Min


Reported by: David Berg, Paradox Development
Date: 1996


Example:
var
msw msWindow
darat dynarray[] anytype
tv tableview
endvar

msw.attach(windowHandle())
msw.enumProperties(darat)
darat.view()

msw.enumProperties("MyProps.db")
tv.open("MyProps.db")
tv.wait()
tv.close()

To index

341 enumWindowNames() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
EnumWindowNames(tableName AnyType) Logical

Creates a list of all child windows of the window. This includes: Name, Class, Position, Size, Handle, Child ID, Parent Handle, Instance.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
msw msWindow
darat dynarray[] anytype
tv tableview
endvar

msw.attach(windowHandle())
msw.enumProperties(darat)

msw.attach(darat["Parent"])
msw.enumWindowNames("MyWindows")
tv.open("MyWindows")
tv.wait()
tv.close()

To index

342 getPosition() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
getPosition(var x AnyType, var y AnyType, var w AnyType, var h AnyType)

Use these methods to get and change the position of the window.


Reported by: David Berg, Paradox Development
Date: 1996


var
msw msWindow
darat dynarray[] anytype
lix,liy,lih,liw longint
endvar

msw.attach(windowHandle())
msw.getPosition(lix,liy,liw,lih)
lix.view()
liy.view()
liw.view()
lih.view()

To index

343 getText() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
getText() String

Use these methods to get and change the text associated with a window. For an edit control, this is the contents of the control.


Reported by: David Berg, Paradox Development
Date: 1996

To index

344 getTitle() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
getTitle() String

Use these methods to get and change the title of the window.


Reported by: David Berg, Paradox Development
Date: 1996

Example
var
msw msWindow
st string
endvar

msw.attach(windowHandle())
st=msw.getTitle()
st.view()

To index

345 hide() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
hide() Logical

Change the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
msw msWindow
endvar

msw.attach(windowHandle())
msw.hide()
sleep(1000)
msw.show()

To index

346 isIconic() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
isIconic() Logical

Get the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

To index

347 isMaximized() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
isMaximized() Logical

Get the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
msw msWindow
endvar

msw.attach(windowHandle())
msw.maximize()
sleep(1000)
if msw.isMaximized() then
   msw.show() ; Restore
endif

To index

348 isMinimized() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
isMinimized() Logical

Get the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
msw msWindow
endvar

msw.attach(windowHandle())
msw.minimize()
sleep(1000)
if msw.isMinimized() then
   msw.show()
endif

To index

349 isVisible() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
isVisible() Logical

Get the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
msw msWindow
endvar

msw.attach(windowHandle())
msw.hide()
sleep(1000)
if not msw.isVisible() then
   msw.show()
endif

To index

350 maximize() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
maximize() Logical

Change the status of the window.


Example Nov 2003

var
msw MSWindow
endvar
msw.attach(windowHandle())
msw.maximize()


Reported by: David Berg, Paradox Development
Date: 1996

To index

351 minimize() method
Buglist Id: Last tested in version: First seen in version:
11 Build 3001.0

Undocumented.

Syntax:
minimize() Logical

Change the status of the window.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
Example:
var
msw msWindow
endvar

msw.attach(windowHandle())
msw.minimize()
sleep(1000)
if msw.isMinimized() then
   msw.show()
endif

To index

352 setPosition() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setPosition(x AnyType, y AnyType, w AnyType, h AnyType)

Use these methods to get and change the position of the window.


Reported by: David Berg, Paradox Development
Date: 1996

To index

353 setText() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setText(text AnyType)

Use these methods to get and change the text associated with a window. For an edit control, this is the contents of the control.


Reported by: David Berg, Paradox Development
Date: 1996

To index

354 setTitle() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
setTitle(title AnyType)

Use these methods to get and change the title of the window.


Example Nov 2003

var
msw msWindow
endvar

msw.attach(windowHandle())
msw.setTitle("MSWindow class test")


Reported by: David Berg, Paradox Development
Date: 1996

To index

355 show() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
show() Logical

Change the status of the window.


Example Nov 2003:
Can be used to restore a maximized window.

var
msw MSWindow
endvar
msw.attach(windowHandle())
msw.show()

Maximize the form, and run the code.


Reported by: David Berg, Paradox Development
Date: 1996

To index

356 windowHandle() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
windowHandle() LongInt

Returns the Window handle of the window the MSWindow variable was attached to.


Reported by: David Berg, Paradox Development
Date: 1996

To index

ObjectPAL---MultiRecord object

288 BlankRecord property
Buglist Id: Last tested in version: First seen in version:
11 Build 3005.04

To index

ObjectPAL---Nationalized Windows

104 Menu Window
Buglist Id: Last tested in version: First seen in version:
11 Build 2331.0

If you create a custom menu and add a menuitem named &Window with at least one item in the popupmenu bound to the menu, Paradox will handle the popupmenu by adding the names of the open windows. When running a nationalized version of Windows (win95) the menuitem is not Window, but the translated name, eg Fönster. If I create a custom menu with a menuitem Fönster, Paradox does not add the names of the open windows.

To index

ObjectPAL---Notebook object

413 CurrentPage property
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Help file says
< Quote >
Returns the active page of the form or notebook, including container objects.
< /Quote >
 
By setting CurrentPage property for a Notebook object, you can control which notepage will be activated when the form is opened.

Example:
In notebook object's open event, you add code like

doDefault
self'currentPage="npCustomer" ; if you have given such a name to a notepage object containing Customer table

For CurrentPage property to work properly, the notepage has to include an object that can get focus, eg a button with TabStop checked, a field with TabStop checked, or a tableFrame. It won't work with a text object or a button wth TabStop unchecked.

Even when CurrentPage property is assigned using a postaction() triggered from the notebook's open event, it won't work properly unless it contains an object that can get focus. Eg the default notepage cannot be activated by a mouseclick until focus has been moved away from the default object.


To activate a notepage with a textobject (or a button with TabStop unchecked) you have to use a different approach.

In notebook's open event, add code

doDefault
self.postAction(userAction)


In the notebook's action event add code

if eventInfo.id()=UserAction then
   disableDefault ; prevents userAction from bubbling
   npInfo.moveto() ; npInfo is a notepage containing nothing but a text object.
endif

With moveTo(), focus is removed from the default object, and the specified notepage is activated.

To index

ObjectPAL---Number type

514 number()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Help file says
< Quote >
number casts value to a Number. value must be in the form of a valid number that can be entered in a field.
< /Quote >

The help files does not mention that since Paradox 7 for Win95/NT, the default format to use when casting a string as a number, is the Windows Number format specified in Control Panel applet Regional Options. You can specify another format using formatSetNumberDefault(). In previous versions, the default format was the format used in the examples.

To index

139 number type
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

According to the Object PALhelp files
< Quote >
Number variables represent floating-point values consisting of a significand (fractional portion, for example, 3.224) multiplied by a power of 10. The significand contains up to 18 significant digits, and the power of 10 ranges from ± 3.4E-4930 to ± 1.1E4930. Assigning values outside of this range to a Number variable causes an error.
< /Quote >

But in the Help Topics help files it says:
< Quote >
Paradox number fields must contain only numbers. Number fields can hold positive or negative values. The range of values possible for a number field is from -10e307 to 10e308 with 15 significant digits. Use number fields when you plan to perform calculations on the values in the fields.
< /Quote >

18 significant digits was related to the use of Borland C compiler. Since P9, Microsoft Visual C compiler is used, and 15 significant digits, 64 bits numeric values rather than Borland's 80 bits.

Data stored in a table has always used 64 bits.


Comments by: Vladimir Menkin
Date: 15 February 2000

Today I tried to run one of my forms, which was written under Pdox5. It uses external DLL written in Delphi. I recompiled this DLL to 32-bit version, ran my form and... - function from dll works, but returns trash value to my Number argument. Futher investigation gave me an answer. Numbers in Paradox 9 are NOT 80-bit as it was in previous versions and as it is written in docs and help! They are 64-bit length! So, Delphi equivalent is NOT "extended" type, but "double".

To see this issue, simply try the following code under Pdox9 (all this code works without problems under Pdox5):

method CheckNumbers()
var
 n number
endvar
n=1e200; OK
n=1e400; error during form compilation (documentation proclaims, that numbers can be up to 1.1E4930)
n=1e100 n=n*n; OK
n=1e200 n=n*n; runtime error
endmethod

To index

357 number() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
Number(numString String, formatSpec String) Number

Converts the passed string to a number, using the provided format specification. This allows working with formatted data. For example, Number("1,234") causes an error, but Number("1,234","EC") returns the number 1234, because we've told Paradox to expect the number to have commas.


Reported by: David Berg, Paradox Development
Date: 1996


Example:
var
   n number
endvar

n=number("123.45", "W.2")
n.view()

To index

ObjectPAL---ObjectPAL Editor

214 Object Listbox
Buglist Id: Last tested in version: First seen in version:
10.0 P3

ObjectPAL Editor

Help files says:
< Quote >
There are two list boxes at the top of the Editor windows. The list box on the left allows you to move between the objects in your document. The list box on the right shows all possible methods or events for the selected object.
< /Quote >

Feature below is not mentioned:
Scrolling the object list in ObjectPAL Editor using down arrow, and up arrow, objects in your form is selected. Scrolling through a container, and its contained objects, multiple objects will get selected. I haven't seen any problems caused by this behaviour, and I don't know if it can be used as a feature.

To index

137 Global Search
Buglist Id: Last tested in version: First seen in version:
11 Build 233

Problem:
Find and FindReplace using GlobalSearch checked SKIPS methods/procs having source size greater than 32 KB.

Steps:
1. Open new form/script/library (or use already existed).
2. Add new method with the contents:
 {
  Add some text file with size > 32 KB here.
 }
 method FindMe()
 endMethod

3. Close that Editor window and open, for example, Var window.
     (or use drop down list to switch to another window)
4. Open Find dialog box.
5. Using Global search try to search for "FindMe".
     Find responds with "No match found."

6. Open FindMe method and move commented part behind the method.
6.1 Repeat steps 3-5
     Again, Find responds with "No match found."

7. Open 2 windows, FindMe and then some other (leaving FindMe opened).
8. Repeat steps 3-5
     Find works as expected.

9. Repeat steps 1-8 testing FindReplace with GlobalSearch checked.
     FindReplace in steps 5 & 6.1 responds with "No match found."


REPORTED BY:
Ivica Kolar

To index

ObjectPAL---ObjectPAL QuickLookup

94 BrowserOption constants
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

In the ObjectPAL quick lookup, BrowserOption constants, there is a constant named BrowseOptPathMustExit. Even though it looks like a typo it's not. The constant once was named this way. In P10, the correct name, BrowseOptPathMustExist, is accepted, even though it's not in the Quick lookup.

To index

ObjectPAL---oleAuto type

117 invoke()
Buglist Id: Last tested in version: First seen in version:
10.010.0

According to the help files
< Quote >
Invokes a method or property in an OLE Automation server.

Syntax

invoke ( const methodName String [, var arg]* ) AnyType

Description

invoke allows you to access methods and properties in an OLE Automation server. The methodName argument specifies the OLE Automation server's internal method and the optional arg arguments are the parameters of the method specified by methodName.

invoke is especially useful when the OLE Automation server has a method or property name that conflicts with an ObjectPAL keyword.
< /Quote >

When trying to specify a property in invoke(), you get an error saying: Error accessing the method 'xxxx', where xxxx is the property name.

Example

the ActiveX progressbar has a property pos.

oa.invoke("pos",0)
will cause the error mentioned.

To index

618 openTypeInfo() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example is using Paradox.Application. I get an error when running code
if not oa.openTypeInfo("Paradox.Application") then
errorshow()
endif
Error message is: Incorrect type library registration for server 11.0

To index

619 openObjectTypeinfo() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example code does not work
< Quote >
   excel.openTypeinfo("Excel.application.9") ; CHANGED FROM 5 to 9
   chart.openObjectTypeInfo(excel, "Chart")
   chart.enumProperties(da)
   da.view()
< /Quote >

When openTypeinfo() is replaced by open(), the code works
   excel.open("Excel.application.9")
   chart.openObjectTypeInfo(excel, "Chart")
   chart.enumProperties(da)
   da.view()

To index

620 unregisterControl() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example is a reference to registerControl(), but that example does not use unregisterControl().

Correct example:
unregisterControl("C:\\OCXLIB\\MYCNTL1.OCX")

To index

ObjectPAL---Page object

703 size property
Buglist Id: Last tested in version: First seen in version:
11 Build 41011 Build 410

If you have a multiple page form, and if you want to resize the pages, this is the code to use:

method open(var eventInfo Event)
   var
      ui uiObject
   endvar
   if eventInfo.isPreFilter() then
      ;// This code executes for each object on the form
   else
      ;// This code executes only for the form
     doDefault
     self.pageTiling=StackPages
     ui.attach(self.first)
     ui.size = Point(750, 550)
     self.pageTiling=TileVertical
   endIf
endMethod

You cannot resize each page individually. You have to stack the pages, resize the first page and then tile the pages.

By: Bertil Isberg
Date: 3 January 2007

To index

ObjectPAL---popupMenu type

208 show()
Buglist Id: Last tested in version: First seen in version:
PX044811 Build 3007.0

show() method of a popupmenu not bound to menu type can return a value NoName. The circumstances when this happens is unknown, but your code should handle this return value in the same way as when the user presses Esc key and a blank value, a zero length string, is returned.

In P7 and P8, NoName was returned if the user pressed Enter when the mouse pointer was outside the list of available items.
Combination of addStaticText() and addSeparator() seems to be involved.

NoName being returned has also been reported for P10 and P11 SP1.

To index

240 addText()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

To index

ObjectPAL---Query type

197 getAnswerName()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P3

A query variable created by query.readFromFile() contains the name of the answer table by default. The answer table specified in query.executeQbe(":alias:Answertable") is not returned by query.getAnswerName(). Instead you will get the name specifed in the QBE file.

Use query.setAnswerName() if you want to retrieve the name of table with query.getAnswerName().

To index

190 setQueryRestartOptions()
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

Can a query executed by ObjectPAL be restarted by Paradox? Do I have to specify SetQueryRestartOptions(NoLock) to prevent it? When I looked closer to this, I found there is not much help to get from the help files.

So this is what I once found when using Paradox 7 and 8 with Bde 4.51. It is partly tested in P9 and P10 with Bde 5.2.

When QueryRestart is specified, an interactively submitted query will restart if data in the tables are changed. A query submitted by ObjectPAL - executeQbe() will return False with an errormessage "Query must be restarted". And it will continue to return False until the second user closes the table.

There is no Table Update Handling / Query Restart Options settings available from the Sql editor. For the ObjectPAL SQL type, OTOH, both getQueryRestartOptions() and setQueryRestartOptions() exist. I can't see that they have any effect on the execuetSql(), though. Obviously, they can be removed.

I don't understand why the setQueryRestartOptions() is considered as a query type method only, as it is not only related to a query variable as such but also to all query variables in a session. The syntax setQueryRestartOptions(QueryRestart) will not only set QueryRestart for one query, but rather for the session.

q.setQueryRestartOptions() will only relate to the specified query variable.
setQueryRestartOptions() seems to relate to all ObjectPAL queries.

Date of Original testings: 3 February 1998

To index

358 dump() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
dump(fileName String)

Dumps information on a query to the specified file.


Reported by: David Berg, Paradox Development
Date: 1996

Example:

var
   q query
endvar

q=Query
ANSWER: :PRIV:ANSWER.DB

:Sample:customer.db | Customer No | Name |
                    | Check | Check A.. |

EndQuery

q.dump("QBEDUMP.TXT")

To index

359 enumFieldStruct() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
enumFieldStruct(const db Database, const answerTableName String) Logical

enumFieldStruct(const db Database, var answerTableTC TCursor) Logical

Writes the structure of a query result to the specified table.


Reported by: David Berg, Paradox Development
Date: 1996

Example
var
   q query
   db database
endvar

db.open(":SAMPLE:")
q=Query
ANSWER: :PRIV:ANSWER.DB

customer.db | Customer No | Name |
                    | Check | Check A.. |

EndQuery

q.enumFieldStruct(db, ":WORK:QueryFieldStruct")
db.close()

To index

88 CheckPlus - CheckDescending
Buglist Id: Last tested in version: First seen in version:
11 Build 233

Running a query with query variable in ObjectPAL, you cannot combine CheckPlus and CheckDescending in a query where tables are joined. You get an errormessage: Capability Not Supported. You can run the query interactively.

To index

23 setLanguageDriver()
Buglist Id: Last tested in version: First seen in version:
PX030811 Build 3008.0

According to the help files:
< Quote >
If you execute a query on a table that uses a different language driver you can use System type's getLanguageDriver to identify the language driver of the table. Set the language driver for the query using setLanguageDriver, to create the query's answer table with the same driver.
< /Quote >

My experience is that query.setLanguageDriver() will not change the table language driver for the answer table, but it will affect how a query image is translated.

To index

46 Tilde variable
Buglist Id: Last tested in version: First seen in version:
PX050911 Build 2339.0

A Constant has to be surrounded with () when used as a tildevariable in a query, like: ~(stVariable)

To index

47 setAnswerFieldOrder()
Buglist Id: Last tested in version: First seen in version:
PX051311 Build 2337.0 W95

When a valid query variable has been given a successful 'setanswerfieldorder' clause, or if a 'fieldorder:' type line is contained in the image of a query just read or assigned to by OPAL's qs=Query ... EndQuery statement, it is impossible to 'uncheck' a query field because :

a) if you first issue a 'checkfield(query, fieldname, checknone)' statement, it will be accepted, though not processed ! This is because the new 'unchecked' status of the field has become incompatible with the
existing 'field order' clause ... ! The 'checkfield' method will indeed return 'true' but save the query to a '.qbe' file and ascertain the field has not been unchecked !

b) if you try to change the order clause first, by removing the name of the field you want to uncheck, it will be rejected also because the field order array has to match the existing structure of the answer table

c) since there is no way to remove the effects of a 'setanswerfieldorder' clause, if you indeed want to uncheck a field, you have to rebuild the query from scratch


Reported by: Pierre G. CEUGNIET
Subj : Bug report : dyn queries
Date: 7 May 1997

To index

65 removeTable() example
Buglist Id: Last tested in version: First seen in version:
10.07.0 W95

The example used requires a specific order of the tables in the query image. Customer has to be the first table, and Orders the second table. If the order of the tables is reversed, the code won't work.

< Quote >
The following example removes the table ORDERS.DB from the query image MYQUERY.QBE:

method pushButton(var eventInfo Event)
var
   qVar Query
endVar

   qVar.readFromFile( "MyQuery.qbe" )
   qVar.removeTable( "Orders.db" ) ; remove Orders.db from
                                            ; the workspace
   qVar.removeCriteria("Customer.db", "Customer No" ) ; clear the
                                            ; example element link.
   qVar.executeQBE()
endMethod
< /Quote >

To index

698 checkField()
Buglist Id: Last tested in version: First seen in version:
11 Build 4109.0 P4

According to the help files, one of the syntaxes is
< Quote >
checkField ( const tableName String, const checkType SmallInt, const fieldName String) Logical
< /Quote >

My experience is that the syntax is:
checkField ( const tableName String, const fieldName String, const checkType SmallInt) Logical

Probably are all syntaxes where rowid is not included incorrect.

Date: 13 August 2006
By: Bertil Isberg

To index

699 insertTable()
Buglist Id: Last tested in version: First seen in version:
11 Build 410

Query type methods can be applied to a query created by readfromfile(). You can read a file, and add a table to the query using insertTable() or appendTable(). There seems to be some restrictions on the query when insertTable() is used, though.

When the QBE file contains a single table, you can use insertTable() to add a new table to the query. When the QBE file contains two or more joined tables, you can't use insertTable(). appendTable() does work in this case.

Date: 13 August 2006
By: Bertil Isberg

To index

547 getTableId() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

The example
< Quote >
The following example retrieves the table ID for the third table and the row ID for the second row of the query MONTHLY.QBE. The code then uses these IDs to determine the criteria set in the Name field.
< /Quote >
 is based on a rather complex query without the query being described.

Here's a suggestion:
Query
ANSWER: :PRIV:ANSWER.DB

lineitem.DB | Order No | Stock No |
            | _join2 | >1000 |
            | _join3 | >1000 |

orders.DB | Order No | Customer No |
          | _join2 | _join1 |
          | _join3 | _join4 |
          

customer.db | Customer No | Name | Street | Country |
            | Check _join1 | C.. | Check | Check |
            | Check _join4 | D.. | Check | Check |
            
EndQuery

To index

548 insertTable() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example code is incorrect. Both setCriteria() are referencing Customer.db.

< Quote >
qVar.appendTable("CUSTOMER.DB")
qVar.checkRow("CUSTOMER.DB", CheckCheck)
qVar.setCriteria("CUSTOMER.DB", "Customer No", "_Join1")
qVar.insertTable("ORDERS.DB", "CUSTOMER.DB")
qVar.setCriteria("CUSTOMER.DB", "Customer No", "_Join1")
qVar.executeQBE()
< /Quote >

Should be

qVar.appendTable("CUSTOMER.DB")
qVar.checkRow("CUSTOMER.DB", CheckCheck)
qVar.setCriteria("CUSTOMER.DB", "Customer No", "_Join1")
qVar.insertTable("ORDERS.DB", "CUSTOMER.DB")
qVar.setCriteria("ORDERS.DB", "Customer No", "_Join1") ; LINE CHANGED
qVar.executeQBE()

To index

550 readFromString() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code contains a line where a path is specified with single \ instead of double
< Quote >
addAlias("sampData", "Standard", "c:\Program Files\WordPerfect Office 2000\Corel\shared\samples")
< /Quote >

Should be:
addAlias("sampData", "Standard", "c:\\Program Files\\WordPerfect Office 2000\\Corel\\shared\\samples")

In another part of the code, a value from a tcursor is used to build a querystring
< Quote >
   ; Now use the Stock No field value in Stock.db in a query string.
   qs = "Query\n\n" +
       ":sampData:Lineitem|Order No|Stock No |\n" +
                         "| _ordNo |" + tc."Stock No" + "|\n\n" +
         ":sampData:Orders|Order No|Customer No |\n" +
                         "| _ordNo|_cust |\n\n" +
       ":sampData:Customer|Customer No|Name|Phone |\n" +
                         "| _cust|Check|Check |\n\n" +
        "EndQuery"

   ; Note that the vertical lines (|) don't have to be aligned.

   qVar.readFromString(qs)
< /Quote >

When tc."Stock No" is concatenated with the other string elements, the numeric value is converted to a string by Paradox. The result of the conversion is probably invalid in most number settings in ControlPanel applet Regional Options.

A better solution is to replace the line
                         "| _ordNo |" + tc."Stock No" + "|\n\n" +
with
                         "| _ordNo |" + string(longInt(tc."Stock No")) + "|\n\n" +

To index

551 removeCriteria()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95

Help file says:
< Quote >
removeCriteria removes the query expression in a specified field, but does not remove check marks. Use setCheck and clearCheck to manipulate query check marks.
< /Quote >

But as shown by the example code, which does not work, removeCriteria() will only remove a criteria specified by setCriteria(). When query variable is created by readFromFile(), you cannot use removeCriteria() to remove the query expression in a field.

To index

552 removeCriteria() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code does not work.
< Quote >
method pushButton(var eventInfo Event)
var
   qVar Query
endVar

   qVar.readFromFile( "Myquery.qbe" )
   qVar.removeCriteria( "Customer.db" , "Name" )
   qVar.executeQBE() ; execute the saved query minus the
                          ; customer name criteria.
endMethod
< /Quote >

To remove a criteria created by readFromFile(), you have to use code like

method pushButton(var eventInfo Event)
var
   qVar Query
   st string
 endVar

   qVar.readFromFile( "MyQuery.qbe" )
   st=qVar.getCriteria("Customer.DB" , "Name" ) ; LINE ADDED
   qVar.setCriteria( "Customer.DB" , "Name", st ) ; LINE ADDED
   qVar.removeCriteria( "Customer.DB" , "Name" )

   qVar.executeQBE() ; execute the saved query minus the
                          ; customer name criteria.

endMethod

To index

672 executeQbe()
Buglist Id: Last tested in version: First seen in version:
11 Build 30211 Build 302

executeQbe() have two syntaxes, one as a method, and one as a procedure. Use the procedure syntax if you're running a query based on non standard databases and want to get the answer table in a tcursor. That way Paradox will get a database handle to which the tcursor can be related.

Using the method syntax, you can get errors, "An error was triggered in a Create operation." , followed by "Invalid field name: " when trying to use the tcursor in a create statement where the tcursor is specified in the like clause.

Date: 25 January 2005

To index

290 Keywords in a query variable
Buglist Id: Last tested in version: First seen in version:
8.07.0 W95 P4

Writing queries in ObjectPAL, you can have a need for keywords allowed in a QBE file. I haven't been able to find them documented in the help files.


The valid keywords are:

        ANSWER table name
        TYPE DBASE or nothing
        OPTIONS NO AUXILIARY TABLES
                                  SERVER or LOCAL
                                  LIVE
        SORT list of fields
        FIELDORDER list of fields

From : Dan Ehrmann (CTech)
Subj : Magic Query Words
Date: 8 January 1998

To index

ObjectPAL---Report type

496 enumUiObjectNames() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

In the example, two tablevies are opened. The tableview variable is only closed after the second table has been closed by the user. A tableview variable should always be closed after an open, otherwise the table will be left open on the desktop.

Modified example:

method pushButton(var eventInfo Event)
{
In the following example, the pushButton method for
describeReport uses enumUIObjectNames and enumUIObjectProperties
to document a report:
}
var
  ordersRep Report
  tempTable TableView
endVar
ordersRep.load("Customer.rsl") ; load report in Report Design window
ordersRep.enumUIObjectNames("zordnames.db") ; write names to table
ordersRep.enumUIObjectProperties("zordprops.db") ; write properties to table
ordersRep.close()
tempTable.open("zordnames") ; observe your handiwork
tempTable.wait()
temptable.close() ; LINE ADDED
tempTable.open("zordprops")
tempTable.wait()
tempTable.close()
endMethod

To index

498 load() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example tries to create a textobject in the page header of a report. When running in Paradox 9 SP 4 and later versions, the object is created in the record band, not in the page band. To make the object be created in the page header, you have to specify the #Page_Header object as the container. In Paradox 7 SP4, the obejct is created in the page header.

Modified code:
method pushButton(var eventInfo Event)

var
  ordersRep Report
  pageTitle UIObject
endVar
if ordersRep.load("Orders.rsl") then
  ; assume report has room in the page header for a text box
  pageTitle.create(TextTool, 1440*3, 720, 1440*2, 360, ordersRep.#Page_Header ) ; LINE MODIFIED
  pageTitle.Name = "NewTitleText"
  pageTitle.Text = "Orders Report " + String(time())
  pageTitle.Color = LightBlue
  pageTitle.Visible = True
  ordersRep.run()
endIf

endMethod

To index

664 Property Margins.Right
Buglist Id: Last tested in version: First seen in version:
11 Build 302

If you try to change the property Margins.Right for a report that contains an object, you will get an error "An error occurred when setting the property named 'Margins.Right' of the object named '<>' of type 'Report'." followed by "Attempted to assign an illegal value to the property."

You can change the right margin when no object is placed in the report.

see also Interactive - Report - Property Margins.Right. DocIssues 663.

To index

690 print() example
Buglist Id: Last tested in version: First seen in version:
11 Build 41010.0

Example is said to use syntax 3 of the print() method, but since Paradox 10 the syntax used is syntax 4.

To index

179 moveToPage()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

moveToPage() will always return true even when trying to move beyond the last page.

To index

361 isDelivered() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isDelivered() Logical

tests to determine if the report is delivered. This check is performed internally, not by the extension of the filename.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
method pushButton(var eventInfo Event)
var
   r report
endvar

r.open("MyReport")
msgInfo(r.isDelivered(),"")
endMethod

COMMENTS:
Using a rsl file renamed to rdl, isDelivered() reported True.

To index

362 isPrintPreview() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isPrintPreview() Logical

returns TRUE if the report is in print preview mode.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
var
   r report
endvar

r.attach("MyReport") ; Assume the report has title = MyReport
msgInfo(r.isPrintPreview(),"")

To index

363 printPreview() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
printPreview( const printPreviewMode SmallInt) Logical

sets the specified preview state. see ObjectPAL-Constants-PrintPreview constants.

printPreview() Logical

toggles between print and not print preview.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example 1
var
   r report
endvar

r.open("MyReport") ; opens the report MyReport.rsl
r.printPreview(printPreviewEnter)
msgInfo(r.isPrintPreview(),"")


Example 2
var
r report
endvar

r.open("a4")
r.printPreview()
msgInfo(r.isPrintPreview(),"")
r.printPreview()
msgInfo(r.isPrintPreview(),"")

To index

249 reportPrintInfo variables
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.0

The reportPrintInfo variables xOffset and yOffset has no functionality unless the printer driver supports them.

Reported by : Brian Bushay (CTech)
Date: 6 June 1997


My experience is that most printers don't work when MakeCopies is set to false. When you set the number of copies from the Print Dialog this is equivalent to makeCopies=true.

Reported by: Brian Bushay Ctech
Date: 19 July 1999


Although intuitively I assumed the makeCopies parameter would not enable/disable 'collate', it does: setting makeCopies = TRUE makes the report print not-collated; FALSE makes the report print collated.

Reported by : Pieter Rijnierse
Date: 22 June 1996

Note: This has been documented for printerSetOptions() at least since Paradox 7, but collate is since Paradox 10 also a reportPrintInfo variable, and it is not mentioned there.

To index

ObjectPAL---Script type

365 isDelivered() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isDelivered() Logical

tests to determine if the script is delivered. This check is performed internally, not by the extension of the filename.


Reported by: Paul Cronk - Corel
Date: 5 april 2000

Example:
var
   scr script
endvar

scr.load("z")
scr.run()
msgInfo(scr.isDelivered(),"")

COMMENT:
This method can only be used when script is created from the form calling the isDelivered().

A script containing code like this:
var
   scr script
endvar

scr.attach()
message(scr.isDelivered())

will cause an unassigned variable error when run from a form.

To index

500 create() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example does not work. Errormessage is: The design object has compile error and will not run.

Here's a modified example
method pushButton(var eventInfo Event)
  var
    theScript Script
    stMsg String
  endVar

stMsg =
"method newMsg()
  msgInfo(\"New message\", \"New message\")
endMethod"

  theScript.create()
  theScript.methodSet("newMsg", stMsg) ; LINE ADDED
; ; LINES ADDED
stMsg =
"method run(var eventInfo Event)
  newmsg()
endMethod"
;; END OF LINES ADDED
  theScript.methodSet("run", stMsg)
  theScript.save("NewMsg") ; Saves script as NEWMSG.SSL.
  theScript.run() ; Calls the script's built-in run method.

endMethod

To index

ObjectPAL---Session type

501 saveProjectAliases() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Syntax error in the example:

   addProjectAlias("MYPROJ", "Standard", "D:\\WORDPERFECT OFFICE 11\\PARADOX\\\MYPROJ")

should be
   addProjectAlias("MYPROJ", "Standard", "D:\\WORDPERFECT OFFICE 11\\PARADOX\\MYPROJ")

( \\\MYPROJ replaced by \\MYPROJ)

To index

418 enumAliasLoginInfo()
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

According to help files
< Quote >
enumAliasLoginInfo writes information about the server alias specified in aliasName to the Paradox table specified in tableName. This method returns True if successful; otherwise, it returns False.

enumAliasLoginInfo operates on aliases that are stored in IDAPI.CFG and on new aliases opened and stored in system memory. This method fails if the table specified in tableName is already open.

enumAliasLoginInfo applies only to remote databases. Standard (Paradox or dBASE) databases are not affected by this method.
< /Quote >

Nothing is said on ODBC drivers. Applying enumAliasLogininfo() on an alias based on Microsoft Access driver, the table created is empty.

You can expect enumAliasLoginInfo() to return the information shown in AliasManager for the alias.

To index

419 getAliasProperty()
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

To index

299 removePassword()
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0 P3

Using addPassword() you can add a password more than once. removePassword() will remove one instance of the password. Until all instances have been removed you have the rights to access the table.


Reported by: "Liz"
Date: 3 September 2003

To index

366 convertFieldInfo() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
convertFieldInfo(const sourceDriver String, var srcFieldDesc DynArray [] AnyType, const destDriver AnyType, var destFieldDesc DynArray [] AnyType) Logical

Converts field information from one driver type to another. The source/destination driver should be the type of database (e.g. "Paradox" or "dBase"), or blank for logical field types. The source field descripter dynarray can have the following indexes:
Index Source Desc
FieldName Name of the field Field name, truncated or converted as necessary
FieldType Type of the field (I'm unsure of the format, although I think it's Paradox Alpha="A", dBase char="C", etc.)
Converted Field type
Size Total size of field Size of field, rounded up (down if forced type conversion makes field smaller)
Dec Number of decimal places
Rounded up as necessary (may be 0 if result is floating point)


Reported by: David Berg, Paradox Development
Date: 1996

To index

14 addAlias()
Buglist Id: Last tested in version: First seen in version:
PX01979.07.0 W95

Check your aliases using BDECFG. If the TYPE field is not "STANDARD" ALL caps then the alias will "work" but the refresh will NOT. I found this out when adding aliases in OPAL using the example code in the help file which shows the type as "Standard".

To index

ObjectPAL---Sql type

163 createAuxTables()
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

There is no createAuxTables() method for Sql type.

The workaround is to do this as it is done in a SQL statement run from the SQL Editor. Include a comment with content like

/*
Answer: :PRIV:ANSWER.DB
AuxTables: False
RunMode: Default
Alias: WORK
LiveAnswer: FALSE
*/

AuxTables: False
is all you need.

In ObjectPAL it will look like

sqlHandle=sql

/*
AuxTables: False
*/
      update px0386b
      set m1=m2
      where id=3

endSql

To index

120 executeSql()
Buglist Id: Last tested in version: First seen in version:
PX009311 Build 2337.0 W95

The text below was written for BDE 3.x. I'm not sure it is relevant for BDE 4.51 and BDE 5.x. I cannot reproduce the errormessages any longer.

sql.executeSql(db, tc) can be used to run embedded sql and getting the answer table in a tcursor. When you do, you can get some confusing errormessages: Table not found, Table is read-only, Token not found.

Let's take a look at this. The basic syntax is

var
db database
sqlHandle sql
tc tcursor
endvar

db.open(":Sample:")
sqlHandle=SQL

SELECT COUNTRY, COUNT(*)
FROM CUSTOMER
GROUP BY COUNTRY

ENDSQL
sqlHandle.wantInMemoryTcursor(Yes)
try
   sqlHandle.executeSql(db, tc)
onFail
   errorShow()
endTry

; Let's use a simple
tc.edit()
; to create an errormessage

BUT you'll get a error message saying Table not found on executeSql().

Rule 1:
When you want to get the answer table in a tcursor, you have to include a comment in the Sql statement, unless you want to have a live query view, because WantInMemoryTcursor() is neglected when there is no comment in the SQL statement.

/*
Alias: Sample
*/

Those lines should be the first lines after sqlHandle=SQL making the statement look like
sqlHandle=SQL

/*
Alias: Sample
*/
SELECT COUNTRY, COUNT(*)
FROM CUSTOMER
GROUP BY COUNTRY

ENDSQL


Rule 2:
If you don't want a Live Query, you have to add sql.wantInMemoryTcursor(Yes) before executeSql().

Without it, you may get Table is Read Only if you try to edit the tcursor and a live query couldn't be produced.

Rule 3:
Running a remote stored procedure with exec procname and getting the answer in a tcursor will produce a Token not found error if you don't include the comment. This is tested with Sybase System 10 only.

sqlHandle=SQL

/*
Alias: SybaseDb
*/
EXEC MyProc

ENDSQL

Conclusion:
Obviously, the database variable is not enough. The SQL comment is sometimes needed, and sometimes seems to be when you want the answer in a tcursor.


Another way of writing the sql statement and running it, is to use the database WORK.

db.open(":Work:")
sqlHandle=SQL

SELECT COUNTRY, COUNT(*)
FROM :Sample:CUSTOMER
GROUP BY COUNTRY

ENDSQL
sqlHandle.wantInMemoryTcursor(Yes)
try
   sqlHandle.executeSql(db, tc)
onFail
   errorShow()
endTry
tc.edit()


There is ONE way to create the SQL statement that I can recommend. Use the SQL Editor and save the statement to a SQL-file.

You can use Edit | Paste From.. to paste it into your ObjectPAL code. If you don't find the /* comment */, open the file with Notepad, and copy all of it into your code.

The Alias specified in the comment, should be the same as the database variable. Or vice versa. Define the database to be the one found in the Alias:-line.

When you create the statement in the Editor, use the Alias button to specify where the query should run. Do not include :Alias:tablename references for the tables unless the query contains tables from different databases. In that case, select a local Alias (or Work) and specify :alias:TableName for the remote tables.

To index

191 setQueryRestartOptions()
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

To index

215 writeSql()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P3

ObjectPAL Reference on writeSql().
< Quote >
Procedure:
2. writeSQL ( const sqlString String, const fileName String ) Logical

Description
......

Syntax 2 is a procedure - use a String variable as the first argument (for example: writeSQL(sqlString, "bigOrder.sql").
< /Quote >

Example provided does not use a string variable but a sql variable.

Syntax should be
2. writeSQL ( const sqlString Sql, const fileName String ) Logical

A string variable has to be converted to a sql variable using
var
   sqlHandle sql
   stSql string
endvar

sqlHandle.readfromString(stSql)

To index

503 setQueryRestartOptions() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

In example 1 - Using executeSql(), part of the code is:
< Quote >
  if qVar.getQueryRestartOptions() <> QueryRestart then
     setQueryRestartOptions(QueryRestart)
  endIf
< /Quote >

qVar.getQueryRestartOptions()
but
setQueryRestartOptions() without an object.

If not a typo, this would require an explanation.

see also Object PAL - Query type - WadId 190

To index

505 readFromString() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example contains a syntax error. exexuteSql() requires a database handle as a parameter.

< Quote >
   if sqlVar.executeSQL(bigOrderTC) then
      doSomething(do, bigOrderTC) ; call custom proc to process data
   else
      errorShow()
   endIf
< /Quote >

should probably be
   if sqlVar.executeSQL(db, bigOrderTC) then ; db ADDED
      doSomething(do, bigOrderTC) ; call custom proc to process data ; do REMOVED
   else
      errorShow()
   endIf


The content of bigorderString is not correct:
< Quote >
   bigOrderString = sqlKeyword +
                    "CustName, Order_no, Sale_date, Qty
                    FROM Customer
                    WHERE Qty > 1000 "
< /Quote >

should be

   bigOrderString = sqlKeyword + " "+ ; " " added
                    "CustName, Order_no, Sale_date, Qty
                    FROM Customer
                    WHERE Qty > 1000 "


The example is described as
< Quote >
The following example prompts the user to type an SQL keyword and uses that keyword in an SQL string. If the user enters a valid SQL keyword
< /Quote >

The text should state that only valid keywords are SELECT and SELECT DISTINCT and maybe a complicated INSERT INTO statement. Neither UPDATE or DELETE can be used with the rest of the statement
                   "CustName, Order_no, Sale_date, Qty
                    FROM Customer
                    WHERE Qty > 1000 "

To index

634 executeSql()
Buglist Id: Last tested in version: First seen in version:
PX02148.0 P17.0 W95 P4

Corrected

< Quote >
Syntax

Method:
1. executeSQL ( const db Database) Logical
2. executeSQL ( const db Database, CONST ansTbl String ) Logical
3. executeSQL ( const db Database, VAR ansTbl Table ) Logical
4. executeSQL ( const db Database, VAR ansTbl TCursor ) Logical

< /Quote >

Furthermore, description of the example was incorrect in Paradox 8

To index

ObjectPAL---statusEvent type

506 statusValue() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 1 - Copying status messages to a field on a form

should mention that the button's labeltext should be "Normal Messages" when form is opened. As the field is visible, the form acts with status magnifying messages.

Add this code to button's open event
doDefault
self'labeltext="Normal Messages"

And add this code to the StatusMessageField's open event
doDefault
self'visible=TRUE

When button is pressed, form behaviour changes to normal handling of messages on the statusbar.


Example 2 - Working with the status method

As the code is in a form level event, it should be:

method status(var eventInfo StatusEvent)

if eventInfo.isPreFilter() then
   ;// This code executes for each object on the form
   if eventinfo.reason() = modeWindow3 then
      if eventinfo.statusvalue()="Persist " then ; note "Persist " is
                                                   ; followed by a space
          persistFldVw() ; call custom method
      endIf
   endIf
else
   ;// This code executes only for the form

endIf
endMethod

To index

ObjectPAL---String type

507 chr() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

On my two PCs, chrToKeyName(chr(167)) returns a blank string, so it looks like sectionkey § does not have a VK name on all keyboards or that chrToKeyName() is language driver dependent.

To index

508 Virtual key codes
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Keys and virtual key codes

ObjectPAL reference - index - virtual key codes - keys and virtual key codes.

< Quote >
Method Description

chrToKeyName Returns the key name of the character contained in a string
VRCodeToKeyName Returns the key name corresponding to a specified ANSI code
< /Quote >

Last line should be
VKCodeToKeyName

To index

509 chrToKeyName()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

see ObjectPAL String type - chr() example WadId 507

Unless there's a typo in that example, not all key names are defined for all keyboards.

To index

510 format() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

296 readFromClipboard()
Buglist Id: Last tested in version: First seen in version:
11 Build 3008.0

According to the help files, string.readFromClipboard()
< Quote >
readFromClipboard reads text from the Clipboard. This method reads text in CF_TEXT format. readFromClipboard returns True if successful; otherwise it returns False.
< /Quote >

If the clipboard does not contain CF_TEXT, but a file or something else with a different clipboard format, string.readFromClipboard() will block the clipboard until Paradox is closed down. No other application can write to the clipboard. Trying to use the clipboard in Paradox will give an error: Could not open Clipboard.

Correct code for using string.readFromClipboard() should be:

var
   stClipboard string
endvar

if clipboardHasFormat("CF_TEXT") then

   if not stClipboard.readfromClipboard() then
      message("Cannot read from clipboard.")
   else
      stClipboard.view()
   endif
else
   message("Current clipboard content cannot be used in this operation.")
endif

Related topics:
binary type - clipboardHasFormat()
binary type - enumClipBoardFormats()

To index

626 upper()
Buglist Id: Last tested in version: First seen in version:
11 Build 3008.0

The OPAL method Upper() does not work as expected for all extended characters, eg french special characters. For example upper (é) = E, upper(ë) =E is wrong, (but upper(ç) = Ç is okay).

We are using Langdriver Pdox ANSI Intl in.


Our french Paradox colleagues tell us, the uppercase name Régis they write REGIS and not RÉGIS.


With Language driver ANSISWFN, upper(é) is Ok, but not upper(ë). BDE 5.2

SETUP:
var
   stLower, stUpper string
endvar

stLower="éèë"
stUpper=stLower(stUpper)

stUpper.view()


Reported by: "Josef Gräf"
Subject: Upper() does not work correctly for french special characters
Date: 16 February 2004

To index

643 chr()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

According to the help files:
< Quote >
chr ( const ansiCode SmallInt ) String

If ansiCode is not an integer between 1 and 255, chr fails.
< /Quote >

This is not true.

Look at this example:
var
st string
endvar
errorTraponWarnings(Yes)
try
   st= "a"+chr(0)+"b"
   msgInfo(string(st.size()), st)
onfail
   errorshow()
endtry
errorTrapOnWarnings(no)


It does not fail.
Size of st is 3. Value of st = a

Reported by: "Michel Claveau/Hamster"
Date: 29 April 2004

To index

702 advMatch()
Buglist Id: Last tested in version: First seen in version:
11 Build 4108.0

This covers how to search for ] and - using advMatch().

The following works in P8, as long as the "]" character is written as the first character in the brackets. (The pattern looks for the characters "]oe " only, the result is "e]]o ").

method run(var eventInfo Event)
    var
       a String
    endVar
    if advMatch("he]]o world","([]oe ]+)", a ) then
       a.view("match result")
    else
       msgInfo("sorry","the pattern did not match")
    endIf
endMethod

This pattern works too: "([^]o]+)". It gets "he".
This pattern gets an "o" without an error: "([-fo])"


To match the "-" character it must be in the first or last position of the group with our without escape sequence:
[-abc] [abc-] or [\\-abc] [abc\\-] all work

To match the "]" place it in the first position unescaped:
[]] -- works. (note [][] works also to match "[" and "]")

These all work with not groupings as well, [^ ...

It is important to note that try to use the "]" character does not give you a compile error. It just doesn't match correctly.

Reported by: Mark Bannister and Uwe Lauth
Date: 30 January 2007

To index

704 search()
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95

According to the help files
< Quote >
search searches for str within a target string. If str is found, search returns the starting character position of str within the target string; otherwise, it returns 0.
< /Quote >
Nothing is said on the result when str is an empty string.
var
    st1,st2 string
endvar
st1="goliath"
st2=""
message( st1.search(st2) ) ;returns 1

Reported by: Mark Bannister
Date: 7 May 2007

To index

705 searchEx()
Buglist Id: Last tested in version: First seen in version:
11 Build 4108.0

To index

706 format()
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

When formatting a date, the help files says
< Quote >
DY1 Year as 1
DY2 Year as 01
DY3 Year as 1901
< / Quote >

DY2 will result in a two digit year when the year is between 1950 and 2049. Outside that range DY2 will give you a four digit year.
DY1 will result in a one digit year when the year is between 2000 and 2009. Outside that range but inside the range 1950-2049, it will give a two digit year. Outside the range 1950-2049, DY1 will give a four digit year.

To index

266 advMatch()
Buglist Id: Last tested in version: First seen in version:
11 Build 2334.5

With advMatch(), you can use () for grouping. However grouping is not further explained in the help files.

What I understand, grouping is used for two different reasons.
A) To make the pattern understood by Paradox.
B) To tell Paradox what should be assigned to variables.

A) Example:
How is the search string ^D/*E/*H.. to be understood? Should the string begin with D/ or with D alone? Guessing, it looks like the pattern is translated to "Begin with D/ followed by E preceded by zero or more /".

Using groupings, ^D(/*)E(/*)H.., will make the pattern more obvious, and you will find more occurences.

If the table contains,
1) ABCDEF
2) DE/FBBB
3) D/E/FBB
4) DE/HAAA
5) D/EHAAA
6) D//E//HAAA
7) DEHAAA

the first string without grouping will find 5 and 6.

The string with grouping will find 4-7.


B)
Example

Search string contains ".. .. ..", and is applied to "Hickory Dickory Dock"

stD="Hickory Dickory Dock"
stD.advmatch( ".. .. ..", stA, stB, stC)

will give blank contents in stA, stB, and stC.

stD.advmatch( "(..) (..) (..)", stA, stB, stC)
will assign Hickory to stA, Dickory to stB, and Dock to stC


Comments: The help files contains an advanced example showing groupings combined with or conditions, and how variables will be assigned a value.


Reported by:
Henry Davie
Sundial Services
Date: 27 October 2000

To index

367 breakApart() method
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
breakApart(tokens array [] string, separators string, delimiter string, stripspaces logical)
 

This version of Breakapart didn't quite make the docs, but it is in the ObjectPAL Quick lookup:


BreakApart(tokens array [] string, separators string, delimiter string, stripspaces logical)

Works the same as Breakapart except that you can specify a delimiter (a quote character) that will block separation on the separator characters, and you can elect to have spaces stripped from your tokens. This allows Breakapart to work the same way as the delimited text Import.


Reported by: David Berg, Paradox Development
Date: 1996


Example:
var
   arstTokens array [] string
   st string
endvar

st="My name is ; /Isberg, Bertil/. I'm living in , Stockholm. "
st.BreakApart(arsttokens , ";.,", "/", TRUE)
arstTokens.view(st)

To index

368 flipCase() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
flipCase() String

flips the case of the string, eg: pAUL becomes Paul.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
var
   st string
endvar

st="Bertil Isberg"
st=st.flipCase()
st.view()

To index

369 isEmailAddress() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isEmailAddress() Logical

returns TRUE if the specified string meets the requirements to be an Email addresss.


My comments:
isEmailAddress() does not accept email addresses containing a dot before the @.


Example:
var
 st string
endvar

st="bertil.isberg@nospam.scbx.se"
if st.isEmailAddress() then
   msgInfo(st, "Accepted as email")
else
   msgInfo(st, "Not accepted email")
endif


Reported by: Paul Cronk - Corel
Date: 5 april 2000

To index

370 isURL() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isURL() Logical

returns TRUE if the specified string meets the requirements to be a valid URL.


My comments:
Only requirement to be a valid URL seems to be a dot anywhere in the string.

Example:
var
 st string
endvar

st="www.swebug.se"

if st.isUrl() then
   msgInfo(st, "Accepted url")
else
   msgInfo(st, "Not accepted as url")
endif


Reported by: Paul Cronk - Corel
Date: 5 april 2000

To index

371 readFromFile() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
readFromFile( const fname String ) Logical

reads the specified file into a string object. Works much the same as memo.readFromFile()


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:

var
   st string
endvar

st.readfromfile("MyTextFile.txt")
st.view()

To index

372 reverse() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
reverse() String

reverses the case of the string, eg: luap, becomes paul.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
var
   st string
endvar

st="Bertil Isberg"

st=st.reverse()
st.view()

To index

373 soundEx() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
soundEx() String


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
var
   st, st2 string
endvar

st="BERTIL ISBERG"
st2=st.soundex()
st2.view()
; st2= B634 I216

To index

374 writeToFile() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
writeToFile( const fname String ) Logical

writes the string to a specified file. Works much the same as memo.writeToFile().


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
var
   st string
endvar

st="BERTIL ISBERG"
st.writeToFile("MyTextFile.TXT")

To index

115 match()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

Help files on match()

< Quote >
 Notes

·Quotes in pattern require special handling, periods do not. To embed a quote, precede it with a backslash (\"). match treats periods as alphanumeric characters.
...
·Earlier versions of PAL required backslashes to delimit periods.
< /Quote >

This is partly true; eg when you are trying to find liz.d in a string, you can specify the pattern as "..liz.d..", but when you are trying to find liz., the pattern has to be "..liz\".\".."

Note: \".\" after liz

To index

171 string() procedure
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0 P4

Help files says:
< Quote >
string ( const value AnyType [ , const value AnyType ] * ) String

string casts a value as a string. If you specify multiple arguments, string will cast them all to strings and concatenate them to one string.
< /Quote >

BUT
the help files does not mention there is a limit on number of arguments that can be passed to the procedure. Limit is 30.

Neither does the help file mention that the resulting string cannot exceed 32767 characters. In other words:

st1=st2+st3 ; no limit on size
st1=string(st2,st3) ; cannot exceed 32767

More findings:
Date: 1 October 2004
By:
"Vladimir Menkin"
"Egbert Babst"
"Bertil Isberg"

String typecast of memo *field* truncates the result to 32767 bytes. String typecast of memo type *variable* does not truncate result.

Assume that we have test.db table with a memo field MemoFld. And this field size greater than 32767 bytes. Say, 40000 bytes. Then:

var
  tc tcursor
  m memo
  st string
endvar
tc.open("test.db")
view(sizeex(tc.MemoFld));shows 40000
view(sizeex(memo(tc.MemoFld)));shows 40000
view(sizeex(string(memo(tc.MemoFld))));shows 40000
m=tc.memoFld
view(sizeex(string(m)));shows 40000
;BUT:
view(sizeex(string(tc.MemoFld)));shows 32767!!!

Look at this:
view(sizeex(string(fill("A",20000),fill("B",20000)))); truncated
view(sizeex(string(fill("A",20000)+fill("B",20000)))); shows 40000

The assumption that memo(tc.MemoFld) and tc.MemoFld are identical can be questioned.

This code
if memo(tc.MemoFld) = tc.MemoFld
causes a syntax error. Incompatible types.

And so does
if memo(tc.MemoFld) = memo(tc.MemoFld)

but not
if tc.MemoFld = tc.MemoFld

Conclusion is: tc.MemoFld is not a memo but a string.

To index

58 isEmpty()
Buglist Id: Last tested in version: First seen in version:
11 Build 2339.0

ObjectPAL reference contains a reference from String type to isEmpty(). Not sure whether this is a bug or a feature where description in the help files is wrong.

In the help files under "String type" there is a reference to isEmpty(). This is the only place where I found it.

The text on isEmpty() states:
< Quote >
Performs the same function as isBlank().
< /Quote >

Let's look at this. Create an empty table with name "abcdef" in working directory

var
 st string
endvar

st="abcdef"
errorTrapOnwarnings(Yes)
try
     msgInfo(st, string(st.isEmpty()))
onfail
 errorShow()
endTry
errorTrapOnWarnings(No)

table is empty but string is not blank.

Change the string to contain "12345" and run the code, and you'll get an error "table does not exist".

Maybe the reference in the help files should be removed.

To index

90 advMatch()
Buglist Id: Last tested in version: First seen in version:
11 Build 2331.0

On match() method, the help files says:
< Quote >
match continues checking for the specified string, looking for all matches. If a multiple match occurs, the operation is performed on the last match found (not the first).
< /Quote >

This is not mentioned on advMatch(), but it should be.

To index

ObjectPAL---Stringlist type

375 isAssigned() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.
Note: Method is documented in ObjectPAL QuickLookup

Syntax:
isAssigned() Logical

returns TRUE if the string list is assigned.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
method run(var eventInfo Event)
var
    strlist stringlist
    f form
endvar
f.open("stringlistform.fsl")
strlist.attach(f)
if strlist.isAssigned() then
   msgInfo (strlist.getString (112), strlist.getString (15))
else
   msgInfo("Not Assigned", "")
endif

endMethod

To index

376 isEmpty() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.
Note: Method is documented in ObjectPAL QuickLookup

Syntax:
isEmpty() Logical

returns TRUE if the stringlist is assigned and empty.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
method run(var eventInfo Event)

var
    strlist stringlist
    f form
endvar

f.open("stringlistform.fsl")
strlist.attach(f)
if not strlist.isEmpty() then
   msgInfo("Stringlist is not empty", "")
else
   msgInfo("Stringlist is empty", "")
endif

endMethod

To index

377 view() method
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
view() Logical

displays the string list in the standard view box.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


COMMENT:
Does not work.

To index

516 attach() example
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0 P3

The example requires that the form has a stringlist defined., otherwise you will get an unassigned variable error.

To index

ObjectPAL---System type

517 enumFonts() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3009.0 P4

Description of the example is incorrect.
< Quote >
The following example creates and lists system fonts in a table named FONTS.DB. The code then searches a TCursor for a font named Modern. If Modern is in the table, the code sets the Font.TypeFace property of an unlabeled field object named balanceField to Modern.
< /Quote >
 
Only the first part "The following example creates and lists system fonts in a table named FONTS.DB. " is still in the example code. The second part of the code was removed in Paradox 8 or 9.

To index

519 enumPrinterForms()
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

According to the help file:
< Quote >
Syntax
enumPrinterForms ( var paperSizes Array[ ] longInt ) Logical

Description
Retrieves a list of the paper sizes currently available for the current printer. The paperSizes array is a list of integers corresponding to the printSizes constants. If printerName is omitted, the current default printer is used.

< /Quote >

There is no way to provide a printerName as I can see.

To index

520 enumRegistryKeys() example
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

For some reason the example is using
enumRegistryKeys( "Software\\WordPerfect Office 11\\Paradox\\11.0\\Pdoxwin", RegKeyCurrentUser, ar )

but the Paradox keys are found under "Software\\Corel\\Paradox\\11.0\\Pdoxwin".

Still there was one key under "Software\\WordPerfect Office 11\\Paradox\\11.0\\Pdoxwin", Designer. Wonder why?

To index

521 enumRegistryValueNames() example
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

For some reason the example is using
enumRegistryKeys( "Software\\WordPerfect Office 11\\Paradox\\11.0\\Pdoxwin", RegKeyCurrentUser, ar )

but the Paradox keys are found under "Software\\Corel\\Paradox\\11.0\\Pdoxwin".

Still there was one key under "Software\\WordPerfect Office 11\\Paradox\\11.0\\Pdoxwin", Designer. Wonder why?

To index

522 errorCode() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The code requires errorTrapOnWarnings(Yes) to cause
  obj.attach("boxOne")
to fail.
Without errorTrapOnWarnings(Yes), code will fail with errorCode()=peUnassigned on
obj.color=Red.

Here's the complete code with changes

var
  obj UIObject
endVar
errorTrapOnWarnings(Yes) ; LINE ADDED
try
  obj.attach("boxOne")
  obj.color = Red
onFail
  if errorCode() = peObjectNotFound then
     obj.create(BoxTool, 180, 180, 360, 360)
     obj.name = "boxOne"
     obj.visible = Yes
     reTry
  else
     fail()
  endIf
endTry
errorTrapOnWarnings(No) ; LINE ADDED

To index

523 errorLog() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The code requires errorTrapOnWarnings(Yes) to cause
  obj.attach("boxOne")
to fail.
Without errorTrapOnWarnings(Yes), code will fail with errorCode()=peUnassigned on
obj.color=RedBlue.

Here's the complete code with changes

var
  obj UIObject
  eCode LongInt
  eMsg String
endVar

errorTrapOnWarnings(Yes) ; LINE ADDED
try
  obj.attach("boxOne")
  obj.color = "RedBlue" ; invalid color constant--will cause an error
                          ; other than peObjectNotFound
onFail
  if errorCode() = peObjectNotFound then
    msgInfo("And the error was", errorMessage())
    obj.create(BoxTool, 180, 180, 360, 360)
    obj.name = "boxOne"
    obj.visible = Yes
    reTry
 else
   ; pop off the original error
   eCode = errorCode()
   eMsg = errorMessage()
   errorPop()
   ; push the original error back onto the stack, but
   ; modify the error message
   errorLog(eCode, self.Name + "::pushButton failed at " +
            String(time()) + ". " + eMsg)
   msgInfo("And the new error is", errorMessage())
   fail()
 endIf
endTry
errorTrapOnWarnings(no) ; LINE ADDED

To index

524 formatGetSpec() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

525 formatSetDateDefault() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Example code
< Quote >
var
  someDate Date
endVar
if formatExist("Windows Long") then
  formatSetDateDefault("Windows Long")
  someDate = date("9/15/92")
  someDate.view() ; displays "Tuesday, September 15, 1992"
else
  msgStop("Stop", "Requested format does not exist.")
endIf
< /Quote >

Two issues:
1)
see ObjectPAL - Examples - General Issues - WADID 592 - Issue 3: Regional settings

2)
Correct order of statements should be:
  someDate = date("9/15/92") ; date has to be specified with your date format.
  formatSetDateDefault("Windows Long")

When default format is changed, the new format should be used when specifying a string to be casted as date.

To index

526 getRegistryValue() example
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

For some reason the example is using registry path
 "Software\\WordPerfect Office 11\\Paradox\\11.0\\Pdoxwin"

but the Paradox keys are found under "Software\\Corel\\Paradox\\11.0\\Pdoxwin".

Still there was one key under "Software\\WordPerfect Office 11\\Paradox\\11.0\\Pdoxwin", Designer. Wonder why?

To index

527 printerGetInfo() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

The example is a reference to printerSetOptions() but that example does not use printerGetInfo().

To index

528 readEnvironmentString() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Example code contains the following lines
< Quote >
; fs.getDir() currently returns some high-ANSI char--not a meaningful string
myDir = getaliaspath(fs.getDir()) ; get the current directory
< /Quote >

fs.getDir() returns a string with no drive letter.

myDir=getAliasPath(":WORK:")
would be a better choice.

To index

529 readProfileString()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

When applying readProfileString() on [windows] section in win.ini, you can be able to read settings even though they are not stored in win.ini any longer.

Test the example code, reading and updating beep key in windows section!

To index

530 searchRegistry()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

SearchRegistry() will store the result in a in-memory tcursor with the structure
< Quote >
Field Type Description

RegistryType A12 Registry object type (Key, ValueName or Data)
RootKeyConst A25 Predefined rootKey constant as a string
KeyPath A255 Full path of the key
ValueName A255 Full value name
Data A255 Full Data
< /Quote >

What's not said is that when searching keys, the content of ValueName and Data is not returned. When searching valuenames, the content of Data is not returned.

To index

531 searchRegistry() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3009.0 P4

In the example, the searchRegistry() parameterlist is specified like this:
< Quote >
searchRegistry( " ", "Corel", 0, 1, tc ) ; Search the registry
                                           ; for keys that have
                                           ; "Corel" in them
......

searchRegistry( " ", "Pdoxwin", 0, 1, tc )
< /Quote >

The first parameter should be an empty string, not a string containing a space.

searchRegistry( "", "Corel", 0, 1, tc ) ; Search the registry
......
searchRegistry( "", "Pdoxwin", 0, 1, tc )

To index

532 sendKeys() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example sends keystrokes to save a notepad file.
< Quote >
   sendKeys("%fs")
< /Quote >

The keys to send depends on your language version of Windows/Notepad.

To index

533 sendKeysActionId() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 2- TabStop
 
If button has TabStop checked, Paradox will be completely locked up.

To index

534 setRegistryValue() example
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

The description of the example is incorrect
< Quote >
The following example sets the current ObjectPAL level in the registry:

var
   strLevel String
endvar

; create key, value and data in regCurrentUser
setRegistryValue( "Software\\Corel\\Myapp\\Settings", "ObjectValue", "An object", regKeyCurrentUser )
< /Quote >

To index

535 sound() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

See also ObjectPAL - System type - sound() - WadId 241

Here's correct code for Paradox 9 and later versions:

method pushButton(var eventInfo Event)
var
   quarterNote, octave, note LongInt
   power Number
endVar
; frequency values for notes in a scale
const
  noteA1 = 110
  noteA#1 = 116
  noteB1 = 123
  noteC1 = 130
  noteC#1 = 138
  noteD1 = 146
  noteD#1 = 155
  noteE1 = 164
  noteF1 = 174
  noteF#1 = 184
  noteG1 = 195
  noteG#1 = 207
  noteA2 = 220
  noteA#2 = 234
  noteB2 = 249
  noteC2 = 265
  noteC#2 = 282
  noteD2 = 300
endConst
; several bars from Peter and the Wolf
sound( 400, noteA1)
sound( 300, noteD1)
sound( 100, noteF#1)
sound( 200, noteA2)
sound( 200, noteB2)
sound( 300, noteA2)

sound( 100, noteF#1)
sound( 200, noteA2)
sound( 200, noteB2)
sound( 300, noteC#2)
sound( 100, noteD2)
sound( 200, noteA2)
sound( 200, noteF#1)
sound( 200, noteD1)
sleep(1000)

; play a few chromatic scales
quarterNote = 240
for octave from 0 to 1
   for note from 0 to 11
      sound( quarterNote, int(pow(2, octave + note / 12.0) * 110))
   endFor
endFor
sound( quarterNote, int(pow(2, 2) * 110)) ; finish out the scale

endMethod

To index

281 errorMessage()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

According to the help files
< Quote >
errorMessage returns a string containing the most recent run-time error message or error condition from the error stack. This method returns the empty string ("") if no error has occurred.
< /Quote >

What's not mentioned is, that the procedure adds a CR/LF combination to the returned string, but only if the string is not NULL

Reported by : Michael J. Williams
Date: 20 June 1997

To index

697 execute()
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

In Win2000, the Paradox Execute() command seems crippled for executing many DOS commands. Just include the extension of the file to execute:

execute("format a:")
won't work, but
execute("format.com a:")
will.

Same with batch files execute("abatch") vs execute("abatch.bat")

An alternate method could be this:
execute("cmd /c c:\\data\\pdoxapps\\info\\mybat", True, exeshownormal)

Reported by: TONY MCGUIRE, and BERTIL ISBERG
Date: 15 May 2002


Under Win9x, you could use
execute("start http://www.corel.com", Yes, ExeShowNormal)
to launch the web browser

On Win2000, this won't work. This is how I load the web browser in Win2000/Pdox9 from OPAL.

execute("rundll32 url.dll,FileProtocolHandler http://cnn.com/", Yes, ExeShowNormal)

Alternate solutions are to use WinAPI shellExecuteA() or
execute("cmd /c start http://www.dn.se", False)

Reported by: DAVE REID and BERTIL ISBERG
Date: 10 August 2000

To index

625 setGlobal() and global()
Buglist Id: Last tested in version: First seen in version:
11 Build 3009.0 P4

TOPIC: setGlobal() - undocumented feature - global variables

I stumbled onto some completely undocumented code that didn't work when I left Corel, so I fixed it:

The following ObjectPAL code works below, that didn't work up until Paradox 9 SP3. It works in SP4 ...

method run ( var eventInfo Event )
var
    g1 smallint
endvar

g1 = 5
setGlobal1 ( g1 )

view ( global1() )

endMethod

You have three global placeholders for an anytype variable. setGlobal1(), global1(), setGlobal2(), global2(), setGlobal3(), global3().

Reported by: Paul Cronk
Date: 10 March 2001


Example:
In form 1

method pushButton(var eventInfo Event)
var
    g1 smallint
endvar
g1 = 5
setGlobal1 ( g1 )
endMethod


In form 2
method pushButton(var eventInfo Event)
view ( global1() )
endMethod

This code retrieves the global variable set in form 1.

To index

655 fileBrowserEx()
Buglist Id: Last tested in version: First seen in version:
11 Build 30211 Build 302

Help file does not mention that some of the filebrowserinfo parameters cannot be used together. As an example, you cannot combine .customfilter with .allowabletypes. If you do, the customfilter will be ignored.

Originally reported by: "Peter Leenen"
Date: 3 September 2004

To index

656 fail()
Buglist Id: Last tested in version: First seen in version:
11 Build 3025.04

Syntax:
fail ( [ const errorNumber SmallInt, const errorMessage String ] )

What's not mentioned is that if you plan to use an errorshow() to show the error created by fail(), you cannot use fail() without parameters. It will cause an error: "You have called fail() without any error code or error message."

Help files also says:
< Quote >
Use an Errors constant or a user-defined error constant to set a value for errorNumber, which specifies an error code on failure. errorMessage (optional) specifies a displayed error message.
< /Quote >
But errormessage is not optional. If errornumber is specified, errormessage has to be specified too. It can be an empty string, though.

To index

684 enumDesktopWindowNames()
Buglist Id: Last tested in version: First seen in version:
11 Build 4109.0 P4

Using the array syntax for this method, you can limit the returned values to only be the Windows with a specified class.
<<
enumDesktopWindowNames ( const windowNames Array [ ] String [, const className String] )
>>

The classNames to use is not specified. It should have been mentioned that classNames are not the same in full Paradox and Paradox runtime., e g a form has className pfw27f32 in full Paradox and pfw27r32 in Runtime.

Reported by: Tom Krieg
Date: 29 May 2005

To index

670 printerSetOptions()
Buglist Id: Last tested in version: First seen in version:
11 Build 30210.0

Parameters that can be set by printerSetOptions() includes PaperSize. Help file says
< Quote >
 Use a PrinterSizes constant to test the value. Paper size is set to prnCustom if the paper size does not match any of the predefined sizes.
< /Quote >
If you do an enumRtlConstants and look at the printerSizes constants they range from approximately 1-68. How ever if you poll your installed printers with enumPrinterForms there are constants in the 200's+. Obviously using Paradox constants will be hit and miss.

Reported by: Jack E. Wasserstein, DDS, Inc.
Date: 22 October 2004

To index

662 errorshow()
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95

errorshow() returns a logical value.

errorShow() returns True if an error was shown, and False if it was not.

doSomething ...
if ErrorShow("couldn't do it") then
   return
endif

Reported by: "Sundial Services"
Date: 18 October 2004

To index

378 addKeys() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
addKeys(const keys String) Logical

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Allows you to insert keys into the recording.


Reported by: David Berg, Paradox Development
Date: 1996

To index

379 compilerTimeInfo() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
compilerTimeInfo(var info DynArray[] AnyType)

Used for internal performance testing


Reported by: David Berg, Paradox Development
Date: 1996


Example:
var
   daratinfo DynArray[] AnyType
endvar
compilerTimeInfo(daratinfo)
daratInfo.view()

To index

380 enumFontSizes() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
enumFontSizes(fontName String, fontSizes Array[] Smallint) Logical

Returns a list of available sizes for the specified font.


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   arsiFontSizes Array[] Smallint
endvar
enumFontSizes("Comic Sans", arsifontSizes)
arsiFontSizes.view()

To index

381 enumFontStyles() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
enumFontStyles(fontName String, fontStyles Array[] String) Logical

Returns a list of available font styles for the specified font


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   arstFontStyles Array[] string
endvar
enumFontStyles("Comic Sans", arstfontStyles)
arstFontStyles.view()

To index

382 errorIsTrapOnWarnings() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
errorIsTrapOnWarnings() Logical

Same as IsErrorTrapOnWarnings


Reported by: David Berg, Paradox Development
Date: 1996

Example:
  errorTrapOnWarnings(not ErrorIsTrapOnWarnings())
  msgInfo("Warning errors are critical", ErrorIsTrapOnWarnings())

To index

383 getRegistryValue() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
getRegistryValue(const key String, const value String) AnyType

Same as getRegistryValue but defaults to a RootKey of HKEY_CURRENT_USER


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   atValue anytype
endvar

atValue=getRegistryValue("Environment", "TEMP")
atValue.view()

To index

384 isAltKeyDown() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isAltKeyDown() Logical

returns TRUE if the alt key is depressed at the time of the call.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:

Add this code to a field object:
Const
  HighRangeVal = Number(10000)
  LowRangeVal = Number(100000)
  DefaultVal = Number(50000)
endConst

method mouseUp(var eventInfo MouseEvent)

switch
  case isAltKeyDown() :
      self.Value = LowRangeVal
      message("Alt-click")
  case isShiftKeyDown() :
      self.Value = HighRangeVal
      message("SHIFT-click")
  case isControlKeyDown() :
       self.Value = HighRangeVal
       message("CTRL-click")
  otherwise :
       self.Value = DefaultVal
       message("Click")
endswitch
endMethod

To index

385 isControlKeyDown() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isControlKeyDown() Logical

returns TRUE if the control key is depressed at the time of the call.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example
see ObjectPAL- System type - proc isAltKeyDown() - WADID 384

To index

386 isShiftKeyDown() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
isShiftKeyDown() Logical

returns TRUE if the shift key is depressed at the time of the call.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example
see ObjectPAL- System type - proc isAltKeyDown() - WADID 384

To index

387 openSQLEditor() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 30010.0

Undocumented.

Syntax:
openSQLEditor(const FileName String, const OpenVQB Logical) Logical

Open the SQL Editor window.


Reported by: Paul Cronk - Corel
Date: 5 april 2000


Example:
openSQLEditor("MySQL.SQL", FALSE)

COMMENT:
Specify the file extension.

To index

388 printerGetLayout() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
printerGetLayout(var pageLayoutInfo PageLayoutInfo) Logical

Fills in a record with information on the current page layout. To get this information, you have to define (and pass) your own record with the following fields:

Field Name Description Data Type
"Device" Device ID# SmallInt
"PageSize" Width, Height Point
"MinSize" Width, Height Point
"BorderTopLeft " Left, Top Point
"BorderBottomRight " Right, Bottom Point
"MarginTopLeft " Left, Top Point
"MarginBottomRight " Right, Bottom Point
"PageOffset" X, Y Point


Reported by: David Berg, Paradox Development
Date: 1996

Example:

Type
     pageLayoutInfo = RECORD
Device SmallInt
PageSize Point
MinSize Point
BorderTopLeft Point
BorderBottomRight Point
MarginTopLeft Point
MarginBottomRight Point
PageOffset Point

     ENDRECORD
endType

method pushButton(var eventInfo Event)
var
pli pagelayoutinfo
endvar
printerGetLayout(pli)
pli.view()
endMethod

To index

389 printerGetPaperSizes() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
printerGetPaperSizes(var paperSizes Array[] String) Logical

Returns a list of all the paper sizes supported by the current printer. Each entry in the array is of the form "id#|name|width|height".


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   arstpaperSizes Array[] String
endvar
printerGetPaperSizes(arstpaperSizes)
arstPapersizes.view()

To index

390 printerGetType() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
printerGetType() SmallInt


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   si smallint
   st string
endvar
si=printerGetType()
constantValueToName("PrinterType", si, st)
st.view()

To index

391 projectViewerIsRestricted() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
projectViewerIsRestricted() Logical

Returns whether or not the project viewer is restricted.


Reported by: David Berg, Paradox Development
Date: 1996

COMMENT:
Does not work in Paradox 11 SP1. It always return True even after ProjectViewerUnRestrict()

To index

392 projectViewerRefresh() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
projectViewerRefresh() Logical

Causes the project viewer to refresh. Useful after you've just added or removed a file that would be displayed in the Project Viewer and you want to make sure your change shows up.


Reported by: David Berg, Paradox Development
Date: 1996

To index

393 projectViewerRestrict() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
projectViewerRestrict() Logical

Closes the project viewer, and restricts it from being reopened (by either ObjectPAL or the UI).


Reported by: David Berg, Paradox Development
Date: 1996

Example:
projectViewerRestrict()

To index

394 projectViewerUnRestrict() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
projectViewerUnRestrict() Logical

Removes the restriction placed on the Project Viewer, allowing it to be opened (by either ObjectPAL or the UI). Does not actually open the Project Viewer (use projectViewerOpen() for that).


Reported by: David Berg, Paradox Development
Date: 1996

Example:
ProjectViewerUnRestrict()

COMMENT:
Form issuing
ProjectViewerRestrict() or ProjectViewerUnRestrict()
must be closed for the restriction to be cleared.

To index

395 recorderContinue() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
recorderContinue( )

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Continues recording after a pause.


Reported by: David Berg, Paradox Development
Date: 1996

To index

396 recorderFlush() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
recorderFlush( )

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Ensures that all buffers are flushed to disk.


Reported by: David Berg, Paradox Development
Date: 1996

To index

397 recorderPause() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
recorderPause( )

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Pauses recording.


Reported by: David Berg, Paradox Development
Date: 1996

To index

398 recorderStart() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
recorderStart(const fileName String) Logical

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Starts recording keystrokes and mouse events. These events are written to the specified file name. The format is the same used by Paradox's SENDKEYS method.


Reported by: David Berg, Paradox Development
Date: 1996

To index

399 recorderStop() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
recorderStop( ) Logical

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Stops recording.


Reported by: David Berg, Paradox Development
Date: 1996

To index

400 resetCompileInformation() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
resetCompileInformation()

Used for internal performance testing


Reported by: David Berg, Paradox Development
Date: 1996

To index

401 sendKeysFromFile() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
sendKeysFromFile(const keysFileName String, const wait Logical) Logical

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Sends keystrokes (and mouse events) to Windows as if you'd typed them. The events are taken from a file, such as the one created by recorderStart above. Wait indicates whether to wait for the keys to be processed, or to return immediately.


Reported by: David Berg, Paradox Development
Date: 1996

To index

402 sendKeysSpeed() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
sendKeysSpeed(const speed Number)

These functions can record key strokes and mouse events. They are believed to have been in most of the Paradox Windows versions; however, due to changes in the 32 bit environment, they do not work in the 32 bit Paradox 7.0.

Sets the playback rate. I'm not sure what the units are.


Reported by: David Berg, Paradox Development
Date: 1996

To index

403 setNewShell() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setNewShell(yesNo Logical )

If you're running on Windows 95 (or Windows NT 4.0) and want to see what Paradox would look/act like under Windows NT 3.51, call setNewShell( No ). Call setNewShell( Yes ) to restore the new shell look.


WARNINGS: This is only in the 32 bit product. Calling setNewShell( Yes ) on Windows NT 3.51 will probably crash as the necessary operating system components are missing.


Reported by: David Berg, Paradox Development
Date: 1996

To index

404 setRegistryValue() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
setRegistryValue(const key String, const value String, const data AnyType) Logical

Same as setRegistryValue but defaults to a RootKey of HKEY_CURRENT_USER


Reported by: David Berg, Paradox Development
Date: 1996


Example:
setRegistryValue("MyName", "BERTIL", "Isberg")

To index

405 SQLupdates() proc
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
SQLupdates(const yesNo Logical)

To index

406 startUpTime() proc
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Undocumented.

Syntax:
startUpTime() LongInt

Used for internal performance testing


Reported by: David Berg, Paradox Development
Date: 1996

Example:
var
   li longInt
endvar
li=startUpTime()
li.view()

To index

241 sound()
Buglist Id: Last tested in version: First seen in version:
PX057011 Build 2339.0 P3

Parameters to the sound() method has been reversed in Paradox 9.

According to help files and as they work in previous versions
sound ( const freqHertz, const durationMilliSecs LongInt )

but they now, Paradox 9 and later versions, work as
sound ( const durationMilliSecs LongInt, const freqHertz Longint )


Note that the help file does not specify a datatype for the freqHertz. It should be Longint.


Reported by: Elmar von Muralt
27 March 2001

To index

237 sysInfo()
Buglist Id: Last tested in version: First seen in version:
7.0 W95 P4

sysInfo() contains information on your version of Windows.
WindowsBuild# The internal build number
WindowsPlatform Win95, NT, or WIN32s
WindowsText Arbitrary information
WindowsVersion Windows version number

Running Paradox 7 on Win2000 or WinXP with application compatibility mode NT4 SP5 will cause the values returned to be as if the Windows version is NT4 SP5.

To index

41 fileBrowserEx()
Buglist Id: Last tested in version: First seen in version:
PX049311 Build 2338.0

When I try to select multiple files using the FileBrowserEx command the Alias returned is always the initial fileBrowserInfo alias ( or Work when parameter is not specified ) and the Drive and Path parameters are always empty. The array contains the complete path to the files selected.

If only one file is selected, the array contains the alias and the file name.

Paradox 9, SP2 installed.

To index

34 enumPrinters()
Buglist Id: Last tested in version: First seen in version:
PX045611 Build 2338.0

In version 9, the enumPrinters procedure returns different information than Paradox 7/16 and 7/32.

According to the help files
< Quote >
If the printer name is Postscript Printer, the driver is PSCRIPT.DRV, and the port is LPT1:

PostScript Printer,pscript,LPT1:
< /Quote >

That is a description of what was returned in Paradox 7.
For example in PDOXWIN 7/16 the name of my printer is "HP LaserJet 5" and the driver name is "HPPCL5MS." However, in Paradox 9 my printer is still "HP LaserJet 5P but the driver name is also "HP LaserJet 5P."


The information returned by enumPrinters() in Paradox 7 looks like what in registry
[HKEY_CURRENT_USER\Printers]
"DeviceOld"="HPLJ4050SeriesPS,winspool,LPT1:"
or
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices]
"HPLJ4SiMXPS"="winspool,LPT2:"
"HPLJ4050SeriesPS"="winspool,LPT1:"
"Fax"="winspool,Ne00:"
or
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts]
"HPLJ4SiMXPS"="winspool,LPT2:,15,45"
"HPLJ4050SeriesPS"="winspool,LPT1:,15,45"
"Fax"="winspool,Ne00:,15,45"

In later versions, P9-P11, the informations looks like what's found in registry
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\HPLJ4050SeriesPS]
"Name"="HPLJ4050SeriesPS"
"Printer Driver"="HP LaserJet 4050 Series PS"
"Port"="LPT1:"
or
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Printers\HPLJ4050SeriesPS]
or
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\HPLJ4050SeriesPS]


Originally reported by: Rex B. Hamilton
Subject: enumPrinters does not return driver names
Date: 18 November 1999

To index

175 sendKeys()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

Help file says:
CAPS LOCK {capslock}, {vk_captial}

Should be:
CAPS LOCK {capslock}, {vk_capital}

To index

181 fileBrowserEx()
Buglist Id: Last tested in version: First seen in version:
10.0 P210.0 P2

fileBrowserInfo parameter to fileBrowserEx() has a setting NewFileOnly, which makes the fileBrowser dialog work like a Save As dialog.

If you want to specify a path where to save the file , you cannot use fbi.path=":alias:subdirectory" in combination with NewFileOnly=true. Instead you have to use getAliasPath(":alias:")+"\\subdirectory".

But help files says:
< Quote >
Path String The path of the selected file or files. The value is returned by the File Browser and cannot be set directly.
< /Quote >

So this could be a Wad.


Reported by: Rodney Wise
Date: 16 May 2002

To index

187 enumPapersources()
Buglist Id: Last tested in version: First seen in version:
11 Build 302

According to the help files:
< Quote >
Syntax

enumPaperSources ( var trays Array[ ] String ) Logical

Description

Retrieves a list of printer trays currently installed on the current printer. The trays array is a list of strings corresponding to the names of the printer trays as provided by the printer driver. If printerName is omitted, the current default printer is used.
< /Quote >

There is no way to provide a printerName as I can see.

To index

157 runExpert()
Buglist Id: Last tested in version: First seen in version:
10.0 P2

Help files does not mention the facility to invoke eg TableRepair from ObjectPAL by an expert type named CoreUI

runExpert( "CoreUI", "TableRepair")

You can find more CoreUI features available from ObjectPAL in registry

[HKEY_CURRENT_USER\Software\Corel\Paradox\10.0\Experts\09\CoreUI]

To index

151 tracerWrite()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

Help file says the syntax is
tracerWrite ( const message String [ , const message String ] * )

but tracerWrite() with no parameter is accepted, even though it doesn't do anything.

To index

147 isTableCorrupt()
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT10.0 RT

PARADOX RUNTIME issue

The method isTableCorrupt() seems to require the tutil32.dll. This file is not installed by default in the Runtime directories, which makes the method not work. It will always return false, and no errortable is produced when using the syntax isTableCorrupt("tablename", "errortablename").

Workaround is to copy tutil32.dll to the \Programs folder of RT installation

To index

148 readEnvironmentString()
Buglist Id: Last tested in version: First seen in version:
10.0 P210.0 P2

ReadEnvironmentString() when used in a calculated field in a report won't assign a value to the field if the master table in the report is empty.

To index

121 setRegistryValue()
Buglist Id: Last tested in version: First seen in version:
10.07.0 W95

Help file says:
< Quote >
Syntax

setRegistryValue ( const key String, const value String, const data AnyType, const rootKey LongInt ) Logical
.....

data accepts the following types:

ObjectPAL Type Registry type Size limitation
....
LongInt DWORD 4 bytes
...
SmallInt DWORD 4 bytes
< /Quote >

But the code
var
 li longint
endvar
li=4
setRegistryValue( "Software\\Milago", "DoubleWord", li, regKeyCurrentUser )

will create a Stringvalue DoubleWord with data="4"

New findings 2002-09:
in P10 SP2, setRegistryValue() creates a doubleword on Win2000, but not on Win95B.

To index

126 fileBrowserEx()
Buglist Id: Last tested in version: First seen in version:
PX052110.0 P28.0

FileBrowser Filetype constant fbIni is specified as (*.ini) in the help files. It should be (*.ini, *.cfg)

To index

127 fileBrowser()
Buglist Id: Last tested in version: First seen in version:
PX052110.0 P27.0 W95 P4

To index

ObjectPAL---Table type

182 create keyword
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P2

Help file on create keyword says:
< Quote >
Notes
If the versionLevel parameter is not set the created table will default to version 4.
< /Quote >

This is not true. versionLevel will be taken from the settings in BDE Administrator.

If I run the example from the help files when LEVEL in BDE Admin is set to 7, I get a Level 7 table.

To index

167 restructure()
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

You can use restructure method to add auxiliary passwords to a table using the secStruct element in the dynarray. The help files does not mention that the master password of the table will be changed to "secret".

To index

168 protect()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P2

According to help files
< Quote >
protect assigns an owner password to a table. The password cannot exceed 31 characters. A password-protected table cannot be accessed without presenting the password specified in password. If the table already has a password, protect fails.
< /Quote >

The last sentence is not true. protect() does not fail. You can use protect("newpassword") to replace the default password "secret" assigned by Paradox create keyword and restructure method. Auxiliary password will be kept.

To index

37 add()
Buglist Id: Last tested in version: First seen in version:
PX046510.07.0 W95

ObjectPAL - .add() does not add data if it does not fit in the destination table. Interactive add will give you a Trim dialog.

setup: Add a table with an A10 field to a table with a A5 field. Any data in the A10 which is wider than 5 characters will not be added. table.add does not work either


Workaround: Any one of following may be used as a work-around.
1. Use Tools | Utilities | Add instead.
2. Make sure the source and destination tables has the same structures.
3. Run a scan loop and fill in the values via ObjectPAL.

To index

15 compact()
Buglist Id: Last tested in version: First seen in version:
PX020610.05.04

compact() functions on a newly created table, with new or old data, added or deleted data.

Always fails if table is restructured so that the field being deleted, altered, or inserted is NOT at the end of the field structure definition.
Usual message during failure of "pack" is "INVALID FIELD DESCRIPTOR".
Also seen "NUMBER IS OUT OF RANGE", and there are no numbers out of range!

To index

57 rename() example
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

The code below is the example on table.rename in the help files. The code does not work if you decide to overwrite the existing table.

If the newname table does exist, it has to be deleted.

< Quote >
The following example renames CUSTOMER.DB to OLDCUST. If OldCust already exists, this code allows you to abort the operation:

; renameCust::pushButton
method pushButton(var eventInfo Event)
var
  tblVar Table
  oldName, newName String
endVar

oldName = "Customer.db"
newName = "OldCust.db"

tblVar.attach(oldName)
if tblVar.isTable() then
  if isTable(newName) then
    if msgQuestion("Confirm", newName + " exists. Overwrite it?") <> "Yes" then
      message("Operation canceled.")
      return
    endIf
  endIf
  tblVar.rename(newName)
  message(oldName + " renamed to " + newName)
else
  msgStop("Stop!", "Can't find " + oldName + " table.")
endIf

endMethod
< /Quote >

To index

59 isTable()
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

Following is from the OPAL.HLP file on Table.isTable. Note that the explanation for Database.isTable is slighty different.

< Quote >
isTable

See Also Example Table Type

Method/Procedure

Reports whether a table exists in a database.

Syntax

isTable ( ) Logical

Description

isTable returns True if the Table variable represents a table that can be opened; otherwise, it returns False.
< /Quote >

The one line summary IS WRONG - the description is true. If another session has an exclusive lock on the table, the procedure returns false (as does method database.istable()).

Reported by: Adrian Fowle

To index

69 setRange()
Buglist Id: Last tested in version: First seen in version:
PX001011 Build 2331.0

To index

252 restructure()
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

According to the help files
< Quote >
secStruct specifies the table from which you can borrow security structure information. Use enumSecStruct to generate the security structure table name (or create it manually). Use the iSecId field in the security structure table to specify the change to be made to the table. Use RestructureModify to modify existing values, RestructureAdd to add, or RestructureDrop to delete.
< /Quote >

The name of the column is iSecNum and not iSecId.

RestructureModify will add new passwords
RestructureDrop does not drop existing passwords.
RestructureAdd seems to work as expected.

Leaving the old values in iSecNum unchanged does not work. If the table contains more than one auxiliary password, only one is left after restructure. You have to edit the secStruct table and change iSecNum to RestructureAdd for all records.

To modify existing auxiliary passwords, you have to remove the old ones by applying an empty secstruct table and then adding new passwords.

When tested in Paradox 9 SP4, auxiliary passwords were not added. It works in Paradox 10.719.

To index

280 empty()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

To index

277 restructure()
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

Example on how to use restructure() is very elementary. Here's another one.

Example of using the restructure method in Paradox 8 or 9. The code takes advantage of the Customer.db table found in the Samples folder.

var
     tbl Table
     tcFlds TCursor
     daratNewStruct DynArray[] Anytype
endvar

tbl.attach( "Customer.db" ) ;Customer.db in the Samples folder
tbl.enumFieldStruct( "field_struct.db" )

tcFlds.open("field_struct.db" )
tcFlds.edit()

scan tcFlds :
   if tcFlds."Field Name" = "Name" then
      tcFlds."Field Name" = "Company Name"
      quitLoop
   endif
endscan

;//delete Phone field from Customer table
scan tcFlds :
   if tcFlds."Field Name" = "Phone" then
      tcFlds.deleteRecord()
      quitLoop
   endif
endscan

;//insert field Test before the Country field
scan tcFlds :
   if tcFlds."Field Name" = "Country" then
      tcFlds.insertBeforeRecord()
      tcFlds.(1) = "Test" ;field name
      tcFlds.(2) = "ALPHA" ;field type
      tcFlds.(3) = 10 ;size
      quitLoop
   endif
endscan


;//add field Test2 at the end of table
tcFlds.end()
tcFlds.insertAfterRecord()
tcFlds.(1) = "Test2" ;field name
tcFlds.(2) = "ALPHA" ;field type
tcFlds.(3) = 10 ;size

tcFlds.endEdit()
tcFlds.close()

daratNewStruct["FIELDSTRUCT"] = "field_struct.db"
tbl.restructure( daratNewStruct )


{
Invalid array of validity check descriptors in most cases means that the table structure has been changed by inserting a column anywhere but as the last column. When you do, field name references sometimes refers to another column than the one you expect. Try to Rebuild the table.

Anytime you change the structure of a table by removing columns and adding columns, rebuild the table. The only valid place for a new column is as the last column.

runExpert( "CoreUI", "TableRepair")
}


Reported by: Michael Juul Hansen
Subject: Dynamic restructure
Date: 9 July 1999

To index

202 nRecords()
Buglist Id: Last tested in version: First seen in version:
11 Build 302

To index

219 cCount()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

To index

225 enumSecStruct()
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P3

Help files does not say explicitly that this method enumerates the auxialiary passwords set on a table. It won't give you information on the master password.

To index

209 restructure()
Buglist Id: Last tested in version: First seen in version:
10.0 P310.0 P3

Restructuring a password protected table by changing the langauge driver or the version level removes the password.

You can add it back by
tblHandle.protect("password")

To index

210 restructure()
Buglist Id: Last tested in version: First seen in version:
10.0 P310.0 P3

Restructuring a table eg by changing some of the field names will cause an error "Invalid array of validity check descriptors" if any of the columns has validity checks.

The scan loop editing the fieldstruct table should look like
scan tcFlds:
   if tcFlds."Field Name" = "Empfänger" then
      tcFlds."Field Name" = "Empfaenger"
   endif
   tcFlds.update("_Required Value", "", "_Min Value", "", "_Max Value", "",
           "_Picture Value", "", "_Default Value", "")
endScan

Removing the validity check information this way, won't remove the validity checks from the table.

I haven't tested this with lookup tables defined. Maybe also that information has to be cleared.


You have to remove dynNewStru["warnings"]=true or errorTrapOnWarnings(Yes) if the field you are changing has validity checks. Otherwise, you'll get a warning Validity Check field modified. And when restructure is run with errorTrapOnwarnings(Yes), it will fail.


An example changing more than one field with validity checks defined:

Table:
DbaseAlias * A18
DbaserDriver A18 Default=A, Required
Xfr_batch S Min=1, Max=500, Default=1, Required
Col4 S Default=5

Changing to
DbaseDriver A10
Xfr_batch I
Col4 I Default=35

Code inside scan loop:

    if tcFlds."Field Name" = "Xfr_batch" then
         if tcFlds."Type" = "SHORT" then
            tcFlds."Type" = "LONG INTEGER"
        endIf
    endif

    if tcFlds."Field Name" = "DbaseDriver" then
        if tcFlds."Size" = "18" then
            tcFlds."Size" = "10"
        endIf
    endif

    if tcFlds."Field Name" = "Col4" then
        if tcFlds."Type" = "SHORT" then
            tcFlds."Type" = "LONG INTEGER"
        endIf
       tcFlds."_Default Value"="35"
   endif

   tcFlds.update("_Required Value", "", "_Min Value", "", "_Max Value", "",
               "_Picture Value", "")

   if tcFlds."Field Name" <> "Col4" then

      if tcFlds."_Default Value"<>"" then
         tcFlds."_Default Value"=""
      endif
   endif

To index

211 restructure()
Buglist Id: Last tested in version: First seen in version:
10.0 P310.0 P3

If table to be restructured has column names with national characters like ä, and ö, those characters will (or can) be converted from ansi to ascii (or vice versa) when table is restructured. Columname Örebro will be changed to ™rebro.

This happens when table language driver is ANSISWFN, or ANSIINTL, but not when language driver is ASCII based, like SWEDFIN, or INTL.

Even though Paradox help files says:
· Paradox does not allow you to use extended characters as field names
it is possible to use such characters.


Conclusion: Especially when using ANSI based language drivers, don't use national characters in column names.

To index

407 addRefInt() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
addRefInt(const RefIntTable String) Logical

addRefInt(const RefIntTable TCursor) Logical

Adds referential integrity or validity constraints to the table (in the variable) using the specification in the input table (cursor). Input table/cursor should (probably) follow the format produced by the corresponding enumeration functions.


Reported by: David Berg, Paradox Development
Date: 1996

To index

409 addValCheck() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
addValCheck(const ValChkTable String) Logical

addValCheck(const ValChkTable TCursor) Logical

Adds referential integrity or validity constaraints to the table (in the variable) using the specification in the input table (cursor). Input table/cursor should (probably) follow the format produced by the corresponding enumeration functions.


Reported by: David Berg, Paradox Development
Date: 1996

To index

671 create keyword
Buglist Id: Last tested in version: First seen in version:
11 Build 3021.0

Create keyword requires errorTrapOnWarnings(yes) to catch any errors. Put the create statement inside a try block surrounded by errorTrapOnWarnings(yes) and errorTrapOnWarnings(No).

To index

675 Language drivers for Paradox tables
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

According to the help files, the language driver PDOX ANSI INTL850 is defined as
< Quote >
Driver name Internal Language / DOS CodePage
Paradox ANSI Intl850 ANSII850 ANSI International/850
< /Quote >

When looking at the table information in Table Repair, the codepage is reported as 1252, and not 850.

To index

685 add()
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

Using ObjectPAL to add data from a local table to a non Paradox table, the update parameter does not work as with Paradox tables. Only non blank columns in the local table are updated in the target table.

Reported by: Anders Jonsson
Date: 27 June 2005

To index

647 isEmpty()
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

To index

624 create keyword
Buglist Id: Last tested in version: First seen in version:
PX026911 Build 3007.0 W95 P4

Create keyword covers how to specify different datatypes when createing a table using ObjectPAL. Information on BCD type is incomplete and the syntax has changed in later versions of Paradox.
< Quote >
Paradox tables -3.5 4.5 5.0 7,8,9,10

Alpha Annn Annn Annn Annn
Memo (none) Mnnn Mnnn Mnnn
Formatted Memo (none) (none) Fnnn Fnnn
Binary (none) Bnnn Bnnn Bnnn
Graphic (none) (none) Gnnn Gnnn
OLE (none) (none) Onnn Onnn
BCD (none) (none) # #

< /Quote >

Correct specification is #nnn, where nnn is number of decimals. In Paradox 7, the specification was #32.nnn.

Specification P7 P9-
# 0 dec 0 dec
#32.4 4 dec 32 dec
#4 Error 4 dec

To index

415 copy() to remote database
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

Using ObjectPAL to copy a local table to a remote database, you are not guaranteed to get the existing indexes created.

Examples:
Customer table with primary key on CustomerNo. No secondary indexes. Spaces in column names removed.

Interactive table copy from ProjectViewer to Interbase/Firebird 6.2.0.794: The primary key is replaced by an index.
tableHandle.copy(): No index is created at all.

Interactive table copy from ProjectViewer to MS SQL SERVER 2000 connected through ODBC driver: Causes an error saying
Error copying primary index.
followed by:
ODBC driver reference -> Incorrect syntax near '.'.
and eventually
Error copying indexes. Table has been copied, but not all indexes have.


Here's code to create an index based on the primary key definition in the local table.

var
   dbHandle database
   tblHandle table
   arstIndex array[] string
   sqlHandle sql
   stIndexCols string
   si smallint
endvar

; Open handle to Interbase database
dbHandle.open(":IBTEST:")

tblHandle.attach("Customer")

; No index name specified = primary key
tblHandle.enumFieldNamesInIndex("", arstIndex)

; create a comma separated list containing the columnnames
stIndexCols=""
for si from 1 to arstIndex.size()
   stIndexCols=stIndexCols+arstIndex[si]+", "
endfor
stIndexCols=stIndexCols.substr(1, stIndexCols.size()-2)

; Copy the table
tblHandle.copy(":IBTEST:CUSTUMER")

; Create the index
; Adjust the code to the database of your choice
; You can replace the create index with alter table add constraint primary key
sqlHandle=Sql

Create index custindex on CUSTOMER (~stIndexCols)

endsql

tblHandle.unattach()
try
   sqlHandle.executeSql(dbHandle)
onFail
   errorShow("Creating index","")
endTry

dbHandle.close()


A similar approach can be applied to the secondary indexes in the local table which can be retrieved using enumIndexStruct()


Issue reported by: "Mike Irwin [CTech]"
Subject: Missing index when copy table to interbase from objectpal
Date: 19 August 2003


Comments by: "Larry DiGiovanni"
Mike:
The table and data are copied, but the Pk and indexes for the remote table are not created.

I tried several ways of doing this:

1. copy - table and data but no index/PK
2. create LIKE, then ADD() - same result
3. enumIndexStruct, enumFieldStruct, then CREATE with STRUCT and INDEXSTRUCT - no table created

To index

536 copy() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code contains lines to ask the user if an existing table should be replaced.
< Quote >
if isTable(destTbl) then ; if "CustBak.db" exists
                              ; ask for confirmation
  if msgQuestion("Copy table", "Overwrite " + destTbl + "?") = "Yes" then
    return
  endIf
endIf
< /Quote >

It should not be = "Yes", but
  if msgQuestion("Copy table", "Overwrite " + destTbl + "?") <> "Yes" then

To index

537 create keyword example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 2 - Using an existing table's structure

contains three different examples. The one titled version 2 is incorrect
< Quote >
; version 2
var
  newSales Table
  salesTC TCursor
endVar
salesTC.open("Sales.dbf")
newSales = CREATE
             LIKE salesTC
           ENDCREATE
< /Quote >

CREATE requires a tablename.

It should be
newsales= CREATE "Newsales.dbf"
            LIKE salesTC
           ENDCREATE

To index

538 createIndex() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Both examples contains minor errors in the comments

Example1 Building a secondary index
< Quote >
; This createIndex statement has the same effect
; as the following INDEX structure:
{
  INDEX tbCust ; Create index for Customer.db.
     MAINTAINED
    ON "Customer No", "Name", "Street"
  ENDINDEX
}
< /Quote >

Should be
  INDEX tbCust ; Create index for Customer.db.
     MAINTAINED
    ON "Customer No", "Name", "Street" to "NumberNameStreet" ; Indexname is ADDED
  ENDINDEX

Example2 Adding unique index tags

< Quote >
; This createIndex statement has the same effect
; as the following INDEX structure:
{
  INDEX tbCust ; Create index for Customer.dbf.
       UNIQUE
    ON "STATE_PROV" ; Index on this field.
    TAG "StatProv" OF "Customer.dbf" ; Name the tag "StatProv".
  ENDINDEX
}
< /Quote >

Should be
  INDEX tbCust ; Create index for Customer.dbf.
       UNIQUE
    ON "STATE_PROV" ; Index on this field.
    TAG "StatProv" OF "Customer.mdx" ; Name the tag "StatProv". ; CHANGED DBF to MDX
  ENDINDEX

To index

539 enumSecStruct() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example assumes the password for the table secrets.db has been provided.

It would be worth mentioning that password for the created table MySecrts is set by Paradox to "secret".

To index

540 isShared()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to the help file
< Quote >
isShared returns True if a table is being shared by another user on a network; otherwise, it returns False. isShared does not report whether a table is being shared with another session.
< /Quote >

isShared() returns TRUE for local tables when BDE setting LocalShare=TRUE.

To index

541 setReadOnly() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code contains code that causes a syntax error
< Quote >
errorTrapOnWarnings()
tblVar.attach("Orders.db") ; attach Table var to Orders.db
< /Quote >

It should be
errorTrapOnWarnings(YES) ; LINE CHANGED
tblVar.attach("Orders.db") ; attach Table var to Orders.db

To index

542 sort keyword example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The description of the example is incorrect.
< Quote >
The following example sorts Customer on the Last Name and First Name fields, and displays the results in the CustSort table:
< /Quote >

It should be

The following example sorts Customer on the Country and Name fields, and displays the results in the CustSort table:

To index

543 subtract() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code does not work. Variable custtbl is not assigned.
< Quote >
var
  insTbl, CustTbl Table
  fs FileSystem
  tblName String
endVar
tblName = privDir() + "\\Inserted.db"

insTbl.attach(tblName)
if insTbl.isTable() then
  insTbl.subtract(custTbl) ; remove from custTbl matching records in insTbl
else
  msgInfo("Sorry", "Can't find " + tblName + " table.")
endIf
< /Quote >

Part of the code should be:
tblName = privDir() + "\\Inserted.db"

insTbl.attach(tblName)
custTbl.attach("Customer.db") ; LINE ADDED

To index

ObjectPAL---TableFrame object

287 BlankRecord property
Buglist Id: Last tested in version: First seen in version:
11 Build 3005.04

Reported by: E.J. Johns ~Borland~
Date: 1 August 1996

The following information was gathered from our web site "http://www.borland.com" and was written by James Kocis.

BlankRecord

BlankRecord reports only whether the first record of an otherwise empty tableframe or a record appended to the table is blank. It does not tell you whether a new or existing record in the midst of a table is blank. If you set the AutoAppend property in the data model to False, you will rarely encounter a value where BlankRecord is True. You can block an attempt to get to that first record in an otherwise empty tableframe by checking its BlankRecord property:

     method canArrive (var eventInfo MoveEvent)
       if self'BlankRecord then
         eventInfo.setErrorCode(UserError)
       endif
     endMethod

Though this technique works, we generally recommend keeping code away from the canArrive, canDepart, arrive and depart built-in methods because doing so slows performance on networks.

To index

136 Property CurrentColumn
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0 P2

According to the help files:
< Quote >
CurrentColumn also allows you to control column rotation and sizing in table frames at design time. Setting this property in the designer does not necessarily affect the visual appearance. Table frames do not have to be selected.
< /Quote >

Problem:
Cannot access TableFrame's property CurrentColumn unless TF has focus.

Steps:
1.1 Open/New/Blank Form.
1.2 Put, in following order, Field object, TableFrame (nami it "tfAB") and
Button object on it.
1.3 In pushButton method of Button object put:
 msgInfo( "Row", tfAB.CurrentRow ) ;Line1
 msgInfo( "Column", tfAB.CurrentColumn ) ;Line2
1.3 Close and save the form as "tfForm.fsl".
2. Run "tfForm.fsl"
3. Press Button
   (Note: TF has no Focus, Focus is at Field object.)

Result:
Error in Line2:
"An error occurred when trying to get the property named 'CurrentColumn' of the object named '' of type 'TableFrame'. "
Followed by: "Cannot access property."

Notes:
OPAL Help topic for CurrentColumn doesn't mention need for TF having Focus in order to access property.
CurrentColumn should behave similar to CurrentRow property.


REPORTED BY:
Ivica Kolar

To index

ObjectPAL---tableView type

193 TVData object
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

ObjectPAL Quick Lookup contains objects named TVData and TVHeading. Looking in ObjectPAL help, you will only find property lists and no examples on how to use those objects.

< Quote >
TableView methods are a subset of the Form type methods and control the Table window's size, position, and appearance. Although you can start and end Edit mode for a table view, you cannot use ObjectPAL to directly edit the data in a table view. You can use ObjectPAL to manipulate TableView properties in the following areas:

· the TableView object as a whole (for example: background color, grid style, number of records, and the value of the active record)
· the field-level data in the table (for example: font, color, and display format(TVData))
· the TableView heading (for example: font, color, and alignment(TVHeading))
< /Quote >

Question:
How can I obtain a TVdata/TVheading object in order to control a TableView's appearance?


Replies:

From: Peter Zevenaar
Date: 5 September 2002
To access tvData tvHeading you have to refer to the actual names:

var
tv Tableview
endvar

tv.open(":PRIV:MyTest.db")
tv.color=DarkBlue ; change color of table
tv.MyFieldName.color=Blue ; change color of particular field
tv.#.font.size=14 ;change font size of the first column (pdx's record number)
tv.MyFieldName.Heading.color=DarkBlue ;change color of MyFieldName's heading


With msginfo(tv.fieldname,"") I found that the record number is referred to as #. For the heading, I rightclicked on a field's heading and chose properties. The properties dialog's title showed MyFieldName_Heading.


From: Liz
NOTE: Although "Class" is listed as a valid property for TVData and TVHeading, if you try to get the class of a tv, one of its fields, or one of the headings for its fields, you'll get an error - also, in the definition of class in objectPAL help, those types (and tableview) are not included as things whose class can be retrieved... Weird.

It also seems you have to access each field and each field's heading individually.


From: Peter Zevenaar
In addition:
stMyString="MyFieldName.Heading"
tv.(stMyString).color=DarkBlue
works as well, which would allow to enumerate FieldNames and change tableview properties automatically for every field.

To index

194 TVHeading object
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

To index

497 wait()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

According to the help file:
< Quote >
wait suspends a method's execution. Execution resumes when the TableView object is closed. When a TableView object has been called by wait, the method suspends execution until the TableView object is closed using the close method.
< /Quote >

IMO, the method suspends execution until the user closes the tablewindow, but the window will be accessible from ObjectPAL closed by close().

To index

ObjectPAL---tCursor type

416 copy() to remote database
Buglist Id: Last tested in version: First seen in version:
11 Build 30011 Build 300

To index

562 insertBeforeRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

563 insertAfterRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

564 insertRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

565 home() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Code contains lines
< Quote >
scan tc:
  tc.fieldValue(1, fldVal)
  fldArray[tc.recNo()] = tc.fldVal
endScan
< /Quote >

should be

scan tc:
  tc.fieldValue(1, fldVal)
  fldArray[tc.recNo()] = fldVal ; LINE CHANGED
endScan

To index

566 isInMemoryTcursor() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Code contains the line:
< Quote >
            tcAnswer.Salary = tcAnswer.Salary * .15
< /Quote >

should be
            tcAnswer.Salary = tcAnswer.Salary *1 .12

To index

567 isShared()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

568 isValid() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example code contains these lines
< Quote >
tc.open("Orders.db")
if NOT tc.isValid("Sale Date", tryValue) then
  msgStop("Error",
  String(tryValue) + " is not valid for this field.")
else ; this condition is never met
  tc."Sale Date" = tryValue
  tc.postRecord()
endIf
< /Quote >

else clause should look like
else ; this condition is never met
  tc.edit() ; LINE ADDED
  tc."Sale Date" = tryValue
  tc.postRecord()
endIf

To index

569 locatePrior() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

For the example to work correctly, tCursor has to move away from first record.

< Quote >
The following code is attached to the open method for thisPage:

; thisPage::open
method open(var eventInfo Event)
  lineTC.open("Lineitem") ; open a TCursor for LineItem.db
endMethod
< /Quote >

Add a line
lineTc.end()
before endMethod

To index

570 setRange()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

ObjectPAL reference - index - tcursor type - setRange() links to table type - setRange(). There is no help for tcursor type - setRange().

To index

571 type() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Code contains a line
< Quote >
if tc.type() = "dBASE"
< /Quote >

It should be
if tc.type() = "DBASE"


The code to compact() the table does not work. Here's a correct example

method pushButton(var eventInfo Event)
var
  tc TCursor
  tb table
endVar

tc.open("Orders.dbf")

; if Orders.db is a dBASE table
if tc.type() = "DBASE" then
  ; remove deleted records
    tc.close()
    tb.attach("Orders.dbf")
    tb.setExclusive(Yes)
    tc.open(tb)
    tc.compact()
    tc.close()
else
  ; otherwise, display the type of table
  msgStop("Stop!", "Orders.db is a " + tc.type() + " table.")
endIf
endMethod

To index

646 isEmpty()
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

If you call isEmpty() after setting a filter, the return value will always be false, unless the table with no filter set is empty.

To index

553 atFirst() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

554 atLast() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

555 copyToArray() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 1- thisForm

The example code contains two more issues.

a) disableDefault is used to prevent an action(DataDeleteRecord)
b) If the record to be deleted is a new unposted record, wrong record will be archived in table CustArc.



a)
When disableDefault is used in this way, code like
if Customer.deleteRecord()
will return TRUE even when record is not deleted. It makes programming ObjectPAL very complex.

I would prefer code like

thisform.attach()
if eventInfo.id() = DataDeleteRecord then ; when user deletes a record
  if thisForm.Editing = True then ; if form is in Edit mode

:::: LINE BELOW REMOVED
;;;;; disableDefault ; don’t delete the record

                                          ; ask for confirmation
     if msgQuestion("Confirm", "Delete record?") = "Yes" then

       tcOrig.attach(CUSTOMER) ; sync TCursor to UIObject
       tcOrig.copyToArray(arcRec) ; store the record in arcRec
       if tcArc.open("CustArc.db") then ; True if tcArc can open CustArc
          tcArc.edit() ; copyFromArray requires Edit
          tcArc.insertAfterRecord() ; create a new record
          tcArc.copyFromArray(arcRec) ; copy arcRec to new record
;;;;;; LINE BELOW REMOVED
::::::: enableDefault ; delete the record in Customer
       else ; can’t open Customer TCursor
          msgStop("Stop!", "Sorry, Can’t archive record.")
          eventInfo.setErrorCode(userError) ; LINE ADDED
       endIf
     else ; user didn’t confirm dialog box
       message("Record not deleted.")
       eventInfo.setErrorCode(userError) ; LINE ADDED
     endIf

  else ; not in Edit mode
    msgStop("Stop!", "Press F9 to edit data.")
    eventInfo.setErrorCode(userError) ; LINE ADDED
  endIf
endIf

b)
Is too complex to handle in the scope of this example.

To index

556 createIndex() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The second example - Building a unique index contains code like

< Quote >
stTbName = "Cust.dbf"

arFieldNames[1] = "CITY"

dyAttrib["UNIQUE"] = True
dyAttrib["MAINTAINED"] = True

; A dBASE index name must be a valid DOS filename.
; If an extension is omitted, .NDX is appended automatically.

dyAttrib["IndexName"] = "City"
< /Quote >

I don't know enough on dBase tables to describe the requirements for this code to work. When Cust.dbf didn't have any existing indices, I had to change the code to:

stTbName = "Cust.dbf"

arFieldNames[1] = "CITY"

dyAttrib["UNIQUE"] = True
dyAttrib["MAINTAINED"] = True

; A dBASE index name must be a valid DOS filename.
; If an extension is omitted, .NDX is appended automatically.

dyAttrib["IndexName"] = "Cust.mdx"
dyAttrib["TagName"] = "City"


The example also contains a comment saying
< Quote >
; This createIndex statement has the same effect
; as the following INDEX structure:
{
  INDEX "Cust.dbf"
       UNIQUE
    ON "CITY", "STATE_PROV"
    TO "CityStat"
  ENDINDEX
}
< /Quote >

This code does not work when tested by me.
Change it to:

  INDEX "Cust.dbf"
       UNIQUE
    ON "CITY", "STATE_PROV"
    TAG "CityStat" OF "Cust.mdx"
  ENDINDEX

You should also remove the part of the original code that opens the tcursor
   if tcCust.open(tbCust) = False then
      msgStop("Stop!", "Can't lock " + stTbName + " table.")
      return
     endif

To index

557 enumRefintStruct() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example contains the following lines of code:
< Quote >
tc.enumRefIntStruct("CustRef.db")
; Write field level information to CustFlds.
tc.enumFieldStruct("CustFlds.db")
tc.close()
; Now create NEWCUST.DB.
; Borrow field level information from CUSTFLDS.DB.
; Borrow referential integrity information from CUSTREF.DB.
tbl = CREATE "NewCust.db"
        STRUCT "CustFlds.db"
        REFINTSTRUCT "CustRef.db"
      ENDCREATE
< /Quote >

To create referential integrity, you may also have to specify INDEXSTRUCT and LANGUAGEDRIVER

tc.enumRefIntStruct("CustRef.db")
tc.enumIndexStruct("CustIdx.db") ;LINE ADDED

; Write field level information to CustFlds.
tc.enumFieldStruct("CustFlds.db")
tc.close()
; Now create NEWCUST.DB.
; Borrow field level information from CUSTFLDS.DB.
; Borrow referential integrity information from CUSTREF.DB.
; Borroe secondary index information from CUSTIDX.DB LINE ADDED

   tbl = CREATE "NewCust.db"
           STRUCT "CustFlds.db"
           INDEXSTRUCT "CustIdx.db"
           REFINTSTRUCT "CustRef.db"
           LANGUAGEDRIVER "ASCII" ; LINE ADDED

The LANGUAGEDRIVER has to be added, if the tables have a different languagedriver than your default specification

To index

558 fieldUnits2() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example assumes you have decimalseparator = .

< Quote >
For the following example, the pushButton method for thisButton concatenates values returned from fieldSize and fieldUnits2 so that both sides of the decimal point are expressed in a single number. For example, if a field’s size is 11 and is defined with 2 decimal places, this method concatenates the values to 11.2.
< /Quote >

Here's a different solution where the variable to hold value is a string instead of a number.

var
  tc TCursor
  i SmallInt
  fldSizes DynArray[] AnyType
  tblName String
  totalSize String ; LINE CHANGED
endVar
tblName = "Scores.dbf"

if tc.open(tblName) then
   ; This FOR loop loads the DynArray with the full field spec.
   ; For example if fieldSize(1) = 11 and fieldUnits2(1) = 2,
   ; one value in the DynArray would be 11.2
  for i from 1 to tc.nFields()
    totalSize = (String(tc.fieldsize(i)) + "." + ; LINE CHANGED
                       String(tc.fieldUnits2(i)) ; LINE CHANGED
    fldSizes[tc.fieldName(i)] = totalSize
  endFor
   ; now show the contents of the DynArray
  fldSizes.view(tblName + " total field sizes.")
else
  msgStop("Sorry", "Can’t open " + tblName + " table.")
endIf

To index

559 getGenFilter() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code contains a couple of issues.

Issue 1:
< Quote >
custTC.open("Customer")
custTC.getGenFilter(dyn) ; Get filter info.
< /Quote >

As the code is written, getGenFilter() on tcursor that has been assigned using tcursor.open() will return an empty array.


Issue 2:
< Quote >
if keysAr.contains(stFilterFld) then
if dyn[stFilterFld] = stCriteria then
return ; Filter is set correctly.
endIf
else
dyn.empty() ; Set filter criteria correctly.
dyn[stFilterFld] = stCriteria
custTC.setGenFilter(dyn)
endIf
< /Quote >

The if statements should probably look like

if keysAr.contains(stFilterFld) then
   if dyn[stFilterFld] = stCriteria then
      return ; Filter is set correctly.
   endIf
endif ; LINE ADDED
;else LINE REMOVED
   dyn.empty() ; Set filter criteria correctly.
   dyn[stFilterFld] = stCriteria
   custTC.setGenFilter(dyn)
;endIf ; LINE REMOVED

To index

560 getIndexName() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example code contains
< Quote >
   ordersTC.open("orders")
   ; Get the index name and assign the value to the String variable indexName.
   ordersTC.getIndexName(indexName)
< /Quote >

After a tcursor.open(), tCursor.getIndexName() will return a blank string as the tCursor always opens on primary key if table is keyed.

To index

657 update()
Buglist Id: Last tested in version: First seen in version:
11 Build 302

Help files does not mention the limit on number of arguments in tcursor.update(). You can update 14 fields with a call to the update() method.

Syntax error is "Maximum number of arguments has been exceeded. "

Reported by: M. McIntire (TeamB)

To index

665 locate()
Buglist Id: Last tested in version: First seen in version:
11 Build 302

Help files does not mention there is a limit on number of columns that can be specified in a locate() statement. The limit is 14. If you specify more than 14 columns, you'll get a syntax error "Maximum number of arguments has been exceeded".

Reported by: "jan"
Date: 16 November 2004

To index

686 add()
Buglist Id: Last tested in version: First seen in version:
11 Build 4107.0 W95 P4

To index

226 enumSecStruct()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

To index

228 cancelEdit()
Buglist Id: Last tested in version: First seen in version:
10.0 P310.0 P3

According to the help files
< Quote >
cancelEdit ends Edit mode without saving changes to the active record. Use cancelEdit before committing or unlocking the record. Once you move the TCursor, changes to the record are committed.
< /Quote >

When cancelEdit() is used, all locks on the table placed by the same session are removed. Records locked by another object in the same session are not unlocked, but the locking information is lost.

NOTE: This only applies to cancelEdit() being used to handle locking conflicts within the same session, that is basically the same instance of Paradox.

An example:
A record is locked in a form or a tableview. In another form, the same table is handled by a tcursor.

var
  tc tcursor
endvar

tc.open(":Buggar:Wad\\Di0228")
tc.edit()
;tc.enumlocks(":Buggar:Wad\\Qz0228a")
if not tc.lockRecord() then
   msgStop("ERROR", "First record is locked.")
   tc.cancelEdit()
else
   msgStop("OK", "We locked first record with no problem.")
   tc."c"="B"
   if not tc.unlockrecord() then
      msgStop("Can't unlockrecord","")
      tc.cancelEdit()
   endif
endIf
;tc.enumlocks(":Buggar:Wad\\Qz0228a")
tc.close()

First time the code is run, the message "First record is locked" is shown. Second time, you'll see the message "We locked first record with no problem". tc.unlockrecord() returns true, but the record in the table is not updated, because the record is locked by the first form / tableview. As soon as you unlock the record in first form / tableview, and lock it once again, you'll get the message "First record is locked"

Uncommenting the tc.enumLocks() calls will show what happens.

On first call to this method, Paradox reports three locks
Image Lock - default when using enumLocks()
Record Lock - record locked by first form / tableView
Table Open No Lock - caused by tc.open()

On the second call after tc.cancelEdit(), Paradox reports two locks
Image Lock
Table Open No Lock

cancelEdit() removed the Record Lock information, even though the record is still locked by the form / tableview.

So don't use tcursor.cancelEdit() when handling locking conflicts in the same session. tcursor.endedit() will end edit mode without committing the record if it can't be unlocked.

Originally reported by: "Bruce R. Brunk"
Date: 19 March 2003

To index

218 cCount()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

ObjectPAL Help files says on cCount():
< Quote >
If the field is numeric, this method handles blank values as specified in the blankAsZero setting for the session. If the field is non-numeric and contains blank fields, cCount returns the number of nonblank values in the column of fields.
< /Quote >

But Help topics on TreatBlankAsZero says:
< Quote >
When enabled, tells Paradox to interpret blanks in calculated fields as the number zero. Otherwise, Paradox treats blanks in calculations the same as blanks in other types of fields. When blanks are not treated as zero, they are not included in summary calculations such as average, count, or min and max. Therefore, these calculations can change, depending on whether or not zeros are counted as blanks.
< /Quote >

The last statement on cCount() is not true. Even non numeric fields are affected by the blankAsZero setting. When blankAsZero is checked, cCount() counts all records.

To index

201 nRecords()
Buglist Id: Last tested in version: First seen in version:
11 Build 302

To index

279 empty()
Buglist Id: Last tested in version: First seen in version:
11 Build 2331.0

According to the help files
< Quote >
empty first tries to gain exclusive rights to the table. If it can't, it tries to place a write lock on the table.

If empty gains exclusive rights, it deletes all records in the table at once. If a write lock is placed on the table, empty must delete each record individually.
< /Quote >

Is this true? And does the description also apply to table.empty() ?



Tests below are done on a table with 100 000 records stored on my local drive using Paradox 11 SP1 with BDE 5.2.

In a single user environment, code like

tcursor.open("table")
tcursor.empty()
does not delete all the records at once. tcursor.empty() seems not even try to get exclusive rights to the table. Records are deleted, one by one.


table.attach("table")
table.empty()
does delete all records at once, and the size of the table is restored.

So table.empty() tries to get exclusive rights, but not tcursor.empty(). The description in the help files is the description of table.empty(), not tcursor.empty().


BUT code like this

table.attach("table")
table.setExclusive(True)
tcursor.open(table)
tcursor.empty()
tcursor.close()
table.unattach()
seems to work exactly like a table.empty(). Even the size of the table is restored.


Using
tcursor.lock("Full")
without a tablevariable involved will not remove all records at once and it won't restore the size of the table.

Neither will
table.lock("Full")
instead of
table.setExclusive(TRUE)
in combination with
tcursor.open(table)
tcursor.empty()


Conclusion:
The main difference between table.empty() and tcursor.empty() seems to be that table.empty() tries to get an exclusive lock without being asked, but tcursor.empty() doesn't.


NOTE: For tcursor.empty() to be immediate, the tCursor must be attached to a table on which setExclusive has been called.

To index

268 locatePattern()
Buglist Id: Last tested in version: First seen in version:
11 Build 2334.5

To index

172 locate()
Buglist Id: Last tested in version: First seen in version:
10.0 P21.0

Help files says:
< Quote >
If the TCursor is using a secondary index, locate finds the first record in the secondary index order.

and

The search is case-sensitive unless ignoreCaseInLocate (Session type) is set to True.
< /Quote >

Combining these two statements, you will come to the conclusion that should have been expressed:
ignoreCaseInLocate() setting has to match the case sensitivity of the index for the index to be used in a locate().

If the table has a secondary case insensitive index, you should specifiy ignoreCaseInLocate(Yes), otherwise the index will not be used, and the performance will be unacceptable on large tables. When the table has a case sensitive index (primary or secondary), recommendation is to specify ignoreCaseInLocate(No), because the setting is a session setting, and it could have been changed somewhere else in your code.


Difference between index used and not used on a table containing 400 000 records.

Index used: 50 000 locates takes 6000 CPU cycles
Index not used: 500 locates takes 290 000 CPU cycles

To index

164 locateNext()
Buglist Id: Last tested in version: First seen in version:
11 Build 2338.0

The helps says:
< Quote >
....
The search begins at the top of the table, but if no match is found, the TCursor returns to the original record. If a match is found, the TCursor moves to that record. This operation fails if the active record cannot be posted (for example: because of a key violation).
< /Quote >

This is incorrect. Search does not begin at top of table.

Look at the uiObject type instead for correct information.

To index

67 cMax()
Buglist Id: Last tested in version: First seen in version:
PX000911 Build 2337.0 W95

tc.cmax() in combination with tc.attach() on a detail table in a form. According to documentation, cmax() respects the restricted view when setRange() is used, but nothing is said on linked tables.

To index

68 setRange()
Buglist Id: Last tested in version: First seen in version:
PX001011 Build 2331.0

When specifying a range on a compound key based on two or more columns, you cannot use blank() as the low or high value on the last column. If you do, the result is unpredictable.

Note: It's documented in the help files for Interactive Paradox. Use the Help button from the setRange dialog, but it is not mentioned in the ObjectPAL help.

< Quote >
Paradox does not recognize blanks as part of a match or range specification.
< /Quote >

In ObjectPAL, you can try to cast the blank value to the appropriate type, eg Column1=1 and Column2 in the range blank() to 8, you can write
tCursor.setRange(1, smallint(blank()), 8)

To index

63 qLocate()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

Here's what the help file says
< Quote >
qLocate does not clear existing record locks on the TCursor. If a lock is present, qLocate will fail. To prevent failure, issue an unLockRecord before the qLocate is called. This could be particularly helpful within a scan
loop.
< /Quote >

In the last paragraph, the sentence < If a lock is present, qLocate will fail. > is not true. An explicit lock will be kept, and implicit lock caused by assigning a value will be cancelled. qLocate() will not fail though.

From: Bertil Isberg
Subject: Help files on tcursor. qLocate()
Date: 18 April 2001

To index

54 add()
Buglist Id: Last tested in version: First seen in version:
PX046510.0

To index

3 isEmpty()
Buglist Id: Last tested in version: First seen in version:
PX009011 Build 2337.0 W95

tCursor.isEmpty() will always return False when a remote table is opened and a range is set on the tcursor. On a local table isEmpty() respects the range set.

To index

77 locatePattern()
Buglist Id: Last tested in version: First seen in version:
PX005310.05.04

To index

84 forceRefresh()
Buglist Id: Last tested in version: First seen in version:
PX04415.01.0

A tcursor based on a table not included in the form's datamodel, when opened, won't see the changes made by other users on a network.

Prior to every locate() and qLocate(), you should have a tc.forceRefresh() to be sure the tcursor is refreshed.

To index

73 add()
Buglist Id: Last tested in version: First seen in version:
PX023411 Build 2337.0 W95

If you add data to a tcursor where the active index is a secondary non unique index, you will only get unique records on the secondary index added.

Eg, in a form, you have a tableFrame, Orders, sorted on a secondary index, Customer No. You attach a tcursor to the tableframe, empty it, and add data from another table having say 10 orders for one specified Customer. You end up with only unique values on the secondary index used for showing the table frame, that is one record as all added records had the same Customer No.

The workaround is to switch index to the primary key before adding the record.

To index

74 attach(tcursor)
Buglist Id: Last tested in version: First seen in version:
PX004511 Build 2337.0 W95

If you attach() a tcursor, tcSecond, to another already opened tcursor, tcFirst, you must close tcSecond before closing tcFirst, otherwise the alias referenced by tcFirst will be left open.


method openTc()
var
   tc,tc2 tcursor
endvar
tc.open(":Sample:Customer")
tc2.attach(tc)
tc2.doSomething();
tc2.close() ; Correct order of closing the tcursors
tc.close()
endMethod

To index

ObjectPAL---textStream type

111 writeString()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

The operator ts.writeString(stringVal) instead of writing into the textStream ts the whole string stringVal, writes there only first L symbols of stringVal, where L can be calculated as follows:

L=mod(stringVal.sizeEx(),65535)

Of course, as long as the length of stringVal does not exceed 65535 bytes, L is simply equal to the length of the string, and the whole string is written without problems. However, if the length of stringVal is greater than 65535 bytes, only a part of it will be effectively written into the textStream.

Reported by: Dmitry Vulis
Subject: TextStream bugs - please verify
Date: 17 June 2001


My comments:
In P10, I can create a 96KB file using the syntax writeString(string1, string2, string3) where string1-string3 are 32Kb strings created by readline.

OTOH, when trying to concatenate string4=string1+string2+string3, I get a 32 KB string written, even though the resulting string, string4 is reported to be 98000 bytes. When I make string3 shorter, so string4 is something like 75K, I get 10K file written.

To index

688 readLine()
Buglist Id: Last tested in version: First seen in version:
11 Build 4105.04

After having read a textstream file into an array, you cannot reposition the cursor and read single lines of the file without reopening the file. You can read the file using readchars(), though.

Reported by: "moroivan"
Date: 19 July 2005

To index

ObjectPAL---Time type

513 time()
Buglist Id: Last tested in version: First seen in version:
11 Build 3007.0 W95 P4

Help file says:
< Quote >
Time variables store times in hour-minute-second-millisecond format. The following characters can be used as separators: blank, tab, space, comma (,), hyphen (-), slash (/), period (.), colon (:), and semicolon (;). Time values must be enclosed in quotation marks.

...........

Valid time values are determined by the current Paradox time format. If the current time format is set to a 12-hour format (for example: hh:mm:ss), Time type methods consider hh:mm:ss to be a valid time format. Use formatSetTimeDefault procedure defined for the System type to set Paradox time formats with ObjectPAL.
< /Quote >

The help files does not mention that since Paradox 7 for Win95/NT, the default format to use when casting a string as a time, is the Windows time format specified in Control Panel applet Regional Options. As the separators can be almost any character as mentioned in the quote, the impoitant part is the 12 hour / 24 hour format setting. You can specify another format using formatSetTimeDefault(). In previous versions, the default format was the format used in the examples.

To index

450 time() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 1: Converting a string value into a time value

see ObjectPAL - Examples - General Issues - WADID 592 - Issue 3: Regional settings

To index

ObjectPAL---Toolbar type

544 setPosition() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Comments in the code is inconsistent:
< Quote >
if tbar.attach("MyToolbar") then
   tbar.getPosition(liX, liY)
   view("From: " + string(liX) + ", "
                 + string(liY) +
          "To: " + string(liX + 2800) + " , "
                 + string(liY + 2800))
   tbar.setPosition(liX + 500, liY + 400)
endif
< /Quote >

Should be:
if tbar.attach("MyToolbar") then
   tbar.getPosition(liX, liY)
   view("From: " + string(liX) + ", "
                 + string(liY) +
          "To: " + string(liX + 500) + " , " ; CHANGED
                 + string(liY + 400)) ; CHANGED
   tbar.setPosition(liX + 500, liY + 400)
endif

To index

545 setPosition()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The position specified with setPosition() is not the same as the one retrieved with getPosition() afterwards.

Run the example code twice.

To index

546 getPosition()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

695 disabling toolbar buttons
Buglist Id: Last tested in version: First seen in version:
11 Build 41011 Build 410

Toolbar type contains methods for adding and removing buttons, but no methods for disabling them, e g
toolbar.addButton(ToolbarEditCluster, ToolbarButtonPush, UserMenu+TBS, BitmapEditCopy, "Edit", "Edit")

You have to use menu type methods for changing the attributes of the menuchoice, e g
setMenuChoiceAttributeByID(UserMenu + TBS, MenuDisabled)

Date: 10 april 2006

To index

265 Bitmap constants
Buglist Id: Last tested in version: First seen in version:
11 Build 23311 Build 233

The OPAL help under "Toolbar bitmaps" lists 122 constants. However the ObjectPAL Quick Lookup dialog for Toolbar bitmap lists 127 constants.

The 5 extra ones are bitmapExit, bitmapInsRecord, bitmapDelRecord, bitmapTProgressBar and bitmapTTrackBar.


Reported by: "Sunil Pillai"
Date: 3 July 2003

To index

ObjectPAL---Tutorial

198 Wrong directory mentioned
Buglist Id: Last tested in version: First seen in version:
11 Build 23310.0

In Setting your current working directory, the text says:
< Quote >
Follow these steps for you to ensure that your working directory is set to the TUTORIAL folder.

To set the TUTORIAL folder as your current working directory

1. Click File menu, Working Directory.
2. In the Set Working Directory dialog box, scroll to locate the TUTORIAL folder.
3. Click the TUTORIAL folder.

The directory path for the TUTORIAL folder should appear in the Directory box.

4. Click OK.
< /Quote >

BUT the examples in the ObjectPAL Tutorial are based on the tables in the Samples directory!

To index

ObjectPAL---Twain type

142 aquire()
Buglist Id: Last tested in version: First seen in version:
10.0 P210.0 P2

To index

ObjectPAL---uiObject type

114 enumFieldNames()
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.0

According to help files on enumFieldNames().

< Quote >
enumFieldNames fills fieldArray with the names of the fields in a table. fieldArray is a resizeable array that you must declare and pass as an argument. If fieldArray already exists, this method overwrites it without asking for confirmation. enumFieldNames returns True if it succeeds; otherwise, it returns False.
< /Quote >
"If fieldArray already exists, this method overwrites it without asking for confirmation." is not true for the uiobject version of enumFieldNames()

To index

124 switchIndex()
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

switchIndex will return false if applied to a hidden uiObject which has focus (contains the active object).

errorTrapOnwarnings(Yes)
orders.visible=False
try
     if not orders.switchindex("Terms") then
         msgInfo("Cannot switch index.", "")
     endif
     orders.setrange("FOB","FOB")
onFail
   errorshow()
endtry
orders.visible=true
errorTrapOnwarnings(No)

And now also this code won't work. Now I get a message saying I can't switch the index, and I also get an error on setRange() because the index is not switched, so the range is applied to primary key, which is Order No. switchIndex won't fail, even though errorTrapOnwarnings(Yes) is specified. Instead it returns false.

More tests: I added a button to hide/show the orders tableframe. Opening the form with Orders visible and setting the index to the primary key. Then I hide the tableframe. Now I cannot use the Filter tool on the toolbar to change the index for Orders.

All these tests are based on the buttons with TabStop unchecked.

My conclusion is, you cannot switch index on a hidden uiObject which is active. You have to move off the object.

To index

173 locate()
Buglist Id: Last tested in version: First seen in version:
10.0 P21.0

To index

178 attach()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95 P4

The help files says:
< Quote >
5. attach ( const report Report [ , objectName String ] ) Logical

Description
attach binds a UIObject variable to a specified design object. You can also use attach to assign a UIObject to an item in an Array.
..........

Syntax 5 binds the variable to the report which is specified by the Report variable report, or to a UIObject which is specified by objectName.
< /Quote >

But, you cannot attach to any object in a running report, e g you can attach to textobjects but not fieldobjects. To attach to a field, you have to put the field inside a textobject, and retrieve the text property of the textobject.

To index

76 locatePattern()
Buglist Id: Last tested in version: First seen in version:
PX005310.05.04

see also Interactive - Locate Dialog - Using wildcards. WadId: 75

There are problems when using LocatePattern to find values that contains space, especially when specifying a trailing space in the value you are searching for, or special characters like +, that can be used in Advanced Pattern Match.

Say you have a field that contains the value (inside the quotes) "aa + bb" and you want to do a locatepattern to find the value.

Try aa.. , aa .. , aa +.. , aa + b..

Using ObjectPAL, specify
advancedWildCardsInLocate(No)
before you do LocatePattern(), and you will find all of the combinations mentioned.


Note:
When specifying the value to locate, include the wildcards in the stringvariable as shown in the help file example

stSearchFor = "C.." ; find customers whose name begins with C
if Customer.locatePattern("Name", stSearchFor) then

instead of
stSearchFor = "C" ; find customers whose name begins with C
if Customer.locatePattern("Name", stSearchFor+"..") then

To index

83 setGenFilter()
Buglist Id: Last tested in version: First seen in version:
PX043011 Build 2331.0

In a report run from a form, you can set a filter on an uiObject. If the report is based on a query, you'll get a errormessage: setGenFilter() failed.

WorkAround:
In a report based on a query, you can add the filter to the query.

To index

56 cancelEdit()
Buglist Id: Last tested in version: First seen in version:
11 Build 2337.0 W95

cancelEdit() - uiObject type

< Quote >
cancelEdit has the same effect as the action constant DataCancelEdit. This means that the following statements are equivalent:

obj.cancelEdit()
obj.action(DataCancelEdit)
< /Quote >

The name of the constant is DataCancelRecord, not DataCancelEdit.

To index

70 setRange()
Buglist Id: Last tested in version: First seen in version:
PX001011 Build 2331.0

To index

200 nRecords()
Buglist Id: Last tested in version: First seen in version:
11 Build 30210.0

Help files says:
< Quote >
When you call nRecords after setting a filter, the returned value does not represent the number of records in the filtered set.
< /Quote >

I cannot verify this any longer. This is true in P5 run with Bde 2.51, but not in any of the 32 bits Paradox run with BDE 5.2.

To index

195 insertAfterRecord()
Buglist Id: Last tested in version: First seen in version:
10.0 P27.0 W95 P4

At the last record in a table, uiObject.insertAfterRecord() will insert a record after the last record only when AutoAppend is checked. Otherwise, the record will be inserted before the last record.

To index

220 setPosition()
Buglist Id: Last tested in version: First seen in version:
10.0 P3

When trying to move an uiObject within a container, and at the same time expand its size, Paradox will handle the operation as changing the size first, and then moving the object. But changing the size may be prevented by the container's size.

There are two workarounds.
1) Change the container's property: Design.ContainObjects to FALSE and restore it afterwards
2) Split the operation in two steps. First move the uiObject and then change its size.

Description:
Recreation steps:
1. Create new form
1.1 put a box on it
1.2 put other box inside the first one,
Start dragging at about 1/2 of container's width, release dragging close to the container's right boundary.
Name that box "aUI".
1.3 Put a button on the form, with the code:
method pushButton(var eventInfo Event)
var
x, y, w, h longint
endvar
aUI.getPosition(x,y,w,h)
;Test 1
aUI.setPosition(x-1000,y,w+1000,h)
;Test 2
; aUI.setPosition(x-1000,y,w,h) ;set new Position
; aUI.setPosition(x-1000,y,w+1000,h) ;set new Size
endMethod
2. Save/Run the form
2.1 Push the button
Result:Position of aUI is changed but not the width.

Workarround:
Use 2 step approach, changing position in the first and size in the second step. Like in Test 2 example.
My explanation:SetPosition uses 4 parameters grouped in:
1) Position, i.e. x,y parameters
2) Size, i.e. w,h parameters
SetPosition() internally processes Size parameters first, then Position. New Size in Test 1 example can not be set, beeing limited by the container's right boundary. Doing other way, processing Position before Size, SetPosition() could solve the issue w/o bringing a new one at the left-upper bounds.

Test done with P10 v...719, results are the same with P8 as well.

Reported by: Ivica Kolar


Workaround changing the Design.ContainObjects property:

aBoxOuter is the container.

aBoxOuter'Design.ContainObjects=FALSE
aBox.getPosition(x,y,w,h)
aBox.setPosition(x-1000,y,w+1000,h)
aBoxOuter'Design.ContainObjects=TRUE

To index

221 attach()
Buglist Id: Last tested in version: First seen in version:
10.0 P310.0 P3

Help files shows 5 different syntaxes for uiObject.attach(). Of these 5, there are two that is relevant for this article, namely

2. attach ( const objectVar UIObject ) Logical
3. attach ( const objectName String ) Logical

Nothing is said in the help files, on how attach() works when you attach a uiobject variable to the builtin object active.

Example:

ui.attach(active) ;get handle to a field in a tableframe
uiOutside.moveTo() ;move focus to an object outside of the table frame
; Code to do something
ui.moveTo() ;restore focus on field in tableframe

BUT..
ui.attach(active) will make ui follow the active object. The statement uiOutside.moveTo() will cause ui point to uiOutside.

To get ui to be attached to the active field in the tableframe, you have to use
ui.attach(active'fullname)
ative'Fullnamecontains a complete reference to field, including a recordobject reference.


If the "Code to do something" in any way refreshes the tableFrame, maybe you don't want to return to the same row in the table frame, but rather the same record (or current record) in the tableframe. Then you could try code shown below:

stActiveName=active'name
uiFld.attach(stActiveName)

And after the code
uiFld.moveto()

In this case, stActiveName will contain a fieldname, and a reference to a fieldname in a tableFrame will activate the current record in the tableFrame.

To index

227 getRgb()
Buglist Id: Last tested in version: First seen in version:
10.0 P310.0 P3

According to the help files:
< Quote >
getRGB returns the component red, green and blue components of the color specified in rgb. rgb is a Colors constant.
< /Quote >

But...
GetRgb() applied on one of the Paradox color constants representing a Windows system color, like CL3DFACE, will return the value of the Windows constant (not equal to the value of the ObjectPAL constant) in the first parameter, siRed, and not the Rgb values of the Windows System color.

Help files does not give any help on how to get the rgb values for a Windows System color represented by a Paradox constant, e g CL3DFACE.

Here's how to do it:

Use getRgb() to get the Windows System color constant in siRed argument. Specifiy siRed as parameter to the Win32API GetSysColor(), and eventually a second call to getRgb() with the value returned from GetSysColor() as color parameter.

Uses "user32"
 GetSysColor(lpIndex cLong) cLong [stdcall]
endUses

And in a suitable event or custom method:
var
 liWindowsColor,
 liPdoxColor LongInt
 siRed SmallInt
 siGreen SmallInt
 siBlue SmallInt
endVar

liPdoxColor=cl3dFace
getRgb(CL3DFACE, siRed, siGreen, siBlue)
; Now siRed contains the value of Windows System Color constant cnColor3DFace

liWindowsColor = GetSysColor(siRed)
; Retriieves the value of the color represented by the System color constant.

getRGB(liWindowsColor, siRed,siGreen,siBlue)
msgInfo(liWindowsColor,"red=" + strval(siRed) +
          ",green=" + strval(siGreen) + ",blue=" + strval(siBlue))


Win32Api solution by: "Rick Kelly"
Date: Fri, 14 Mar 2003

To index

269 locatePattern()
Buglist Id: Last tested in version: First seen in version:
11 Build 233

To index

271 LineSpacing property
Buglist Id: Last tested in version: First seen in version:
PX044011 Build 2335.04

According to help files, LineSpacing property
< Quote >
Specifies the number of blank lines to print between each line of text in a field or text object.
< /Quote >

but the LineSpacing property is not available neither from ObjectExplorer nor from ObjectPAL for fieldobjects. And it is not available in Design mode, only in Run Mode for a formatted memo field.



From: Brian Bushay Ctech
Subject: Linespacing in formatted memo field
Date: 25 June 1999

Here is how you can do it in Objectpal. The key point here is that Linespacing is a property of a text object not a memo field. When you edit a memo field it creates a text object. The following code will drill down to it. The code needs to account for differences between the field controls of Edit and Labeled to find the text object


var
  ui,ui2 uiobject
  stType string
endvar
edit()
ui.attach(f1) ;where F1 is the field you want to set spacing on
ui.moveto()
ui.Action(editEnterMemoview)
ui.action(selectEnd)
ui.attach(ui.first)
if ui.Class = "EditRegion" then
   ;need to find text object
   ui.attach(ui.first)
endif
ui.setproperty("LineSpacing",TextTripleSpacing)
f1'Touched=True ; to make the field touched


Touched property solution by: Christoph Torge and Mark De Revere
Date: 1 April 1996

To index

272 Alignment property
Buglist Id: Last tested in version: First seen in version:
11 Build 2335.04

According to help files, the Alignment properties

< Quote >
Specifies the position of text relative to a field or text object.
< /Quote >

but when a formatted memo has property CompleteDisplay=True, the Alignment property is not available.

To index

411 setOCXWantKeys() method
Buglist Id: Last tested in version: First seen in version:

Undocumented.

Syntax:
setOCXWantKeys(const wantKeys Logical) Logical

This (and other OCX information) is documented only in the 7.0 (32 bit) README file. It allows you to compensate for poorly written OCX's failing to request the keystrokes they need. Call MYOCX.setOCXWantKeys(TRUE) if an OCX you're using isn't getting the keystrokes you think it should. See the Paradox README for more information.


Reported by: David Berg, Paradox Development
Date: 1996

To index

696 bringToFront()
Buglist Id: Last tested in version: First seen in version:
11 Build 41011 Build 410

Using bringtofront() in the open event of an uiObject may prevent other object's open event from executing.

Look at this:
A form has a tableframe and a pushButton. The button partially covers the tableframe, and the button is in front of the tableframe.

Button contains this code in the open event.
msgInfo("I'm the button","")

When form executes, the button's open event will execute.

Add this code to the tableframe's open event.
self.bringtoTop()

When form executes, the button's open event won't run. Open events are executing in the reversed z-order, the topmost object's event will execute last. When the order is changed by bringtoFront(), tableframe is in front, and there is no more object to open.

Two solutions:
1) Call bringtofront() from the form's open event, after doDefault in the else clause.

2) Use postAction() in the tableframe's open event to trigger an action, which will execute after the form is fully opened.

tableframe open event
self.postAction(userAction+1)

tableframe action event
if eventinfo.id()=UserAction+1 then
   disableDefault; prevent the event from bubbling
   self.bringtofront()
endif

Issue reported by "Greg"
Date: 29 May 2006

To index

666 locate()
Buglist Id: Last tested in version: First seen in version:
11 Build 302

To index

648 isEmpty()
Buglist Id: Last tested in version: First seen in version:
11 Build 3027.0 W95 P4

To index

499 create()
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The syntax is:

1. create ( const objectType SmallInt, const x LongInt, const y LongInt, const w LongInt, const h LongInt [, const container UIObject ] )

Using a reporthandle as container, you'll get the recordband in Paradox 9 SP4 and later versions, but the PageHeader in Paradox 7 SP4.

See ObjectPAL - report type - load() example - WadId 498

To index

572 atFirst() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

573 atLast() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

574 bringToFront() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Page object has to be named pge1

To index

576 cancelEdit() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

1) see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 2- TabStop

2) Code as written requires the pageobject to be named pageOne

To index

577 copyToArray() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

578 deleteRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

579 edit() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Code used is not correct
< Quote >
if ORDERS."Sale Date".value > ORDERS."Ship Date".value then
  ; start Edit mode for the form
  ORDERS.edit()
  ; if Sale Date is later than Ship Date, change Ship Date
  ORDERS."Ship Date".value = ORDERS."Sale Date".value + 5
  ORDERS.endEdit() ; end editingchanges to the record
                        ; can't be canceled
endIf
< /Quote >

ORDERS."Sale Date" and ORDERS."Ship Date" are invaild uiObejct names.
Should be "Sale_Date" and "Ship_Date"

To index

580 end() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

581 getRange() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example is described as:
< Quote >
The following example uses ObjectPAL to link two unlinked tables in the data model. Assume that a form has the Orders and Lineitem tables in its data model and they are not linked. getRange is used on a table frame bound to the Lineitem table to retrieve the values that specify the current range.
The following code is attached to the record object's arrive method of a table frame that is bound to the Orders table:

;Record :: arrive
method arrive(var eventInfo MoveEvent)
   var
      arSet Array[] AnyType
      arGet Array[] AnyType
   endVar

   LINEITEM.getRange(arGet) ;Retrieve values of range.

   arSet.setSize(2) ;Specify size of array.
   arSet[1] = string(Order_No.value)
   arSet[2] = string(Order_No.value)

   if (arSet.size() = arGet.size()) and (arSet <> arGet) then
      LINEITEM.setRange(arSet) ;Specify range of records.
   endIf
endMethod
< /Quote >

If there is no range, specified for LINEITEM, when the code executes, you'll get an error on arSet<>arGet.

Change the code
   var
      arSet Array[] AnyType
      arGet Array[] AnyType
   endVar

   LINEITEM.getRange(arGet) ;Retrieve values of range.

   arSet.setSize(2) ;Specify size of array.
   arSet[1] = string(Order_No.value)
   arSet[2] = string(Order_No.value)

   if (arSet.size() = arGet.size()) then ; LINE CHANGED
    if (arSet <> arGet) then ; LINE ADDED
       LINEITEM.setRange(arSet) ;Specify range of records.
      endif ; LINE ADDED
   endIf


Add code to LINEITEM's close event
self.setRange() ; LINE ADDED

When form has opened, specify a range on Lineitem interactively, and move to Orders.

To index

582 insertBeforeRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

583 insertRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

There is no separate example for insertRecord(), only a reference to insertBeforeRecord() example, but in that example insertRecord() is not used. In the code, change CUSTSORT.insertBeforeRecord() to CUSTSORT.insertRecord().

To index

584 isEmpty() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

585 getPosition() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The circle should be named floatCircle.

In the code shown below, change the use of the objectname buttonlabel, which is the name of the text object contained by the button, to self'labeltext. labeltext is a property of the button itself.

< Quote >
if buttonLabel = "Start Timer" then ; if stopped, then start
  buttonLabel = "Stop Timer" ; change label
  self.setTimer(100) ; tell timer to issue a timer
                              ; event every 100 milliseconds
else
  buttonLabel = "Start Timer" ; change label
  self.killTimer() ; stop the timer
endIf
< /Quote >

to

if self'labeltext = "Start Timer" then ; if stopped, then start
  self'labeltext = "Stop Timer" ; change label
  self.setTimer(100) ; tell timer to issue a timer
                              ; event every 100 milliseconds
else
  self'labeltext = "Start Timer" ; change label
  self.killTimer() ; stop the timer
endIf

To index

586 killTimer() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The circle should be named floatCircle.

In the code shown below, change the use of the objectname buttonlabel, which is the name of the text object contained by the button, to self'labeltext. labeltext is a property of the button itself.

< Quote >
if buttonLabel = "Start Timer" then ; if stopped, then start
  buttonLabel = "Stop Timer" ; change label
  self.setTimer(100) ; tell timer to issue a timer
                              ; event every 100 milliseconds
else
  buttonLabel = "Start Timer" ; change label
  self.killTimer() ; stop the timer
endIf
< /Quote >

to

if self'labeltext = "Start Timer" then ; if stopped, then start
  self'labeltext = "Stop Timer" ; change label
  self.setTimer(100) ; tell timer to issue a timer
                              ; event every 100 milliseconds
else
  self'labeltext = "Start Timer" ; change label
  self.killTimer() ; stop the timer
endIf

To index

587 enumSource() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

tvSource is not closed after the wait() statement. The second enumSource() cannot create a new table.

Lines of code should be:

   tvSource.open(stTbName)

   ; Suspend execution until you close the table view.
   tvSource.wait()
   tvSource.close() ; LINE ADDED

   btnLocks.enumSource(stTbName, kNoRecurse)

To index

588 getHtmlTemplate() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To get the output described in the example, create the form with a single record layout. Do NOT use a tableframe.

To index

589 locateNextPattern() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Typo in the code.

> is missing in the line that should look like
if custNames.size() > 0 then ; if there's anything in the array

To index

590 locatePriorPattern() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code is using method locatePrior() instead of locatePriorPattern().

< Quote >
if Cust.locatePrior("City", searchFor, "Name", "..C..") then ; find record
< /Quote >

should be
if Cust.locatePriorPattern("City", searchFor, "Name", "..C..") then ; find record

To index

591 lockRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example 1 - Locking a record

Issue 1)
Example is using form variable thisForm, but in this case, also CUSTOMER.isEdit().

Remove line
if thisForm.editing then
and also the
endif
that belongs to the if statement.


Issue 2)
see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 2- TabStop

Issue 3)
Do NOT name the record object.

Change the line
       obj.custRec."Name" = "Right Diver" ; quotes on Name indicate
to
       obj."Name" = "Right Diver" ; quotes on Name indicate

Complete code
var
  obj UIObject
endVar
obj.attach(CUSTOMER)
obj.locate("Name", "Sight Diver")
if CUSTOMER.isEdit() then
   if NOT obj.lockRecord() then
      msgStop("Lock failed", "recordStatus(\"Locked\") is " +
           String(obj.recordStatus("Locked")))
  else
      msgStop("Lock succeeded", "recordStatus(\"Locked\") is " +
            String(obj.recordStatus("Locked")))
      obj."Name" = "Right Diver" ; quotes on Name indicate
                                           ; field name instead of
                                           ; property
      obj.unlockRecord()
   endIf
else
    msgInfo("Status", "You must be in edit mode to lock and change records.")
endIf


Example 2: Determining whether a record is locked

Issue 1: see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 1- thisForm

Issue 2: see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 2- TabStop

Issue 3:
Do NOT name the record object.
Two lines of code are changed. They are marked with LINE CHANGED below


Complete code in button is:

var
  obj,
  recObj UIObject
endVar

obj.attach(CUSTOMER)
obj.locate("Name", "Sight Diver")
if thisForm.editing then
  obj.lockRecord() ; no write access to Locked property
                                   ; so use method to lock record
  recObj.attach(Customer_No) ; LINE CHANGED

  if NOT recObj.Locked then ; check the property to see
                                   ; if the record is locked
     msgStop("Lock failed", "recObj.Locked is " +
             String(recObj.Locked))
  else
     msgStop("Lock succeeded", "recObj.Locked is " +
             String(recObj.Locked))
     obj."Name" = "Right Diver" ; LINE CHANGED
      ; name is in quotes to indicate Name
                                    ; field instead of obj's Name property
     obj.unlockRecord()
  endIf
else
  msgInfo("Status", "You must be in edit mode to lock and change records.")
endIf

To index

593 menuAction() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

594 mouseRightDouble() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

For some unknown reason, mouseExit() event is triggered after mouseRightDouble().

To index

595 mouseRightDown() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

For some unknown reason, mouseExit() event is triggered after mouseRightDown().

To index

596 mouseRightUp() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

For some unknown reason, mouseExit() event is triggered after mouseRightUp().

To index

597 moveToRecNo() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

see ObjectPAL - Examples - General issues - WADID 592 - ISSUE 2- TabStop

Also, the example is based on Paradox tables, even though help files says:
< Quote >
Use moveToRecNo only for dBASE tables. Use moveToRecord for Paradox tables.
< /Quote >

To index

598 moveToRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

599 lockStatus() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Running the example code, I get an error on the line
< Quote >
l = unlock(CustTC, "ALL") ; remove any locks
< /Quote >

"ALL" is not a valid locktype for unlock() method. Full, Read, Write are the locktypes mentioned in the help files.

To index

600 nextRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

601 nRecords() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

602 sendToBack() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Give the multirecordobjects a color. Transparent doesn't look good in this case.

To index

603 postAction() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

The example code does not work. You'll get a Operation is not valid during refresh, and a loop.

Change the code in the tableframe's action event

method action(var eventInfo ActionEvent)

   if eventInfo.id() = UserAction + 1 then ;If ID is user
; LINE BELOW CHANGED fldLineTotal should be used
      dmPut("LINEITEM2", "Total", fldLineTotal.value) ;action and
; Qty.postRecord() ;post changes.
; LINE ABOVE REMOVED - CAUSES LOOP
   endIf

endmethod

To index

604 setPosition() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Circle should be named floatCircle.

In timer event, < missing:
Line should be if x < 4320 then

To index

605 setTimer() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Circle should be named floatCircle.
In description, button is named toggleButton. In code, the name is button.

Change button.labeltext to self'labeltext

if self.LabelText = "Start Timer" then ; if stopped, then start
  self.LabelText = "Stop Timer" ; change label
  self.setTimer(10) ; start the timer
else
  self.LabelText = "Start Timer" ; change label
  self.killTimer() ; stop the timer
endIf

To index

606 postRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

607 priorRecord() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

608 recordStatus() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

To index

609 view() example
Buglist Id: Last tested in version: First seen in version:
11 Build 300

Example is described as:
< Quote >
The following example assumes that a form contains a table frame named CUSTOMER that is bound to the Customer table, and a button. The following code is attached to the button's pushButton method. This code creates an array of seven UIObjects and views each item in the array.

; page::mouseUp
method mouseUp(var eventInfo MouseEvent)
< /Quote >

The code as described is bound to mouseUp() event on the pageobject. There is no button.

All object's described in the code has to be created in advance.

To index

Runtime

Runtime---Files required

264 Objects created by experts
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT10.0 P2 RT

If you create objects by using the object experts in Paradox, and want to use these objects with Paradox runtime, you may have to distribute some files and include the alias pdxExperts in your application.

With the field expert you can create an edit field named [Memo field with popup edit window]. This field requires the expmemo.fdl form from Experts\Field folder to be available. The path to the form is generated by the expert, but you may want to change it. The form itself requires the alias pdxExperts pointing to a folder where ExpertsSL.pxr is to be found. The string list file itself is also required.

To index

Runtime---Installation

660 Silent installation
Buglist Id: Last tested in version: First seen in version:
11 Build 30210.0

Help files says:
< Quote >
To install Paradox Runtime from your own setup
· Launch Paradox using the following command line options:
· pdx11run.exe /q INSTALLDIR="D:\myapp\runtime11" SHARED="c:\corelshared" /I
This will cause Paradox Runtime to install silently, to "D:\myapp\runtime11".
< / Quote >

The rightmost command line parameter is an upper case i (and not a lower case L)

Reported by: "Tony McGuire"
Date: 16 October 2004

To index

Runtime---Nationalized Windows

152 Installation
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT

PARADOX RUNTIME

Installing Runtime 10 on a computer running Swedish version of Windows, the BDE will not reflect the regional settings. Language drivers, date format, decimal separator will be US standard.

This is tested on Windows 2000 and Windows 98.

Haven't tested to install full version on a computer without a previous BDE install.


REPORTED BY: Anders Jonsson
Date: 9 March 2002

To index

Runtime---ProjectViewer

295 ProjectViewer
Buglist Id: Last tested in version: First seen in version:
PX069111 RT Build 23310.0 P2 RT

ProjectViewer in Paradox Runtime is the one used in Paradox 7, and you can't expect the same behaviour in ProjectViewer in Runtime as in full Paradox.

To index

Runtime---TableRepair

125 Files required
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT10.0

PARADOX RUNTIME

From Paradox 10 help files: Paradox Runtime Developer Help | Installing Paradox Runtime | Overview: Installing Paradox Runtime

< Quote >
In addition, you may also distribute the following files if they are required by your application:

Table Repair Utility:

· TUTIL32.DLL
· TUTIL32.FDL
· TUWWR32.DLL
· TUTILITY.HLP

< /Quote >

In full Paradox 10, Tutil32.fdl is found in the Paradox directory, tutil32.dll, and tuwwr32.dll in Programs directory. The tutility.hlp and tutil32.hlp is not found anywhere but in my Paradox 7 directories.

Paradox 10 forgets to mention two more files needed for Paradox 10, but not for previous versions of Paradox, ExpertsSL.PXR and Expsrv01.LDL. Both found in the Experts directory.


You also need an alias named pdxExperts, which should be created prior to opening the tutil32.fdl.

if not isdir("C:\\Program Files\\Corel\\Paradox 10 Runtime\\Paradox\\experts") then
   makedir("C:\\Program Files\\Corel\\Paradox 10 Runtime\\Paradox\\experts")
endif
addalias("pdxExperts","STANDARD","C:\\Program Files\\Corel\\Paradox 10 Runtime\\Paradox\\experts")

Furthermore, you may have to add a registry key

the key:
HKCU\Software\Corel\Paradox\10.0\Configuration\ParadoxDir
is required for the Table Repair to work

Set Default = Paradox directory under runtime.
Then put experts as a subfolder under Paradox and set pdxEperts alias to point there. Only
Expertssl.pxr
Expsrv01.ldl

are required to be there.

By: Tony McGuire
      Bertil Isberg
      Jack E. Wasserstein, DDS

To index

Runtime---Unavailable features

263 PublishAs
Buglist Id: Last tested in version: First seen in version:
10.0 P2 RT10.0 P2 RT

The only available PublishAs feature for reports is PublishAsRtf. Paradox Runtime does not included the converters for converting from Rtf to other wordprocessor formats.

To index