home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / WTJ9403.ZIP / WILDASS / SOURCE / DESKTOP.CPP < prev    next >
C/C++ Source or Header  |  1993-08-14  |  14KB  |  499 lines

  1. #include <afxwin.h>
  2. #include <afxext.h> 
  3. #include <ctl3d.h> 
  4.  
  5. #include "desktop.h"
  6. #include "toolhelp.h"
  7. #include "tasks.h"
  8.  
  9. CDesktopWindow::CDesktopWindow()
  10. {}
  11.  
  12. CDesktopWindow::CDesktopWindow( const char * pszExePath, HTASK hTask )
  13. {
  14.    m_strExePath = pszExePath;
  15.    m_hTask = hTask;
  16. }
  17.  
  18. void
  19. CDesktopWindow::Create( const char * pszExePath, HTASK hTask )
  20. {
  21.    m_strExePath = pszExePath;
  22.    m_hTask = hTask;
  23. }
  24.  
  25. BOOL 
  26. CDesktopWindow::IsIconic() const
  27. {
  28.    return m_fIsIconic;
  29. }
  30. const CRect& 
  31. CDesktopWindow::WindowRect() const
  32. {
  33.    return m_rectWnd;
  34. }
  35.  
  36. void 
  37. CDesktopWindow::Move( BOOL fIconic, const CRect& rect )
  38. {
  39.    if ( fIconic )
  40.    {
  41. //      MoveIconic( rect );
  42.       TRACE("WARNIGN: MoveIconic is unstable. Code not executed\n");
  43.    }
  44.    else
  45.    {         
  46.       CWnd * pWnd = CWnd::FromHandle( m_hWnd );
  47.       pWnd->MoveWindow( rect );         
  48.    }      
  49. }
  50.    
  51. /*static */ BOOL CALLBACK __export 
  52. CDesktopWindow::EnumAllWindowsProc( HWND hWnd, LPARAM lParam )
  53. {
  54.    CPtrList * lstPtrHWnd = (CPtrList*)lParam;
  55.    
  56.    HWND * pHWND = new HWND;
  57.    *pHWND = hWnd;
  58.    lstPtrHWnd->AddTail( (void*)pHWND );
  59.    return TRUE;
  60. }
  61.    
  62. void 
  63. CDesktopWindow::MoveIconic( const CRect& rect )
  64. {   
  65.    CWnd * pWnd = CWnd::FromHandle( m_hWnd );
  66.    
  67.    // to move an iconic window, we need to get the icons window title nad move it
  68.    // to, as the window title is aseperate window (more or less of its own)
  69.    // title windows are of #32772 ....
  70.    // VERIFY( EnumChildWindows( pWnd->m_hWnd, EnumChildProc, 0 ));
  71.    // ... only, icon titles on the desktop are no child windows .....
  72.    // use findWindow instead                
  73.    // rubbish, won`t work: we`ll find the first one allways...
  74.    // the following works                               
  75.                                
  76.    // build a list of all windows..
  77.    CPtrList lstWindows;
  78.    EnumWindows( EnumAllWindowsProc, (LPARAM)&lstWindows); 
  79.    
  80.    // iterate the window list and find the title window belonging to the
  81.    // parent we`ve got...
  82.    for ( POSITION pos=lstWindows.GetHeadPosition(); pos!=NULL; )
  83.    {  
  84.       // get a CWNd to this HWNd
  85.       HWND * pHWnd = (HWND*)lstWindows.GetNext( pos );
  86.       CWnd * pWndTitle = CWnd::FromHandle( *pHWnd );
  87.       
  88.       // get a CWnd to "this" window
  89.       CWnd * pWnd = CWnd::FromHandle( m_hWnd );
  90.       
  91.       // check if this is a window-title window
  92.       char szClassName[10];
  93.       GetClassName( pWndTitle->m_hWnd, szClassName, 9 );
  94.       if ( CString( szClassName ) == "#32772" )
  95.       {
  96.          // found a title window - is it the one we need ?
  97.          if ( pWndTitle->GetParent() == pWnd )
  98.          {  
  99.             // we really found it !!!!!
  100.             // step 1: get the offset from icon to title text window
  101.             CRect rectIcon, rectTitle;
  102.             pWnd->GetWindowRect( &rectIcon );
  103.             pWndTitle->GetWindowRect( &rectTitle );
  104.             CSize vecTitle = rectIcon.TopLeft() - rectTitle.TopLeft();
  105.             
  106.             // moe em
  107.             pWnd->MoveWindow( rect );
  108.             
  109.             pWndTitle->MoveWindow( rect.left - vecTitle.cx, rect.right - vecTitle.cy, 
  110.                                    rectTitle.Width(), rectTitle.Height() );
  111.                                    
  112.             // done
  113.             return;                                   
  114.          }
  115.       }
  116.    }
  117. }
  118.  
  119. HTASK 
  120. CDesktopWindow::HTask() const 
  121. { return m_hTask; }
  122.  
  123. const char * 
  124. CDesktopWindow::ExePath() const 
  125. { return m_strExePath; }
  126.  
  127. UINT 
  128. CDesktopWindow::ShowState() const 
  129. { return m_swState; }
  130.  
  131. void 
  132. CDesktopWindow::WndInfo( HWND hWnd, BOOL fIsIconic, const CRect& rectWnd /*, const char * pszModuleName*/ )
  133. {
  134.    m_hWnd = hWnd;
  135.    m_fIsIconic = fIsIconic;
  136.    m_rectWnd = rectWnd;
  137.       
  138.    // get the showstate of this window
  139.    CWnd * pWnd = CWnd::FromHandle( hWnd );
  140.    
  141.    // needs to be initilaized, even if they dont say so
  142.    WINDOWPLACEMENT wp;   
  143.    wp.length = sizeof( WINDOWPLACEMENT );
  144.    VERIFY( pWnd->GetWindowPlacement( &wp ));
  145.    m_swState = wp.showCmd;
  146.       
  147. //   m_strModuleName = pszModuleName;
  148. }
  149.    
  150. void 
  151. CDesktopWindow::DumpProfile( const char * pszTag, UINT idEntry )
  152. {               
  153.    char szTmp[10];
  154.    itoa( idEntry, szTmp, 10 );
  155.       
  156.    CString strApp("App");
  157.    strApp+=szTmp;
  158.    CString strInfo("Info");
  159.    strInfo+=szTmp;
  160.       
  161.    char szBuffer[256];
  162.    wsprintf( szBuffer, "%d,%d,%d,%d,%d,%d", m_fIsIconic, m_rectWnd.left,
  163.             m_rectWnd.bottom, m_rectWnd.top, m_rectWnd.right, m_swState );
  164.    AfxGetApp()->WriteProfileString( pszTag, strApp, m_strExePath );
  165.    AfxGetApp()->WriteProfileString( pszTag, strInfo, szBuffer );
  166. }
  167.    
  168. BOOL 
  169. CDesktopWindow::ReadProfile( const char * pszTag, UINT idEntry ) 
  170. {
  171.    char szTmp[10];
  172.    itoa( idEntry, szTmp, 10 );
  173.       
  174.    CString strApp("App");
  175.    strApp+=szTmp;
  176.    CString strInfo("Info");
  177.    strInfo+=szTmp;
  178.  
  179.    m_strExePath =  AfxGetApp()->GetProfileString( pszTag, strApp );
  180.       
  181.    if ( m_strExePath.IsEmpty() )
  182.       return FALSE;
  183.          
  184.    CString strInfoLine =  AfxGetApp()->GetProfileString( pszTag, strInfo );
  185.       
  186.    if ( strInfoLine.IsEmpty() )
  187.       return FALSE;
  188.       
  189.    sscanf( strInfoLine, "%d,%d,%d,%d,%d,%d",  &m_fIsIconic, &m_rectWnd.left,
  190.             &m_rectWnd.bottom, &m_rectWnd.top, &m_rectWnd.right, &m_swState );
  191.        
  192.    return TRUE;
  193. }
  194.  
  195. /*static*/ BOOL CALLBACK __export 
  196. CDesktop::EnumWindowsProc( HWND hWnd, LPARAM lParam )
  197. {
  198.    CWnd * pWnd = CWnd::FromHandle( hWnd );
  199.    CDesktopWindow * pDWnd = (CDesktopWindow*)lParam;
  200.          
  201.    CRect rectWnd;
  202.    pWnd->GetWindowRect( &rectWnd );
  203.       
  204.    // is this window iconic ?
  205.    // in which case we don`t need to enumerate anymore
  206.    if ( pWnd->IsIconic() )
  207.    {
  208.       pDWnd->WndInfo( hWnd, TRUE, rectWnd );
  209.       return FALSE;   
  210.    }
  211.    
  212.    // if this is either an overlapped or a pop-up window,
  213.    // lets think its what we want
  214.    // oh yes, shuld have a parent too - and should be visible
  215.    DWORD nStyle = pWnd->GetStyle();
  216.       
  217.    if ( ( nStyle & WS_OVERLAPPEDWINDOW ) ||
  218.         ( nStyle & WS_POPUPWINDOW ))
  219.    {  
  220.       if ( ! pWnd->GetParent() )
  221.       {
  222.          if( pWnd->IsWindowVisible() )
  223.          {
  224.             pDWnd->WndInfo( hWnd, FALSE, rectWnd );
  225.          }         
  226.          else
  227.          {
  228.             TRACE1("%s - WARNING: skipping possible main window. window is invisible\n", AfxGetAppName() );
  229.          }
  230.       }         
  231.    }
  232.             
  233.    return TRUE;
  234. }  
  235.    
  236. // close this desktop
  237. void 
  238. CDesktop::Close()
  239. {
  240.    // step one: try to close it nicely
  241.    for ( POSITION pos = GetHeadPosition(); pos!=NULL; )
  242.    {
  243.       CDesktopWindow * pWnd = GetNext( pos );
  244.       TASKENTRY te;
  245.       te.dwSize = sizeof(TASKENTRY);
  246.       // create a CTask from this taks
  247.       if ( TaskFindHandle( &te, pWnd->HTask() ))
  248.       {         
  249.          TRACE("Trying to close: %s\n", pWnd->ExePath() );
  250.          CTask aTask( &te );
  251.          aTask.Die();
  252.       }
  253.    }
  254.       
  255.    // step two: build _another_ desktop, and see whats left
  256.    // in case there are things left, kill them dead
  257.    CDesktop killerDesktop;
  258.       
  259.    if ( killerDesktop.GetCount() )
  260.    {
  261.       if ( AfxMessageBox("going to Kill dead current apps. Proceed ?", MB_OKCANCEL ) == IDOK )
  262.       {
  263.          for ( POSITION pos = killerDesktop.GetHeadPosition(); pos!=NULL; )
  264.          {
  265.             CDesktopWindow * pWnd = killerDesktop.GetNext( pos );
  266.             TerminateApp( pWnd->HTask(), NO_UAE_BOX );
  267.          }
  268.       }
  269.    }
  270. }
  271.    
  272. CDesktop::CDesktop( const char * pszName )
  273. {
  274.    m_strName = pszName;
  275. }  
  276.    
  277. // a desktop without a name cannot be dumped      
  278. CDesktop::CDesktop()
  279. {
  280.    m_strName = "";
  281. }
  282.    
  283. CDesktop::~CDesktop()
  284. {
  285.    for ( POSITION pos=GetHeadPosition(); pos!=NULL; )
  286.    {
  287.       delete GetNext( pos );
  288.    }
  289. }      
  290.    
  291. void 
  292. CDesktop::PlayBack()
  293. {                
  294.    // read the snapshot from the profile
  295.    ReadProfile();
  296.       
  297.    // if theres nothing in the list now, there
  298.    // no desktop to playback
  299.    if ( ! GetCount() )
  300.    {
  301.       AfxMessageBox("Empty desktop !");
  302.       return;
  303.    }  
  304.  
  305.    // remove all currently running apps from the desktop       
  306.    CDesktop curDesktop;       
  307.    TRACE0("Beginnigng to close current desktop\n");
  308.    curDesktop.Create();  // create it
  309.    curDesktop.Close();   // close it
  310.    TRACE0("Current desktop closed\n");
  311.  
  312.    // iterate the list of apps to launch
  313.    for ( POSITION pos = GetHeadPosition(); pos!=NULL; )
  314.    {
  315.       CDesktopWindow * pWnd = GetNext( pos );
  316.          
  317.       // try to run the apps
  318.       UINT nRet = WinExec( pWnd->ExePath(), pWnd->ShowState() );
  319.    
  320.       TRACE1("Trying to launch %s\n", pWnd->ExePath() );
  321.       if ( nRet < 32 )
  322.       {
  323.          AfxMessageBox( CString("Problem running ") + CString( pWnd->ExePath() ) );
  324.       }
  325.    }      
  326.       
  327.    // to now move the windows were we want them, we create another
  328.    // current desktop. than, we iterate the list, look for the needed
  329.    // main window in the current desktop by using the exename from the
  330.    // actual desktop, retrieve the Cdesktopwindow and move it
  331.    CDesktop newDesktop;
  332.    newDesktop.Create();
  333.    for ( POSITION posMove=GetHeadPosition(); posMove!=NULL; )
  334.    {                                           
  335.       CDesktopWindow * pOld = GetNext( posMove );
  336.       POSITION posFound = newDesktop.Find( pOld->ExePath() );
  337. #ifdef _DEBUG      
  338.       if ( ! posFound )
  339.       {
  340.          TRACE1("WARNING: Window for %s not found in Desktop list\n", pOld->ExePath() );   
  341.          continue;
  342.       }      
  343. #endif      
  344.       CDesktopWindow * pNew = newDesktop.GetAt( posFound );
  345.       newDesktop.RemoveAt( posFound );
  346.       pNew->Move( pOld->IsIconic(), pOld->WindowRect() );
  347.       delete pNew;
  348.    }
  349. }  
  350.  
  351. POSITION 
  352. CDesktop::Find( const char * pszExeName )
  353. {
  354.    for ( POSITION pos=GetHeadPosition(); pos!=NULL; )
  355.    {  
  356.       POSITION posReturn = pos;
  357.       CDesktopWindow * pWnd = GetNext( pos );
  358.       if ( CString( pWnd->ExePath() ) == CString( pszExeName ) )
  359.       {
  360.          // GetPrev( pos );
  361.          return posReturn;
  362.       }
  363.    }     
  364.    
  365.    return NULL;
  366. }
  367.     
  368.    
  369. void 
  370. CDesktop::Create()
  371. {      
  372.    // create a task list
  373.    CTaskList lstTasks;
  374.               
  375.    // for all tasks, find the main window and
  376.    // store the needed information
  377.    for ( POSITION pos=lstTasks.GetHeadPosition(); pos!=NULL; )
  378.    {
  379.       CTask * pTask = lstTasks.GetNext( pos );
  380.          
  381.       // if this is ourselves _or_ an winoldapp window, skip it
  382.       if ( CString("WINOLDAP")==pTask->ModuleName() )
  383.       {  
  384.          // there is no supported way to get the running application
  385.          // from the WINOAP module. (this is, when the task listed in the
  386.          // task queue is winoapp.mod)
  387.          // maybe the article from windows/dos dev journal, dec 92 helps...
  388.          TRACE1("%s - WARNING: skipping an app during tasklist build: this is an old app\n", AfxGetAppName() );
  389.          continue;
  390.       }        
  391.       
  392.       if ( ! CString( "MORESPAC" ).CompareNoCase(pTask->ModuleName()) ) 
  393.       {
  394.          TRACE("skiiping ourselves ...\n");
  395.          continue;              
  396.       }         
  397.          
  398. #ifdef _DEBUG             
  399.       // if this is a debug build, ignore dbwinexe too
  400.       if ( CString("DBWINEXE")==pTask->ModuleName() )
  401.       {
  402.          TRACE1("%s - WARNING: skipping dbwin during tasklist build\n", AfxGetAppName() );
  403.          continue;
  404.       }
  405.       // and ignore msvc 
  406.       if ( CString("MSVC")==pTask->ModuleName() )
  407.       {
  408.          TRACE1("%s - WARNING: skipping msvc during tasklist build\n", AfxGetAppName() );
  409.          continue;
  410.       }
  411. #endif
  412.              
  413.       // create a new DesktopWindow
  414.       CDesktopWindow * pDWnd = new CDesktopWindow( pTask->ExeName(), pTask->HTask() );            
  415.          
  416.       // TRACE("\nEnumerating the windows of task: -%s- [Module:-%s-]\n", pTask->ExeName(), pTask->ModuleName() );
  417.       EnumTaskWindows( pTask->HTask(), EnumWindowsProc, (LPARAM)pDWnd );
  418.          
  419.       // add this app to our list
  420.       AddTail( pDWnd );
  421.    } 
  422. }                
  423.  
  424. void
  425. CDesktop::Snapshot()
  426. {
  427.    // create it
  428.    Create();
  429.    
  430.    // dump this layout to the profile
  431.    DumpProfile();
  432. }   
  433.    
  434. // Dump this desktop to the profile
  435. void 
  436. CDesktop::DumpProfile()
  437. {         
  438.    // make sure this is not a temporary desktop
  439.    ASSERT( ! m_strName.IsEmpty() );
  440.                                                       
  441.    // clean the rpfile 
  442.    CString strFile = AfxGetAppName() + CString(".ini");
  443.    WritePrivateProfileString( m_strName, NULL, NULL, strFile );
  444.          
  445.    int idEntry=0;   
  446.    for ( POSITION pos=GetHeadPosition(); pos!=NULL;)
  447.    {
  448.       CDesktopWindow * pWnd = GetNext( pos );      
  449.       pWnd->DumpProfile( m_strName, idEntry );         
  450.       idEntry++;
  451.    }
  452. }  
  453.    
  454. void 
  455. CDesktop::ReadProfile()
  456. {
  457.    int idEntry = 0;
  458.    while ( TRUE )
  459.    {
  460.       CDesktopWindow * pWnd = new CDesktopWindow();
  461.       if ( ! pWnd->ReadProfile( m_strName, idEntry ) )
  462.       {
  463.          delete pWnd;
  464.          break;
  465.       }
  466.       AddTail( pWnd );   
  467.       idEntry++;
  468.    }
  469. }
  470.  
  471.    
  472. // avoid casts in usage  
  473. CDesktopWindow*& 
  474. CDesktop::GetNext( POSITION& rPos )
  475. {
  476.    return (CDesktopWindow*&) CObList::GetNext(rPos);
  477. }
  478.    
  479. CDesktopWindow* 
  480. CDesktop::GetNext( POSITION& rPos ) const
  481. {
  482.    return (CDesktopWindow*) CObList::GetNext(rPos);
  483. }
  484.    
  485. CDesktopWindow*& 
  486. CDesktop::GetAt( POSITION pos )
  487. {
  488.    return (CDesktopWindow*&) CObList::GetAt( pos );
  489. }
  490.    
  491. CDesktopWindow* 
  492. CDesktop::GetAt( POSITION pos ) const
  493. {
  494.    return (CDesktopWindow*) CObList::GetAt( pos );
  495. }
  496.  
  497.  
  498.       
  499.