Komfortabler Dateimanager mit vielen Funktionen

SysLink-Control unter Windows 2000

By Sven on 18.04.2008 - 10:00 in Windows SDK

Mit Hilfe des SysLink-Controls lassen sich anklickbare Hypertext-Elemente in einem Fenster darstellen. Die Formatierung des Textes erfolgt mit Hilfe von <a>anklickbarer Text</a>-Tags. Bei Aktivierung durch Maus oder Tastatur wird das Elternfenster informiert und es kann die jeweilige Aktion durchführen. Leider ist das SysLink-Control erst ab der ComCtl32.dll V6 enthalten und lässt sich so nur ab Windows XP verwenden.

Unter Windows 2000 gibt es ebenfalls ein SysLink-Control. Es ist aber nicht Bestandteil der ComCtl32.dll, die Implementierung erfolgt in der Shell32.dll. Mit Hilfe der Funktion LinkWindow_RegisterClass lässt sich das Control registrieren und verwenden. Der hauptsächliche Unterschied zum SysLink-Control von Windows XP ist der Name der Fensterklasse. Unter Windows XP heißt das Control SysLink, unter Windows 2000 Link Window. Zudem unterstützt die Windows 2000-Implementierung keine HREF und ID-Attribute innerhalb des Anchor-Tags.

Die verschiedenen Fensterklassen-Namen erschweren die Verwendung von SysLink-Controls in Dialogvorlagen. Der Dialog kann nur erzeugt werden, wenn alle verwendeten Fensterklassen registriert sind. Der Dialogeditor von Visual Studio verwendet SysLink als Fensterklasse, das verhindert aber die Anzeige des Dialogs unter Windows 2000.

Mit einem kleinen Trick lässt sich das Problem recht einfach lösen. Beim Start der Anwendung wird geprüft, ob die Fensterklasse SysLink existiert. Wenn nicht, dann wird mit Hilfe von LinkWindow_RegisterClass die Fensterklasse Link Window registriert. Anschließend ruft man die Fensterklassen-Daten für Link Window ab, ändert den Namen auf SysLink und registriert die Klasse unter dem neuen Namen. Nun kann man auch unter Windows 2000 mit SysLink arbeiten.

Das ganze sieht dann so aus:

BOOL RegisterCommonControls()
{
    // Common Controls initialisieren
    INITCOMMONCONTROLSEX initCCex;
    initCCex.dwSize = sizeof(initCCex);
    initCCex.dwICC = ICC_WIN95_CLASSES | ICC_LINK_CLASS;

    // Common Controls initialisieren
    InitCommonControlsEx(&initCCex);

    // Erfolg?
    BOOL fSuccess = FALSE;

    // Fensterklasse abrufen
    WNDCLASSW wndLinkClass;
    if (!GetClassInfoW(NULL, L"SysLink", &wndLinkClass))
    {
        // Registrierungsfunktion
        typedef BOOL (WINAPI* pfnLinkWindowRegisterProc)();

        // Shell32-Dll laden
        HINSTANCE hModShell32 = LoadLibraryW(L"shell32.dll");
        if (NULL != hModShell32)
        {
            // Funkion importieren
            pfnLinkWindowRegisterProc pfnLinkWindowRegister = reinterpret_cast<pfnLinkWindowRegisterProc>(GetProcAddress(hModShell32, MAKEINTRESOURCEA(258)));
            if (NULL != pfnLinkWindowRegister)
            {
                fSuccess = pfnLinkWindowRegister();
            }

            // Dll freigeben
            FreeLibrary(hModShell32);
        }

        // Fensterklasse fuer "Link Window" registriert
        if (fSuccess)
        {
            // Fensterklasse abrufen
            if (GetClassInfoW(NULL, L"Link Window", &wndLinkClass))
            {
                // Fensterklasse auf SysLink setzen
                wndLinkClass.lpszClassName = L"SysLink";

                // Fensterklasse registrieren
                if (!RegisterClassW(&wndLinkClass))
                {
                    fSuccess = FALSE;
                }
            }

            // Fehler beim Abruf der Fensterklasse
            else
            {
                fSuccess = FALSE;
            }
        }
    }

    // Fensterklasse existiert bereits
    else
    {
        fSuccess = TRUE;
    }

    // Erfolg
    return fSuccess;
}

Es gibt einen Kommentar zu diesem Beitrag

Trackback URL | RSS-Feed für Kommentare

  1. Oliver sagt:

    Coole Sache. Danke für die Infos un den Code. Leider muß ich bei WinDirStat noch ältere Systeme unterstützen. Aber wozu gibt es denn Subclassing.

Top