Hi people! This is Iczelion MDI example.
format PE GUI 4.0
entry start
include 'win32a.inc'
MI_NEW = 40005
MI_CLOSE = 40006
MI_EXIT = 40001
MI_TILEHOR = 40002
MI_TILEVER = 40003
MI_CASCADE = 40004
section '.data' data readable writeable
insH dd ?
wndFH dd ?
wndCH dd ?
wndFTitle db 'Tutorial 32',0
wndMdiTitle db 'Mdi Child',0
wndFClsName db 'TUT_32',0
wndCClsName db 'MDICLIENT',0
wndMdiClsName db 'TUT_32_MDI',0
wndCCcs CLIENTCREATESTRUCT
wndMdiCs MDICREATESTRUCT
wndCls WNDCLASS
wndMsg MSG
wndFMenuH dd ?
wndMdiMenuH dd ?
msg1 db 'Are you sure you want to',13,10,'close this window ?',0
section '.code' code readable executable
start:
invoke GetModuleHandle,0
mov [insH],eax
mov [wndCls.hInstance],eax
mov [wndCls.style],CS_HREDRAW or CS_VREDRAW
mov [wndCls.lpfnWndProc],window_procedure
mov [wndCls.lpszClassName],wndFClsName
mov [wndCls.hbrBackground],COLOR_APPWORKSPACE
mov [wndCls.lpszMenuName],30
invoke LoadIcon,NULL,IDI_APPLICATION
mov [wndCls.hIcon],eax
invoke LoadCursor,NULL,IDC_ARROW
mov [wndCls.hCursor],eax
invoke RegisterClass,wndCls
mov [wndCls.lpszMenuName],NULL
mov [wndCls.lpfnWndProc],window_child_procedure
mov [wndCls.lpszClassName],wndMdiClsName
invoke RegisterClass,wndCls
invoke CreateWindowEx,WS_EX_CLIENTEDGE,wndFClsName,wndFTitle,\
WS_OVERLAPPEDWINDOW + WS_CLIPCHILDREN + WS_VISIBLE,\
CW_USEDEFAULT,CW_USEDEFAULT,500,320,\
NULL,NULL,[insH],NULL
mov [wndFH],eax
invoke LoadMenu,[insH],31
mov [wndMdiMenuH],eax
;+---------------------------+
;| entering the message loop |
;+---------------------------+
window_message_loop_start:
invoke GetMessage,wndMsg,NULL,0,0
or eax,eax
je window_message_loop_end
invoke TranslateMDISysAccel,[wndCH],wndMsg
or eax,eax
jne window_message_loop_start
invoke TranslateMessage,wndMsg
invoke DispatchMessage,wndMsg
jmp window_message_loop_start
window_message_loop_end:
invoke DestroyMenu,[wndMdiMenuH]
invoke ExitProcess,0
;+----------------------+
;| the window procedure |
;+----------------------+
proc window_procedure,hWnd,uMsg,wParam,lParam
push ebx esi edi
cmp [uMsg],WM_COMMAND
je wmCOMMAND
cmp [uMsg],WM_CREATE
je wmCREATE
cmp [uMsg],WM_DESTROY
je wmDESTROY
wmDEFAULT:
invoke DefFrameProc,[hWnd],[wndCH],[uMsg],[wParam],[lParam]
jmp wmBYE
wmCREATE:
invoke GetMenu,[hWnd]
mov [wndFMenuH],eax
invoke GetSubMenu,eax,1
mov [wndCCcs.hWindowMenu],eax
mov [wndCCcs.idFirstChild],100
invoke CreateWindowEx,NULL,wndCClsName,NULL,\
WS_CHILD + WS_CLIPCHILDREN + WS_VISIBLE,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,\
[hWnd],NULL,[insH],wndCCcs
mov [wndCH],eax
mov [wndMdiCs.szClass],wndMdiClsName
mov [wndMdiCs.szTitle],wndMdiTitle
push [insH]
pop [wndMdiCs.hOwner]
mov [wndMdiCs.x],CW_USEDEFAULT
mov [wndMdiCs.y],CW_USEDEFAULT
mov [wndMdiCs.cx],CW_USEDEFAULT
mov [wndMdiCs.cy],CW_USEDEFAULT
jmp wmBYE
wmCOMMAND:
cmp [wParam],0xFFFF and MI_EXIT
je wmCOMMAND_MI_EXIT
cmp [wParam],0xFFFF and MI_NEW
je wmCOMMAND_MI_NEW
cmp [wParam],0xFFFF and MI_TILEHOR
je wmCOMMAND_MI_TILEHOR
cmp [wParam],0xFFFF and MI_TILEVER
je wmCOMMAND_MI_TILEVER
cmp [wParam],0xFFFF and MI_CASCADE
je wmCOMMAND_MI_CASCADE
cmp [wParam],0xFFFF and MI_CLOSE
je wmCOMMAND_MI_CLOSE
jmp wmDEFAULT
wmCOMMAND_MI_NEW:
invoke SendMessage,[wndCH],WM_MDICREATE,0,wndMdiCs
jmp wmBYE
wmCOMMAND_MI_EXIT:
invoke SendMessage,[wndFH],WM_CLOSE,0,0
jmp wmBYE
wmCOMMAND_MI_TILEHOR:
invoke SendMessage,[wndCH],WM_MDITILE,MDITILE_HORIZONTAL,0
jmp wmBYE
wmCOMMAND_MI_TILEVER:
invoke SendMessage,[wndCH],WM_MDITILE,MDITILE_VERTICAL,0
jmp wmBYE
wmCOMMAND_MI_CASCADE:
invoke SendMessage,[wndCH],WM_MDICASCADE,MDITILE_SKIPDISABLED,0
jmp wmBYE
wmCOMMAND_MI_CLOSE:
invoke SendMessage,[wndCH],WM_MDIGETACTIVE,0,0
invoke SendMessage,eax,WM_CLOSE,0,0
jmp wmBYE
wmDESTROY:
invoke PostQuitMessage,0
wmBYE:
pop edi esi ebx
ret
endp
proc window_child_procedure,hWnd,uMsg,wParam,lParam
cmp [uMsg],WM_MDIACTIVATE
je wcmMDIACTIVATE
cmp [uMsg],WM_CLOSE
je wcmCLOSE
wcmDEFAULT:
invoke DefMDIChildProc,[hWnd],[uMsg],[wParam],[lParam]
ret
wcmMDIACTIVATE:
mov eax,[lParam]
cmp eax,[hWnd]
jne @f
invoke GetSubMenu,[wndMdiMenuH],1
invoke SendMessage,[wndCH],WM_MDISETMENU,[wndMdiMenuH],eax
jmp wcmMDIACTIVATE_EXIT
@@:
invoke GetSubMenu,[wndFMenuH],1
invoke SendMessage,[wndCH],WM_MDISETMENU,[wndFMenuH],eax
wcmMDIACTIVATE_EXIT:
invoke DrawMenuBar,[wndFH]
jmp wcmBYE
wcmCLOSE:
invoke MessageBox,[wndCH],msg1,wndFTitle,MB_YESNO
cmp eax,IDYES
jne wcmBYE
invoke SendMessage,[wndCH],WM_MDIDESTROY,[hWnd],0
wcmBYE:
ret
endp
section '.idata' import data readable
library KERNEL32, 'KERNEL32.DLL',\
USER32, 'USER32.DLL'
import KERNEL32,\
GetModuleHandle, 'GetModuleHandleA',\
ExitProcess, 'ExitProcess'
import USER32,\
RegisterClass, 'RegisterClassA',\
CreateWindowEx, 'CreateWindowExA',\
DefWindowProc, 'DefWindowProcA',\
LoadCursor, 'LoadCursorA',\
LoadIcon, 'LoadIconA',\
LoadMenu, 'LoadMenuA',\
DestroyMenu, 'DestroyMenu',\
GetMenu, 'GetMenu',\
GetSubMenu, 'GetSubMenu',\
DrawMenuBar, 'DrawMenuBar',\
SendMessage, 'SendMessageA',\
GetMessage, 'GetMessageA',\
MessageBox, 'MessageBoxA',\
DestroyWindow, 'DestroyWindow',\
DefFrameProc, 'DefFrameProcA',\
DefMDIChildProc, 'DefMDIChildProcA',\
TranslateMessage, 'TranslateMessage',\
TranslateMDISysAccel, 'TranslateMDISysAccel',\
DispatchMessage, 'DispatchMessageA',\
PostQuitMessage, 'PostQuitMessage'
section '.rsrc' resource data readable
LANG_NEUTRAL = 0x00
SUBLANG_NEUTRAL = 0x00
MFT_SEPARATOR = 0x800
MI_NEW = 40005
MI_CLOSE = 40006
MI_EXIT = 40001
MI_TILEHOR = 40002
MI_TILEVER = 40003
MI_CASCADE = 40004
30 MENUEX
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
{
POPUP "&File"
{
MENUITEM "&New", MI_NEW
MENUITEM "",0,MFT_SEPARATOR
MENUITEM "&Exit", MI_EXIT
}
POPUP "&Window"
{
MENUITEM "Tile Horizontal", MI_TILEHOR
MENUITEM "Tile Vertical", MI_TILEVER
MENUITEM "Cascade", MI_CASCADE
}
}
31 MENUEX
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
{
POPUP "&File"
{
MENUITEM "&New", MI_NEW
MENUITEM "&Close", MI_CLOSE
MENUITEM "",0,MFT_SEPARATOR
MENUITEM "&Exit", MI_EXIT
}
POPUP "&Window"
{
MENUITEM "Tile Horizontal", MI_TILEHOR
MENUITEM "Tile Vertical", MI_TILEVER
MENUITEM "Cascade", MI_CASCADE
}
}