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 szEmailURLeax 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!
Number of downloads: 401