Показать сообщение отдельно
Старый 19.01.2009, 12:35   #10  
petergunn is offline
petergunn
Участник
 
118 / 274 (10) ++++++
Регистрация: 30.08.2005
Адрес: Tyumen
Цитата:
Сообщение от Dima_Dima Посмотреть сообщение
Возможно ли с помощью класса Infolog (или другого) выяснить какие формы были открыты?
...
А если есть надобность выяснить имя предпоследней открытой формы?
...
Если интересуют только заголовки открытых в Ax окон, подобно тому что отображается в форме 'Выбрать окно' (меню Окно\Окна...), то можно средствами Win32 API перебрать дочерние MDI окна приложения.

В качестве примера вот что получилось для DAx 4.0, с учетом дополнительно открытых рабочих областей:
X++:
static void jbShowAxWindowList(Args _args)
{
    DLLFunction     dllFunctionIsWindowVisible  ;
    DLLFunction     dllFunctionGetClassName     ;

    container       conWorkspaceListWnd ;
    Counter         counterWorkspace    ;
    Counter         counterWindowTotal  ;
    HWND            hWndAxWorkspace     ;

    #define.WorkspaceView(0)    //  0 - all workspaces, 1 - only current workspace
    #define.UserDLL( 'USER32' )
    #WinAPI

    str getClassName( HWND _hWnd )  //  Win32 API GetClassName function
    {
        #define.nMaxCount(512)

        DLL     dllUser ;
        Binary  binaryClassName = new Binary( #nMaxCount *2 ) ;
        ;

        if( !dllFunctionGetClassName )
        {
            dllUser = new DLL( #UserDLL ) ;
            dllFunctionGetClassName = new DLLFunction( dllUser, 'GetClassNameW' ) ;
            dllFunctionGetClassName.returns( ExtTypes::DWord ) ;
            dllFunctionGetClassName.arg( ExtTypes::DWord, ExtTypes::Pointer, ExtTypes::DWord ) ;
        }

        if( !dllFunctionGetClassName.call( _hWnd, binaryClassName, #nMaxCount ) )
            return '' ;

        return binaryClassName.wString( 0 ) ;
    }

    boolean isWindowVisible( HWND _hWnd )  //  Win32 API IsWindowVisible function
    {
        DLL dllUser ;
        ;

        if( !dllFunctionIsWindowVisible )
        {
            dllUser = new DLL( #UserDLL ) ;
            dllFunctionIsWindowVisible = new DLLFunction( dllUser, 'IsWindowVisible' ) ;
            dllFunctionIsWindowVisible.returns( ExtTypes::Word ) ;
            dllFunctionIsWindowVisible.arg( ExtTypes::DWord ) ;
        }

        return dllFunctionIsWindowVisible.call( _hWnd ) ;
    }

    Counter showWorkspaceVisibleWindowList( HWND _hWndWorkspace, int _workspaceNum = 0 )
    {
        HWND    hWndClientMDI   ;
        HWND    hWndAxMDI       ;
        HWND    hWndAxPane      ;

        TempStr         tempStr         ;
        IdentifierName  objectName      ;
        Name            workSpaceName   ;
        Counter         counterWindow   ;

        System.Text.RegularExpressions.Match    sysMatch;

        #define.MdiClientWndClass('MDIClient')
        #define.AxMainFrameWndClassName('AxMainFrame')
        #define.AxMdiChildWndClassName('AxMDIChildWindow')
        #define.AxPaneWndClassName('AxPaneWnd')
        ;

        if( getClassName( _hWndWorkspace ) != #AxMainFrameWndClassName )
            throw error( strfmt( "Invalid class name of window %1", _hWndWorkspace ) ) ;

        workSpaceName = WinAPI::getWindowText( _hWndWorkspace ) ;
        setprefix( workSpaceName ) ;

        if( !_workspaceNum && workSpaceName )   //  if '_workspaceNum' not specified (=0), try get him from main window caption
        {
            sysMatch = System.Text.RegularExpressions.Regex::Match( workSpaceName, @'\d+' ) ;
            if( sysMatch.get_Success() )
            {
                tempStr = sysMatch.get_Value() ;
                _workspaceNum = str2int( tempStr ) ;
            }
        }

        hWndClientMDI = WinApi::findWindowEx( _hWndWorkspace, 0, #MdiClientWndClass, '' ) ;
        hWndAxMDI = WinApi::findWindowEx( hWndClientMDI, 0, #AxMdiChildWndClassName, '' );
        while( hWndAxMDI )
        {
            if( isWindowVisible( hWndAxMDI ) )
            {
                hWndAxPane = WinAPI::findWindowEx( hWndAxMDI, 0, #AxPaneWndClassName, '' ) ;
                objectName = WinAPI::getWindowText( hWndAxPane ) ;  //  try get 'internal' formRun name

                counterWindow++ ;
                info( strfmt(   "%1%2%3%4 [HWND: %5]",
                                _workspaceNum ? int2str( _workspaceNum ) + ' - ' : '',
                                objectName,
                                objectName ? ' : ' : '',
                                WinAPI::getWindowText( hWndAxMDI ),
                                hWndAxMDI ) ) ;
            }
            hWndAxMDI = WinAPI::getWindow( hWndAxMDI, #GW_HWNDNEXT ) ;  //  next AxMDI window
        }

        return counterWindow ;
    }
    ;

    info( "Dynamics AX window list" ) ;
    
    #if.WorkspaceView(0)    //  all workspaces
    conWorkSpaceListWnd = infolog.getWorkspaceList() ;
    for( counterWorkspace = 1; counterWorkspace <= conlen( conWorkSpaceListWnd ); counterWorkspace++ )
    {
        hWndAxWorkspace = conpeek( conWorkSpaceListWnd, counterWorkspace ) ;
        counterWindowTotal += showWorkspaceVisibleWindowList( hWndAxWorkspace ) ;
    }
    #endif  //  WorkspaceView(0)
    
    #if.WorkspaceView(1)    //  only current workspace
    counterWindowTotal = showWorkspaceVisibleWindowList( infolog.hWnd( xInfo::currentWorkspaceNum() ), xInfo::currentWorkspaceNum() ) ;
    #endif  //  WorkspaceView(1)
    
    info( strfmt( "Listed %1 windows", counterWindowTotal ) ) ;
}
За это сообщение автора поблагодарили: Dima_Dima (1).