;半年前发现有个控件能实现超链接(是汇编代码),当时没有保存代码,认为这是雕虫小技,何足挂齿。
;过后,用到超链接的,用按钮的功能实现。
;再过后,感觉有必要使用超链接控件。
;在网上搜索,大多是超类化或者子类话文本控件什么的,好烦。
;今天搜索到了,一定保存。
;后来发现在vs2008的工具栏上也有这个控件。
;在微软的msdn上看,需要先调用一个函数:InitCommonControlsEx。
;可这个函数始终失败!原来还需要设置:
;在汇编中解决的办法是在资源中加入一个xml文件,其内容见附后。
;在vs中是加入如下代码:
;// Enable Visual Style
;#if defined _M_IX86
;#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
;#elif defined _M_IA64
;#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
;#elif defined _M_X64
;#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
;#else
;#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
;#endif
;#pragma endregion
;实现后还要处理一些消息,有点小遗憾。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include comctl32.inc
includelib comctl32.lib
include shell32.inc
includelib shell32.lib
include gdi32.inc
includelib gdi32.lib
.data?
buffer db 512 dup (0) ;最好把报0换成 ?
.code
hInstance dd 0
hWinMain dd 0
szClassName db "made by correy",0
pwndclassex dd 48,3,offset liuchunli,0,0,0,0,0,6,0,offset szClassName,0
stMsg MSG <>
icex INITCOMMONCONTROLSEX <>
hLink dd 0
szSysLink dw "S","y","s","L","i","n","k",0
szhtml db "wellcome to my website:<a href="
db 34
db "http://correy.webs.com"
db 34
db ">乐观园"
db "</a>"
db 13,10 ;不可以"<br>";
db "If you have any problem, please email me:<a href="
db 34
db "mailto:leguanyuan@163.com"
db 34
db ">leguanyuan@126.com"
db "</a>"
db 13,10
db 0
hwndFrom dd 0
liuchunli proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
LOCAL hdc:HDC, ps:PAINTSTRUCT
.if uMsg == WM_CLOSE;放置后面会反应更快点。
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,0
.elseif uMsg == WM_CREATE
invoke lstrlen,addr szhtml
inc eax
invoke MultiByteToWideChar,CP_ACP, 0,addr szhtml,eax,addr buffer,256
invoke CreateWindowExW,200h,offset szSysLink,offset buffer, WS_CHILD or WS_VISIBLE or WS_TABSTOP,0,0,610,200,hWnd,9,hInstance,NULL
mov hLink,eax
.elseif uMsg == WM_NOTIFY
mov eax,dword ptr [lParam]
mov eax,[eax+8]
.if eax == 4 || eax == -2;NM_RETURN == -4 NM_CLICK == -2
mov eax,dword ptr [lParam]
mov eax,[eax]
mov hwndFrom,eax
mov eax,dword ptr [lParam]
mov eax,[eax+12+4] ;加一个NMHDR的大小,再加自己的位置。
mov esi,hwndFrom
mov edi,hLink
.if esi == edi || eax == 0
mov eax,dword ptr [lParam]
add eax,7ch; == 12+16+48*2;MAX_LINKID_TEXT == 48
invoke ShellExecuteW,hWnd,0,eax,0,0,SW_SHOWDEFAULT
.endif
;还有更多的结构属性,等待自己去发掘。
.endif
;.elseif uMsg == WM_PAINT ;此处的注释不删除,是个小知识点。
;invoke BeginPaint,hWnd,addr ps
;mov hdc,eax
;invoke SetTextColor,hdc,0000 ;这个数好像没有用,但没有,又不会显示。原来是上下两句不能少。也即是说,有这个消息,必须加那两行。
;invoke EndPaint,hWnd,addr ps
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret;不能去掉。
.endif
xor eax,eax;这两行可以去掉?
ret
liuchunli endp
start:
mov icex.dwSize , sizeof icex
mov icex.dwICC , ICC_LINK_CLASS
invoke InitCommonControlsEx,addr icex
invoke GetModuleHandle,0
mov hInstance,eax
mov pwndclassex+20,eax
invoke LoadCursor,0,32512;加载箭头鼠标。
mov pwndclassex+28,eax
;invoke GetStockObject,BLACK_BRUSH
;mov pwndclassex+32,eax
invoke RegisterClassEx,addr pwndclassex
invoke CreateWindowEx,200h,offset szClassName,offset szClassName,0Cf0000h,80000000h,80000000h,710,530,0,0,hInstance,0;0Ca0000h
mov hWinMain,eax
invoke ShowWindow,hWinMain,1;若不想显示,此行也可以去掉。
again:invoke GetMessage,addr stMsg,0,0,0
cmp eax,0
je exit
invoke DispatchMessage,addr stMsg
jmp again
exit:invoke ExitProcess,0
end start
;made at 2011.09.26
;xml文件的内容如下:根据情况,你可以再修改。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
</dependentAssembly>
</dependency>
</assembly>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;下面是子类化实现的。
.586
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\shell32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\shell32.lib
UrlProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
.data?
hInst DWORD ?
hFont DWORD ?
hFontUl DWORD ?
lpOrgStaticProc DWORD ?
lpOrgWebProc DWORD ?
hBrush DWORD ?
bMouseOver DWORD ?
msg MSG <?>
hEmail DWORD ?
hWeb DWORD ?
hMain DWORD ?
.code
start:
jmp @F
szWndClsMain BYTE "SSC_MAIN", 0
szWndClsStatic BYTE "STATIC", 0
szAppName BYTE "Static Subclass Example", 0
szEmailText BYTE "Send Gunner Mail", 0
szEmailURL BYTE "mailto://gunner@gunnerinc.com", 0
szWebText BYTE "Visit Gunners Webpage", 0
szWebURL BYTE "http://www.gunnerinc.com", 0
szShelOpen BYTE "open", 0
szFontName BYTE "Verdana", 0
@@:
call Startup
.while TRUE
invoke GetMessage, addr msg, NULL, 0, 0
.break .if !eax
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endw
mov eax, msg.message
invoke ExitProcess, eax
Startup proc uses ebx
LOCAL lfnt:LOGFONT
LOCAL wc:WNDCLASSEX
invoke GetModuleHandle, NULL
mov hInst, eax
;##### Create 2 fonts
invoke RtlZeroMemory, addr lfnt, sizeof LOGFONT
;##### Reg font
mov lfnt.lfHeight, -11
mov lfnt.lfWeight, FW_NORMAL
invoke szCatStr, addr lfnt.lfFaceName, offset szFontName
invoke CreateFontIndirect, addr lfnt
mov hFont, eax
;##### Bold font
mov lfnt.lfUnderline, TRUE
invoke CreateFontIndirect, addr lfnt
mov hFontUl, eax
;##### Register main window class
invoke RtlZeroMemory, addr wc, sizeof WNDCLASSEX
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, offset WndProcMain
push hInst
pop wc.hInstance
mov wc.hbrBackground, COLOR_HIGHLIGHT + 1; COLOR_3DFACE + 1
mov wc.lpszClassName, offset szWndClsMain
invoke LoadIcon, NULL, IDI_EXCLAMATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
;##### Coords to center window
invoke GetSystemMetrics, SM_CXSCREEN
sub eax, 300
shr eax, 1
xchg eax, ebx
invoke GetSystemMetrics, SM_CYSCREEN
sub eax, 123
shr eax, 1
;##### Create main window
invoke CreateWindowEx,
WS_EX_APPWINDOW or WS_EX_CONTROLPARENT,
offset szWndClsMain,
offset szAppName,
WS_OVERLAPPED or WS_SYSMENU or WS_MINIMIZEBOX or WS_VISIBLE,
ebx, eax,
300, 123,
HWND_DESKTOP, NULL,
hInst, NULL
mov hMain, eax
ret
Startup endp
WndProcMain proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
local rect:RECT
mov eax, uMsg
.if eax == WM_CREATE
;##### 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
;##### URL is dif than text, save URL
invoke SetWindowLong, eax, GWL_USERDATA, offset szEmailURL
;##### Subclass control
invoke SetWindowLong, hEmail, GWL_WNDPROC, UrlProc
mov lpOrgStaticProc, eax
invoke SendMessage, hEmail, WM_SETFONT, hFont, FALSE
;##### Web Hyperlink
invoke CreateWindowEx,
NULL,
offset szWndClsStatic,
offset szWebText,
WS_CHILD or WS_VISIBLE or SS_NOTIFY,
76, 60,
137, 17,
hWin, 0,
hInst, 0
mov hWeb, eax
;##### URL is dif than text, save URL
invoke SetWindowLong, eax, GWL_USERDATA, offset szWebURL
;##### Subclass control
invoke SetWindowLong, hWeb, GWL_WNDPROC, offset UrlProc
mov lpOrgStaticProc, eax
invoke SendMessage, hWeb, WM_SETFONT, hFont, FALSE
invoke GetSysColorBrush,COLOR_HIGHLIGHT ; COLOR_3DFACE
mov hBrush, eax
.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
.elseif eax == WM_CLOSE
invoke DeleteObject, hFont
invoke DeleteObject, hFontUl
invoke DeleteObject, hBrush
invoke DestroyWindow, hWin
.elseif eax == WM_DESTROY
invoke PostQuitMessage, NULL
.else
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
.endif
xor eax, eax
ret
WndProcMain endp
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
end start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
//下面是c/c++代码。
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#pragma comment(lib,"comctl32.lib")
#pragma comment( linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' \
version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"" )
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Baby Cat") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_LINK_CLASS;
InitCommonControlsEx(&icex);
if (!RegisterClass (&wndclass))
{
MessageBeep(0);
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("Tu Meo"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
static RECT rect ;
TEXTMETRIC tm;
static int cxClient, cyClient , cxChar , cyChar ;
static TCHAR szBuffer[1024];
static HWND hLink;
switch ( message ){
case WM_CREATE:
hLink = CreateWindow(WC_LINK,TEXT("For more Information <A Href=\"www.google.com\">Click Here</A> or ")\
TEXT("<A id=\"idInfo\">Here</A>"),WS_CHILD | WS_VISIBLE | WS_TABSTOP,0,0,300,200,hwnd,NULL,GetModuleHandle(0),NULL);
break;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
break;
case WM_NOTIFY:
{
LPNMHDR pp = (LPNMHDR)lParam;
switch ( pp->code ){
case NM_CLICK:
case NM_RETURN:
{
PNMLINK lp = (PNMLINK)lParam;
LITEM li = lp->item;
if ( pp->hwndFrom == hLink && li.iLink == 0 )
ShellExecute(hwnd,TEXT("Open"),li.szUrl,NULL,NULL,SW_SHOWDEFAULT);
else if( _tcscmp(li.szID,TEXT("idInfo")) == 0)
MessageBox(hwnd,TEXT("Allo"), TEXT("Test"), MB_OK );
}
break;
}
}
break;
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
return 0;
}
没有评论:
发表评论