May 15, 2024, 04:31:16 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


TabbedMDI UI Template

Started by WayneA, October 05, 2010, 09:39:02 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

WayneA

October 05, 2010, 09:39:02 PM Last Edit: October 09, 2010, 02:33:33 AM by WayneA
$Include "windows.inc"
Declare Import,SetWindowSubclass(hWnd As UInt,pfnSubclass As UInt,uIdSubclass As UInt,dwRefData As UInt),Int
Declare Import,RemoveWindowSubclass(hWnd As UInt,pfnSubclass As UInt,uIdSubclass As UInt),Int
Declare Import,DefSubclassProc(hWnd As UInt,uMsg As UInt,wParam As UInt,lParam As UInt),UInt
AutoDefine "Off"
Dim wndMain,wndChild[1024] As Window
OpenWindow wndMain,0,0,640,480,@MaxBox|@MinBox|@Size|@MDIFrame|WS_CLIPCHILDREN,0,"Tabbed MDI Template",&wndMainProc
AttachMainMenu(wndMain)
InitTabbedMDI(wndMain)
AddChild(wndMain,wndChild)
WaitUntil IsWindowClosed wndMain
End

Sub wndMainProc
Select @Message
Case @IDCreate
SetWindowSubclass(wndMain.hWnd,&MDISubClass,1,&wndMain)
Case @IDControl
If @ControlID=1 And @NotifyCode=@TCN_SelChange Then
_SetFocus(tcGetItemData(wndMain,1,tcGetSelectedTab(wndMain,1)))
EndIf
Case @IDMenuPick
Select @MenuNum
Case 101 ' File->New
AddChild(wndMain,wndChild)
EndSelect
Case @IDCloseWindow
CloseWindow wndMain
EndSelect
EndSub

Sub MDISubClass(hWnd As UInt,uMsg As UInt,wParam As UInt,lParam As UInt,uIdSubclass As UInt,dwRefData As UInt),UInt
Dim hwndSave As UInt
Dim result As UInt
Select uMsg
Case WM_SIZE
hwndSave=*<Window>dwRefData.hClient
*<Window>dwRefData.hClient=0
result=DefSubclassProc(hWnd,uMsg,wParam,lParam)
*<Window>dwRefData.hClient=hwndSave
SizeTabbedMDI(wndMain)
Return result
Case WM_DESTROY
RemoveWindowSubclass(hWnd,&MDISubClass,1)
EndSelect
Return DefSubclassProc(hWnd,uMsg,wParam,lParam)
EndSub

Sub wndChildProc
Select @Message
Case @IDCreate
Control *<Window>@HitWindow,@Button,"Test",0,0,50,50,0,1
Case @IDControl
If @ControlID=1 And @NotifyCode=0 Then
MessageBox *<Window>@HitWindow,GetCaption(*<Window>@HitWindow),"Test"
EndIf
Case WM_SETFOCUS
LitChild(wndMain,*<Window>@HitWindow)
Case @IDCloseWindow
RemChild(wndMain,*<Window>@HitWindow)
EndSelect
EndSub

Sub AddChild(parent As Window,child[] As Window),Int
Dim i,c As Int
For i=0 to 1023
If IsWindowClosed(child[i]) Then
OpenWindow child[i],@UseDefault,0,0,0,@MaxBox|@MinBox|@Size,wndMain,Using("Child #",i),&wndChildProc
c=tcGetTabCount(parent,1)
tcInsertTab parent,1,c,Using("Child #",i)
tcSetItemData parent,1,c,child[i].hWnd
'tcSetSelectedTab(parent,1,i) This didn't work if the tabs aren't in order.
LitChild(parent,child[i])
Return i
EndIf
Next i
Return -1
EndSub

Sub RemChild(parent As Window,child As Window),Int
Dim i As Int
For i=0 to 1023
If tcGetItemData(parent,1,i)=child.hWnd Then
tcDeleteTab(parent,1,i)
CloseWindow child
Return i
EndIf
Next i
Return -1
EndSub

Sub LitChild(parent As Window,child As Window),Int
Dim i As Int
For i=0 to 1023
If tcGetItemData(parent,1,i)=child.hWnd Then
tcSetSelectedTab(parent,1,i)
Return i
EndIf
Next i
Return -1
EndSub

Sub InitTabbedMDI(win As Window)
Dim l,t,w,h As Int
GetClientSize win,l,t,w,h
h-=AttachStatusBar(win,null)
_MoveWindow(win.hClient,0,25,w,h-25,True)
TabControl win,0,0,0,0,@TCS_Tabs,0,1
SetFont win,"Courier New",8,400,0,1
SetSize win,0,0,w,25,1
EndSub

Sub SizeTabbedMDI(win As Window)
Dim l,t,w,h As Int
GetClientSize win,l,t,w,h
h-=ResizeStatusBar(win,w,null)
_MoveWindow(win.hClient,0,25,w,h-25,True)
SetSize win,0,0,w,25,1
EndSub

Sub AttachMainMenu(win As Window)
BeginInsertMenu win,0
MenuTitle "&File"
MenuItem "&New\tCtrl+N",0,101
Separator
MenuItem "&Open\tCtrl+O",0,102
MenuItem "&Save\tCtrl+S",0,103
MenuItem "Save As...",0,104
Separator
MenuItem "E&xit\tAlt+F4",0,999
EndMenu
AddAccelerator win,@FControl|@FVirtKey,Asc("N"),101
AddAccelerator win,@FControl|@FVirtKey,Asc("O"),102
AddAccelerator win,@FControl|@FVirtKey,Asc("S"),103
EndSub

Sub AttachStatusBar(win As Window,Opt nPanes=0 As Int,...),Int
Dim i,iPanes[128] As Int
Dim pArgs As Pointer
Dim l,t,w,h As UInt
Control win,@Status,"",0,0,0,0,0,999
If nPanes Then
pArgs=VA_Start(nPanes)
nPanes=IIf(nPanes>128,128,nPanes)
For i=0 to nPanes-1
iPanes[i]=*<Int>(pArgs+(i*4))
Next i
ControlCMD(win,999,@SWSetPanes,nPanes,iPanes)
EndIf
ControlCMD(win,999,@SWResize)
GetSize win,l,t,w,h,999
Return h
EndSub

Sub ResizeStatusBar(win As Window,clientWidth As UInt,Opt nPanes=0 As Int,...),Int
Dim i,iPanes[128],tPane As Int
Dim pArgs As Pointer
Dim l,t,w,h As UInt
ControlCMD(win,999,@SWResize)
If nPanes Then
pArgs=VA_Start(nPanes)
nPanes=IIf(nPanes>128,128,nPanes)
For i=0 to nPanes-1
tPane=*<Int>(pArgs+(i*4))
iPanes[i]=IIf(tPane=-1,-1,clientWidth-tPane)
Next i
ControlCMD(win,999,@SWSetPanes,nPanes,iPanes)
EndIf
GetSize win,l,t,w,h,999
Return h
EndSub

Sub IIf(cond As Int,IfTrue As Int,IfFalse As Int),Int
Dim ret As Int
_asm
cmp dword [ebp+8],0
je .false
mov dword eax,[ebp+12]
mov dword [ebp+16],eax
.false:
mov dword eax,[ebp+16]
mov dword [ebp-4],eax
_endasm
Return ret
EndSub
99 little bugs in the code,
99 bugs in the code,
Fix one bug,
Compile again,
104 little bugs in the code...

All code I post is in the public domain.

ZeroDog

Nice.  Thanks.  :)

A manifest would make this look really nice.

mrainey

Software For Metalworking
http://closetolerancesoftware.com

Bruce Peaslee

Bruce Peaslee
"Born too loose."
iTired (There's a nap for that.)
Well, I headed for Las Vegas
Only made it out to Needles

WayneA

Updated the code. There was a bug that if the tabs got out of order and you opened a new window it would select the wrong tab.

Also, when I posted this I did it right after I uncommented a line that shouldn't be there (the @IDSize handler). Resizing is smoother when handled in the subclassed handler.

The keyboard accelerators don't work.. The children seem to get it instead of the parent. Might be easy to fix but I haven't toyed with it yet.
99 little bugs in the code,
99 bugs in the code,
Fix one bug,
Compile again,
104 little bugs in the code...

All code I post is in the public domain.