.386
.model flat, stdcall
option casemap :none

include windows.inc

incboth MACRO incl
	include incl.inc
	includelib incl.lib
ENDM

incboth kernel32
incboth user32
incboth gdi32
incboth shell32

.const
	IDD_MAINDIALOG			EQU					101
	
	IDM_ABOUT				EQU					101
	IDM_WEBLINK				EQU					102
	IDM_QUIT				EQU					103
	
	IDC_CURSOR				EQU					1001
	
	IDI_WORLDOFF			EQU					101
	IDI_WORLDON				EQU					102

.data?
	hInstance				HINSTANCE			?
	
	hCursor					HANDLE				?
	
	hIconWorldOff			HANDLE				?
	hIconWorldOn			HANDLE				?

.code

DlgProc		PROTO	hWnd:HWND, uMsg:DWORD, wParam:DWORD, lParam:DWORD

start:
	invoke GetModuleHandle, NULL
	mov hInstance, eax
	
	invoke DialogBoxParam, hInstance, IDD_MAINDIALOG, NULL, addr DlgProc, NULL

	invoke ExitProcess, NULL
	
;-------------------------------------------------------------------------------
.data
	szwin32asm			db				"http://win32asm.cjb.net",0
	szAboutCaption		db				"Menu Weblink",0
	szAboutText			db				"(c) Entro-P Jan 2000",13,10
						db				"mail: entro-p@asmz.com",13,10,13,10
						db				"This is not meant as an optimized example,",13,10
						db				"but merely a clear example on _how_ it is done!",0
	szQuitNow			db				"Quit now ?",0						
;-------------------------------------------------------------------------------

sSIZE	struct
	px		DWORD		?
	py		DWORD		?
sSIZE	ends

.code
DlgProc		PROC	hWnd:HWND, uMsg:DWORD, wParam:DWORD, lParam:DWORD
	local	mii					:MENUITEMINFO
	local	hMenu				:HANDLE
	local	r					:RECT
	local	lFont				:LOGFONT
	local	s					:sSIZE
	local	cxBitmap			:DWORD
	local	cyBitmap			:DWORD
	local	cyBitmapAdd			:DWORD

	.IF uMsg == WM_INITDIALOG
		invoke LoadIcon, hInstance, 1
		invoke SendMessage, hWnd, WM_SETICON, ICON_BIG, eax
		
		invoke LoadCursor, hInstance, IDC_CURSOR
		mov hCursor, eax
		invoke LoadIcon, hInstance, IDI_WORLDOFF
		mov hIconWorldOff, eax
		invoke LoadIcon, hInstance, IDI_WORLDON
		mov hIconWorldOn, eax
		
		invoke GetMenu, hWnd
		invoke GetSubMenu, eax, 0
		mov hMenu, eax
		mov mii.cbSize, SIZEOF mii
		mov mii.fMask, MIIM_TYPE 		
		invoke GetMenuItemInfo, hMenu, IDM_WEBLINK, FALSE, addr mii
		or mii.fType, MFT_OWNERDRAW
		invoke SetMenuItemInfo, hMenu, IDM_WEBLINK, FALSE, addr mii
		
	.ELSEIF uMsg == WM_COMMAND
		mov eax, wParam
		shr eax, 16
		.IF eax == BN_CLICKED
			mov eax, wParam
			and eax, 0FFFFh
			.IF eax == IDM_ABOUT
				invoke MessageBox, hWnd, addr szAboutText, addr szAboutCaption, MB_ICONINFORMATION + MB_OK
			.ELSEIF eax == IDM_WEBLINK
				invoke LoadCursor, NULL, IDC_WAIT
				invoke SetCursor, eax
				invoke ShellExecute, NULL, NULL, addr szwin32asm, NULL, NULL, NULL
			.ELSEIF eax == IDM_QUIT
				invoke SendMessage, hWnd, WM_CLOSE, NULL, NULL
			.ENDIF
		.ENDIF
	.ELSEIF uMsg == WM_MEASUREITEM
		.IF ! wParam ; menu
			push edi
			mov edi, lParam
			assume edi: ptr MEASUREITEMSTRUCT
			.IF [edi].itemID == IDM_WEBLINK		; menu --> win32asm.cjb.net
				invoke GetSystemMetrics, SM_CYMENUSIZE
				mov [edi].itemHeight, eax
				invoke GetWindowDC, hWnd
				push ebx
				mov ebx, eax
				invoke GetTextExtentPoint32, ebx, addr szwin32asm, (SIZEOF szwin32asm)-1, addr s
				mov ebx, eax
				mov eax, s.px
				sub eax, ebx
				pop ebx
				sub eax, 30	; wierd, found this in some docs, if there's any
							; items that i'm not drawing myself, then i windows
							; adds 30 to the highest WM_MEASUSEITEM result.  GO M$!!!!
				mov [edi].itemWidth, eax
			.ENDIF
			assume edi: nothing
			pop edi
		.ENDIF	
	.ELSEIF uMsg == WM_DRAWITEM
		.IF ! wParam ; menu
			push edi
			mov edi, lParam
			assume edi: ptr DRAWITEMSTRUCT
			.IF [edi].itemID == IDM_WEBLINK		; menu --> win32asm.cjb.net
				mov eax, [edi].itemAction
				push eax
				and eax, ODA_DRAWENTIRE
				mov eax, TRUE
				.IF eax ; must draw entire rect
					invoke DrawEdge, [edi].hdc, addr [edi].rcItem , NULL, BF_MIDDLE
					pop eax
					or eax, ODA_SELECT    ; force text redraw
					push eax
				.ENDIF

				invoke GetSystemMetrics, SM_CYMENUSIZE
				.IF eax > 16
					mov cyBitmapAdd, eax
					sub cyBitmapAdd, 16
					shr cyBitmapAdd, 1
					
					mov eax, 16
				.ELSE
					mov cyBitmapAdd, eax	
				.ENDIF
				mov cyBitmap, eax
				invoke GetSystemMetrics, SM_CXMENUSIZE
				.IF eax > 16
					mov eax, 16
				.ENDIF
				mov cxBitmap, eax

				pop eax
				and eax, ODA_SELECT
				.IF eax	; selection changed
					mov eax, [edi].itemState
					and eax, ODS_SELECTED	
					.IF eax	; selected
						inc [edi].rcItem.left
						mov eax, cyBitmapAdd 
						add [edi].rcItem.top, eax
						invoke DrawIconEx, [edi].hdc, [edi].rcItem.left, [edi].rcItem.top, hIconWorldOn, cxBitmap, cyBitmap, NULL, NULL, DI_NORMAL
						mov eax, cyBitmapAdd 
						sub [edi].rcItem.top, eax
						dec [edi].rcItem.left
						invoke SetCursor, hCursor
						invoke GetSysColor, COLOR_ACTIVECAPTION
						invoke SetTextColor, [edi].hdc, 00A00000h
					.ELSE 	; not selected
						inc [edi].rcItem.left
						mov eax, cyBitmapAdd 
						add [edi].rcItem.top, eax
						invoke DrawIconEx, [edi].hdc, [edi].rcItem.left, [edi].rcItem.top, hIconWorldOff, cxBitmap, cyBitmap, NULL, NULL, DI_NORMAL
						mov eax, cyBitmapAdd 
						sub [edi].rcItem.top, eax
						dec [edi].rcItem.left
						invoke LoadCursor, NULL, IDC_ARROW	
						invoke SetCursor, eax
						invoke GetSysColor, COLOR_WINDOWTEXT
						invoke SetTextColor, [edi].hdc, eax
					.ENDIF
					push eax ; old text colour
					
					invoke GetCurrentObject, [edi].hdc, OBJ_FONT
					push ebx
					mov ebx, eax
					invoke GetObject, ebx, SIZEOF lFont, addr lFont
					pop ebx
				    mov lFont.lfUnderline, TRUE
				    invoke CreateFontIndirect, addr lFont
					invoke SelectObject, [edi].hdc, eax
					push eax ; old font
					push [edi].rcItem.left
					mov eax, cyBitmap
					add eax, 3 ; text gap 3 pixels ( 2 + 1 )
					add [edi].rcItem.left, eax ; add button width
					invoke DrawText, [edi].hdc, addr szwin32asm, (SIZEOF szwin32asm)-1, addr [edi].rcItem, DT_VCENTER + DT_SINGLELINE
					pop [edi].rcItem.left
					pop eax ; old font
					invoke SelectObject, [edi].hdc, eax
					pop eax ; old text colour
					invoke SetTextColor, [edi].hdc, eax
				.ENDIF	
			.ENDIF			
			assume edi: nothing
			pop edi
		.ENDIF	
	.ELSEIF uMsg == WM_CLOSE
		invoke MessageBox, hWnd, addr szQuitNow, addr szAboutCaption, MB_ICONINFORMATION + MB_YESNO
		.IF eax == IDYES
			invoke EndDialog, hWnd, NULL
		.ENDIF	
	.ELSE
		xor eax, eax
		ret
	.ENDIF
	mov eax, TRUE
	ret
DlgProc		ENDP	

;-------------------------------------------------------------------------------

end start