| By Vince Fabro | Article Rating: |
|
| February 1, 1999 12:00 AM EST | Reads: |
8,645 |
You stumble on a bug in your application. In order to troubleshoot it you need to see the raw data inside your DataWindow but the columns you need aren't visible. ... You open a window in your application, and even though you don't change any of its data it still prompts you to save when closing. What has changed? ... A drop-down DataWindow isn't displaying the right values at runtime, but it retrieves just fine when you preview it at design time. Where's the data? ... You're pulling your hair out trying to get some modify/describe syntax to work, and it's taking forever between changing your code, saving and rerunning your application. Can you possibly get the syntax right and still get home on time?
The solution to all of these problems can be found in the PFC DataWindow properties dialog - after we make some enhancements, that is.
The DataWindow Properties Dialog
The PFC originally included a DataWindow debug window, which I found very helpful. With the major changes that came in PFC 6.0, the debug window was replaced by the DataWindow properties dialog, which both added and removed functionality. (I needn't mention PFC 7.0 because of the paucity of changes.) One thing I like about the PFC 6.0 dialog is that it's easy to add new debugging capabilities simply by extending existing tabs and adding new tabs. In this article I'll describe a useful enhancement to some existing DataWindow properties tabs, which essentially restores a PFC 5.0 feature that was removed in PFC 6.0. In addition, we'll add two new DataWindow properties tabs: a drop-down DataWindow tab and a Modify/Describe tab.
But first, if you aren't familiar with the DataWindow properties dialog, then obviously you don't know what you're missing! In order to access the dialog you must enable the "property" service. You can do this either by calling of_SetProperty or of_SetSharedProperty. I call of_SetSharedProperty because with one call I instantiate a shared service (referenced with the shared variable snv_Property), which makes the service accessible to all DataWindow controls in the entire application. (The function of_SetProperty, on the other hand, instantiates the same service but stores the reference in an instance variable so that it's accessible only to the current DataWindow control.) After the service is instantiated at runtime, you can right-click on your DataWindow control and the "DataWindow Properties..." option will be visible in the popup menu (see Figure 1).
Selecting the "DataWindow Properties..." option will open the DataWindow Properties dialog and its Services tab page, as in Figure 2. (Note: These figures show the DataWindow properties dialog after making the enhancements in this article.) I rarely use the Services tab, but I frequently use the "Buffers" and "StatusFlags" tabs (see Figures 3 and 4, respectively). Try them out. They're both pretty self-explanatory, and there's even on-line PFC help!
Now that I've finished explaining the "standard" way to open the DataWindow properties dialog, I can wink and nod and tell you how I really open it. The problem I have with calling of_SetSharedProperty or even of_SetProperty is that they both enable a menu option in a popup menu that users have access to. I don't want my users saying, "I wonder what that DataWindow Properties' thingy does?" So I coded a secret key sequence that opens the DataWindow properties dialog. To maintain secrecy, I'll include a simplified version here.
Open u_dw and insert a new event called "KeyDown," mapped to the pbm_dwnkey event ID (see Figure 5). Then add the following code to that event:
// Event KeyDown:With this code in u_dw you won't have to write any additional code to access the DataWindow properties dialog, and your users won't have easy access to it. All you have to do is set focus on your DataWindow control, hit Shift-Ctrl-Alt-D and the DataWindow properties dialog will open!
// If you press Shift-Ctrl-Alt-D, the //DataWindow property window will
// display
if Key = KeyD! and keyflags = 3 and
& KeyDown (KeyAlt!) then
// Turn on the property service for // all DWs.
this.of_SetSharedProperty // (true)
this.Event pfc_Properties ()
end if
// End if the User hit the // right key combo.return 0
Now that we're all at least vaguely familiar with the DataWindow properties dialog, let's add some cool debugging capabilities.
Extending the Buffers and StatusFlags Tabs
Some useful features were lost when the PFC 5.0 DataWindow debugger became the PFC 6.0 DataWindow properties dialog. One that I used quite frequently was the ability to view all of the raw data in any DataWindow. Notice in see Figures 3 and 4 that there are radio buttons labeled "Original" and "All Columns" - those options aren't available in the base PFC. These figures show the original view, which uses the same DataWindow object that your user sees. Notice in Figures 6 and 7, however, that every column's data is visible and editable. That's what allows me to peer inside any DataWindow's data, and it's all at runtime!
Let's start by extending the Buffers tab. The GUI is quite simple, but the code is fairly involved.
- Open u_tabpg_dwproperty_buffers.
- Add two radio buttons(rb_original and rb_all) at the bottom of the DataWidow.
- Set the radio buttons' text and default rb_original to checked.
- Shrink the DataWindows to make room for the radio buttons.
- Place an invisible group box around the radio buttons. (This step is optional, but it's good technique.)
- Write the following code for rb_original.
parent.Event pfc_PropertyInitialize (inv_attrib)
- Write the code for rb_all (see Listing 1).
- Save and close the tab page. (Note: I had to regenerate pfc_w_dwproperty and w_dwproperty because otherwise I got a runtime error.)
- The code that refers to dw_requestor-duplicate:
dw_requestorduplicate.Create(ls_dw_syntax,ls_error)
if len(ls_error) > 0 then
MessageBox("Create:",ls_error)
return
end if
idw_Requestor.ShareData(dw_requestorview) - The code that refers to the buffer radio buttons:
if rb_primary.checked then
Parent.Event pfc_PropertyBufferChanged(Primary!)
elseif rb_deleted.checked then
Parent.Event pfc_PropertyBufferChanged(Delete!)
else
Parent.Event pfc_PropertyBufferChanged(Filter!)
end if
- The code for rb_all assumes that the DataWindow uses SQLCA as its transaction object, which may not be the case. If needed, you can extend u_dw and add an of_GetTransObject.
- As noted in the code, the section of code that replaces retrieval arguments doesn't work with all DBMSs. Different DBMS vendors have different formats for some data types, and datetime values are what I've had problems with in the past. In my own framework (the NewMedia PFC) I use different formats depending on the DBMS.
- Even though the Buffers tab displays data from the Filter! and Delete! buffers, editing that data won't actually change data in the main DataWindow.
- The "Original" and "All Columns"don't view display drop-down DataWindows.
Regardless of these limitations, the Buffers and StatusFlags tabs are my most frequent reason for using the DataWindow properties dialog. The ability to see the raw data inside a Data
The Drop-Down DataWindow Tab
I can safely say that half of the DataWindows in my applications include drop-down DataWindows. That's probably pretty common. For the most part, using drop-down DataWindows is quite straightforward. But we spend very little time debugging straightforward things. The reason I created a drop-down DataWindow properties tab is because there are many occasions in my applications where dropdowns are filtered for one reason or another. Unfortunately, there have also been occasions where those filtered drop-downs don't display the expected values. The drop-down DataWindow tab in Figure 8 permits me to see inside my drop-downs. The tab page's GUI is not too difficult. It's based on the Buffers tab page, which is the second tab in the DataWindow Properties dialog. The master DataWindow lists all the drop-downs in the DataWindow being debugged. The detail DataWindow displays the contents of the selected drop-down DataWindow. Then there are radio buttons for selecting which buffer to display, and buttons for sorting and filtering. Because it's based on the Buffers tab, you can start by saving the Buffers tab under a different name. Open pfc_u_tabpg_dw-property_buffers in PFCUTIL.PBL and save it as u_tabpg_dwproperty_childdws in PFEUTIL.PBL. (Actually, mine lives in an extension layer between the PFC and the PFE.)
>
Then make the following changes to the GUI:
- Change the GUI by deleting the extraneous controls in the group box.
- Add the "Child DataWindow:" text above the detail DataWindow.
- Resize and rearrange the controls to make room for the master DataWindow (note that there are actually two detail DataWindows - one is for displaying the Primary! buffer, and the other is for the Filter! and Delete! buffers.).
- Add the "Drop-down DataWindow Columns:" text at the top of the tab page.
- Add the master DataWindow (dw_children, based on u_dw).
- Create an external grid DataWindow object named d_dwproperty_childdws that has two char(40) columns ("colname" and "dataobject").
- Set the DataObject property of dw_children to d_dwproperty_childdws.
- Delete the Undelete button.
Insert a new function called of_LoadChild, which takes a row (al_row) as its argument. This function will load the selected child DataWindow object into the detail DataWindows and refresh the view (see Listing 2).
The tab page will already have code in the following events: pfc_PropertyBufferChanged, pfc_PropertyInitialize, pfc_PropertyOpen, pfc_PropertyStats and pfc_PropertyUndelete. You can delete the code from the pfc_PropertyInitialize and pfc_PropertyUndelete events. Then make the following changes:
- Change pfc_PropertyBufferChanged by deleting all references to cb_undelete.
- Change pfc_PropertyStats to the code in Listing 3).
- Use the script in Listing 4 for pfc_PropertyPopulate.
- Add the following code to the master DataWindow's RowFocusChanged event:
// Event RowFocusChanged:
// Load the newly selected child DataWindow.
return parent.of_LoadChild (currentrow) - Change the code for dw_requestorduplicate by deleting all scripts except for the constructor event and set the tab page's Text property to "DDDWs" on the General tab. And that's it for the tab page! But in order to use it you'll have to add it to the DataWindow properties tab control.
The Modify/Describe Tab
The power of Modify and Describe never ceases to amaze me. But occasionally I have a lot of trouble getting the syntax to work as I'd like. (And I suspect I'm not alone in that experience!) In these situations the PowerBuilder debugger is rarely helpful, and the DataWindow painter isn't always helpful either. Then one day a light went on and I realized how easy it would be to build a Modify/Describe debugging tab. It took very little time to build, as you'll see, and it can be quite helpful.
Create a new tab page by inheriting from u_tabpg_dwproperty_base in PFEUTIL.PBL. The most difficult part about constructing this tab page is the GUI (see Figure 10). Make it the same size as the other tabs (1198x1200). Add some text controls, a couple of multiline edits (mle_syntax and mle_result), few buttons and an edit mask (em_position). Don't forget to inherit from base PFC controls! Finally, set the Text property on the tab page's General tab to "Modify."
The code couldn't get any easier. Here's the code for the Modify button:
mle_result.text = idw_requestor.Modify ( &Here's the code for the Describe button:
mle_syntax.text)
mle_result.text = idw_requestor.Describe ( &And here's the code for the Go to button:
mle_syntax.text)
mle_syntax.SelectText (Integer (em_position.text), 0)The purpose of the Go to button is to help in those situations when you get an error message from your Modify/Describe call such as "Line 1 Column 14: incorrect syntax." The line and column numbers are sometimes useful, but a more advanced "Go to" that accepted a line and column number would be more useful.
mle_syntax.SetFocus ()
Save the tab page as u_tabpg_dwproperties_modify, close the painter and add it to u_tab_dwproperties just as before. (Don't forget to regenerate pfc_w_dwproperty and w_dwproperty!)
Closing Thoughts
Probably the biggest benefit from using a framework such as the PFC is productivity gains from code reuse. But why shouldn't your framework also help you debug and troubleshoot problems? So I hope you find these enhancements to the DataWindow properties dialog a useful addition to your PFC. And to take PFC debugging one step further, I'd suggest that you check into the debug service and SQL Spy. (How about Shift-Ctrl-Alt-S?)
Published February 1, 1999 Reads 8,645
Copyright © 1999 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Vince Fabro
Vince Fabro is a practice leader at the Columbus branch of newmedia, a consulting firm
headquartered in Cleveland, Ohio. He's a CPD professional and certified PowerBuilder instructor who has been using PowerBuilder since version 2.
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- How PowerBuilder Got Its Groove Back
- The Cloud Has Cross-Border Ambitions
- Ulitzer Names The World's 30 Most Influential Virtualization Bloggers
- Ulitzer Named "New Media" Partner of Greatly Anticipated iStrategy Event in Berlin
- Risks and Enterprise Mobility?
- Steps for Success in Enterprise Mobility?
- Are Mobile Luddites Resisting Mobility?
- The Difference Between Web Hosting and Cloud Computing
- Sybase CTO to Speak at 4th International Cloud Computing Expo
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- Five Reasons to Choose a Private Cloud
- Seeding The Cloud: The Future of Data Management
- The Threat Behind the Firewall
- Economy Drives Adoption of Virtual Lab Technology
- Tips for Efficient PaaS Application Design
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- Where Are RIA Technologies Headed in 2008?
- PowerBuilder History - How Did It Evolve?
- The Top 250 Players in the Cloud Computing Ecosystem
- Custom Common Dialogs Using SetWindowsHookEx
- DDDW Tips and Tricks
- OLE - Extending the Capabilities of PowerBuilder
- DataWindow.NET How To: Data Entry Form
- Book Excerpt: Sybase Adaptive Server Anywhere
- Sybase ASE 12.5 Performance and Tuning
- Working with SOA & Web Services in PowerBuilder
- Office 2003 Toolbar: A New Look For Your Old PowerBuilder App
- Dynamically Creating DataWindow Objects

































