| 
 |  | 
  
    |  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_targetDataWindowChild ldwc_target
 DataStore lds_target
 CHOOSECASE 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
 RETURNTrue In PowerBuilder 5 and 6 you may use a more efficient and elegant code:  //////////////////////////////////////////////////// PowerBuilder 5&6 new style //
 /////////////////////////////////////////////////
 global functionboolean
    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: 
      DoubleStringDateTimeTime 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 variablemenu 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) thenif 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 tipuint 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_handlestring ls_class, ls_title
 DataStore lds_test
 ls_class = "PBDW050" //
    PBDW60 for PB6 // create test DataStorelds_test = CREATE datastore
 lds_test.DataObject = "d_test"
 // Get DataStore handlell_handle = FindWindowA(ls_class, ls_title)
 IF ll_handle = 0 THENbeep(2)
 MessageBox("Warning", "Not found!", Exclamation!)
 RETURN
 END IF
 // unhide and resizeSetWindowPos(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 windowCode 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_windowSetNull(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 TrueisNull(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. |  |