Textfeld einfügen ohne Rahmen/Rand

Wer häufig Textfelder in Word einfügt, wünscht sich früher oder später, die Umrandung des Feldes default ausschalten zu können, um nicht bei jedem einzelnen neuen Textfeld zuerst den Rand ausschalten zu müssen. Dafür bietet sich zunächst in der Symbolleiste Zeichnen im Dialogfeld Zeichnen die Option Als Standard für Autoform festlegen an. Leider funktioniert das nur so lange, bis ein Pfeil oder eine Linie einzufügen ist. Schaltet man nämlich für die Textfelder den Rand aus und definiert dies als Standard, so sind die folgenden Pfeile und Linien default nicht zu sehen, womit die Option für diesen Zweck definitiv unbrauchbar ist.

Die folgende Routine ist genau zu diesem Zweck gedacht: Sie fügt wie gewohnt ein Textfeld ein, das voreingestellt keinen Rahmen hat. Man bringt die Prozedur am besten in einem eigenen Modul unter und weist der Prozedur »NeuesTextfeld« z. B. eine → Schaltfläche in der Symbolleiste Zeichnen zu. Dann hat man bei jedem Textfeld die Wahl, ob mit oder ohne Rahmen.

Der grundlegende Code, der die Realisierung des lange gehegten Plans ermöglichte, stammt von → Peter Marchert (www.outlook-stuff.com), dem ich an dieser Stelle herzlich danke.
Der AddressOf-Operator, der die Nutzung auch unter MS Word 97 (Word 8, VBA 5) sicherstellt, wurde mir dankenswerterweise von MVP Max Kaffl (aka Nepumuk) zur Verfügung gestellt.
So ist die folgende Routine ein echtes Gemeinschaftswerk und läuft unter allen Word-Versionen ab Word 97 (Word 8).



Option Explicit   

#If VBA6 = False Then
'============================================================================
' Alternative um die AddressOf() -Fkt. unter Office 97 zu ersetzen
' bedingt kompiliert, damit auch unter VBA5 lauffähig
'============================================================================
Private Declare Function GetCurrentVbaProject Lib "vba332.dll" Alias "EbGetExecutingProj" ( _
ByRef hProject As Long) As Long Private Declare Function GetFuncID Lib "vba332.dll" Alias "TipGetFunctionId" ( _
ByVal hProject As Long, _
ByVal strFunctionName As String, _
ByRef strFunctionId As String) As Long Private Declare Function GetAddr Lib "vba332.dll" Alias "TipGetLpfnOfFunctionId" ( _
ByVal hProject As Long, _
ByVal strFunctionId As String, _
ByRef lpfn As Long) As Long #End If

'============================================================================
' Windowstimer setzen
'============================================================================
Declare Function SetTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) _
As Long '============================================================================
' Windowstimer löschen
'============================================================================
Declare Function KillTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long) As Long
Public Const lngAPITIMER As Long = &H10000
Public lngTIMERID As Long

#If VBA6 = False Then
Public Function AddrOf(strFuncName As String) As Long
' Nachbau von Max Kaffl aka Nepumuk für den Operator AddressOf aus VBA 6
' gibt den Funktionszeiger einer public VBA Funktion zurück
' Parameter: strFuncName ... Funktionsname
' Return: >0 Adresse, 0 Fehler
' Aufruf zb lFuncPtr& = AddrOf("MyPublicFunc")

Dim hProject As Long, lResult As Long, lpfn As Long
Dim strID As String, strFuncNameUnicode As String

Const NO_ERROR = 0
AddrOf = 0

' Konvert strFuncName Unicode
strFuncNameUnicode = StrConv(strFuncName, vbUnicode)

' Handle des VBA - Moduls holen
Call GetCurrentVbaProject(hProject)

If hProject <> 0 Then
' FunktionsID der VBA-Funktion ermitteln
lResult = GetFuncID(hProject, strFuncNameUnicode, strID)
If lResult = NO_ERROR Then
' Adresse des FunktionsID holen
lResult = GetAddr(hProject, strID, lpfn)
If lResult = NO_ERROR Then: AddrOf = lpfn
End If
End If

End Function
#End If

Sub NeuesTextfeld()
On Error Resume Next
'------------------------------------------------------------------------
' Ruft den Befehl Einfügen Textfeld auf.
'------------------------------------------------------------------------
CommandBars.FindControl(ID:=139).Execute
#If VBA6 = False Then
lngTIMERID = SetTimer(0, lngAPITIMER, 100, AddrOf("Timer_Procedure"))
#Else
lngTIMERID = SetTimer(0, lngAPITIMER, 100, AddressOf Timer_Procedure)
#End If
'------------------------------------------------------------------------
' Startet den Windowstimer und ruft alle 100 Millisekunden die Prozedur
' "Timer_Procedure" auf, die rote Anzeige für Syntax erscheint offenbar,
' weil AddressOf für andere Bezeichnung reserviert ist, läuft trotzdem.
'------------------------------------------------------------------------
End Sub

Public Sub Timer_Procedure()
On Error Resume Next
'------------------------------------------------------------------------
' Wenn die Markierung im Textfeld steht, ist das Textfeld eingefügt worden.
' Nun wird der Timer gelöscht, und es kann weitergehen mit dem Ausblenden des Randes.
' Dieser Teil und die Adaption stammen von Nora Richter aka Lisa.
'------------------------------------------------------------------------
If Selection.StoryType = wdTextFrameStory Then
KillTimer 0, lngTIMERID
With Selection
.ShapeRange.Line.Visible = msoFalse
.ShapeRange.TextFrame.MarginLeft = 0#
.ShapeRange.TextFrame.MarginRight = 0#
.ShapeRange.TextFrame.MarginTop = 0#
.ShapeRange.TextFrame.MarginBottom = 0#
.Collapse
End With
End If
End Sub
Schreibbüro Richter, Georg-Schumann-Str. 8, 04105 Leipzig, Tel.: (03 41) 59 008 95