MDI Application Beispiel

  • Hab mal ein Beispiel gemacht, wie man eine richtige MDI-Applikation mit AutoIt erstellen kann.
    Es ist zwar noch kein fertiges Programm und ich glaube es enthält irgendwo noch Fehler, aber damit kann man schon was anfangen.

    Viel Spaß!

    Spoiler anzeigen
    [autoit]

    #cs
    Multiple Document Interface example in AutoIt
    Author: funkey
    Date: 2011, 23rd of September
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    #include <WinAPIEx.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GuiMenu.au3>
    #include <GuiEdit.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $IDC_ARROW = 32512
    Global Const $tagCLIENTCREATESTRUCT = "HANDLE hWindowMenu;UINT idFirstChild"
    Global Const $tagMDICREATESTRUCT = "ptr szClass;ptr szTitle;HANDLE hOwner;int x;int y;int cx;int cy;DWORD style;LPARAM lParam"

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $CW_USEDEFAULT = 0x80000000
    Global Const $IDM_FIRSTCHILD = 50000
    Global Const $WM_MDIGETACTIVE = 553
    Global Const $WM_MDICREATE = 544
    Global Const $WM_MDIACTIVATE = 546
    Global Const $WM_MDITILE = 550
    Global Const $WM_MDICASCADE = 551
    Global Const $MF_ENABLED = 0

    [/autoit] [autoit][/autoit] [autoit]

    Global $hInstance = _WinAPI_GetModuleHandle(0)
    Global $hProcChild = DllCallbackRegister('_WndProcChild', 'lresult', 'hwnd;uint;wparam;lparam')
    Global $hCursor = _WinAPI_LoadCursor(0, $IDC_ARROW)
    Global $tIcon = DllStructCreate('ptr;ptr')
    _WinAPI_ExtractIconEx(@SystemDir & '\shell32.dll', 130, DllStructGetPtr($tIcon, 1), DllStructGetPtr($tIcon, 2), 1)
    Global $hIcon = DllStructGetData($tIcon, 1)
    Global $hIconSm = DllStructGetData($tIcon, 2)

    [/autoit] [autoit][/autoit] [autoit]

    If _MDI_RegisterChildClass() = 0 Then
    ConsoleWrite("Error Registering WindowClass!" & @CRLF)
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui = GUICreate("AutoIt MDI-Example by funkey", -1, -1, -1, -1, BitOR($WS_MAXIMIZE, $GUI_SS_DEFAULT_GUI))
    GUISetOnEvent(-3, "_Exit", $hGui)
    GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

    [/autoit] [autoit][/autoit] [autoit]

    Global $filemenu = GUICtrlCreateMenu("&File")
    Global $file_new = GUICtrlCreateMenuItem("&New Child", $filemenu)
    GUICtrlSetOnEvent(-1, "_NewMDIChild")
    Global $file_close = GUICtrlCreateMenuItem("E&xit", $filemenu)
    GUICtrlSetOnEvent(-1, "_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    Global $windowmenu = GUICtrlCreateMenu("&Window")
    Global $window_tileH = GUICtrlCreateMenuItem("Tile &horizontal", $windowmenu)
    GUICtrlSetOnEvent(-1, "_TileH")
    Global $window_tileV = GUICtrlCreateMenuItem("Tile &vertical", $windowmenu)
    GUICtrlSetOnEvent(-1, "_TileV")
    Global $window_cascade = GUICtrlCreateMenuItem("&Cascade", $windowmenu)
    GUICtrlSetOnEvent(-1, "_Cascade")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $hClient = _MDI_CreateClient($hGui)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW, $hGui)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hChild = _MDI_CreateChild($hClient, "Untitled 0", "MDIChild")
    _CreateEditOnMDI($hChild)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(20000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _TileH()
    _SendMessage($hClient, $WM_MDITILE, 1, 0);
    EndFunc ;==>_TileH

    [/autoit] [autoit][/autoit] [autoit]

    Func _TileV()
    _SendMessage($hClient, $WM_MDITILE, 0, 0);
    EndFunc ;==>_TileV

    [/autoit] [autoit][/autoit] [autoit]

    Func _Cascade()
    _SendMessage($hClient, $WM_MDICASCADE, 0, 0);
    EndFunc ;==>_Cascade

    [/autoit] [autoit][/autoit] [autoit]

    Func _NewMDIChild()
    Static $i = 0
    $i += 1
    _CreateEditOnMDI(_MDI_CreateChild($hClient, "Untitled " & $i, "MDIChild"))
    EndFunc ;==>_NewMDIChild

    [/autoit] [autoit][/autoit] [autoit]

    Func _CreateEditOnMDI($hChild)
    Local $aPos = WinGetClientSize($hChild)
    _GUICtrlEdit_Create($hChild, "", 5, 5, $aPos[0] - 10, $aPos[1] - 10, BitOR($ES_MULTILINE, $ES_WANTRETURN, $ES_AUTOVSCROLL))
    EndFunc ;==>_CreateEditOnMDI

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _WinAPI_UnregisterClass('MDIChild')
    GUIDelete($hGui)
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $hChildMDI
    If $nNotifyCode >= $IDM_FIRSTCHILD Then
    _WinAPI_DefFrameProc($hWnd, $hClient, $WM_COMMAND, $wParam, $lParam)
    Else
    $hChildMDI = _SendMessage($hClient, $WM_MDIGETACTIVE, 0, 0, 0, "wparam", "lparam", "hwnd")
    If $hChildMDI Then
    _SendMessage($hChildMDI, $WM_COMMAND, $wParam, $lParam)
    EndIf
    EndIf
    _WinAPI_DefFrameProc($hWnd, $hClient, $WM_COMMAND, $wParam, $lParam)
    EndFunc ;==>_WM_COMMAND

    [/autoit] [autoit][/autoit] [autoit]

    Func _MDI_RegisterChildClass()
    Local $sClass = 'MDIChild'
    Local $tClass = DllStructCreate('wchar[' & StringLen($sClass) + 1 & ']')
    DllStructSetData($tClass, 1, $sClass)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tWCEX = DllStructCreate($tagWNDCLASSEX)
    DllStructSetData($tWCEX, 'Size', DllStructGetSize($tWCEX))
    DllStructSetData($tWCEX, 'Style', 3)
    DllStructSetData($tWCEX, 'hWndProc', DllCallbackGetPtr($hProcChild))
    DllStructSetData($tWCEX, 'ClsExtra', 0)
    DllStructSetData($tWCEX, 'WndExtra', 0)
    DllStructSetData($tWCEX, 'hInstance', $hInstance)
    DllStructSetData($tWCEX, 'hIcon', $hIcon)
    DllStructSetData($tWCEX, 'hCursor', $hCursor)
    DllStructSetData($tWCEX, 'hBackground', 1);_WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_3DFACE)))
    DllStructSetData($tWCEX, 'MenuName', 0)
    DllStructSetData($tWCEX, 'ClassName', DllStructGetPtr($tClass))
    DllStructSetData($tWCEX, 'hIconSm', $hIconSm)
    ;~ DllStructSetData($tWCEX, 'hIconSm', 0)

    [/autoit] [autoit][/autoit] [autoit]

    Return _WinAPI_RegisterClassEx($tWCEX)
    EndFunc ;==>_MDI_RegisterChildClass

    [/autoit] [autoit][/autoit] [autoit]

    Func _MDI_CreateClient($hMDIParent)
    Local $aClientSize = WinGetClientSize($hGui)
    Local $iMenuHeight = _WinAPI_GetSystemMetrics(15)
    Local $tCLIENTCREATESTRUCT = DllStructCreate($tagCLIENTCREATESTRUCT)
    DllStructSetData($tCLIENTCREATESTRUCT, "hWindowMenu", _GUICtrlMenu_GetItemSubMenu(_GUICtrlMenu_GetMenu($hGui), 1))
    DllStructSetData($tCLIENTCREATESTRUCT, "idFirstChild", $IDM_FIRSTCHILD)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hMDIClient = _WinAPI_CreateWindowEx( _
    0, "MDICLIENT", "", 0x52000000, _ ; Fensterstile (WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE)
    0, 0, $aClientSize[0], $aClientSize[1] - $iMenuHeight, _ ; Position und Grösse des Fensters
    $hMDIParent, 0, $hInstance, _
    DllStructGetPtr($tCLIENTCREATESTRUCT))
    Return $hMDIClient
    EndFunc ;==>_MDI_CreateClient

    [/autoit] [autoit][/autoit] [autoit]

    Func _MDI_CreateChild($hMDIClient, $sTitle, $sClassName)
    Local $tClass = DllStructCreate('wchar[' & StringLen($sClassName) + 1 & ']')
    DllStructSetData($tClass, 1, $sClassName)
    Local $tTitle = DllStructCreate('wchar[' & StringLen($sTitle) + 1 & ']')
    DllStructSetData($tTitle, 1, $sTitle)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tMDICREATESTRUCT = DllStructCreate($tagMDICREATESTRUCT)
    DllStructSetData($tMDICREATESTRUCT, 'szClass', DllStructGetPtr($tClass))
    DllStructSetData($tMDICREATESTRUCT, "szTitle", DllStructGetPtr($tTitle))
    DllStructSetData($tMDICREATESTRUCT, "hOwner", $hInstance)
    DllStructSetData($tMDICREATESTRUCT, "x", $CW_USEDEFAULT)
    DllStructSetData($tMDICREATESTRUCT, "y", $CW_USEDEFAULT)
    DllStructSetData($tMDICREATESTRUCT, "cx", $CW_USEDEFAULT)
    DllStructSetData($tMDICREATESTRUCT, "cy", $CW_USEDEFAULT)
    DllStructSetData($tMDICREATESTRUCT, "style", 0)
    DllStructSetData($tMDICREATESTRUCT, "lParam", 0)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hRet = _SendMessage($hMDIClient, $WM_MDICREATE, 0, DllStructGetPtr($tMDICREATESTRUCT), 0, "wparam", "lparam", "hwnd")
    Return $hRet
    EndFunc ;==>_MDI_CreateChild

    [/autoit] [autoit][/autoit] [autoit]

    Func _WndProcChild($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
    Case $WM_MDIACTIVATE
    Local $hMenu = _GUICtrlMenu_GetMenu($hGui)
    If $hWnd = HWnd($lParam) Then
    _GUICtrlMenu_EnableMenuItem($hMenu, 1, BitOR($MF_BYPOSITION, $MF_ENABLED))
    Else
    _GUICtrlMenu_EnableMenuItem($hMenu, 1, BitOR($MF_BYPOSITION, $MF_GRAYED))
    EndIf
    _GUICtrlMenu_DrawMenuBar($hGui)
    EndSwitch
    Return _WinAPI_DefMDIChildProc($hWnd, $iMsg, $wParam, $lParam)
    EndFunc ;==>_WndProcChild

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_DefMDIChildProc($hWnd, $iMsg, $wParam, $lParam)
    Local $Ret = DllCall('user32.dll', 'lresult', 'DefMDIChildProcW', 'hwnd', $hWnd, 'uint', $iMsg, 'wparam', $wParam, 'lparam', $lParam)
    If @error Then Return SetError(1, 0, 0)
    Return $Ret[0]
    EndFunc ;==>_WinAPI_DefMDIChildProc

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_DefFrameProc($hWnd, $hWndMDIClient, $iMsg, $wParam, $lParam)
    Local $Ret = DllCall('user32.dll', 'lresult', 'DefFrameProcW', 'hwnd', $hWnd, 'hwnd', $hWndMDIClient, 'uint', $iMsg, 'wparam', $wParam, 'lparam', $lParam)
    If @error Then Return SetError(1, 0, 0)
    Return $Ret[0]
    EndFunc ;==>_WinAPI_DefFrameProc

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Hi funkey,

    das hatte ich auch bereits versucht.
    Aber wenn ich eines der MDI-Childs angeklickt habe, dann hat sich AutoIt verabschiedet ...
    Das Beispiel ist aus dem "Petzold".

    Werde mir Dein Beispiel mal ansehen ... ;)

    EDIT:
    Das mein Skript abstürzt kann aber auch daran liegen, dass ich das Hauptfenster nicht via GUICreate erzeuge ...


    Gruß
    Greenhorn