Welcome Guest!
 VB 6 Helper
 Previous Message All Messages Next Message 
VB6 Helper Newsletter  Rod Stephens
 Apr 16, 2004 21:29 PDT 

As some people pointed out, when I described MDAC last week I meant
MSDE. Uh, yea. It was just a test to see how many of you were paying
attention (apparently only about 3 or 4 were ;-)
-----
Have you started porting applications to VB .NET yet? Email me your
experiences (RodSte-@vb-helper.com). Let me know what's been hard,
what's been easy, what the biggest differences are, what workarounds and
pitfalls you've discovered, etc.
-----
Next Friday (April 23) I'm giving a talk at the "Denver Microsoft Visual
Studio .NET User Group" (http://www.denvervisualstudio.net) about
control creation in VB .NET. If you're near Denver, drop by!
-----
Have a great week and thanks for subscribing!

Rod
RodSte-@vb-helper.com
==========

    VB6 Contents:
1. Converted HowTo: Display a directory structure in a TreeView
controls, and save and restore the hierarchy in a file
2. Converted HowTo: Use TreeView and ListView controls together
3. Converted HowTo: Edit, save, and load TreeView data
4. Converted HowTo: Change a TreeView control's tooltip when the mouse
moves over different nodes
5. Converted HowTo: Display an appropriate popup menu when the user
right clicks on a TreeView node
6. Converted HowTo: Uninstall a program
7. Converted HowTo: Use VC++ to create a DLL file and use its functions
in Visual Basic 6
8. Converted HowTo: Find the Windows directory without using the API
9. Converted HowTo: Get the Windows directory from the environment
10. Converted HowTo: Show memory usage while creating and removing
windowed and windowless ActiveX controls
11. Converted HowTo: Make substitutions in a WMF file
12. Converted HowTo: Interactively change a font's height, width,
weight, and font name
13. Converted HowTo: Draw stretched, squeezed, and rotated text
14. Converted HowTo: Stretch a picture to fill a PictureBox
15. Converted HowTo: Resize controls to fit when a form resizes
16. Converted HowTo: Use the GetDIBits and SetDIBits API functions to
convert a picture to gray scale
17. Converted HowTo: Use the GetDIBits and SetDIBits API functions to
convert a picture to blue scale in three ways

    Both Contents:
18. Karen Watterson's Weekly Destinations and Diversions (D & D)
==========
++++++++++
   <VB6>
++++++++++
==========
1. Converted HowTo: Display a directory structure in a TreeView
controls, and save and restore the hierarchy in a file
http://www.vb-helper.com/howto_treeview_directory.html
http://www.vb-helper.com/HowTo/howto_treeview_directory.zip

Thanks to Sergio Perciballi (oig-@postmaster.co.uk).

When you click the Go button, the program gets ready, opens a text file,
and calls subroutine Get_Files.

Private Sub cmdGo_Click()
    Dim x As Integer, S$
    Dim file_name As String

    file_name = App.Path
    If Right$(file_name, 1) <> "\" Then file_name = file_name & "\"
    Open file_name & "Mytest.txt" For Output As #1

    Text1.Text = ""
    TreeView1.Nodes.Clear

    file_name = txtPath.Text
    If Right$(file_name, 1) <> "\" Then file_name = file_name & "\"

    Text1.Text = Text1.Text & file_name & vbCrLf
    ' need \ on end of key here------------|
    Set fnode = TreeView1.Nodes.Add(, , file_name, file_name)
    'initial data to file; topmost root of tree
    Print #1, file_name
    'initialise variables
    FIndent = 1
    FIndex = 0
    Text1.Visible = False
    TreeView1.Visible = False
    LblPrompt.Caption = "Processing drive..."
    LblPrompt.Refresh
    'note does not end with '\'
    StrtPath = Left$(file_name, Len(file_name) - 1)
    'start the directory reading
    Get_Files StrtPath
    Text1.Visible = True
    TreeView1.Visible = True
    LblPrompt.Caption = "Finished"

    Close 1

End Sub

Subroutine Get_Files uses the Dir$ command to get the subdirectories
inside a directory. It prints the subdirectory names into the text file
and adds nodes for them in the TreeView control. It recursively calls
itself to get the files contained in the subdirectory.

Private Sub Get_Files(FPath As String)
    Dim file_name As String
    Dim File_Path As String
    Dim File_Read As Integer
    Dim x As Boolean, xTemp As Integer, S$
    Dim I As Integer
    On Error Resume Next
    FIndent = FIndent + 1
    File_Path = FPath & "\"
    file_name = Dir$(File_Path, vbDirectory)
    File_Read = 1
    x = False

    Do While file_name <> ""
        If file_name <> "." And file_name <> ".." Then
            If GetAttr(File_Path & file_name) <> vbDirectory Then
                FIndex = FIndex + 1
            Else
                StrtPath = File_Path & file_name

                Set fnode = TreeView1.Nodes.Add(File_Path, tvwChild,
FPath & "\", file_name)

                'changed to dash/hyphen for readability
                Text1.Text = Text1.Text & "->" & String(FIndent *
FIndent, "_") & file_name & vbCrLf
                S$ = ""
                ''possible hack ; if FIndent=1 this doesn't execute
                For xTemp = 2 To FIndent
                    S$ = S$ & vbTab
                Next
                'write to a file; number of levels= number of tabs
                Print #1, S$ & file_name

                FIndex = FIndex + 1
                x = True
                'recursive call
                Get_Files StrtPath

            End If

        End If
        If x = True Then
            file_name = Dir$(File_Path, vbDirectory)
            For I = 2 To File_Read
                file_name = Dir$
            Next
            x = False
        End If
        file_name = Dir$
        File_Read = File_Read + 1

    Loop
    FIndent = FIndent - 1

End Sub

Subroutine LoadTreeViewFromFile loads the text file into a TreeView
control. It uses "Line Input" to read the files' lines. For each line,
it counts the number of Tab characters at the beginning of the line and
adds the new directory name to the appropriate level in the TreeView
control.

Private Sub LoadTreeViewFromFile(ByVal file_name As String, ByVal trv As
TreeView)
    Dim fnum As Integer
    Dim text_line As String
    Dim level As Integer
    Dim tree_nodes() As node
    Dim num_nodes As Integer
    
    fnum = FreeFile
    Open file_name For Input As fnum

    trv.Nodes.Clear
    Do While Not EOF(fnum)
        ' Get a line.
        Line Input #fnum, text_line

        ' Find the level of indentation.
        level = 1
        Do While Left$(text_line, 1) = vbTab
            level = level + 1
            text_line = Mid$(text_line, 2)
        Loop

        ' Make room for the new node.
        If level > num_nodes Then
            num_nodes = level
            ReDim Preserve tree_nodes(1 To num_nodes)
        End If

        ' Add the new node.
        If level = 1 Then
            Set tree_nodes(level) = trv.Nodes.Add(, , , text_line)
        Else
            Set tree_nodes(level) = trv.Nodes.Add(tree_nodes(level - 1),
tvwChild, , text_line)
            'tons faster without this
            ''tree_nodes(level).EnsureVisible
        End If
    Loop

    Close fnum

End Sub
==========
2. Converted HowTo: Use TreeView and ListView controls together
http://www.vb-helper.com/howto_treeview_and_listview.html
http://www.vb-helper.com/HowTo/howto_treeview_and_listview.zip

The EmployeeProjects class contains a ProjectNames collection that
stores the projects that an empolyee is working on. Subroutine
AddProjects adds a new EmployeeProjects object to the Projects
collection. It takes as parameters an employee's name and a parameter
list of project names. It makes a new EmployeeProjects object and adds
the project names to the ProjectNames collection. It then adds the
EmployeeProjects object to the Projects collection using the person's
name as its key.

' Save information about these projects for this
' employee.
Private Sub AddProjects(emp_name As String, ParamArray proj_names() As
Variant)
Dim emp_proj As New EmployeeProjects
Dim i As Integer

    ' Add the project names to the EmplyeeProjects
    ' object for this employee.
    For i = LBound(proj_names) To UBound(proj_names)
        emp_proj.ProjectNames.Add proj_names(i)
    Next i
    
    ' Add emp_proj to the collection of EmployeeProjects.
    Projects.Add emp_proj, emp_name
End Sub

When you press on a TreeView node, the OrgTree_MouseDown saves a
reference to the node you are pressing.

When you release the mouse, the OrgTree_Click event handler uses the
node's key to look up the corresponding EmployeeProjects object in the
Projects collection. If such an object exists, the program displays its
project names in the TreeView control.

Private Sub OrgTree_MouseDown(Button As Integer, Shift As Integer, x As
Single, y As Single)
    Set SourceNode = OrgTree.HitTest(x, y)
End Sub

' Display the data for this node in the ListView.
Private Sub OrgTree_Click()
Dim emp_proj As EmployeeProjects
Dim column_header As ColumnHeader
Dim list_item As ListItem
Dim obj As Object
Dim i As Integer

    ' Clear the ListView.
    lvProjects.ListItems.Clear
    lvProjects.ColumnHeaders.Clear
    
    ' Get the employee's EmployeeProjects object.
    If SourceNode Is Nothing Then Exit Sub
    On Error GoTo NoProjects
    Set emp_proj = Projects(SourceNode.Key)
    On Error GoTo 0

    ' Fill in the ListView.
    ' Create the column header.
    Set column_header = lvProjects. _
        ColumnHeaders.Add(, , "Project", _
        2 * TextWidth("Project"))

    With emp_proj.ProjectNames
        For i = 1 To .Count
            Set list_item = lvProjects.ListItems.Add(, , .Item(i))
            list_item.Icon = 1
            list_item.SmallIcon = 1
        Next i
    End With
    
NoProjects:
    Exit Sub
End Sub

This program also includes drag and drop features that lets you
rearrange the TreeView's nodes.
==========
3. Converted HowTo: Edit, save, and load TreeView data
http://www.vb-helper.com/howto_treeview_save_load.html
http://www.vb-helper.com/HowTo/howto_treeview_save_load.zip

Thanks to Sergio Perciballi (oig-@postmaster.co.uk).

This program displays trees using a TreeView control. Use buttons to add
and remove nodes. Use the right mouse button to drag them from one
position to another in the tree.

See the code for details.
==========
4. Converted HowTo: Change a TreeView control's tooltip when the mouse
moves over different nodes
http://www.vb-helper.com/howto_treeview_tip.html
http://www.vb-helper.com/HowTo/howto_treeview_tip.zip

The TreeView control's MouseMove event handler determines whether the
left button is down. If it is, then the program selects the node under
the mouse and begins a drag. If the left mouse button is not pressed,
then the event handler calls subroutine SetToolTip.

SetToolTip sees if the mouse has moved since it was last called. If it
has moved, then the code uses the HitTest method to see what node is
under the mouse. If this is not the same node that was under the mouse
last time, then the program sets the TreeView control's ToolTipText
property to the node's name.

Private Sub OrgTree_MouseMove(Button As Integer, Shift As Integer, X As
Single, Y As Single)
    If Button = vbLeftButton Then
        ' Start a new drag. Note that we do not get
        ' other MouseMove events while the drag is
        ' in progress.
        
        ' See what node we are dragging.
        SourceType = NodeType(SourceNode)

        ' Select this node. When no node is highlighted,
        ' this node will be displayed as selected. That
        ' shows where it will land if dropped.
        Set OrgTree.SelectedItem = SourceNode

        ' Set the drag icon for this source.
        OrgTree.DragIcon = IconImage(SourceType)
        OrgTree.Drag vbBeginDrag
    ElseIf Button = 0 Then
        SetToolTip X, Y
    End If
End Sub

' If the mouse has moved, change the tool tip.
Private Sub SetToolTip(ByVal X As Single, ByVal Y As Single)
Static last_x As Single
Static last_y As Single
Static node_over As Node
Dim new_node_over As Node

    ' See if the mouse has moved.
    If (last_x = X) And (last_y = Y) Then Exit Sub
    last_x = X
    last_y = Y

    ' See what node we're over.
    Set new_node_over = OrgTree.HitTest(X, Y)
    If node_over Is new_node_over Then Exit Sub
    Set node_over = new_node_over

    ' Set the tool tip text to be the node's key minus
    ' the first 2 characters (which give its type).
    If new_node_over Is Nothing Then
        OrgTree.ToolTipText = ""
    Else
        OrgTree.ToolTipText = Mid$(node_over.Key, 3)
    End If
End Sub
==========
5. Converted HowTo: Display an appropriate popup menu when the user
right clicks on a TreeView node
http://www.vb-helper.com/howto_treeview_popup.html
http://www.vb-helper.com/HowTo/howto_treeview_popup.zip

In the TreeView's MouseDown event handler, the program uses the
control's HitTest method to get the node under the mouse. If the right
mouse button is down, the code calls subroutine ShowPopup.

ShowPopup checks the node's type and shows and hides the appropriate
context menu items. Alternatively you could use different popup menus
for different kinds of nodes. It then uses the PopupMenu statement to
display the popup menu.

Private Sub OrgTree_MouseDown(Button As Integer, Shift As Integer, x As
Single, y As Single)
    Set SourceNode = OrgTree.HitTest(x, y)
    SourceType = NodeType(SourceNode)

    Set OrgTree.SelectedItem = SourceNode

    ' If the right button is down, display the
    ' appropriate context menu.
    If Button = vbRightButton Then ShowPopup
End Sub

' Display the appropriate popup menu items.
Private Sub ShowPopup()
    ' See what kind of node this is and
    ' hide the invalid popup menu items.
    Select Case SourceType
        Case otNone
            ' Allow add factory.
            mnuPopupAddFactory.Visible = True
            mnuPopupAddGroup.Visible = False
            mnuPopupAddPerson.Visible = False

            mnuPopupDeleteSep.Visible = False
            mnuPopupDeleteObject.Visible = False
        Case otFactory
            ' Allow add factory or group.
            mnuPopupAddFactory.Visible = True
            mnuPopupAddGroup.Visible = True
            mnuPopupAddPerson.Visible = False

            mnuPopupDeleteSep.Visible = True
            mnuPopupDeleteObject.Visible = True
            mnuPopupDeleteObject.Caption = "&Delete Factory"
        Case otGroup
            ' Allow add factory, group, or person.
            mnuPopupAddFactory.Visible = True
            mnuPopupAddGroup.Visible = True
            mnuPopupAddPerson.Visible = True

            mnuPopupDeleteSep.Visible = True
            mnuPopupDeleteObject.Visible = True
            mnuPopupDeleteObject.Caption = "&Delete Group"
        Case otPerson
            ' Allow add factory, group, or person.
            mnuPopupAddFactory.Visible = True
            mnuPopupAddGroup.Visible = True
            mnuPopupAddPerson.Visible = True

            mnuPopupDeleteSep.Visible = True
            mnuPopupDeleteObject.Visible = True
            mnuPopupDeleteObject.Caption = "&Delete Person"
    End Select

    ' Display the popup menu.
    PopupMenu mnuPopup
End Sub
==========
6. Converted HowTo: Uninstall a program
http://www.vb-helper.com/howto_uninstall.html
http://www.vb-helper.com/HowTo/howto_uninstall.zip

Use the st6unst.exe program (VB6) in the Windows directory, passing is
the log file created during program installation.

To use this example, build an installation package for program Test
using the Package and Deployment Wizard. Install the program and run it.

Then run program Uninstall. Tell it where to find the log file created
during the installation.

Program Uninstall uses the following code to run program st6unst.exe in
the Windows directory.

Private Sub Command1_Click()
    Shell WindowsDirectory() & _
        "\st6unst.exe -n """ & _
        Text1.Text & """"
End Sub

' Return the windows directory.
Private Function WindowsDirectory() As String
Dim buf As String * 256
Dim return_len As Long

    return_len = GetWindowsDirectory(buf, Len(buf))
    WindowsDirectory = Left$(buf, return_len)
End Function
==========
7. Converted HowTo: Use VC++ to create a DLL file and use its functions
in Visual Basic 6
http://www.vb-helper.com/howto_vcc_dll.html
http://www.vb-helper.com/HowTo/howto_vcc_dll.zip

I have found 2 methods to do this. The first makes the VC++ easier and
the Visual Basic messier. The second makes the VC++ harder and the
Visual Basic easier.

Method 1: Easy VC++, Hard VB

1. VC++: Invoke New\Projects\Win32 Dynamic-Link Library. Enter the
directory where you want the VC++ project and the project name
(MyFuncsProject in the example).

2. VC++: Invoke New\Files\C++ Source File. Check the Add To Project box.
Enter the file name (MyFuncs.cpp in the example).

3. VC++: Enter the function's source code. Use __declspec (note the two
underscores) to export the function's symbol. Use 'extern "C"' to
minimize name mangling by VC++.

// Define DllExport to declare exported symbols.
#define DllExport __declspec( dllexport )

// Prototype the function.
// Use 'extern "C"' to minimize name mangling.
extern "C" DllExport long MyCFunc(long x);

// Define the function.
extern "C" DllExport long MyCFunc(long x)
{
    return x * x;
}

4. VC++: Set project options using Project\Settings. On the C/C++ tab,
select the Code Generation category. Then change Calling Convention to
__stdcall.

5. VC++: Select Build\Set Active Configuration. Select the Release
configuration. Repeat step 4 to make the options apply to the release
configuration in addition to the debug configuration. Use Build\Set
Active Configuration to reselect the debug configuration if desired.

6. VC++: Build the project (press F7 or use the Build menu). This
creates the DLL file.

7. VB: In your Visual Basic program, declare the DLL function using the
DLL file's full path name. The function's name in the DLL file has been
slightly mangled by VC++. The name is an underscore, followed by the
name you gave it, followed by "@", followed by the number of bytes in
the function's argument list. In this example the name is _MyCFunc@4
because the function takes one 4 byte argument (a long integer).

Private Declare Function MyCFunc Lib _
    "C:\VBHelper\VcDll\Method1\Release\MyFuncsProject.dll" _
    Alias "_MyCFunc@4" _
    (ByVal x As Long) As Long

Private Sub Command1_Click()
Dim x As Long
Dim y As Long

    x = CInt(Text1.Text)
    y = MyCFunc(x)
    Label1.Caption = Str$(y)
End Sub

*** HINT: To quickly determine the mangled name of the function, find
the DLL file in Windows Explorer. Right click on the file and select the
"Quick View" command. This presents an editor showing information about
the DLL. Page down 2 or 3 pages and you will find a list of exported
symbols available in the DLL. One of these will be the mangled function
name.

8. VB: Run the program. <\OL>
-----
Method 2, Hard VC++, Easy VB

Steps 1 through 5 are the same as in Method 1.

6. VC++: New\Text File. Check the Add To Project box. Enter the file
name. Give it a .DEF extension (MyFuncs.def in the example).

7. VC++: Enter definition file information that tells VC++ to export the
function with the mangled name using the name you want it to have. The
following code makes the exported name MyCFunc equivalent to _MyC-@4.


EXPORTS
MyCFunc=_MyCFunc@4

8. VC++: Build the project (press F7 or use the Build menu). This
creates the DLL file.

*** HINT: Use Quick View to verify the exported names. Find the DLL file
in Windows Explorer. Right click on the file and select the "Quick View"
command. Page down 2 or 3 pages and you will find a list of exported
symbols available in the DLL. This includes both the mangled name and
the name you specified in the .DEF file.

9. VB: In your Visual Basic program, declare the DLL function using the
DLL file's full path name. Use the name you placed in the .DEF file not
the mangled name.

Private Declare Function MyCFunc Lib _
    "C:\VBHelper\VcDll\Method2\Release\MyFuncsProject.dll" _
    (ByVal x As Long) As Long

Private Sub Command1_Click()
Dim x As Long
Dim y As Long

    x = CInt(Text1.Text)
    y = MyCFunc(x)
    Label1.Caption = Str$(y)
End Sub
==========
8. Converted HowTo: Find the Windows directory without using the API
http://www.vb-helper.com/howto_windir_wo_api.html
http://www.vb-helper.com/HowTo/howto_windir_wo_api.zip

Thanks to Pablo Handler (pablo.h-@hrc.es).

The prorgam opens the file C:\MSDOS.SYS and looks for the windir=
assignment.

Private Sub Form_Load()
Dim FF As Integer
Dim LINE As String

    FF = FreeFile
    Open "C:\MSDOS.SYS" For Input As FF
    Do
        Line Input #FF, LINE
    Loop While InStr(1, LCase$(LINE), "windir=", 1) = 0
    Close FF

    Label2.Caption = Mid(LINE, 8)
End Sub
==========
9. Converted HowTo: Get the Windows directory from the environment
http://www.vb-helper.com/howto_windir_environ.html
http://www.vb-helper.com/HowTo/howto_windir_environ.zip

Thanks to Bill Hileman (dasi-@gator.net).

The program uses the Environ$ statement to read the windir environment
variable.

Private Sub Form_Load()
    Label2.Caption = Environ$("windir")
End Sub
==========
10. Converted HowTo: Show memory usage while creating and removing
windowed and windowless ActiveX controls
http://www.vb-helper.com/howto_windowed_windowless_memory_use.html
http://www.vb-helper.com/HowTo/howto_windowed_windowless_memory_use.zip

The cmdMakeWindowed button makes or removes a windowed ActiveX control.
It then calls subroutine ShowStatistics to show the memory usage. The
cmdMakeWindowless is similar except it makes a windowless control.

Private Sub cmdMakeWindowed_Click()
Dim ctl As Control

    If cmdMakeWindowed.Caption = "Remove Windowed" Then
        Me.Controls.Remove "windowed_control"
        cmdMakeWindowed.Caption = "Make Windowed"
    Else
        Set ctl = Me.Controls.Add("Project1.WindowedControl",
"windowed_control")
        With ctl
            .Move Label2.Left + Label2.Width, Label2.Top
            .Visible = True
        End With
        cmdMakeWindowed.Caption = "Remove Windowed"
    End If

    DoEvents
    ShowStatistics
End Sub

Subroutine ShowStatistics uses the GlobalMemoryStatus API function to
get information about the system's global memory. It displays the
information and the difference between the current usage and the that of
the last time the routine ran.

Private Sub ShowStatistics()
Static old_mem As MEMORYSTATUS
Dim mem As MEMORYSTATUS
Dim txt As String

    GlobalMemoryStatus mem

    With mem
        txt = txt & "% used:                " & Format$(.dwMemoryLoad,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & "Total physical memory: " & Format$(.dwTotalPhys,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & "Physical memory free: " & Format$(.dwAvailPhys,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & "Total page file size: " &
Format$(.dwTotalPageFile, "@@@@@@@@@@@") & vbCrLf
        txt = txt & "Free page file size:   " &
Format$(.dwAvailPageFile, "@@@@@@@@@@@") & vbCrLf
        txt = txt & "Total virtual memory: " & Format$(.dwTotalVirtual,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & "Free virtual memory:   " & Format$(.dwAvailVirtual,
"@@@@@@@@@@@") & vbCrLf
    End With
    Label1.Caption = txt

    If old_mem.dwMemoryLoad > 0 Then
        txt = ""
        txt = txt & Format$(mem.dwMemoryLoad - old_mem.dwMemoryLoad,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & Format$(mem.dwTotalPhys - old_mem.dwTotalPhys,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & Format$(mem.dwAvailPhys - old_mem.dwAvailPhys,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & Format$(mem.dwTotalPageFile -
old_mem.dwTotalPageFile, "@@@@@@@@@@@") & vbCrLf
        txt = txt & Format$(mem.dwAvailPageFile -
old_mem.dwAvailPageFile, "@@@@@@@@@@@") & vbCrLf
        txt = txt & Format$(mem.dwTotalVirtual - old_mem.dwTotalVirtual,
"@@@@@@@@@@@") & vbCrLf
        txt = txt & Format$(mem.dwAvailVirtual - old_mem.dwAvailVirtual,
"@@@@@@@@@@@") & vbCrLf
        Label2.Caption = txt
    End If
    old_mem = mem
End Sub
==========
11. Converted HowTo: Make substitutions in a WMF file
http://www.vb-helper.com/howto_wmf_substitute.html
http://www.vb-helper.com/HowTo/howto_wmf_substitute.zip

The program reads the WMF file. It then uses the Substitute subroutine
to replace token strings in the WMF file with useful data values. This
example fills in a name and address.

The program then writes the revised WMF data into a temporary file and
displays the results.

Private Sub Command1_Click()
Dim txt As String
Dim fnum As Integer

    fnum = FreeFile
    Open Text1.Text For Binary As fnum
    
    txt = Input(LOF(fnum), #fnum)
    
    Close fnum

    ' Insert the name.
    Substitute txt, _
        "$$nom67890123456789012345678901234567890", _
        "Rod Stephens"

    ' Insert the street.
    Substitute txt, _
        "$$rue6789012345678901234567890", _
        "1234 Programmer Way"

    ' Insert the place, country, and postal code.
    Substitute txt, _
        "$$pays7890123456789012345678901234567890", _
        "Bugville CO 80301, USA"

    ' Save the new WMF file.
    Open "C:\Temp\NewFile.WMF" For Binary As fnum Len = Len(txt)
    Put #fnum, , txt
    Close fnum

    ' Load the WMF file.
    Picture1.Picture = LoadPicture("C:\Temp\NewFile.WMF")
End Sub

Subroutine Substitute makes the replacement value the same length as the
token. It then replaces the token with the replacement value.

' Replace the token with the value in the string.
Private Sub Substitute(txt As String, ByVal token As String, ByVal value
As String)
Dim pos As Long

    ' Make sure the value is not too long.
    value = Left$(value, Len(token))

    ' Make the value the same length as the token.
    value = value & Space$(Len(token) - Len(value))
    
    ' Make the replacement.
    pos = InStr(txt, token)
    txt = Left$(txt, pos - 1) & _
        value & _
        Right$(txt, Len(txt) - (pos + Len(token)) + 1)
End Sub
==========
12. Converted HowTo: Interactively change a font's height, width,
weight, and font name
http://www.vb-helper.com/howto_stretch_text_interactive.html
http://www.vb-helper.com/HowTo/howto_stretch_text_interactive.zip

When you change the font's height, width, weight, font name, or text,
the appropriate control's event handler calls subroutine ShowFont. That
routine calls the CustomFont function to make a new font. It uses
SelectObject to install the font on the form, draws some text, uninstals
the font, and uses DeleteObject to free the font's resources.

Private Sub ShowFont()
Dim wid As Long
Dim hgt As Long
Dim wgt As Long
Dim newfont As Long
Dim oldfont As Long

    On Error Resume Next

    ' Select the new font.
    wid = CLng(txtWidth.Text)
    hgt = CLng(txtHeight.Text)
    wgt = cboWeight.ItemData(cboWeight.ListIndex)
    newfont = CustomFont(hgt, wid, 0, 0, _
        wgt, False, False, False, cboFont.Text)
    oldfont = SelectObject(hdc, newfont)

    ' Display the text.
    Line (0, 0)-(1000, 1000), BackColor, BF
    CurrentX = 10
    CurrentY = cboFont.Height + cboFont.Top + 10
    Print txtText.Text
    Picture = Image

    ' Restore the original font.
    newfont = SelectObject(hdc, oldfont)

    ' Free font resources (important!)
    DeleteObject newfont
End Sub

Function CustomFont uses the CreateFont API function to make a new font
and return the font's handle.

' Make a customized font and return its handle.
Private Function CustomFont(ByVal hgt As Long, ByVal wid As Long, ByVal
escapement As Long, ByVal orientation As Long, ByVal wgt As Long, ByVal
is_italic As Long, ByVal is_underscored As Long, ByVal is_striken_out As
Long, ByVal face As String) As Long
Const CLIP_LH_ANGLES = 16   ' Needed for tilted fonts.

    CustomFont = CreateFont( _
        hgt, wid, escapement, orientation, wgt, _
        is_italic, is_underscored, is_striken_out, _
        0, 0, CLIP_LH_ANGLES, 0, 0, face)
End Function
==========
13. Converted HowTo: Draw stretched, squeezed, and rotated text
http://www.vb-helper.com/howto_custom_fonts.html
http://www.vb-helper.com/HowTo/howto_custom_fonts.zip

When the form loads, it calls subroutine DrawRotatedText to draw text
with various heights, widths, and angles of rotation.

Private Sub Form_Load()
Const PI = 3.14159625
Const FW_NORMAL = 400   ' Normal font weight.

Dim I As Long
Dim cx As Long
Dim cy As Long

    AutoRedraw = True

    DrawRotatedText "Stretched", 10, 10, 10, 20, _
        "Times New Roman", FW_NORMAL, 3600, False, _
        False, False
    DrawRotatedText "Stretched", 10, 20, 10, 30, _
        "Times New Roman", FW_NORMAL, 3600, False, _
        False, False
    DrawRotatedText "Stretched", 10, 30, 10, 40, _
        "Times New Roman", FW_NORMAL, 3600, False, _
        False, False
    DrawRotatedText "Squeezed", 30, 10, 10, 50, _
        "Times New Roman", FW_NORMAL, 3600, False, _
        False, False
    DrawRotatedText "Squeezed", 30, 5, 10, 70, _
        "Times New Roman", FW_NORMAL, 3600, False, _
        False, False
    DrawRotatedText "Squeezed", 30, 3, 10, 90, _
        "Times New Roman", FW_NORMAL, 3600, False, _
        False, False

    cx = ScaleWidth - 20
    cy = ScaleHeight - 20
    For I = 90 To 180 Step 20
        DrawRotatedText "     Some Rotated Text", 20, 0, _
            cx + Cos(I / 180 * PI), _
            cy + Sin(I / 180 * PI), _
            "Times New Roman", FW_NORMAL, I * 10, _
            False, False, False
    Next I
End Sub

Subroutine DrawRotatedText uses the CreateFont API function to make the
desired font. It uses SelectFont to install the font on the form, draws
the text, uninstalls the font, and uses DeleteObject to free the font's
resources.

Private Sub DrawRotatedText(ByVal txt As String, _
    ByVal hgt As Long, ByVal wid As Long, _
    ByVal X As Single, ByVal Y As Single, _
    ByVal font_name As String, _
    ByVal weight As Long, ByVal escapement As Long, _
    ByVal use_italic As Boolean, ByVal use_underline As Boolean, _
    ByVal use_strikethrough As Boolean)

Const CLIP_LH_ANGLES = 16   ' Needed for tilted fonts.
Const PI = 3.14159625
Const PI_180 = PI / 180#

Dim newfont As Long
Dim oldfont As Long

    newfont = CreateFont(hgt, wid, _
        escapement, escapement, weight, _
        use_italic, use_underline, _
        use_strikethrough, 0, 0, _
        CLIP_LH_ANGLES, 0, 0, font_name)
    
    ' Select the new font.
    oldfont = SelectObject(hdc, newfont)
    
    ' Display the text.
    CurrentX = X
    CurrentY = Y
    Print txt

    ' Restore the original font.
    newfont = SelectObject(hdc, oldfont)
    
    ' Free font resources (important!)
    DeleteObject newfont
End Sub
==========
14. Converted HowTo: Stretch a picture to fill a PictureBox
http://www.vb-helper.com/howto_stretch_picture.html
http://www.vb-helper.com/HowTo/howto_stretch_picture.zip

When the form resizes, it makes the picVisible control fill the form.
When the picVisible control resizes, the program uses the PaintPicture
method to copy a hidden picture onto it.

' Make picVisible fill the form.
Private Sub Form_Resize()
    picVisible.Move 0, 0, ScaleWidth, ScaleHeight
End Sub

' Copy the image into picVisible.
Private Sub picVisible_Resize()
    picVisible.PaintPicture picHidden.Picture, _
        0, 0, picVisible.ScaleWidth, _
        picVisible.ScaleHeight, _
        0, 0, picHidden.ScaleWidth, _
        picHidden.ScaleHeight, vbSrcCopy
End Sub

My book "Visual Basic Graphics Programming"
(http://www.vb-helper.com/vbgp.htm) shows how to resize a picture
smoothly without jagged aliasing effects.
==========
15. Converted HowTo: Resize controls to fit when a form resizes
http://www.vb-helper.com/howto_stretch_controls.html
http://www.vb-helper.com/HowTo/howto_stretch_controls.zip

When the program starts, it saves the controls' positions and dimensions
in Form_Load. It saves the controls' original sizes when the program
starts rather than using their current dimensions as the form resizes so
roundoff problems don't ruin the calculations after several resizes.

Private Type ControlPositionType
    Left As Single
    Top As Single
    Width As Single
    Height As Single
    FontSize As Single
End Type

Private m_ControlPositions() As ControlPositionType
Private m_FormWid As Single
Private m_FormHgt As Single

' Save the form's and controls' dimensions.
Private Sub SaveSizes()
Dim i As Integer
Dim ctl As Control

    ' Save the controls' positions and sizes.
    ReDim m_ControlPositions(1 To Controls.Count)
    i = 1
    For Each ctl In Controls
        With m_ControlPositions(i)
            If TypeOf ctl Is Line Then
                .Left = ctl.X1
                .Top = ctl.Y1
                .Width = ctl.X2 - ctl.X1
                .Height = ctl.Y2 - ctl.Y1
            Else
                .Left = ctl.Left
                .Top = ctl.Top
                .Width = ctl.Width
                .Height = ctl.Height
                On Error Resume Next
                .FontSize = ctl.Font.Size
                On Error GoTo 0
            End If
        End With
        i = i + 1
    Next ctl

    ' Save the form's size.
    m_FormWid = ScaleWidth
    m_FormHgt = ScaleHeight
End Sub

Private Sub Form_Load()
    SaveSizes
End Sub

When the form resizes, it calls subroutine ResizeControls.
ResizeControls scales each control's Left, Top, Width, Height, and font
size properties by the same amount by which the form has changed size.

Private Sub Form_Resize()
    ResizeControls
End Sub

' Arrange the controls for the new size.
Private Sub ResizeControls()
Dim i As Integer
Dim ctl As Control
Dim x_scale As Single
Dim y_scale As Single

    ' Don't bother if we are minimized.
    If WindowState = vbMinimized Then Exit Sub

    ' Get the form's current scale factors.
    x_scale = ScaleWidth / m_FormWid
    y_scale = ScaleHeight / m_FormHgt

    ' Position the controls.
    i = 1
    For Each ctl In Controls
        With m_ControlPositions(i)
            If TypeOf ctl Is Line Then
                ctl.X1 = x_scale * .Left
                ctl.Y1 = y_scale * .Top
                ctl.X2 = ctl.X1 + x_scale * .Width
                ctl.Y2 = ctl.Y1 + y_scale * .Height
            Else
                ctl.Left = x_scale * .Left
                ctl.Top = y_scale * .Top
                ctl.Width = x_scale * .Width
                If Not (TypeOf ctl Is ComboBox) Then
                    ' Cannot change height of ComboBoxes.
                    ctl.Height = y_scale * .Height
                End If
                On Error Resume Next
                ctl.Font.Size = y_scale * .FontSize
                On Error GoTo 0
            End If
        End With
        i = i + 1
    Next ctl
End Sub

For a more complete example, see the Stretchable control in my book
"Custom Controls Library" (http://www.vb-helper.com/ccl.htm).
==========
16. Converted HowTo: Use the GetDIBits and SetDIBits API functions to
convert a picture to gray scale
http://www.vb-helper.com/howto_make_gray.html
http://www.vb-helper.com/HowTo/howto_make_gray.zip

The MakeGray subroutine prepares some data structures and then uses the
GetDIBits API function to get the picture's bitmap data. It chnges each
picel's red, green, and blue components to the average of those three
values. It then uses SetDIBits to save the changes into the PictureBox.

' Convert a color image to gray scale.
Private Sub MakeGray(ByVal picColor As PictureBox)
Dim bitmap_info As BITMAPINFO
Dim pixels() As Byte
Dim bytes_per_scanLine As Integer
Dim pad_per_scanLine As Integer
Dim X As Integer
Dim Y As Integer
Dim ave_color As Byte

    ' Prepare the bitmap description.
    With bitmap_info.bmiHeader
        .biSize = 40
        .biWidth = picColor.ScaleWidth
        ' Use negative height to scan top-down.
        .biHeight = -picColor.ScaleHeight
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = BI_RGB
        bytes_per_scanLine = ((((.biWidth * .biBitCount) + 31) \ 32) *
4)
        pad_per_scanLine = bytes_per_scanLine - (((.biWidth *
.biBitCount) + 7) \ 8)
        .biSizeImage = bytes_per_scanLine * Abs(.biHeight)
    End With

    ' Load the bitmap's data.
    ReDim pixels(1 To 4, 1 To picColor.ScaleWidth, 1 To
picColor.ScaleHeight)
    GetDIBits picColor.hdc, picColor.Image, _
        0, picColor.ScaleHeight, pixels(1, 1, 1), _
        bitmap_info, DIB_RGB_COLORS

    ' Modify the pixels.
    For Y = 1 To picColor.ScaleHeight
        For X = 1 To picColor.ScaleWidth
            ave_color = CByte((CInt(pixels(pixR, X, Y)) + _
                pixels(pixG, X, Y) + _
                pixels(pixB, X, Y)) \ 3)
            pixels(pixR, X, Y) = ave_color
            pixels(pixG, X, Y) = ave_color
            pixels(pixB, X, Y) = ave_color
        Next X
    Next Y

    ' Display the result.
    SetDIBits picColor.hdc, picColor.Image, _
        0, picColor.ScaleHeight, pixels(1, 1, 1), _
        bitmap_info, DIB_RGB_COLORS
    picColor.Picture = picColor.Image
End Sub

My book "Visual Basic Graphics Programming"
(http://www.vb-helper.com/vbgp.htm) has a lot more information about
graphics.
==========
17. Converted HowTo: Use the GetDIBits and SetDIBits API functions to
convert a picture to blue scale in three ways
http://www.vb-helper.com/howto_make_blue.html
http://www.vb-helper.com/HowTo/howto_make_blue.zip

The ZeroRedGreen, BlueAverage, and KeepBlueBrightness subroutines
convert an image into shades of blue in different ways. All use
GetDIBits to get the picture's pixel data, modify the data, and then use
SetDIBits to update the picture.

Subroutine ZeroRedGreen sets the green and blue components of each pixel
to zero. The result is all blue but darker than the original because the
red and green contributions to brightness have been removed.

For Y = 1 To picColor.ScaleHeight
    For X = 1 To picColor.ScaleWidth
        pixels(pixR, X, Y) = 0
        pixels(pixG, X, Y) = 0
    Next X
Next Y


Subroutine BlueAverage sets each pixel's blue component to the average
of its red, green, and blue components. It sets the red and green
components to zero. The result is darker than the original because each
pixel's total color component values is one third its original value.

For Y = 1 To picColor.ScaleHeight
    For X = 1 To picColor.ScaleWidth
        pixels(pixB, X, Y) = CByte( _
            (CInt(pixels(pixR, X, Y)) + _
            pixels(pixG, X, Y) + _
            pixels(pixB, X, Y)) \ 3 _
        )
        pixels(pixR, X, Y) = 0
        pixels(pixG, X, Y) = 0
    Next X
Next Y

Subroutine KeepBlueBrightness sets each pixel's blue component to the
sum of its red, green, and blue components. If this sum is greater than
255, it sets the blue component to 255 and splits the remainder between
the red and green components. The result is a brighter shade of blue.
This version gives the best result.

For Y = 1 To picColor.ScaleHeight
    For X = 1 To picColor.ScaleWidth
        blue_color = CInt(pixels(pixR, X, Y)) + _
            pixels(pixG, X, Y) + _
            pixels(pixB, X, Y)
        If blue_color > 255 Then
            red_color = (blue_color - 255) \ 2
            green_color = red_color
            blue_color = 255
        Else
            red_color = 0
            green_color = 0
        End If
        pixels(pixR, X, Y) = red_color
        pixels(pixG, X, Y) = green_color
        pixels(pixB, X, Y) = blue_color
    Next X
Next Y

My book "Visual Basic Graphics Programming"
(http://www.vb-helper.com/vbgp.htm) has a lot more information about
graphics.
==========
++++++++++
<Both>
++++++++++
==========
18. Karen Watterson's Weekly Destinations and Diversions (D & D)
http://www.vb-helper.com/karens_weekly_diversions.html

(With Karen's apologies for the length (although I see nothing to
apologize for ;-)).

Readable
- Michael Weinhardt's Extending Windows Forms with a Custom Validation
Component Library
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms03162004.asp>.

- Brian Connolly's Random Sampling in T-SQL
<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsqlpro04/html/sp04c1.asp>.

- Simon Cozens' free online book on Perl
<http://learn.perl.org/library/beginning_perl/>.
- The first and second issues of MSDN's "Journal" for architects
<http://msdn.microsoft.com/architecture/journal/>. (Emphasis seems to be
on SOA.). Related: Microsoft's Patterns and Practices Summits
<http://www.pnpsummit.com/_pnp.aspx> in Redmond (May 11-13), Reading, UK
(Jun 14-16)), and Reston (Oct 5-7). Also related: Architecture webcasts
such recent ones on GAPP
nts.microsoft.com/CUI/EventDetail.aspx?EventID=1032249518&Culture=en-US>
("guidance on patterns and practices," not to be confused with GAAP),
architecture for .NET apps
ts.microsoft.com/CUI/EventDetail.aspx?EventID=1032250810&Culture=en-US>,
and Sandy Khaund's forthcoming Apr 22 webcast updating P&Ps
<http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032247641&Culture=en-US>.


Go to <http://www.microsoft.com/seminar/events/webcasts/default.mspx>
(searchable via architect) to find other on demand architecture
webcasts.
- Microsoft's overview of its new "open" Office 2003 XML Reference
Schemas <http://www.microsoft.com/office/xml/overview.mspx>. Download
them here
<http://www.microsoft.com/downloads/details.aspx?FamilyId=FE118952-3547-420A-A412-00A2662442D9&displaylang=en>.

- Brian Bischof's helpful 530 page (and self-published!) Crystal Reports
.NET Programming <http://www.crystalreportsbook.com/FreeEbook.asp> book
with code in both VB.NET and C#. Read his free intro tutorial, but be
sure to check out his links and consider buying the book, too!
- See the January 12, 2004, Washington Technology for Gartner's Hype
Cycle for government technologies
<http://www.washingtontechnology.com/news/18_19/emerging-tech/22455-1.html>.

- Interesting article on the new CMMI (Capability Maturity Model
Integration)
<http://www.fcw.com/fcw/articles/2004/0329/feat-cmmi-03-29-04.asp>.
Related: Carnegie MellonCMMI Web Site <http://www.sei.cmu.edu/cmmi/>.
- Bruce Miller's excellent article, Coming Soon: E-Records: What every
DBA should know about record-keeping requirements
<http://www.db2mag.com/story/showArticle.jhtml;jsessionid=E2AWCFLTYBRTYQSNDBOCKHY?articleID=17602314>.

- The 28th quarterly issue of Robert Seiner's TDAN <http://www.tdan.com>
(free online journal for data admins). Sample articles: Dave Marco on
"Managed Meta Data Environment," David Hay on "Modeling Business Rules:
What Data Models Cannot Do," and Malcolm Chisholm on "Understanding
Hidden Subtypes," along with regular feature columns by Craig Mullins
and Fabian Pascal.
- Read some of the content from Being Human: Readings from the
Presidents' Council on Bioethics <http://www.bioethics.gov/bookshelf/>
print edition (only 5000 copies printed).
- Interesting summary of some research from the UK's Cranfield School of
Management on categorizing businesses by their persona (explorers,
harvesters, fighters, or crusaders)
<http://www.sas.com/news/sascom/2004q1/feature_cranfield.html>.
- Bran Selic's UML 2.0: Exploiting Abstraction and Automation
<http://www.sdtimes.com/opinions/guestview_098.htm>.
- The May 2004 issue of Inc Magazine <http://www.inc.com> (not online
yet) has a great "how I did it" interview with Michael Powell, of
Portland's Powell's bookstore. Related: Powells.com
<http://www.powells.com>.
- Peter Denning on the Great Principles of Computing
<http://www.acm.org/ubiquity/interviews/v4i48_denning.html> in the
November 2003 issue of "Communications of the ACM." (ACM membership
required to read that article.) Some of content available in a free
online interview (see esp. last half) about his work at the Naval
Postgraduate School. Excerpt: "There are two categories of principles -
mechanics and design. Mechanics refers to the fundamental laws and
recurrences of computation. Mechanics subdivides into five categories;
we call them computation, communication, coordination, recollection, and
automation. Design refers to process - conventions we use to organize
ourselves to build good computing systems - and to architecture -
conventions for arranging the components of systems." He thinks the
field needs "storytellers with the skills of Richard Feynman in physics,
Carl Sagan in Astronomy, or Bob Hazen in general science."
- Useful Q&A with Grady Booch in the April issue of e-Pro Magazine
<http://www.e-promag.com/> (free subscription required to read it).
Sample: "As for the future, in the short term, I see the continuing rise
of two major platforms (.NET and J2EE)..., a rise in outsourcing of
commodity projects, and the growth of design and architectural
patterns."
- Fascinating profiles of 11 "innovators & influencers"
<http://www.informationweek.com/showArticle.jhtml?articleID=17000400>
from the Dec. 22, 2003, issue of Information Week. Not the standard
folks.
- In the April 24 issue of Business Week, Gene Marcial speculates that
Borland may be in Microsoft's "sights."
<http://www.businessweek.com/magazine/content/04_15/b3878143_mz027.htm>

KB Articles (mainly related to programming Exchange with .NET)
- 314383 How to use the CDOEX Library to retrieve messages from a user's
Inbox by using VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314383>
- 314197 How to use the HttpWebRequest class and the HttpWebResponse
class to retrieve the properties of an object in VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314197>
- 314180 How to retrieve all the items in a public folder on a computer
that is running Exchange 2000
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314180>
- 314188 How to search for the URI property of a sender's e-mail
submission and to send an e-mail message by using this property in
VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314188>
- 308278 HOW TO: Retrieve and Display Records from an Access Database by
Using ASP.NET, ADO.NET, and VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b308278>
- 313775 How to use the CDOSYS Library to send an e-mail message by
using the SMTP port in VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b313775>
- 314199 How to use the HttpWebRequest class and the HttpWebResponse
class to send an e-mail message by using VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314199>
- 314193 How to use the HttpWebRequest class and the HttpWebResponse
class to delete an object by using VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314193>
- 314190 How to create a Contact item by using the HttpWebRequest class
and the HttpWebResponse class in VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314190>
- 314367 How to use the CDOEX Library to create a recurring meeting that
has exceptions in VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314367>
- 314195 How to retrieve an object's security descriptor property by
using VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314195>
- 314196 How to list folders or items in a user's mailbox by using the
HttpWebRequest class and the HttpWebResponse class in VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314196>
- 314363 How to create a contact by using an Item object in VB.NET
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b314363>
- 810415 Access 2002 Format Database Bloat Is Not Stopped by Compacting
<http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b810415>

Downloadable
- NUnit <http://www.nunit.org/>, a unit-testing framework for all .Net
languages
- NDoc <http://sourceforge.net/projects/ndoc/>, documentation generator
for .NET.
- Windows CE 5.0 Technology Preview
<http://msdn.microsoft.com/embedded/prodinfo/future/techpreview/default.aspx>.

- Beta version of JNetDirect's JSQLMapper
<http://www.jnetdirect.com/products.php?op=jsqlmapper> (free reg
required).
- Nagios <http://www.nagios.org/about.php>, an open source host, service
and network monitoring program that runs under Linux.
- Eval versions of a variety of interesting-sounding controls
<http://www.9rays.net/cgi-bin/components_downloads.cgi> (though I
haven't tried any yet), including Instrumentation Widgets for Mobile
Devices.
- Eval version of Intel's (was Digital's) Visual Fortran 8.0
<http://www.intel.com/software/products/compilers/fwin/>.
- Free SOA editor <http://www.capescience.com/soa/> from Cape Clear.
- GOF patterns in C# <http://www.dofactory.com/Patterns/Patterns.aspx>.

Misc
- Advantage CA-Datacom 11.0 available
<http://www3.ca.com/Solutions/ProductFamily.asp?ID=118>. ("Venerable"
mainframe DBMS that offers extremely high performance). (CA also owns
Ingres <http://www3.ca.com/Solutions/Product.asp?ID=1013>).
- Windows applications equivalents under Linux
<http://linuxshop.ru/linuxbegin/win-lin-soft-en/table.shtml>.
- Did you know that Project Green
//www.eweek.com/article2/0,4149,1556268,00.asp?kc=EWRSS03119TX1K0000594>
refers to Microsoft's initiative to bring its four business application
suites (Great Plains, Solomon, Navision, and Axapta) together on a
single code base?

Related: new release of Great Plains 8.0
<http://www.eweek.com/article2/0,1759,1552532,00.asp>.
- According to Wayne Eckerson, the director of education and research
for The Data Warehousing Institute <http://www.tdwi.com>, we should
expect more consolidation in the BI industry (similar to Business
Objects' acquisition of Crystal Decisions), more focus on dashboards and
backlash against ad hoc BI, and, yes, more BI outsourcing.
- Oracle and Dell have banded together to supply users with relatively
inexpensive Dell servers pre-loaded with Oracle
<http://www1.us.dell.com/content/topics/global.aspx/licensing/en/oracle_program598?c=us&cs=555&l=en&s=biz>.

- My sister turns 50 this year, but it's also the 50th anniversary of
the first shopping mall (Victor Gruen's Southdale Shopping Center in
Edina, MN) and also the 50th anniversary of Roger Bannister's
sub-four-minute mile
<http://news.bbc.co.uk/sport1/hi/athletics/3594179.stm>.
- New US acronym: RINO = Republican in name only
<http://www.wordspy.com/words/rino.asp>. Related: 60 Seconds with Paul
McFedries <http://www.fastcompany.com/magazine/79/qa.html>.
- Zooland <http://surf.de.uu.net/zooland/> - "the artificial life
resource."
- New York Botanical Garden's Digital Imaging Project
<http://sciweb.nybg.org/science2/herbarium_imaging/home.asp>.
- View any of more than 2300 scientific visualizations from NASA's
Scientific Visualization Studio
<http://svs.gsfc.nasa.gov/search/Keywords/index.html>. And not just
space - many about Antarctica, for example.
- The December 2003 issue of HBR had an interesting short article on the
"gurus' gurus." Top picks: Peter Drucker <http://www.peter-drucker.com/>
(no surprise), James March
<http://gobi.stanford.edu/facultybios/bio.asp?ID=190> (a social
scientist at Stanford), Herbert Simon
<http://www.nobel.se/economics/laureates/1978/simon-autobio.html> (Nobel
laureate economist and social scientist who died in 2001), and Paul
Lawrence <http://hbswk.hbs.edu/item.jhtml?id=3567&t=organizations> (org
researcher at Harvard Business School).
- DestinationCRM recently summarized Gartner's 2004 CRM MarketScope for
Midsize Enterprises. Garnering positive ratings were Best Software's
Sales Logix, Onyx Software, and Salesforce.com.
- New card deck 52 Most Dangerous Liberals in America
<http://www.nrbookservice.com/BookPage.asp?prod_cd=c6219> distributed by
William Buckley's "New Republic" :-)
- Good tutorial information on GIS
<http://www.innovativegis.com/basis/>.
- Earth science data (and info) <http://nssdc.gsfc.nasa.gov/earth/>.
- The English in India <http://www.harpers.org/TheEnglishInIndia.html>
(from the 10/1862 issue of Harper's New Monthly Magazine.)
==========
Archives:
    http://www.topica.com/lists/VBHelper
    http://www.topica.com/lists/VB6Helper
    http://www.topica.com/lists/VBNetHelper
    
http://www.vb-helper.com/cgi-bin/mojo/mojo.cgi?flavor=archive&list=VB_Helper_Newsletter


Post questions at:
    http://www.topica.com/lists/VBHelperQA
	
 Previous Message All Messages Next Message 
  Check It Out!

  Topica Channels
 Best of Topica
 Art & Design
 Books, Movies & TV
 Developers
 Food & Drink
 Health & Fitness
 Internet
 Music
 News & Information
 Personal Finance
 Personal Technology
 Small Business
 Software
 Sports
 Travel & Leisure
 Women & Family

  Start Your Own List!
Email lists are great for debating issues or publishing your views.
Start a List Today!

© 2001 Topica Inc. TFMB
Concerned about privacy? Topica is TrustE certified.
See our Privacy Policy.