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 >
Wrap
C/C++ Source or Header
|
1993-08-14
|
14KB
|
499 lines
#include <afxwin.h>
#include <afxext.h>
#include <ctl3d.h>
#include "desktop.h"
#include "toolhelp.h"
#include "tasks.h"
CDesktopWindow::CDesktopWindow()
{}
CDesktopWindow::CDesktopWindow( const char * pszExePath, HTASK hTask )
{
m_strExePath = pszExePath;
m_hTask = hTask;
}
void
CDesktopWindow::Create( const char * pszExePath, HTASK hTask )
{
m_strExePath = pszExePath;
m_hTask = hTask;
}
BOOL
CDesktopWindow::IsIconic() const
{
return m_fIsIconic;
}
const CRect&
CDesktopWindow::WindowRect() const
{
return m_rectWnd;
}
void
CDesktopWindow::Move( BOOL fIconic, const CRect& rect )
{
if ( fIconic )
{
// MoveIconic( rect );
TRACE("WARNIGN: MoveIconic is unstable. Code not executed\n");
}
else
{
CWnd * pWnd = CWnd::FromHandle( m_hWnd );
pWnd->MoveWindow( rect );
}
}
/*static */ BOOL CALLBACK __export
CDesktopWindow::EnumAllWindowsProc( HWND hWnd, LPARAM lParam )
{
CPtrList * lstPtrHWnd = (CPtrList*)lParam;
HWND * pHWND = new HWND;
*pHWND = hWnd;
lstPtrHWnd->AddTail( (void*)pHWND );
return TRUE;
}
void
CDesktopWindow::MoveIconic( const CRect& rect )
{
CWnd * pWnd = CWnd::FromHandle( m_hWnd );
// to move an iconic window, we need to get the icons window title nad move it
// to, as the window title is aseperate window (more or less of its own)
// title windows are of #32772 ....
// VERIFY( EnumChildWindows( pWnd->m_hWnd, EnumChildProc, 0 ));
// ... only, icon titles on the desktop are no child windows .....
// use findWindow instead
// rubbish, won`t work: we`ll find the first one allways...
// the following works
// build a list of all windows..
CPtrList lstWindows;
EnumWindows( EnumAllWindowsProc, (LPARAM)&lstWindows);
// iterate the window list and find the title window belonging to the
// parent we`ve got...
for ( POSITION pos=lstWindows.GetHeadPosition(); pos!=NULL; )
{
// get a CWNd to this HWNd
HWND * pHWnd = (HWND*)lstWindows.GetNext( pos );
CWnd * pWndTitle = CWnd::FromHandle( *pHWnd );
// get a CWnd to "this" window
CWnd * pWnd = CWnd::FromHandle( m_hWnd );
// check if this is a window-title window
char szClassName[10];
GetClassName( pWndTitle->m_hWnd, szClassName, 9 );
if ( CString( szClassName ) == "#32772" )
{
// found a title window - is it the one we need ?
if ( pWndTitle->GetParent() == pWnd )
{
// we really found it !!!!!
// step 1: get the offset from icon to title text window
CRect rectIcon, rectTitle;
pWnd->GetWindowRect( &rectIcon );
pWndTitle->GetWindowRect( &rectTitle );
CSize vecTitle = rectIcon.TopLeft() - rectTitle.TopLeft();
// moe em
pWnd->MoveWindow( rect );
pWndTitle->MoveWindow( rect.left - vecTitle.cx, rect.right - vecTitle.cy,
rectTitle.Width(), rectTitle.Height() );
// done
return;
}
}
}
}
HTASK
CDesktopWindow::HTask() const
{ return m_hTask; }
const char *
CDesktopWindow::ExePath() const
{ return m_strExePath; }
UINT
CDesktopWindow::ShowState() const
{ return m_swState; }
void
CDesktopWindow::WndInfo( HWND hWnd, BOOL fIsIconic, const CRect& rectWnd /*, const char * pszModuleName*/ )
{
m_hWnd = hWnd;
m_fIsIconic = fIsIconic;
m_rectWnd = rectWnd;
// get the showstate of this window
CWnd * pWnd = CWnd::FromHandle( hWnd );
// needs to be initilaized, even if they dont say so
WINDOWPLACEMENT wp;
wp.length = sizeof( WINDOWPLACEMENT );
VERIFY( pWnd->GetWindowPlacement( &wp ));
m_swState = wp.showCmd;
// m_strModuleName = pszModuleName;
}
void
CDesktopWindow::DumpProfile( const char * pszTag, UINT idEntry )
{
char szTmp[10];
itoa( idEntry, szTmp, 10 );
CString strApp("App");
strApp+=szTmp;
CString strInfo("Info");
strInfo+=szTmp;
char szBuffer[256];
wsprintf( szBuffer, "%d,%d,%d,%d,%d,%d", m_fIsIconic, m_rectWnd.left,
m_rectWnd.bottom, m_rectWnd.top, m_rectWnd.right, m_swState );
AfxGetApp()->WriteProfileString( pszTag, strApp, m_strExePath );
AfxGetApp()->WriteProfileString( pszTag, strInfo, szBuffer );
}
BOOL
CDesktopWindow::ReadProfile( const char * pszTag, UINT idEntry )
{
char szTmp[10];
itoa( idEntry, szTmp, 10 );
CString strApp("App");
strApp+=szTmp;
CString strInfo("Info");
strInfo+=szTmp;
m_strExePath = AfxGetApp()->GetProfileString( pszTag, strApp );
if ( m_strExePath.IsEmpty() )
return FALSE;
CString strInfoLine = AfxGetApp()->GetProfileString( pszTag, strInfo );
if ( strInfoLine.IsEmpty() )
return FALSE;
sscanf( strInfoLine, "%d,%d,%d,%d,%d,%d", &m_fIsIconic, &m_rectWnd.left,
&m_rectWnd.bottom, &m_rectWnd.top, &m_rectWnd.right, &m_swState );
return TRUE;
}
/*static*/ BOOL CALLBACK __export
CDesktop::EnumWindowsProc( HWND hWnd, LPARAM lParam )
{
CWnd * pWnd = CWnd::FromHandle( hWnd );
CDesktopWindow * pDWnd = (CDesktopWindow*)lParam;
CRect rectWnd;
pWnd->GetWindowRect( &rectWnd );
// is this window iconic ?
// in which case we don`t need to enumerate anymore
if ( pWnd->IsIconic() )
{
pDWnd->WndInfo( hWnd, TRUE, rectWnd );
return FALSE;
}
// if this is either an overlapped or a pop-up window,
// lets think its what we want
// oh yes, shuld have a parent too - and should be visible
DWORD nStyle = pWnd->GetStyle();
if ( ( nStyle & WS_OVERLAPPEDWINDOW ) ||
( nStyle & WS_POPUPWINDOW ))
{
if ( ! pWnd->GetParent() )
{
if( pWnd->IsWindowVisible() )
{
pDWnd->WndInfo( hWnd, FALSE, rectWnd );
}
else
{
TRACE1("%s - WARNING: skipping possible main window. window is invisible\n", AfxGetAppName() );
}
}
}
return TRUE;
}
// close this desktop
void
CDesktop::Close()
{
// step one: try to close it nicely
for ( POSITION pos = GetHeadPosition(); pos!=NULL; )
{
CDesktopWindow * pWnd = GetNext( pos );
TASKENTRY te;
te.dwSize = sizeof(TASKENTRY);
// create a CTask from this taks
if ( TaskFindHandle( &te, pWnd->HTask() ))
{
TRACE("Trying to close: %s\n", pWnd->ExePath() );
CTask aTask( &te );
aTask.Die();
}
}
// step two: build _another_ desktop, and see whats left
// in case there are things left, kill them dead
CDesktop killerDesktop;
if ( killerDesktop.GetCount() )
{
if ( AfxMessageBox("going to Kill dead current apps. Proceed ?", MB_OKCANCEL ) == IDOK )
{
for ( POSITION pos = killerDesktop.GetHeadPosition(); pos!=NULL; )
{
CDesktopWindow * pWnd = killerDesktop.GetNext( pos );
TerminateApp( pWnd->HTask(), NO_UAE_BOX );
}
}
}
}
CDesktop::CDesktop( const char * pszName )
{
m_strName = pszName;
}
// a desktop without a name cannot be dumped
CDesktop::CDesktop()
{
m_strName = "";
}
CDesktop::~CDesktop()
{
for ( POSITION pos=GetHeadPosition(); pos!=NULL; )
{
delete GetNext( pos );
}
}
void
CDesktop::PlayBack()
{
// read the snapshot from the profile
ReadProfile();
// if theres nothing in the list now, there
// no desktop to playback
if ( ! GetCount() )
{
AfxMessageBox("Empty desktop !");
return;
}
// remove all currently running apps from the desktop
CDesktop curDesktop;
TRACE0("Beginnigng to close current desktop\n");
curDesktop.Create(); // create it
curDesktop.Close(); // close it
TRACE0("Current desktop closed\n");
// iterate the list of apps to launch
for ( POSITION pos = GetHeadPosition(); pos!=NULL; )
{
CDesktopWindow * pWnd = GetNext( pos );
// try to run the apps
UINT nRet = WinExec( pWnd->ExePath(), pWnd->ShowState() );
TRACE1("Trying to launch %s\n", pWnd->ExePath() );
if ( nRet < 32 )
{
AfxMessageBox( CString("Problem running ") + CString( pWnd->ExePath() ) );
}
}
// to now move the windows were we want them, we create another
// current desktop. than, we iterate the list, look for the needed
// main window in the current desktop by using the exename from the
// actual desktop, retrieve the Cdesktopwindow and move it
CDesktop newDesktop;
newDesktop.Create();
for ( POSITION posMove=GetHeadPosition(); posMove!=NULL; )
{
CDesktopWindow * pOld = GetNext( posMove );
POSITION posFound = newDesktop.Find( pOld->ExePath() );
#ifdef _DEBUG
if ( ! posFound )
{
TRACE1("WARNING: Window for %s not found in Desktop list\n", pOld->ExePath() );
continue;
}
#endif
CDesktopWindow * pNew = newDesktop.GetAt( posFound );
newDesktop.RemoveAt( posFound );
pNew->Move( pOld->IsIconic(), pOld->WindowRect() );
delete pNew;
}
}
POSITION
CDesktop::Find( const char * pszExeName )
{
for ( POSITION pos=GetHeadPosition(); pos!=NULL; )
{
POSITION posReturn = pos;
CDesktopWindow * pWnd = GetNext( pos );
if ( CString( pWnd->ExePath() ) == CString( pszExeName ) )
{
// GetPrev( pos );
return posReturn;
}
}
return NULL;
}
void
CDesktop::Create()
{
// create a task list
CTaskList lstTasks;
// for all tasks, find the main window and
// store the needed information
for ( POSITION pos=lstTasks.GetHeadPosition(); pos!=NULL; )
{
CTask * pTask = lstTasks.GetNext( pos );
// if this is ourselves _or_ an winoldapp window, skip it
if ( CString("WINOLDAP")==pTask->ModuleName() )
{
// there is no supported way to get the running application
// from the WINOAP module. (this is, when the task listed in the
// task queue is winoapp.mod)
// maybe the article from windows/dos dev journal, dec 92 helps...
TRACE1("%s - WARNING: skipping an app during tasklist build: this is an old app\n", AfxGetAppName() );
continue;
}
if ( ! CString( "MORESPAC" ).CompareNoCase(pTask->ModuleName()) )
{
TRACE("skiiping ourselves ...\n");
continue;
}
#ifdef _DEBUG
// if this is a debug build, ignore dbwinexe too
if ( CString("DBWINEXE")==pTask->ModuleName() )
{
TRACE1("%s - WARNING: skipping dbwin during tasklist build\n", AfxGetAppName() );
continue;
}
// and ignore msvc
if ( CString("MSVC")==pTask->ModuleName() )
{
TRACE1("%s - WARNING: skipping msvc during tasklist build\n", AfxGetAppName() );
continue;
}
#endif
// create a new DesktopWindow
CDesktopWindow * pDWnd = new CDesktopWindow( pTask->ExeName(), pTask->HTask() );
// TRACE("\nEnumerating the windows of task: -%s- [Module:-%s-]\n", pTask->ExeName(), pTask->ModuleName() );
EnumTaskWindows( pTask->HTask(), EnumWindowsProc, (LPARAM)pDWnd );
// add this app to our list
AddTail( pDWnd );
}
}
void
CDesktop::Snapshot()
{
// create it
Create();
// dump this layout to the profile
DumpProfile();
}
// Dump this desktop to the profile
void
CDesktop::DumpProfile()
{
// make sure this is not a temporary desktop
ASSERT( ! m_strName.IsEmpty() );
// clean the rpfile
CString strFile = AfxGetAppName() + CString(".ini");
WritePrivateProfileString( m_strName, NULL, NULL, strFile );
int idEntry=0;
for ( POSITION pos=GetHeadPosition(); pos!=NULL;)
{
CDesktopWindow * pWnd = GetNext( pos );
pWnd->DumpProfile( m_strName, idEntry );
idEntry++;
}
}
void
CDesktop::ReadProfile()
{
int idEntry = 0;
while ( TRUE )
{
CDesktopWindow * pWnd = new CDesktopWindow();
if ( ! pWnd->ReadProfile( m_strName, idEntry ) )
{
delete pWnd;
break;
}
AddTail( pWnd );
idEntry++;
}
}
// avoid casts in usage
CDesktopWindow*&
CDesktop::GetNext( POSITION& rPos )
{
return (CDesktopWindow*&) CObList::GetNext(rPos);
}
CDesktopWindow*
CDesktop::GetNext( POSITION& rPos ) const
{
return (CDesktopWindow*) CObList::GetNext(rPos);
}
CDesktopWindow*&
CDesktop::GetAt( POSITION pos )
{
return (CDesktopWindow*&) CObList::GetAt( pos );
}
CDesktopWindow*
CDesktop::GetAt( POSITION pos ) const
{
return (CDesktopWindow*) CObList::GetAt( pos );
}