Page 1 of 1

MASM - Creating a Hyperlink

#1 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 858
  • View blog
  • Posts: 2,284
  • Joined: 28-March 11

Posted 30 July 2011 - 07:49 PM

I am not good at writing docs, so we'll see how this goes. Question has come up frequently over the years - how to make a Hyplerlink? Well, you can use the SysLink control, but that is not available on all Windows versions. Here we will use a static control and a subclass.

You will need a basic understanding of MASM. Source is attached.

Somewhere in your startup code, create two fonts, one normal, and one underlined (Could be any attribute really, bold, big, small. One is for the normal static text, and the other is used for the mouse hover)

In your main Window proc, create your static control with SS_NOTIFY and save the returned handle.
        ;#####  Email Hyperlink
        invoke  CreateWindowEx, 
                    NULL, 
                    offset szWndClsStatic, 
                    offset szEmailText, 
                    WS_CHILD or WS_VISIBLE or SS_NOTIFY, 
                    88, 20, 
                    117, 17, 
                    hWin, 0, 
                    hInst, 0
        mov     hEmail, eax

The control is created with text saying: Send Gunner Mail but where is the URL going to be? All windows 4 bytes of space for us to use, so we are going to save a pointer to the URL there. Makes it easier to subclass a few controls and use the same proc.

        ;#####  URL is dif than text, save URL
        invoke  SetWindowLong, eax, GWL_USERDATA, offset szEmailURL
eax is the handle of the static control just created
Next, we will subclass the control:
        ;#####  Subclass control
        invoke  SetWindowLong, hEmail, GWL_WNDPROC, UrlProc
        mov     lpOrgStaticProc, eax


It is very important to save the address of the original static class proc. In the code attached, I create 2 controls and they will both use lpOrgStaticProc.

Almost done with the Main window proc, next we have to set and change the font colors and background and we do that by handling the msg WM_CTLCOLORSTATIC.
	.elseif eax==WM_CTLCOLORSTATIC
		mov     ecx, hEmail
		mov     edx, hWeb
		.if ecx == lParam || edx == lParam
			.if bMouseOver
				mov		eax, Red			
			.else
			    mov     eax, Yellow
			.endif
			invoke  SetTextColor, wParam, eax
			invoke  SetBkMode, wParam, TRANSPARENT
			mov		eax, hBrush
		.endif
		ret

What we are doing here is, if lParam equals our controls handles then we change the font color. Mouse over our control, we change the color to red, otherwise the color is yellow. For this example I used red and yellow, but to expand on this you can get the colors Explorer and IE uses for Links and Hover from the registry and use those.

Now, for our subclass proc:
UrlProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
local   rect:RECT

	mov		eax,uMsg
	.if eax == WM_MOUSEMOVE
	    invoke  GetClientRect, hWin, addr rect
		invoke  GetCapture
		;#####  Make sure the mouse is in our control
		.if eax != hWin
			mov		bMouseOver, TRUE
			invoke  SetCapture, hWin
			invoke  SendMessage, hWin, WM_SETFONT, hFontUl, TRUE
		.endif
		mov		edx,lParam
		movzx	eax,dx
		shr		edx,16
		.if eax > rect.right || edx > rect.bottom
		    ;#####  moved out of control
			mov		bMouseOver, FALSE
			invoke  ReleaseCapture
			invoke  SendMessage, hWin, WM_SETFONT, hFont, TRUE
		.endif

	.elseif eax == WM_LBUTTONUP
		mov		bMouseOver, FALSE
		invoke  ReleaseCapture
		invoke  SendMessage, hWin, WM_SETFONT, hFont, TRUE
		
		;#####  Get URL we stored with the control
		invoke  GetWindowLong, hWin, GWL_USERDATA
		invoke  ShellExecute, hMain, offset szShelOpen, eax, NULL, NULL, SW_SHOWNORMAL

	.elseif eax==WM_SETCURSOR
		invoke  LoadCursor, NULL, IDC_HAND
		invoke  SetCursor, eax
		
	.else
		invoke  CallWindowProc, lpOrgStaticProc, hWin, uMsg, wParam, lParam
		ret
	.endif
	xor		eax,eax
	ret
UrlProc endp

Basically, if the mouse is over our control, we change the font to underline and when the mouse is out of our control or after a click we change it back to normal.

Once we click on the "link" we have to get the address of the url we saved earlier, we do that with GetWindowLong and pass the returned address to ShellExecute.

We change the cursor to a hand (any cursor you want really) in WM_SETCURSOR

An important call in the subclass is to pass on the messages we are not handling to back to the OS with CallWindowProc.

All fairly simple.. play with the attached code (RadASM project file included) and have fun as I do with Assembly! :bananaman:

Attached File(s)



Is This A Good Question/Topic? 1
  • +

Replies To: MASM - Creating a Hyperlink

#2 calvinthedestroyer  Icon User is offline

  • D.I.C Lover

Reputation: 167
  • View blog
  • Posts: 1,911
  • Joined: 13-October 07

Posted 30 July 2011 - 08:24 PM

Nice tutorial.
What version of MASM/Windows is this for?
Was This Post Helpful? 0
  • +
  • -

#3 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 858
  • View blog
  • Posts: 2,284
  • Joined: 28-March 11

Posted 30 July 2011 - 09:50 PM

Should be good down to 95, developed on Win7 x86. Using ml 6.15.8803
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1