Tidbits of Application Development
PopupControlExtender issues
A PopupControlExtender can be used in an ASP.NET application for a control to show a pop-up window when it is clicked. Like other Ajax controls, it works on the client side (i.e., it does not generate a post-back). This means the content of the pop-up needs to be filled for each row if the pop-up window is used to produce a drill-through effect for a GridView, or a way to generate a post-back needs to be devised. The following is a way to generate post-back so the content of the pop-up window can be dynamic:
- Change the field for pop-up to a template field.
- Add a button control, then add the PopupControlExtender to this control and make it invisible.
- Add another button control and create a handler for the command event. Assign the index of the row of the GridView to the CommandArgument (i.e., CommandArgument="<%# ((GridViewRow) Container).RowIndex %>").
- In the command event handler, produce the content of the pop-up control, which could be another GridView, then the following client-side Javascript to click the invisible button:
- Page.ClientScript.RegisterStartupScript(typeof(string), "Click", "document.getElementById(\"" + bt.ClientID + "\").click()", true);
This is supposed to work. It indeed generates post-back and clicking to show the pop-up control. Unfortunately, the pop-up control is not a pop-up anymore. It is merely turned from invisible to visible, staying at its original place instead of popping up when the control is clicked.
Web-based applications development
For a client-side application (i.e., an application running in a browser on a client machine), a Java applet has more capacity than other choices that are widely supported by browsers. I have had enough with ActiveX after touching it briefly.
For server-side applications, ASP.NET makes its development as easy as a desktop application. ASP.NET is widely supported.
Programming Socket with Embedded VC++
There is no other choice but CCeSocket.
The confusing point is that CCeSocket is derived from CSocket, which is derived from CAsyncSocket, but CCeSocket supports asynchronous notification while CSocket does not. CCeSocket objects can use the notification handling functions of CAsyncSocket. There is a difference between CCeSocket and CAsyncSocket in terms of how the notification is implemented, but users of these classes usually do not need to know the details.
Programming Database with Embedded VC++
Microsoft has been touting Embedded VC++ as the most powerful tool for programming Windows CE, or the best tool for programming handheld devices. They have also been promoting the universal data access model - ADO. However, they do not support ADO in Embedded VC++ as in VC++. To use ADO, you would have to settle for their less powerful tool- Embedded VB or use classes created by a third party as they suggest.
Connecting twice needed
Sometimes, a connection to a remote site (e.g, FTP connection, socket connection) needs to be tried twice to establish the first connection for an application.
Programming Java 3-D
A good starting point is Java 3D API Collateral.
Another good site is the Java 3D Community Site.
Considering the inherent poor performance of Java, Java 3-D is surprisingly fast.
Three-D programming involves two aspects: 1. creating virtual objects; 2. defining how to view the scene of virtual objects. These two aspects are buried in Java in the form of Java 3-D's complicated scene graph. Fortunately, for many 3-D tasks, Java 3-D has a convenient class, SimpleUniverse, that takes care of many regular 3-D programming tasks and the viewing aspect, so the programmers can focus on creating the objects.
The architecture of the Java 3-D API has been poorly designed. Although Java is undoubtedly one of the best object-oriented languages, Java 3-D API is mainly procedure-oriented. For example, a virtual object and its behaviors (e.g., rotating) are forcefully separated into different classes. What is even more ironic is that an object is a child of its behavior in the scene graph hierarchy.
The object-oriented way to look at the Scene Graph is as follows:
- Create objects by constructing Leaf instances (e.g., Shape3D) and NodeComponent instances that define some properties of the objects.
- Create transformations by constructing instances of TransformGroup and string them into a chain, and attach the Leaf instance to the tail of the chain.
- Attach the head of the TransformGroup chain to an instance of Branch Group.
- Attach the instance of Branch Group to a Locale instance that can be regarded as a reference point in the virtual universe.
- Attach the Locale instance to a VirtualUniverse instance.
Follow the steps similar to the above step 1 - 3 to create a view branch and attach it to the Locale object. Ironically, in Java-3D, you need to do the above in the reverse order.
Basic Steps:
- Create a new Canvas3D and add it to a component (e.g., JPanel).
- Create a SimpleUniverse based on the above Cavas3D.
- Create a content BranchGroup.
- Create a Transform3D.
- Create a TransformGroup based on the Transform3D and configure it (e.g., set capabilities).
- Create the objects (e.g., instances of Shape3D) and add them to the TransformGroup. This is the core part of Java 3D programming. Most development time is spent on creating objects.
- Repeat steps 1-3 to add more objects.
- Create a BranchGroup and add all the TransformGroups to this BranchGroup.
- Add the content BranchGroup to the SimpleUniverse.
As stated above, the most important and time-consuming step is 3.3 - constructing objects. Some simple objects can be created by constructing a Shape3D object with a Geometry object or both a Geometry object and an Appearance object. For a complex object, it may be a good idea to create a new class extended from Shape3D, but one has to remember that all the Geometry objects contained in a Shape3D object must be of the same equivalence class. This means a very complex object has to be put together with multiple Shape3D objects.
Programming with Java
It is a pity that Java does not have an enumerating data type as the enum in C++.
(written originally in 2011)