Access Migration: Stolperstein “Benutzerdefinierte Toolbars”

Kürzlich habe ich bei einer Migration von Access2000 zu Access2007 festgestellt, dass eine in Access 2000 benutzerdefinierte Toolbar in Access 2007 nicht unbedingt das zu erwartende Verhalten an den Tag legt.
Konkret wurde in der Access 2000 Version beim Öffnen von Berichten eine benutzerdefinierte Toolbar eingeblendet, die unter anderem auch einen Standard-Schließen Button hatte. Im Zuge der Migration nach 2007 fiel dann auf, dass dieser Standard-Schließen Button nicht mehr funktioniert.
Ich habe mir dann mit einem kleinen Workaround geholfen, der zwar nicht wirklich elegant ist, aber in Anbetracht der begrenzten Anzahl von Reports in dieser Applikation einen guten Dienst erweist und sich vor allem als Access 2000- und Access 2007-tauglich erweist.

Der Standard-Close-Button wurde entfernt, stattdessen ein Button in der Toolbar integriert, der ein Makro aufruf. Dieses Makro wiederrum ruft die folgende Funktion auf:

Public Function CloseCurrentReport()
    Dim vReport As Variant
    With CurrentProject
        For Each vReport In .AllReports
            If CurrentProject.AllReports(vReport.Name).IsLoaded Then
                DoCmd.Close acReport, vReport.Name, acSaveNo
                Exit For
            End If
        Next vReport
    End With
End Function

Manchmal muss man eben auch die Wege gehen, die nicht ganz so schick sind.

Ein weiterer Quick-And-Dirty Ansatz zur Einstellung des Dienstes gegen Windows Search Indexer im Akkubetrieb

Und hier wie versprochen der zweite Teil des Artikels „Quick-and-Dirty-Ansatz gegen Windows Search Indexer im Akkubetrieb“. Nun schauen wir uns noch das kleine Einstellungsprogramm an. Das Programm an sich ist vielleicht gar nicht so wirklich der Rede wert, weil alles was das Programm im Kern macht schon im ersten Teil erwähnt wurde:
– Werte in die Registry schreiben und lesen mit der Methode „GetSettings“.

Dennoch gibt eine kleine Vorstellung dieses Programms. Auch deswegen weil es neben dem Registry-Zugriff noch ein weiteres kleines Feature gibt, was sicherlich gut zu wissen ist. Ich spreche über die Technik, wie man ein Programm in der Tray verschwinden lässt und somit aus der Taskbar rausbekommt. Man sieht es jeden Tag, und eigentlich ist es auch kein Hexenwerk… wie immer mit der Einschränkung „wenn man weiß wie es geht“. Also frisch ans Werk:
Ich habe ein Formular gebaut, welches zwei Controls enthält um die Werte für unseren Anti-Search-Indexer bearbeitbar zu machen. Zum einen eine Checkbox um dem Dienst zu sagen ob er überhaupt losrennen soll oder nicht und zum anderen eine Textbox in der man die Sekunden eintragen kann, die die Länge eines PollIntervalls definiert.
Neben einem Savebutton und einem NotifierIcon (aus der Toolbox) ist das auch alles, was wir brauchen. Wer es ein wenig hübscher mag – so wie ich – wird sich damit natürlich nicht zufrieden geben und das Formular noch ein wenig „pimpen“, aber das ist Kür.
Entscheidend sind nun zwei Funktionalitäten.

Speichern und Laden
Im Form-Load rufe ich die Funktion „LoadInputValues“ auf. Die Funktion holt sich die Werte aus der Registry und initialisiert damit die entsprechenden Controls im Formular. Ein schicker Zweizeiler.

    Public Sub LoadInputValues()
        Me.txtPollInterval.Text = GetSetting(Application.ProductName, "Parameters", "PollInterval", "10")
        Me.cbIsRunning.Checked = GetSetting(Application.ProductName, "Parameters", "IsRunning", True)
    End Sub

Das Speichern ist analog. Hier für gibt es die Funktion „SaveInputValues“ die im Click-Event des Save-Buttons aufgerufen wird. Als Argument gebe ich das aufrufende Formular (Me) mit um prüfen zu können, in welchem State sich das Formular befindet. Denn nur wenn das Fenster „normal“ ist, soll auch gespeichert werden.
Die Weitergabe von „Me“ ist natürlich in dem Beispiel umgehbar. Bei einem Quick-And-Dirty-Attempt darf man das ruhig mal so machen :)

    Public Sub SaveInputValues(ByVal FormInUse As Form)
        If FormInUse.WindowState.ToString = "Normal" Then
            SaveSetting(Application.ProductName, "Parameters", "PollInterval", Me.txtPollInterval.Text.ToString)
            SaveSetting(Application.ProductName, "Parameters", "IsRunning", Me.cbIsRunning.Checked.ToString)
        End If
    End Sub

Formular anzeigen und in Tray minimieren
Hierzu brauchen wir nur zwei Zutaten. Zum einen müssen wir das Resize-Event programmieren und darüber hinaus müssen wir das NotifierIcon irgendwie beleben, sonst kriegen wir das Programm nicht mehr aus der Tray raus.

Zuerst werden wir uns um das Resize kümmern. Hier wird geprüft auf was für einen Resize-Status genau reagiert werden soll. Nur im Fall von „Minimize“ müssen wir was tun, denn in „Normal“ sind wir schon und „Maximize“ wurde bei mir Disabled bzw. per Dialog-Form als Option rausgenommen.
Soll das Fenster also Minimiert werden, verstecken wir das Formular schlicht und einfach mit „Hide“ und definieren, dass auch der Eintrag in der Taskbar nicht angezeigt werden soll. Dafür blenden wir aber das NotifierIcon ein.

    Private Sub fMain_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        'resize
        If Me.WindowState = FormWindowState.Minimized Then
            Me.ShowInTaskbar = False
            Me.Hide()
            Me.NotifierIcon.Visible = True
        End If
    End Sub

Wie es weitergeht ist wohl schon jetzt ersichtlich. Wir müssen auf das NotifierIcon reagieren (Doppelclick) und dann das Formular wieder einblenden und in der Taskbar anzeigen. Das NotifierIcon blenden wir dann wieder aus. Um unser Formular auch wieder korrekt anzuzeigen, legen wir auch den WindowState fest.

    Private Sub NotifierIcon_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotifierIcon.DoubleClick
        'DoubleClick
        Me.Show()
        Me.WindowState = FormWindowState.Normal
        Me.ShowInTaskbar = True
        Me.NotifierIcon.Visible = False
    End Sub

Et voila. Schon sind wir durch. Kurz und schmerzlos: bis zum nächsten Eintrag.