majkinetor has done it before and as HLink it is a part of his Forms Framework. Nevertheless I've written this class. The main advantage is, that it adjusts the controls height for a given width automatically. For all other details have a look at the inline documentation, please.
Class_SysLink_Control.ahk:
; ======================================================================================================================
; AHK 1.1.04 +
; ======================================================================================================================
; Function: Support for SysLink controls - http://msdn.microsoft.com/en-us/library/bb760704%28VS.85%29.aspx
; They may be useful in some cases, but they offer very few options for customizing.
; AHK version: 1.1.04.00 (U32)
; Language: English
; Tested on: Win XPSP3, Win VistaSP2 (32 Bit)
; Version: 0.0.02.03/2011-10-08/just me
; How to use: To create a new Syslink control use MySysLink := New SysLink_Control()
; passing up to four parameters:
; HGUI - HWND of the GUI (Pointer)
; Content - Text to show in the control (String)
; ----------- Optional ---------------------------------------------------------
; Options - Options for positioning and sizing (X, Y, W, H) (String)
; as used in "Gui, Add" command.
; Defaults: X - automatically positioned by GUI
; Y - automatically positioned by GUI
; W - 200
; H - 0 (the height will be adjusted to fit the text)
; The options "BackgroundTrans" and "Border" are supported also.
; Function - Function to be called on WM_NOTIFY messages (String)
; Default: "_SysLink_Notifications"
; On success - New returns an object with seven public keys:
; HWND - HWND of the control (Pointer)
; X - X-position (Integer)
; Y - Y-position (Integer)
; W - Width of the control (Integer)
; H - Height of the control (Integer)
; ID - Id of the control (>= 0x4000) (Integer)
; DUMMY - HWND of the GUI text control (Pointer)
; On failure - New returns False, ErrorLevel contains additional informations.
;
; To destroy the control afterwards simply assign an empty string or zero (e.g. MySysLink := "").
;
; Remarks: MSDN: "The SysLink control supports the anchor tag(<a>) along with the attributes HREF and ID.
; An HREF can be any protocol, such as http, ftp, and mailto. An ID is an optional name,
; unique within a SysLink control, and it is associated with an individual link.
; Links are also assigned a zero-based index according to their position within the string."
;
; The scripts provides the function _SysLink_Notifications() as default handler for
; NM_CLICK and NM_RETURN notifications (the only notifications associated with the control).
; This function only will run clicked URLs. If you want to do another action or to respond also
; to clicks on IDs, you have to pass the name of a function accepting exactly four parameters
; (Hwnd, Msg, wParam, lParam) to be called instead.
;
; This class is using Class_Notification.ahk from http://www.autohotkey.com/forum/topic75591.html
; because I think it makes things easier. If you want to handle other notifications in your script,
; you should use it too.
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
#include Class_Notification.ahk ; http://www.autohotkey.com/forum/topic75591.html
; ======================================================================================================================
Class SysLink_Control {
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE Properties and Methods ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; CONSTRUCTOR __New()
; ===================================================================================================================
__New(HGUI, Content, Options = "", Function = "") {
Global Notification
Static DefaultFunc := "_SysLink_Notifications"
Static INIT := False
Static HDEFFONT := 0
Static DEFAULT_GUI_FONT := 17
Static ICC_LINK_CLASS := 0x00008000
Static IDC_SYSLINK := 0x4000
Static WC_LINK := "SysLink"
Static LWS_TRANSPARENT := 0x0001
Static WM_USER := 0x400
Static LM_GETIDEALHEIGHT := (WM_USER + 0x301)
Static WM_SETFONT := 0x0030
Static WM_GETFONT := 0x0031
Static NM_FIRST := 0
Static NM_CLICK := (NM_FIRST-2)
Static NM_RETURN := (NM_FIRST-4)
Static WS_TABSTOP := 0x00010000
Static WS_BORDER := 0x00800000
Static WS_VISIBLE := 0x10000000
Static WS_CHILD := 0x40000000
Static DefaultW := 200
Static DefaultH := 0
If !(INIT) {
VarSetCapacity(ICCX, 8, 0)
NumPut(8, ICCX, 0, "UInt")
NumPut(ICC_LINK_CLASS, ICCX, 4, "UInt")
If !DllCall("Comctl32.dll\InitCommonControlsEx", "Ptr", &ICCX)
Return False
HDEFFONT := DllCall("Gdi32.dll\GetStockObject", "Int", DEFAULT_GUI_FONT)
INIT := True
}
If !DllCall("User32.dll\IsWindow", "UPtr", HGUI) {
ErrorLevel := "Invalid parameter HGUI: " . HGUI
Return False
}
If (Function <> "") {
If !IsFunc(Function) || (Func(Function).MaxParams <> 4) {
ErrorLevel := "Invalid parameter NotifyFunc: " . Function
Return False
}
} Else {
Function := DefaultFunc
}
W := DefaultW
H := DefaultH
Opts := {X: "", Y: "", W: "", H: ""}
Options := Trim(RegExReplace(Options, "\s+", " "))
SL_STYLES := WS_TABSTOP | WS_VISIBLE | WS_CHILD
Loop, Parse, Options, %A_Space%
{
If (A_LoopField = "BackgroundTrans") {
SL_STYLES |= LWS_TRANSPARENT
Continue
}
If (A_LoopField = "Border") {
SL_STYLES |= WS_BORDER
Continue
}
O := SubStr(A_LoopField, 1, 1)
If InStr("XYWH", O)
Opts[O] := A_LoopField
}
If (Opts.W <> "")
W := Opts.W
If (Opts.H <> "")
H := Opts.H
Options := Opts.X . " " . Opts.Y . " " . Opts.W . " " . Opts.H
Gui, %HGUI%:Add, Text, %Options% hwndHDUMMY, X
GuiControlGet, CP, Pos, %HDUMMY%
HFONT := DllCall("SendMessage", "Ptr", HDUMMY, "Int", WM_GETFONT, "Ptr", 0, "Ptr", 0, "UPtr")
If !(HFONT)
HFONT := HDEFFONT
X := CPX
Y := CPY
If (W = Opts.W)
W := CPW
If (H = Opts.H)
H := CPH
HSL := DllCall("CreateWindowExW", "UInt", 0, "WStr", WC_LINK, "WStr", Content, "UInt", SL_STYLES
, "Int", X, "Int", Y, "Int", W, "Int", H
, "Ptr", HGUI, "Ptr", IDC_SYSLINK, "Ptr", 0, "Ptr", 0, "Ptr")
If ((ErrorLevel) || !(HSL)) {
ErrorMsg := "Couldn't create SysLink control!`nErrorLevel: " . ErrorLevel . " - HWND: " . HSL
ErrorLevel := ErrorMsg
Return False
}
DllCall("SendMessage", "Ptr", HSL, "Int", WM_SETFONT, "Ptr", HFONT, "Ptr", False)
If (H = DefaultH) {
H := DllCall("SendMessage", "Ptr", HSL, "Int", LM_GETIDEALHEIGHT, "Ptr", W, "Ptr", 0)
DllCall("MoveWindow", "Ptr", HSL, "Int", X, "Int", Y, "Int", W, "Int", H, "Int", False)
If (H <> CPH)
Gui, %HGUI%:Add, Text, x%X% y%Y% w%W% h%H% hwndHDUMMY +BackgroundTrans
}
This.HWND := HSL
This.X := X
This.Y := Y
This.W := W
This.H := H
This.ID := IDC_SYSLINK
This.DUMMY := HDUMMY
IDC_SYSLINK += 1
Notification.Register(HSL, NM_CLICK, Function, "N")
Notification.Register(HSL, NM_RETURN, Function, "N")
}
; ===================================================================================================================
; DESTRUCTOR __Delete()
; ===================================================================================================================
__Delete() {
Global Notification
Static NM_FIRST := 0
Static NM_CLICK := (NM_FIRST-2)
Static NM_RETURN := (NM_FIRST-4)
If (This.HWND) {
Notification.Unregister(This.HWND, NM_CLICK)
Notification.Unregister(This.HWND, NM_RETURN)
DllCall("DestroyWindow", "Ptr", This.HWND)
}
}
}
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE Functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ======================================================================================================================
_SysLink_Notifications(Hwnd, Msg, wParam, lParam) {
; lParam is a pointer to a NMLINK structure containing NMHDR and LITEM structures
; -> http://msdn.microsoft.com/en-us/library/bb760714%28VS.85%29.aspx
Static NM_FIRST := 0
Static NM_CLICK := (NM_FIRST-2)
Static NM_RETURN := (NM_FIRST-4)
Static MAX_LINKID_TEXT := 48
Static L_MAX_URL_LENGTH := (2048 + 32 + 3) ; 3 : sizeof("://"))
Static OffHwnd := 0
Static OffID := OffHwnd + A_PtrSize
Static OffCode := OffID + A_PtrSize
Static OffLITEM := OffCode + 4
Static OffMask := OffLITEM
Static OffItem := OffMask + 4
Static OffState := OffItem + 4
Static OffStmask := OffState + 4
Static OffID := OffStmask + 4
Static OffUrl := OffID + (MAX_LINKID_TEXT * 2)
Url := StrGet(lParam + OffUrl, L_MAX_URL_LENGTH, "UTF-16")
If (Trim(URl))
Run, *Open %Url%
}
; ======================================================================================================================Small example:#NoEnv
#Include Class_SysLink_Control.ahk
Gui, New, +hwndHGUI +OwnDialogs, SysLink GUI
Gui, Margin, 20, 20
Gui, Color, 0xE0E0E0
Gui, Font, s12 q5, Courier New
TXT := "For more information about AutoHotkey <A HREF=""http://www.autohotkey.com/forum"">visit the forum</A>, please."
SLC := New SysLink_Control(HGUI, TXT, "w300 BackgroundTrans Border")
If !IsObject(SLC) {
MsgBox, Couldn't create SysLink control!`n%ErrorLevel%
ExitApp
}
Gui, Font
Gui, Font, s10 q5
Gui, Add, Edit, wp, Automatically positioned Edit!
Gui, Show
Return
GuiClose:
ExitApp:!: SysLink controls are using Unicode. I didn't test it with an ANSI version so I don't know whether the script will run flawlessly in this environment.New version on 2011-09-16:[*:21kx25k0]Note: Requires AHK 1.1.04+
[*:21kx25k0]Changed positioning and sizing to use an option string supporting common GUI options, so positioning and sizing will be done as expected for common GUI controls. In addition a transparent text control is added above the SysLink control to make GUI aware of the control.
[*:21kx25k0]Added new options BackgroundTrans and Border
[*:21kx25k0]Changed control's default font to default GUI font
[*:21kx25k0]Added new parameter Font to pass a font description string supporting the common Gui, Font syntax for size, weight, quality, and name.
[*:21kx25k0]Still only styles valid for WinXP are supported.Update on 2011-09-16: Sometimes things look more complicate than they are:[*:21kx25k0]Removed parameter font.
[*:21kx25k0]Changed controls's default behavior to use the current GUI font.
[*:21kx25k0]Updated script and sample.Update on 2011-10-09:[*:21kx25k0]Added new property DUMMY to yield the HWND of the associated GUI text control.




