|
|
Secrets of ListView, PictureListBox, DropDownPictureListBox,
TreeView, and Application Icon
Undocumented PowerBuilder: The following constants of enumerated data type may
be used as Picture Names in any ListView, PictureListBox, DropDownPictureListBox, TreeView
as well as Icon Name in the Application object properties:
Question!
Exclamation!
Hand!
StopSign!
Information!
ApplicationIcon!
Error!
WinLogo!
Rectangle!
For instance, some constants mentioned above can be used in a custom MessageBox
window instead of bitmaps. Moreover, they can be changed dynamically from the script. Note
that the images are consistent with the Operation System and have different look under
Windows 3.1 and Windows 95/Windows NT. They look exactly like the images in the system
MessageBox. To implement a custom MessageBox:
- Create a response window with the ListView control.
- Launch the control's properties dialog, then enter the desired icon name in the Picture
Name list on the Large Picture tab. You can type in any picture name from the Stock
Pictures or type in any of the enumerated constants from the list given earlier, even if
the pictures are not represented in the Stock Pictures box. After that, switch to the Item
tab and enter one item in the Item list. Switch to the General tab and deselect the
"Enabled" and "Scrolling"; select "None" for Border; select
Background Color same as the window color. Close the properties dialog window.
- Resize the ListView control so that it fits only the picture.
- Place MultiLineEdit control on the window for custom message text. Place and code the
desired MessageBox buttons; complete other customizations and coding.
|
|
|
|
If you think your application features perfect
bulletproof security system then try it with the "KGB Spy".
Using KGB Spy you can "click" disabled and hidden buttons and controls. Check
for yourself.
Here you can download KGB Spy. Use this program to test your
security. To run KGB Spy you will need PowerBuilder 6 deployment kit.
KGB Spy source code can be dowloaded here.
|
 |
|
|
DataWindow
property sheet: General tab.
Undocumented PowerBuilder: On-line help says: "DataWindow property sheet,
General tab, DataWindow Object Name - The name of the DataWindow object you want to embed
in the Window."
However, you can also specify the name of PSR file you want to embed in the Window. You
cannot use the Browse button to paste the PSR file name, but you can type it in or paste
the name from the Clipboard. For example: when your DataWindow control always displays
REPORT.PSR file, which your program dynamically creates, you do not have to code this
DataWindow control for attaching the PSR file in run-time.
|
|
|
|
DYNAMIC Function Call.
On-line help says: "When you specify a dynamic call, the function or event does
not have to exist when you compile the code. You are saying to the compiler: trust me -
there will be a suitable function or event available at execution time."
There are also the situations when the functions do exist in compile time, but you cannot
call them directly because of the compiler's "Function not found" (actually
"type mismatch") error. Using the DYNAMIC function call often allows significant
reduction of the code logic branching. Consider the following example:
////////////////////////////////////////
// PowerBuilder old style //
////////////////////////////////////////
global function boolean f_zoom_out( powerobject
apo_target )
DataWindow ldw_target
DataWindowChild ldwc_target
DataStore lds_target
CHOOSE CASE TypeOf(
apo_target )
CASE DataWindow!
ldw_target = apo_target
ldw_target.Modify('DataWindow.Zoom=90')
CASE DataWindowChild!
ldwc_target = apo_target
ldwc_target.Modify('DataWindow.Zoom=90')
CASE DataStore!
lds_target = apo_target
lds_target.Modify('DataWindow.Zoom=90')
CASE ELSE
// invalid argument type
RETURN False
END CHOOSE
RETURN True
In PowerBuilder 5 and 6 you may use a more efficient and elegant code:
//////////////////////////////////////////////////
// PowerBuilder 5&6 new style //
/////////////////////////////////////////////////
global function boolean
f_zoom_out( powerobject apo_target )
RETURN (apo_target.DYNAMIC
Modify('DataWindow.Zoom=90') = '')
You may apply this technique for other objects and functions as well. However, in
PowerBuilder 5 some very important functions such as Describe cannot be called dynamically
due to the compiler limitations.
|
|
|
|
Secrets of
DataWindows - CPU and other global functions.
Undocumented PowerBuilder:DataWindow Painter provides the incomplete list of
functions that may be used in the DataWindow expressions. For instance, you can use the
CPU( ) function in DataWindow Painter expressions even if it is not listed in the
"Modify Expression: Functions list box."
This function might be useful when dealing with fractions of a second in a DataWindow.
Perhaps you want to have some animation in the DataWindow and build an expression using
Bitmap( ) function. Such an expression can tell PowerBuilder how to change the bitmap
without intervention from outside of the DataWindow. Therefore, you may want to code the
following expression:
Bitmap(CASE( mod( cpu(), 200 )
WHEN IS <= 50 THEN
'file1.bmp'
WHEN IS <= 100 THEN
'file2.bmp'
WHEN IS <= 150 THEN
'file3.bmp'
ELSE 'file4.bmp') )
Now if you set the "Timer Interval" property for the DataWindow object
to 50 milliseconds, PowerBuilder will loop through file 1 to 4 and simulate the animated
picture. Note that you also need to create at least one expression that uses Today()
function otherwise PowerBuilder will ignore "Timer Interval". If you do not want
this expression appearing on the screen then set its visible property to 0.
When evaluating DataWindow expressions, PowerBuilder performs up to three lookups for
the functions called in the expression. First, it checks DataWindow Painter's specific
functions. Second, it checks user-defined global functions. Finally, it checks global
system functions. This is why you can call many system functions in the DataWindow
expressions including the CPU ( ). Moreover, knowing this, you can create some kind of
macro language in PowerBuilder, which does not have to be compiled yet and can be executed
in run-time. For instance, the following command will display a MessageBox:
string ls_command
// ... some file operations to read a command from the
script file. Perhaps it is
// MessageBox ("Dynamic Message", "Hello World")
dw_1.Describe("Evaluate(' " + ls_command + " ', 1)")
Keep in mind that any DataWindow expression must return one of the following data
types:
- Double
- String
- DateTime
- Time
Within an expression, a function can return other data types (such as boolean, date, or
integer) but the final value of an expression is converted to one of the four data types
above.
Click here to download tiny sample application that utilizes
CPU( ) function to simulate a screen saver.
|
 |
|
|
Secrets of
DataWindows - Timer Event.
Undocumented PowerBuilder:In the DataWindow control, declare the Timer event
mapped to the PowerBuilder PBM_TIMER event. Your initial impression is that nothing new
will happen. However, if you set the "Timer Interval" property (see Properties:
General tab page) to any non-zero value in the attached DataWindow object, you will find
out that PowerBuilder now fires the timer event for the DataWindow control. Note that
PowerBuilder starts DataWindow timer only if the attached DataWindow has at least one
expression that calls Today( ) or Now( ) functions. Also, note that the value for the
"Timer Interval" must be specified in milliseconds rather than in seconds, as it
is in the Timer() Powerscript function. Now code this new timer event and PowerBuilder
will take care of it. This method allows having the timer event in the DataWindow without
declaring and calling external functions, and this works both under 16-bit and 32-bit
Windows.
|
|
|
|
Overriding System Functions.
Perhaps some time ago you have developed a nice, user-friendly PowerBuilder
application. Today your boss is asking you to update this application and make it even
more friendlier by programming it to beep before displaying a MessageBox, e.g using sounf
effects for informing operators that a certain error occured.
What to do? One solution is to change tons of existing scripts and inserting Beep(1)
before the MessageBox ( ) call. Another solution is to override the system MessageBox ( )
by creating user-defined global function with the same name. As an experienced programmer
you should ask: "But how can I call the system function from this one? If I call
MessageBox( ) from this function, PowerBuilder will recursively call this function again
and again and it will go to an endless loop until Stack overflow
error occurs." Following is the technique you can use to call the system function and
avoid the endless loop:
global function integer
messagebox (readonly string
as_title, readonly string
as_message)
systemfunctions lsf_PB
integer li_rc
beep(1)
lsf_PB = CREATE systemfunctions
li_rc = lsf_PB.MessageBox(as_title, as_message)
DESTROY lsf_PB
RETURN li_rc
You may need to overload this function for the all argument types you use. If you plan
to override several system functions, consider declaring a global variable of the
SystemFunctions type, which you can create on the Open event of your application object
and destroy on its Close event.
Warning: The described method for overriding system functions works fine in
PowerBuilder 5 only. Unfortunately, it causes run-time errors in PowerBuilder 6 and does
not event compile in later versions.
|
|
|
|
Secrets of
Menus - Animated Toolbar Icons.
Undocumented PowerBuilder: To simplify GUI development PowerBuilder, provides
two events for each menu item: Selected and Clicked. Remember that menu level events are
not native to Windows and they are generated and fired by PowerBuilder. Indeed, Windows
sends all messages to the window that owns the menu and then PowerBuilder in turn
dispatches and forwards messages to the appropriate menu items.
On-line help says: "Selected event occurs when the user highlights an item on the
menu using the arrow keys or the mouse, without choosing it to be executed." However,
this event also occurs when the user places the mouse pointer over a toolbar icon for a
moment and PowerBuilder displays the icon's ToolbarTip (PowerBuilder uses the toolbar text
attribute for the ToolbarTip). This feature allows us to code the Selected event so that
when it is fired we can change the Toolbar Icon for the appropriate menu item then restore
original picture when the icon loses focus. The trick is to distinguish whether the event
is triggered when the user highlights the menu item or whether PowerBuilder triggers this
event before the ToolbarTip appears.
You will need to do the following:
- Declare the menu level instance variable
menu im_last_selected
- Declare 2 menu level functions:
public subroutine mf_select (menu am_menuitem)
public subroutine mf_unselect()
- For each menu item that has a toolbar icon, code mf_select(this)
in the item Selected event.
- Make sure each menu item that features a toolbar icon gets one icon for the Toolbar
Picture Name and another for the Toolbar Down Picture Name. These icons should be slightly
different so that the user will see the animation effect.
In the parent window or in the common window ancestor, declare the new user event
WM_MENUSELECT mapping PBM_MENUSELECT; then code in this event:
if Handle(this.MenuID)
= hmenu then this.MenuID.DYNAMIC
mf_unselect()
Following are codes for the functions menthoined above:
public subroutine mf_unselect ()
if isValid(im_last_selected) then
if im_last_selected.tag <> "" then
im_last_selected.ToolBarItemName =
im_last_selected.tag
end if
end if
public subroutine mf_select (menu
am_menuitem)
// First, find out what caused Selected event: the menu item
selection or the toolbar item tip
uint lui_flags, MF_HILITE = 128
lui_flags = IntHigh(Message.WordParm)
// because PB does not support Bitwise operations like lui_flags =
lui_flags AND MF_HILITE
// we have to use different method to check the highlight bit
lui_flags -= mod(lui_flags, MF_HILITE)
if mod(lui_flags, MF_HILITE * 2) > 0 then
return // menu item text is selected
if am_menuitem.ToolBarItemDown then
return // ignore icons, which are displayed down
if am_menuitem.tag = ""
then
am_menuitem.tag = am_menuitem.ToolBarItemName
end if
im_last_selected = am_menuitem
am_menuitem.ToolBarItemName = am_menuitem.ToolBarItemDownName
Note that in this example a menu item tag is used for temporarily storing the item's
Picture Name. If your application is already using menu item tags, you will need to
declare another menu level instance variable, which you will use instead.
|
|
Click here to download tiny sample PB 6 application
that features animated Toolbar Icons.
|
 |
|
|
Secrets of
Environment Object
Undocumented PowerBuilder: An environment Object in PowerBuilder 6 has the
new undocumented property Language of enumerated type LanguageID. This makes it very
useful for multi-language applications. For a list of available IDs launch PowerBuilder
Object Browser, then select Enumerated tab; after that, find and highlight LanguageID type
in the left pane then expand its properties in the right pane.
|
|
|
|
DataWindow
Row Selection Color
Undocumented PowerBuilder: As you know standard PowerBuilder function
SelectRow(long Row, boolean
State) can be used to highlight rows in a DataWindow. Before PowerBuilder highlights the
row, it calls Windows API to retrieve system-defined color for an active selection.
If you want to know which color will be used for selected rows, you can call the
GetSysColor function from Windows API. Following is a the required declaration for this
external function:
.// The GetSysColor function retrieves the current color of the
specified display
// element. For "Active Selection" use COLOR_HIGHLIGHT = 13
FUNCTION long GetSysColor(long color_element)
LIBRARY "user32"
For 16-bit environments, change the type of color_element argument to integer and
library name to "user." Pass 13 as a color_element to get row selection color.
By the way, some PowerBuilder functions like SelectRow ( ) successfully accept invalid
row numbers. For instance, SelectRow( -1, TRUE) acts as
SelectRow( 0, TRUE) and, therefore, successfully deselects
all selected rows.
|
|
|
|
Secrets of
DataStore Implementation
PowerBuilder Internals: On-line help says: "A DataStore is a
non-visual DataWindow control. DataStores act just like DataWindow controls except that
many of the visual properties associated with DataWindow controls do not apply to
DataStores. However, because you can print DataStores, PowerBuilder provides some events
and functions for DataStores that pertain to the visual presentation of the data. " I
wonder why everything else in the PowerBuilder documentation except this paragraph says
that a DataStore is a non-visual object when it is really a hidden DataWindow control.
Let's prove that a DataStore is a regular DataWindow control implemented as a top-level
hidden popup window. Two external functions are needed for unhiding DataStores.
FUNCTION boolean
SetWindowPos( &
long hwnd, /* handle
of window */
long hWndInsertAfter, /* placement-order handle */
int x, /*
horizontal position */
int y, /*
vertical position */
int cx, /*
width */
int cy, /*
height */
uint uFlag /*
window-positioning flags */ ) LIBRARY "user32"
FUNCTION ulong FindWindowA(REF string class, REF string name) LIBRARY
"user32"
We will use SetWindowPos function to show and resize the DataStore window, which is
hidden and initially has zero size. Because the PowerBuilder compiler mostly treats
DataStore as a pure non-visual object, it protects us from getting the handle of DataStore
directly. That is why we will use FindWindowA function to find a DataStore window. For
simplicity, we will call this function only once. This function will return the handle of
the first found DataStore. The Following script demonstrates how to unhide a DataStore.
Note that different PowerBuilder versions use different names of window classes for
windows created within PowerBuilder. In PowerBuilder 5 a DataStore as well as a DataWindow
class is PBDW050, in PowerBuilder 6 it is PBDW60.
ulong ll_handle
string ls_class, ls_title
DataStore lds_test
ls_class = "PBDW050" //
PBDW60 for PB6
// create test DataStore
lds_test = CREATE datastore
lds_test.DataObject = "d_test"
// Get DataStore handle
ll_handle = FindWindowA(ls_class, ls_title)
IF ll_handle = 0 THEN
beep(2)
MessageBox("Warning", "Not found!", Exclamation!)
RETURN
END IF
// unhide and resize
SetWindowPos(ll_handle, 0, 0, 0, 300, 300, 64)
MessageBox("DataStore", "Now
you can see non-visual datastore!", Exclamation!)
DESTROY lds_test
If you will examine PowerBuilder 5 DataStores, you can even make them editable. How is
that, huh?
You can also use Windows SPY programs to search DataStores. A SPY program is usually a
standard part of any C++ compiler package. You can find one that is included in Watcom C++
Class Builder that comes with PowerBuilder Enterprise.
You can easily convert a DataStore window to a regular DataWindow control by calling
the SetParent function from Windows API . For details, please see Windows API
documentation.
There are several improvements made in PowerBuilder 6 DataStores compared to the
previous version. One of them is disabling DataStore painting (or should I say DataWindow
painting?), which greatly improves performance, especially when doing multiple data
manipulations in a DataStore.
I wonder why the DataWindow control is not inherited from the DataStore, which would be
logical and would significantly improve the performance of thousands of PowerBuilder
developers by eliminating unnecessary code duplication when programming DataWindow and
DataStore services.
|
|
|
|
Secrets of
DataWindow - Minimizing DataWindow Control
Undocumented PowerBuilder: As you know a DataWindow control may have a
title bar with minimize and maximize boxes and a control box (an icon in Windows 95) with
the control menu. As opposed to normal windows, when the user minimizes a DataWindow
control it completely disappears instead of displaying an icon that represents the
minimized DataWindow. Well, not really. PowerBuilder traps the Resize event and hides the
DataWindow. It also happens when the user closes DataWindow using its control menu. To
unhide the DataWindow control, simply restore the control's visibility attribute.
my_dw.visible = True
|
|
|
|
Secrets of
PowerBuilder Resource Files (PBR)
Undocumented PowerBuilder: Unfortunately, the documentation provided with
PowerBuilder does not list all the resources supported by PowerBuilder. There is no exact
definition of the resource term. In most places we can see definitions like this one:
"Resource File Name - Specify a PowerBuilder resource file for the dynamic library if
it uses resources, such as bitmaps and icons, and you want the resources included in the
dynamic library." As far as I know, a resource file may contain names of graphic
files (BMP, RLE, WMF, CUR, ICO, etc.) and names of dynamically referenced objects
(UserObject, Window, Menu and DataWindow). You do not need to include names of dynamically
referenced objects if you are going to compile dynamic libraries (no matter PBDs or DLLs)
and these objects are compiled into PBD/DLL. But you do need to include them if you
compile just a single EXE. The format for specifying an object in the resource file is
MYLIBRARY.PBL (MYOBJECT). For example: REPORTS.PBL (W_CASH_BALANCE). The name of the
resource is not case sensitive.
|
|
|
|
PowerBuilder Dates and Y2000 Compliance
Many corporations are currently certifying products as Y2K compliant. In PowerBuilder,
when saving DataWindow data in text files, we often deal with short date formats that
include a 2-digit year. However, there is a way to change the format so that the date is
saved using a 4-digit year. PowerBuilder looks in the system registry for the format for
Date. Changing the format for Date requires changing the Registry setting for the
sShortDate value under HKEY_CURRENT_USER\Control Panel\International. There you can find
short Time format as well. To make PowerBuilder use a 4-digit year, you just need to
change sShortDate value to whatever you want then save DataWindow contents and restore the
old format. You can use standard PowerBuilder registry functions to perform this task
programmatically.
|
|
|
|
Secrets of
Menus - Toolbar Icon Tip and Text
Undocumented PowerBuilder: On-line help provides the following definition for
the ToolbarItemText property of the menu item: "ToolbarItemText - Specifies the text
that displays in the toolbar item when the display text option is on for toolbars."
As you know, PowerBuilder also uses this property for the toolbar icon tips. How many
times have you wanted to make the text long for the tip and short for the icon? Here is an
extremely simple but undocumented way to do that: In the Toolbar Text property, specify
different text, separated by comma, for the icon and the tip. For example:
"Excel,Save report in MS Excel format.
|
|
|
|
Secrets of
Table Painter - Open Table Dialog
Undocumented PowerBuilder: To quickly locate the desired table in the Select
Table dialog box just start typing its name and PowerBuilder will scroll the list box to
the nearest match. This undocumented feature is very useful when your list of database
tables is really long.
|
|
|
|
Secrets of Menus
- Dynamically Adding New Menu Items
Undocumented PowerBuilder: The menu Item[] property is not
fixed array as many of you think. Nothing can stop you from adding the new elements to
this array. The trick is to force PowerBuilder to redraw updated menu properly. The
following example demonstrate how to do this.
- Create new window with any existing menu attached to it.
- Place a new button on the window
- Code Clicked event for the button:
MenuID.Item[UpperBound(MenuID.Item[]) + 1] = CREATE menu
MenuID.Item[UpperBound(MenuID.Item[])].text = "&New Menu
Item"
MenuID.Item[UpperBound(MenuID.Item[])].ToolBarItemName = "Save!"
MenuID.Item[UpperBound(MenuID.Item[])].ToolBarItemVisible = True
// force PB to redraw menu with the new item added
Hide(MenuID.Item[1])
Show(MenuID.Item[1])
- Run the new window and click on the button one or more times
|
|
|
|
Most
Simple Method To Count TreeView Items
Use the following code to quickly count items in the TreeView control:
li_count = Send(handle(treeview_control), 4357, 0, 0)
To find out how many items can be fully visible in the TreeView control visible area
use the following script:
li_count = Send(handle(treeview_control), 4368, 0, 0)
|
|
|
|
Do you know that any program you create in PowerBuilder is property of Sybase, Inc. No
kidding, it is not yours as you might think. Here is the proof:
- Open Windows Explorer.
- Locate your EXE and right-click on it.
- Choose Properties menu then jump to the Version property page. Click here to see a sample.
- Check the Company name and Copyright notice. Make sure to click on the Copyright notice
then scroll it to right.
If you fill strong that your work belongs to you, not to Sybase, Inc. use Resource
Editor from any C++ package to correct EXE header. Unfortunately you have to do this each
time you have a new executable compiled. By the way, you probably know that in any other
programming system (take VisualBasic for instance) users can customize their EXE headers
(usually via project properties) so that the correct information gets compiled into EXE.
|
|
|
|
Undocumented PowerBuilder: On-line help provides the following definition for
the GetChild ( ) function:
Provides a reference to a child DataWindow or to a report in a composite DataWindow, which
you can use in DataWindow functions to manipulate that DataWindow or report.A child
DataWindow is a DropDownDataWindow in a DataWindow object. A report is a
DataWindow that is part of a composite DataWindow.
According to the definition above, a call to GetChild ( ) for the nested report that is
part of a tabular DataWindow fails and the function returns -1. So there is no way you can
get a reference to the nested DataWindow that is part of a non-composite
DataWindow. Well, not really. Just remember that all DataWindow
presentation styles are equal, except "Grid". Therefore, the work-around for
this GetChild ( ) issue is the following:
- Export your "Tabular", "Free form", "Graph" ( or whatever
) style DataWindow.
- In the third line of the export file change "processing=0" (or whatever) to
"processing=5".
- Import back this export file.
- Enjoy working GetChild ( ) and everything else that you have had working before.
|
|
|
|
This utility fixes invalid column IDs in the datawindow definition.
Most often we get invalid IDs in design time (DataWindow Painter) when we copy columns
from one datawindow and paste them into another datawindow. This happens when the source
and the target datawindows have same column names but different column order or different
number of columns.
Click here to download DW_FIX.EXE. You will need PowerBuilder 6
deployment kit in order to run DW_FIX.
|
 |
|
|
Undocumented PowerBuilder: You can have a menu in a
response window?
Although this is not standard windows GUI, it could be handy sometimes. Use the
ChangeMenu( ) function in the open event to associate a menu with the window.
|
|
|
|
Undocumented PowerBuilder: You can have a MDI frame
without a menu and without a toolbar? Create a menu with only one item, which is
invisible and disabled and use that menu for the MDI frame.
|
|
|
|
Undocumented PowerBuilder: As you know you can use SyntaxFromSQL
function to generate DataWindow source code based on a SQL SELECT statement.Then you can
pass the source code returned by SyntaxFromSQL directly to the Create function to create
new datawindow dynamically. On-line helps says that for SyntaxFromSQL argument you can use
only a string whose value is a valid SQL SELECT statement. However, in
PowerBuilder 6.0 and above you can also use EXEC <procedure name>
<parameters>, where you substitute <procedure name> with the actual
stored procedure name and <parameters> with the actual parameter values instead of
parameter names. For example, you can use NULL as a value for each required
parameter. After you have the new datawindow created, you can use the Modify function to
correct parameter names in the datawindow SQL.
|
|
|
|
Can you have a toolbar in a response window? Or may be
you want a second or third toolbar on your MDI sheet window?
Although this is not directly supported PB feature, it could be handy sometimes. Moreover
this is really simple and portable. I mean you can take your existing windows, code,
menus, and toolbars and reuse them with very little changes. Download sample code here.
|
 |
|
|
As you probably know, SaveAs function can save
datawindow contents in MS Excel format, but ... Yes, unfortunately, it saves raw
data only, forget about computed columns, formats, group headers and footers. Not
many people have a solution for this problem. However, the solution is quite simple:
- SaveAs you datawindow to HTMLTable! file.
- Use OLE with Excel to convert the HTML file to Excel native format.
This method works quite well with grid-style reports and other style datawindows, but
it is as good as good PowerBuilder datawindow conversion to HTML.
Check out sample code here.
|
|
|
|
This article contains information that is useful in creating PB applications where
asynchronous functions need to be called. An example may be when you need to call a heavy
database stored procedure and don't want your application to remain locked while the
procedure executes.Click here
to download ZIP file containing the article and the example code that you can use in your
applications.
|
 |
|
|
Undocumented PowerBuilder: The most simple and efficient way to
have both MDI frame and MDI sheets share the same toolbar and avoid multiple toolbars is
to give them the same name. You can do this in the application open event:
this.ToolBarFrameTitle = "Toolbar"
this.ToolBarSheetTitle = "Toolbar"
|
|
|
|
This trick is in case you need trigger a event from a application to another.
Basically, the tip is about calling PB Send() function with
ne following parameters:
handle: handle of
target application.
#message 1023 + XX, where XX is the
number of a pbm_customXX message.
longword a optional long parameter
long
a
optionar long parameter. You can't send string as long in this case.
Click here to
download ZIP file containing two sample PB applications demonstrating this
technique: a source application, wich send a message, and a target application wich
receive that message. Both are
in PB 6.5..
|
 |
|
|
This excellent tip demonstrates how you can catch and handle SQL errors.
This tip is based on exception handling methods available in other languages, like Delphi,
C++ or Java.
In PB8, exception handling is included but, while we migrate to PB8...
This solution could be used in all PB versions (I hope).
Click here to download ZIP
file containing the sample PB applications wtih complete source code (PB 6.5).
|
 |
|
|
window my_window
SetNull(my_window)
isValid(my_window) --> as you expect, it returns False
So far so good...and now, let's see how it works for dwo object in the
datawindow events. Let's consider a situation when we have a script for datawindow clicked
event and pehaps we clicked inside the datawindow, but not on any object.
isValid(dwo) --> as you don't expect, it returns True
isNull(dwo) --> returns True
Surprise? bug? or may be it is a feature?
Note: old good GetObjectAtPointer() always works correctly as well as
GetClickedColumn() and GetRow() are still much more reliable than these event
arguments.
|
|
|
|
This library contains ready for "copy and paste" declarations of most
Window API functions, structures and constants. You will find there everything, from
declarations of functions for working with standard Windows controls to WinSock interface.
Do yourself a favor and download this library. If you don't need
it today, you will need it tomorrow.
|
 |
|
|
Although perhaps the two were never meant meet, accessing Topspeed (.TPS) database
tables from Powerbuilder via the ODBC driver from Soft Velocity is possible. Here is how...
|
|
Note: This page is maintained by Dmitriy
Evinshteyn
|
|
Press Ctrl+D to bookmark this page. I
will add more tips soon.
Have a cool tip? Why don't share with other? Email your tip and I will add it to this
page along with a link to your site.
|
|