I want to set a static control into a HyperLink, just like About of RadAsm. But the string in that static control disappear when it run. Here is the code sample:


LinkProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
pushad
mov eax,uMsg
.if eax==WM_LBUTTONUP
invoke ShellExecute,0,0,CTXT("http://www.vxer.net"),0,0,0
.elseif eax==WM_SETCURSOR
invoke SetCursor,hCur ;the hand cursor
.else
invoke GetWindowLong,hWin,GWL_USERDATA
mov ebx,eax
invoke CallWindowProc,ebx,hWin,uMsg,wParam,lParam
.endif
popad
mov eax,TRUE
ret
LinkProc endp

SetLinkProc proc
LOCAL _hWnd
pushad
invoke GetDlgItem,hDlg,IDC_STC_LINK
mov _hWnd,eax
invoke SetWindowLong,_hWnd,GWL_WNDPROC,addr LinkProc
invoke SetWindowLong,_hWnd,GWL_USERDATA,eax
popad
ret
SetLinkProc endp


What's wrong?
Posted on 2004-12-28 22:49:53 by dyna
Look at the MasmEd source.




/siddhartha
Posted on 2004-12-29 00:41:34 by siddhartha
When I add a manifest resource into the project, the string will disappear.
And if I delete the manifest, it's OK.
So I think the problem comes from the manifest resource.

That manifest is a XML file, to give software a XP-Style interface.
Here is the XP.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
name="Microsoft.Windows.Shell.ClassXP"
processorArchitecture="x86"
version="1.0.0.0"
type="win32"/>
<description>ClassXP</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>


Who knows how to solve the problem?
Posted on 2004-12-29 02:09:59 by dyna
Hi dyna

Nothing wrong with the manifest, a few bugs with your subclass proc.



.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive

include UrlControl.inc

.code

start:

invoke GetModuleHandle,NULL
mov hInstance,eax

invoke InitCommonControls
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
invoke ExitProcess,0

;########################################################################

LinkProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL buffer[256]:BYTE

mov eax,uMsg
.if eax==WM_LBUTTONUP
invoke GetWindowText,hWin,addr buffer,sizeof buffer
invoke ShellExecute,0,0,addr buffer,0,0,0
xor eax,eax
.elseif eax==WM_SETCURSOR
invoke LoadCursor,0,IDC_HAND
invoke SetCursor,eax ;the hand cursor
xor eax,eax
.else
invoke GetWindowLong,hWin,GWL_USERDATA
invoke CallWindowProc,eax,hWin,uMsg,wParam,lParam
.endif
ret

LinkProc endp

SetLinkProc proc hDlg:HWND
LOCAL _hWnd

invoke GetDlgItem,hDlg,1001
mov _hWnd,eax
invoke SetWindowLong,_hWnd,GWL_WNDPROC,addr LinkProc
invoke SetWindowLong,_hWnd,GWL_USERDATA,eax
ret

SetLinkProc endp

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg
.if eax==WM_INITDIALOG
invoke SetLinkProc,hWin
.elseif eax==WM_COMMAND
mov edx,wParam
movzx eax,dx
shr edx,16
.if edx==BN_CLICKED
.if eax==IDCANCEL
invoke SendMessage,hWin,WM_CLOSE,NULL,NULL
.endif
.endif
.elseif eax==WM_CLOSE
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

DlgProc endp

end start


KetilO
Posted on 2004-12-29 03:42:27 by KetilO
it works.

That means I should LoadCursor and SetCursor in the Contol's DlgProc, right? But why should return FALSE? (xor eax,eax) I tried set eax ==1, it's also OK.




thank u very much, Ketilo, every time I ask for help, u always helped me!
Posted on 2004-12-29 04:19:14 by dyna
another problem, or maybe an advice.
it seem's that if some registers value be changed in WndProc, it will crash on Windows2000.

For example:
i use New Project-->Win32 App-->DialogApp.tpl to build a exe file. It runs OK both in WinXP and Win2000.

Then I add some code like this:

.if eax==WM_INITDIALOG

mov ebx,123123
mov ecx,123123


Then the EXE file will crash on Win2000, but Ok on WinXP.
So I always change the template code by inject PUSHAD and POPAD.



DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
pushad
mov eax,uMsg
.if eax==WM_INITDIALOG
mov ebx,123123
mov ecx,123123
.elseif eax==WM_COMMAND

.elseif eax==WM_CLOSE
invoke EndDialog,hWin,0
.else
popad
mov eax,FALSE
ret
.endif
popad
mov eax,TRUE
ret
DlgProc endp


So i think u could change the template code for more compatibility.
I test this on Simplified Chinese Windows2000 and Windows XP.
Or maybe it's just my fool mistake. haha
Posted on 2004-12-29 04:53:40 by dyna
Hi dyna

Be careful what registers you use in a windows callback function. ebx,esi and edi must be preserved. Also the return value from a callback is important. The LoadCursor function has nothing to do with it.

Preserving registers in a callback:



DlgProc proc uses ebx esi edi,hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM


KetilO
Posted on 2004-12-29 05:31:38 by KetilO
thank u for the answer.
Because I'm not good at GDI programming, I seldom wrote programs with interface. :cry:

The last question(hope not bother u :oops: )

How can I change the color of the text in a static control,when mouse moves in and change the color back when mouse move elsewhere?
Just like RadASM About, it becomes blue with underline.

I'v read some source code, but they all use DrawText directly, not a static control.

can u help me? or give me some sample code?

best wishes for u!
Posted on 2004-12-29 09:13:40 by dyna
Hi dyna



IDD_DLGABOUT equ 4900
IDC_EDTABOUT equ 1001
IDC_URL equ 1002

.data?

OldUrlProc dd ?
fMouseOver dd ?
hUrlFont dd ?
hUrlFontU dd ?
hUrlBrush dd ?

.code

UrlProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rect:RECT
LOCAL buffer[128]:BYTE

mov eax,uMsg
.if eax==WM_MOUSEMOVE
invoke GetClientRect,hWin,addr rect
invoke GetCapture
.if eax!=hWin
mov fMouseOver,TRUE
invoke SetCapture,hWin
invoke SendMessage,hWin,WM_SETFONT,hUrlFontU,TRUE
.endif
mov edx,lParam
movzx eax,dx
shr edx,16
.if eax>rect.right || edx>rect.bottom
mov fMouseOver,FALSE
invoke ReleaseCapture
invoke SendMessage,hWin,WM_SETFONT,hUrlFont,TRUE
.endif
.elseif eax==WM_LBUTTONUP
mov fMouseOver,FALSE
invoke ReleaseCapture
invoke SendMessage,hWin,WM_SETFONT,hUrlFont,TRUE
invoke GetWindowText,hWin,addr buffer,sizeof buffer
invoke ShellExecute,hWnd,addr iniOpen,addr buffer,NULL,NULL,SW_SHOWNORMAL
.elseif eax==WM_SETCURSOR
invoke LoadCursor,NULL,IDC_HAND
invoke SetCursor,eax
.else
invoke CallWindowProc,OldUrlProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret

UrlProc endp

AboutProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL lf:LOGFONT

mov eax,uMsg
.if eax==WM_INITDIALOG
invoke SetWindowText,hWin,addr AppName
invoke SendDlgItemMessage,hWin,IDC_EDTABOUT,WM_SETTEXT,0,addr AboutMsg
invoke SendDlgItemMessage,hWin,IDC_URL,WM_SETTEXT,0,addr AboutUrl
invoke GetDlgItem,hWin,IDC_URL
invoke SetWindowLong,eax,GWL_WNDPROC,addr UrlProc
mov OldUrlProc,eax
invoke SendMessage,hWin,WM_GETFONT,0,0
mov hUrlFont,eax
invoke GetObject,hUrlFont,sizeof LOGFONT,addr lf
mov lf.lfUnderline, TRUE
invoke CreateFontIndirect,addr lf
mov hUrlFontU,eax
invoke GetSysColor,COLOR_3DFACE
invoke CreateSolidBrush,eax
mov hUrlBrush,eax
.elseif eax==WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
and eax,0FFFFh
.if edx==BN_CLICKED
.if eax==IDOK
invoke SendMessage,hWin,WM_CLOSE,NULL,NULL
.endif
.endif
.elseif eax==WM_CTLCOLORSTATIC
invoke GetDlgItem,hWin,IDC_URL
mov edx,eax
xor eax,eax
.if edx==lParam
.if fMouseOver
mov eax,0FF0000h
.endif
invoke SetTextColor,wParam,eax
invoke SetBkMode,wParam,TRANSPARENT
mov eax,hUrlBrush
.endif
ret
.elseif eax==WM_CLOSE
invoke DeleteObject,hUrlFontU
invoke DeleteObject,hUrlBrush
invoke EndDialog,hWin,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

AboutProc endp

This is things you can download from my website.

KetilO
Posted on 2004-12-29 14:22:00 by KetilO
thank you KetilO, i succeed.
Hope it's not too late to say: Merry Christmas and Happy New Year!
Posted on 2004-12-29 21:52:49 by dyna