Un-Mapping Mapped Network Drives Andrew Coates - dFPUG-Portal
Un-Mapping Mapped Network Drives Andrew Coates - dFPUG-Portal
Un-Mapping Mapped Network Drives Andrew Coates - dFPUG-Portal
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Improving the interface<br />
Figure 1 illustrates the new Visual Basic project.<br />
The first order of business is addressing the first<br />
limitation of too much functionality (yes, I know that<br />
sounds funny). The following code is associated with the<br />
grid control. Most of the code deals with the visual<br />
characteristics of the grid—location and size. The most<br />
important method is the SetDataSource Member.<br />
Remember, in VFP, an ADO RecordSet can’t be bound to<br />
the DataGrid control. This is how you can get around that<br />
limitation. Pass the ADO RecordSet to the control, and<br />
have the control do the binding for you within its<br />
boundaries! It works like a charm.<br />
Private Sub UserControl_Initialize()<br />
'When the control is dropped onto the form,<br />
'the grid must be positioned in the upper-<br />
'left corner of the container.<br />
With DataGrid<br />
.Left = 0<br />
.Top = 0<br />
End With<br />
End Sub<br />
Private Sub UserControl_Resize()<br />
'When the container is resized, we want the<br />
'grid to also resize.<br />
With DataGrid<br />
.Width = ScaleWidth<br />
.Height = ScaleHeight<br />
End With<br />
End Sub<br />
'WARNING! DO NOT REMOVE OR MODIFY<br />
'THE FOLLOWING COMMENTED LINES!<br />
'MemberInfo=14<br />
Public Sub SetDataSource(recordset As ADODB.recordset)<br />
Set DataGrid.DataSource = recordset<br />
End Sub<br />
With this design, the services of our grid control<br />
are very granular. Its only purpose is to accept an<br />
ADO RecordSet and display the data. We’ll reserve the<br />
more complicated tasks of responding to events for<br />
another control.<br />
The other control in the Visual Basic project consists<br />
of one user interface element—a Label control. There’s<br />
quite a lot of code behind this control—far too much to<br />
Figure 1. The new Visual Basic ActiveX control project contains<br />
two ActiveX controls.<br />
print in its entirety. However, I’ll highlight the most<br />
important pieces of code.<br />
Going back to the limitations of the first design, no<br />
public interfaces existed to make the ADO DataSource<br />
variable. Also, all of the events in the previous design<br />
were private. This meant that while the control within its<br />
boundaries recognized the event, no mechanism existed<br />
for the control to surface those events to its own interface.<br />
This means that any application environment hosting the<br />
control wouldn’t have the ability to have its own code<br />
execute when those events have fired. After all, that’s<br />
what it’s all about—having the ability to attach VFP code<br />
to ADO events.<br />
The first lines of code in the VB ActiveX control<br />
are as follows:<br />
Dim WithEvents oconn As ADODB.Connection<br />
Dim WithEvents ors As ADODB.recordset<br />
This provides that ability to the ActiveX control to<br />
respond to events that each of these objects will fire. The<br />
previous design took advantage of this ability and<br />
attached Visual Basic code to those events. In the old<br />
design, when an ADO connection was established, a<br />
MessageBox dialog box appeared, stating that the ADO<br />
connection was complete. While not very useful, it served<br />
to illustrate how events could be trapped. Visual Basic<br />
code is nice, but we work in VFP. We need the ability to<br />
surface these events so that VFP code can be used.<br />
Custom events<br />
Remember when VFP 3.0 was released back in 1995? We<br />
were given the ability to define our own methods and<br />
properties. Defining events, on the other hand, was<br />
something that wasn’t—and still isn’t—-provided. I, for<br />
one, didn’t see the big deal in this. After all, there are<br />
hundreds of events already defined. Why would I need<br />
more? As you’ll see, the ability to define custom events is<br />
a very powerful capability.<br />
To illustrate the power of events, I’ll focus on the<br />
MoveComplete event of the ADO RecordSet object. This<br />
event fires whenever the record changes. This event gets<br />
fired as a result of invoking the MoveFirst, MovePrevious,<br />
MoveNext, or MoveLast methods. The MoveComplete<br />
event also fires when an ADO RecordSet is first opened.<br />
Before looking at the custom event, let’s take a look at<br />
the code for the internal event that gets fired:<br />
Private Sub ors_MoveComplete( _<br />
ByVal adReason As ADODB.EventReasonEnum, _<br />
ByVal pError As ADODB.Error, _<br />
adStatus As ADODB.EventStatusEnum, _<br />
ByVal pRecordset As ADODB.recordset)<br />
RaiseEvent movecomplete(adReason, pError, _<br />
adStatusCancel, pRecordset)<br />
End Sub<br />
In this code, the internal ors_RecordSet object<br />
variable will respond to the MoveComplete event. This<br />
code block, in turn, will fire. The code to key on is the<br />
RaiseEvent statement. Notice that another MoveComplete<br />
16 FoxTalk December 1998<br />
http://www.pinpub.com