• Keine Ergebnisse gefunden

Das SysLink-Control

Im Dokument Win32API-Tutorials für Delphi (Seite 154-158)

4. CommonControls

4.10. Das SysLink-Control

4.10.1. Das SysLink-Control erzeugen

Das SysLink-Control ist ein neues Common Control, das allerdings erst ab Windows XP zur Verfügung steht. Es erfordert außerdem eine Manifestdatei (beiliegend oder in den Ressourcen der Anwendung), damit die Common Controls 6.0 geladen werden können. Andernfalls sehen Sie das Control nicht.

Ihre Delphi-Version sollte natürlich auch aktuell genug sein. Ist dies nicht der Fall, dann nutzen Sie bitte die beiliegende Unit "CommCtrl_Fragment.pas", die alle notwendigen Deklarationen enthält.

Das Control bietet eine recht einfache Möglichkeit, Webseiten, Mailadressen usw. im Programm unterzubringen, wobei die typische Linkform genutzt wird. Technisch können Sie es am besten mit einem Label vergleichen, da auch zusätzlicher Text möglich ist:

Bevor Sie das Control erzeugen, müssen Sie die neue Klasse ICC_LINK_CLASS mit dem Befehl

"InitCommonControlsEx" initialisieren:

var icc: TInitCommonControlsEx = (

dwSize:sizeof(TInitCommonControlsEx);

dwICC:ICC_LINK_CLASS;);

begin

InitCommonControlsEx(icc);

{ ... } end;

Das PSDK sagt sogar, dass der Befehl "CoInitialize" aufzurufen ist. Es funktioniert interessanterweise aber auch ohne. Das Erzeugen des Controls geht dann wie üblich mit "CreateWindowEx" vonstatten. Als Klassenname ist

"SysLink" (bzw. die Konstante WC_LINK) anzugeben:

const

LINK_TEXT2 : widestring =

'Hier geht´s zu <a href=" http://www.microsoft.com">Microsoft</a>.' + #13#10 + 'Oder?';

hLink2 := CreateWindowExW(0,WC_LINK,pwidechar(LINK_TEXT2),WS_VISIBLE or WS_CHILD,

10,60,160,45,wnd,IDC_LCONTROL2,hInstance,nil);

An diesem Beispiel sehen Sie, dass die gewünschte URL wie in einer HTML-Seite angegeben wird. Das Control interpretiert in diesem Fall das Tag href und stellt den Text dazwischen als Link dar. Zu beachten ist aber, dass ich die Konstante als widestring deklariert habe und daher auch "CreateWindowExW" benutzen musste.

Neben href wird momentan vom Control nur noch id unterstützt, das Sie beispielsweise für interne Zwecke innerhalb der Anwendung verwenden können.

Hinweis

Beachten Sie in der o.g. Konstante LINK_TEXT2 bitte das Leerzeichen vor der URL. Geben Sie es nicht an, wird beim Auslesen der URL komischerweise das H entfernt, so dass aus der Webadresse "ttp://www.microsoft.com" wird. Der Grund für dieses merkwürdige Verhalten ist mir leider unbekannt. Darauf hinweisen möchte ich Sie, auch wenn es sich dabei um einen Denkfehler von mir handeln sollte. (Oder vielleicht gerade deshalb.)

Bei der Benutzung des id-Tags passiert das übrigens nicht. Hier ist das Leerzeichen nicht erforderlich, und die ID wird dennoch komplett erkannt.

'<a id="Hallo">Hallo</a>'

4.10.2. Mehrere Links in einem Control

Jedes SysLink-Control unterstützt mehr als einen Link. Im obigen Quellcodeausschnitt haben wir lediglich eine Webseite angegeben. Das Beispielprogramm erzeugt aber vorher bereits ein anderes SysLink-Control, das zwei verschiedene id -Links enthält.

LINK_TEXT1 = 'Oft zitiert: <a id="Hallo">Hallo</a>, ' + #13#10 + '<a id="Welt">Welt</a>.';

Jeder Link besitzt seinen eigenen internen Indexwert, der in jedem Control bei Null beginnt. Aus diesem Grund besitzen die anfangs gezeigte URL (www.microsoft.com) und der hier zu sehende id-Link "Hallo" beide den Index Null.

4.10.3. Klick und Hopp!

Wenn Sie das Control benutzen, wird die Nachricht "WM_NOTIFY" an Ihre Anwendung gesendet. Die code-Membervariable gibt dabei an, ob es sich um einen Klick oder um das Ergebnis der Enter-Taste handelt:

WM_NOTIFY:

case PNMHdr(lp)^.code of NM_RETURN,

NM_CLICK:

{ ... } end;

Sie haben nun die Möglichkeit, mit den internen Indexwerten oder mit den IDs und URLs zu arbeiten. Empfehlenswert ist natürlich die Auswertung der Indexes, da sich diese nicht ändern. Im Beispielprogramm wird Ihnen beim Klick auf die Links lediglich die ID bzw. URL angezeigt, daher wollen wir hier ein detailliertes (aber fiktives) Beispiel machen.

Nehmen wir also an, wenn der Anwender auf die beiden Links "Hallo" und "Welt" klickt, sollen interne Programmfunktionen ausgelöst werden, die in dem Fall durch Dialogboxen simuliert werden:

if(hwndFrom = hLink1) then

case PNMLink(lp)^.item.iLink of

0: MessageBox(wnd,'Aktion 1','Hallo',0);

1: MessageBox(wnd,'Aktion 2','Welt!',0);

end;

Etwas interessanter wird es allerdings, wenn Sie die IDs direkt vergleichen. Da Sie mit Hilfe des Beispielprogramms die ID des Links "Hallo" ändern können, reagiert dieser also je nach Situation unterschiedlich:

if(lstrcmpW(PNMLink(lp)^.item.szId,'Hallo') = 0) then MessageBox(wnd,'Aktion 1','Hallo',0)

else if(lstrcmpW(PNMLink(lp)^.item.szId,'Welt') = 0) then MessageBox(wnd,'Aktion 2','Welt!',0)

else if(lstrcmpW(PNMLink(lp)^.item.szId,'Morgenstund') = 0) then MessageBox(wnd,'Aktion 3','Hallo',0)

else

MessageBox(wnd,'Link ins Nichts?',nil,MB_ICONWARNING);

Die URL aus dem zweiten SysLink-Control leiten Sie dagegen ohne viel Aufhebens an den Standardbrowser Ihres Systems weiter. Da es sich bei der szUrl-Variablen um einen Unicode-String handelt, müssen Sie aber die entsprechende Funktion "ShellExecuteW" verwenden:

if(hwndFrom = hLink2) then

4.10.4. ID und URL eines Links ändern

Zum Ändern einer ID oder URL benötigen wir zuerst eine Variable vom Typ TLItem. Dieses Record erwartet zuerst in der mask-Membervariablen die Flags, die angeben, was wir ändern wollen. In jedem Fall muss das Flag LIF_ITEMINDEX gesetzt werden, da wir den jeweiligen Link über dessen internen Index ansprechen. Wollen wir die ID ändern, geben wir zusätzlich das Flag LIF_ITEMID an. Bei der Änderung der URL wäre stattdessen LIF_URL zu benutzen:

li.mask := LIF_ITEMINDEX or LIF_ITEMID;

Dann geben wir den Index des Links an, den wir ändern wollen:

li.iLink := 0;

Nun kopieren wir entweder die neue ID oder die neue URL in den jeweils dafür vorgesehenen Textpuffer des Records.

Weil es sich um widechar-Arrays handelt, ist "lstrcpyW" zu benutzen. Als Beispiel wollen wir einem Link eine neue ID zuweisen und benutzen dafür szId:

lstrcpyW(li.szId,'Morgenstund');

Bei einer neuen URL sähe die Anweisung so aus (beachten Sie, dass hier szUrl gefüllt wird):

lstrcpyW(li.szUrl,'http://www.borland.com');

Die neuen Einstellungen reichen wir dann mit Hilfe der Nachricht "LM_SETITEM" an das jeweilige SysLink-Control weiter.

SendMessage(hLink1,LM_SETITEM,0,LPARAM(@li));

Hinweis

Beachten Sie bitte, dass es auch möglich ist, einem href-Link eine neue ID zuzuweisen. Das macht zwar nicht viel Sinn, funktioniert aber.

li.mask := LIF_ITEMINDEX or LIF_ITEMID;

li.iLink := 0;

lstrcpyW(li.szId,'blabla');

SendMessage(hLink2,LM_SETITEM,0,LPARAM(@li));

In dem Fall hätte nun der URL-Link des zweiten SysLink-Controls die ID "blabla". Angezeigt wird allerdings (auf Grund der Auswertung im Beispielprogramm weiterhin die originale URL. Letztlich entscheiden Sie also, womit Sie arbeiten und was Sie ändern.

TLItem-Definition

typedef struct tagLITEM { UINT mask;

int iLink;

UINT state;

UINT stateMask;

WCHAR szID[MAX_LINKID_TEXT];

WCHAR szUrl[L_MAX_URL_LENGTH];

} LITEM

4.10.5. Text des SysLink-Controls ändern

Wenn Sie den Text des Controls komplett ändern wollen, dann benutzen Sie dazu die Unicode-Version des bereits bekannten Befehls "SetWindowText" ("SetWindowTextW"):

SetWindowTextW(hLink2,

'Das hier ist <a href=" http://www.borland.com">Borland</a>-Revier.');

Im Dokument Win32API-Tutorials für Delphi (Seite 154-158)