Create a geoprocessing tool to buffer a layer and retrieve messages
BufferDlg.vb
' Copyright 2010 ESRI
' 
' All rights reserved under the copyright laws of the United States
' and applicable international laws, treaties, and conventions.
' 
' You may freely redistribute and use this sample code, with or
' without modification, provided you include the original copyright
' notice and use restrictions.
' 
' See the use restrictions.
' 

Imports Microsoft.VisualBasic
Imports System
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Geoprocessor
Imports ESRI.ArcGIS.Geoprocessing
Imports ESRI.ArcGIS.AnalysisTools

Partial Public Class BufferDlg : Inherits Form
  'in order to scroll the messages textbox to the bottom we must import this Win32 call
  <DllImport("user32.dll")> _
  Private Shared Function PostMessage(ByVal wnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
  End Function

  Private m_hookHelper As IHookHelper = Nothing
  Private Const WM_VSCROLL As UInteger = &H115
  Private Const SB_BOTTOM As UInteger = 7

  Public Sub New(ByVal hookHelper As IHookHelper)
    InitializeComponent()

    m_hookHelper = hookHelper
  End Sub

  Private Sub bufferDlg_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    If Nothing Is m_hookHelper OrElse Nothing Is m_hookHelper.Hook OrElse 0 = m_hookHelper.FocusMap.LayerCount Then
      Return
    End If

    'load all the feature layers in the map to the layers combo
    Dim layers As IEnumLayer = GetLayers()
    layers.Reset()
    Dim layer As ILayer = layers.Next()
    Do While Not layer Is Nothing
      cboLayers.Items.Add(layer.Name)
      layer = layers.Next()
    Loop
    'select the first layer
    If cboLayers.Items.Count > 0 Then
      cboLayers.SelectedIndex = 0
    End If

    Dim tempDir As String = System.IO.Path.GetTempPath()
    txtOutputPath.Text = System.IO.Path.Combine(tempDir, (CStr(cboLayers.SelectedItem) & "_buffer.shp"))

    'set the default units of the buffer
    Dim units As Integer = Convert.ToInt32(m_hookHelper.FocusMap.MapUnits)
    cboUnits.SelectedIndex = units
  End Sub

  Private Sub btnOutputLayer_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOutputLayer.Click
    'set the output layer
    Dim saveDlg As SaveFileDialog = New SaveFileDialog()
    saveDlg.CheckPathExists = True
    saveDlg.Filter = "Shapefile (*.shp)|*.shp"
    saveDlg.OverwritePrompt = True
    saveDlg.Title = "Output Layer"
    saveDlg.RestoreDirectory = True
    saveDlg.FileName = CStr(cboLayers.SelectedItem) & "_buffer.shp"

    Dim dr As DialogResult = saveDlg.ShowDialog()
    If dr = System.Windows.Forms.DialogResult.OK Then
      txtOutputPath.Text = saveDlg.FileName
    End If
  End Sub

  Private Sub btnBuffer_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnBuffer.Click
    'make sure that all parameters are okay
    Dim bufferDistance As Double
    Double.TryParse(txtBufferDistance.Text, bufferDistance)
    If 0.0 = bufferDistance Then
      MessageBox.Show("Bad buffer distance!")
      Return
    End If

    If (Not System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(txtOutputPath.Text))) OrElse ".shp" <> System.IO.Path.GetExtension(txtOutputPath.Text) Then
      MessageBox.Show("Bad output filename!")
      Return
    End If

    If m_hookHelper.FocusMap.LayerCount = 0 Then
      Return
    End If

    'get the layer from the map
    Dim layer As IFeatureLayer = GetFeatureLayer(CStr(cboLayers.SelectedItem))
    If Nothing Is layer Then
      txtMessages.Text &= "Layer " & CStr(cboLayers.SelectedItem) & "cannot be found!" & Constants.vbCrLf
      Return
    End If

    'scroll the textbox to the bottom
    ScrollToBottom()
    'add message to the messages box
    txtMessages.Text &= "Buffering layer: " & layer.Name & Constants.vbCrLf

    txtMessages.Text += Constants.vbCrLf & "Get the geoprocessor. This might take a few seconds..." & Constants.vbCrLf
    txtMessages.Update()
    'get an instance of the geoprocessor
    Dim gp As ESRI.ArcGIS.Geoprocessor.Geoprocessor = New ESRI.ArcGIS.Geoprocessor.Geoprocessor()
    gp.OverwriteOutput = True
    txtMessages.Text &= "Buffering..." & Constants.vbCrLf
    txtMessages.Update()

    'create a new instance of a buffer tool
    Dim buffer As ESRI.ArcGIS.AnalysisTools.Buffer = New ESRI.ArcGIS.AnalysisTools.Buffer(layer, txtOutputPath.Text, CStr(bufferDistance) & " " & CStr(cboUnits.SelectedItem))
    'execute the buffer tool (very easy :-))
    Dim results As IGeoProcessorResult = CType(gp.Execute(buffer, Nothing), IGeoProcessorResult)
    If results.Status <> esriJobStatus.esriJobSucceeded Then
      txtMessages.Text &= "Failed to buffer layer: " & layer.Name & Constants.vbCrLf
    End If
    txtMessages.Text += ReturnMessages(gp)
    'scroll the textbox to the bottom
    ScrollToBottom()

    txtMessages.Text += Constants.vbCrLf & "Done." & Constants.vbCrLf
    txtMessages.Text &= "-----------------------------------------------------------------------------------------" & Constants.vbCrLf
    'scroll the textbox to the bottom
    ScrollToBottom()

  End Sub

  Private Function ReturnMessages(ByVal gp As ESRI.ArcGIS.Geoprocessor.Geoprocessor) As String
    Dim sb As StringBuilder = New StringBuilder()
    If gp.MessageCount > 0 Then
      Dim Count As Integer = 0
      Do While Count <= gp.MessageCount - 1
        System.Diagnostics.Trace.WriteLine(gp.GetMessage(Count))
        sb.AppendFormat("{0}" & Constants.vbLf, gp.GetMessage(Count))
        Count += 1
      Loop
    End If
    Return sb.ToString()
  End Function

  Private Function GetFeatureLayer(ByVal layerName As String) As IFeatureLayer
    'get the layers from the maps
    Dim layers As IEnumLayer = GetLayers()
    layers.Reset()

    Dim layer As ILayer = layers.Next()
    Do While Not layer Is Nothing
      If layer.Name = layerName Then
        Return TryCast(layer, IFeatureLayer)
      End If
      layer = layers.Next()
    Loop

    Return Nothing
  End Function

  Private Function GetLayers() As IEnumLayer
    Dim uid As UID = New UIDClass()
    uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"
    Dim layers As IEnumLayer = m_hookHelper.FocusMap.Layers(uid, True)

    Return layers
  End Function

  Private Sub ScrollToBottom()
    PostMessage(CType(txtMessages.Handle, IntPtr), WM_VSCROLL, CType(SB_BOTTOM, IntPtr), CType(IntPtr.Zero, IntPtr))
  End Sub
  Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCancel.Click
    Me.Close()
  End Sub
End Class