Index: src/ch/ClipboardMonitor.cpp
===================================================================
diff -u
--- src/ch/ClipboardMonitor.cpp	(revision 0)
+++ src/ch/ClipboardMonitor.cpp	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -0,0 +1,332 @@
+//******************************************************************************
+//   Copyright (C) 2001-2008 by Jozef Starosczyk
+//   ixen@copyhandler.com
+//
+//   This program is free software; you can redistribute it and/or modify
+//   it under the terms of the GNU Library General Public License
+//   (version 2) as published by the Free Software Foundation;
+//
+//   This program is distributed in the hope that it will be useful,
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//   GNU General Public License for more details.
+//
+//   You should have received a copy of the GNU Library General Public
+//   License along with this program; if not, write to the
+//   Free Software Foundation, Inc.,
+//   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+/// @file ClipboardMonitor.cpp
+/// @brief Contains the implementation of clipboard monitor package.
+//******************************************************************************
+#include "stdafx.h"
+#include "ClipboardMonitor.h"
+#include "ch.h"
+#include "task.h"
+#include "../libchcore/EngineCfg.h"
+#include "CfgProperties.h"
+#include "charvect.h"
+#include "FolderDialog.h"
+#include "task.h"
+#include "ShutdownDlg.h"
+
+CClipboardMonitor CClipboardMonitor::S_ClipboardMonitor;
+
+CClipboardMonitor::CClipboardMonitor() :
+	m_hThread(NULL),
+	m_hKillEvent(NULL)
+{
+}
+
+CClipboardMonitor::~CClipboardMonitor()
+{
+	Stop();
+}
+
+bool CClipboardMonitor::StartMonitor(CTaskArray* pTasks)
+{
+	return CClipboardMonitor::S_ClipboardMonitor.Start(pTasks);
+}
+
+bool CClipboardMonitor::StopMonitor()
+{
+	return CClipboardMonitor::S_ClipboardMonitor.Stop();
+}
+
+bool CClipboardMonitor::Start(CTaskArray* pTasks)
+{
+	m_pTasks = pTasks;
+
+	m_hKillEvent = ::CreateEvent(NULL, FALSE, FALSE, _T("CH Clipboard Monitor"));
+	if(m_hKillEvent == NULL)
+	{
+		m_pTasks = NULL;
+		return false;
+	}
+	m_hThread = ::CreateThread(NULL, 0, &CClipboardMonitor::ClipboardMonitorProc, &CClipboardMonitor::S_ClipboardMonitor, 0, NULL);
+	if(m_hThread == NULL)
+	{
+		CloseHandle(m_hKillEvent);
+		m_hKillEvent = NULL;
+		m_pTasks = NULL;
+		return false;
+	}
+	return true;
+}
+
+bool CClipboardMonitor::Stop()
+{
+	if(m_hThread != INVALID_HANDLE_VALUE)
+	{
+		::SetEvent(m_hKillEvent);
+		DWORD dwRes = WaitForSingleObject(m_hThread, 5000);
+		CloseHandle(m_hThread);
+		CloseHandle(m_hKillEvent);
+		m_hThread = NULL;
+		m_hKillEvent = NULL;
+		m_pTasks = NULL;
+		return dwRes == WAIT_OBJECT_0;
+	}
+	return true;
+}
+
+DWORD WINAPI CClipboardMonitor::ClipboardMonitorProc(LPVOID pParam)
+{
+	CClipboardMonitor* pData = (CClipboardMonitor*)pParam;
+
+	// bufor
+	TCHAR path[_MAX_PATH];
+	//	UINT i;	// counter
+	CTask *pTask;	// ptr to a task
+	CClipboardEntry* pEntry=NULL;
+
+	// register clipboard format
+	UINT nFormat=RegisterClipboardFormat(_T("Preferred DropEffect"));
+	UINT uiCounter=0, uiShutCounter=0;
+	LONG lFinished=0;
+	bool bEnd=false;
+
+	chcore::engine_config& rConfig = chcore::engine_config::Acquire();
+	for(;;)
+	{
+		if (uiCounter == 0 && rConfig.get_bool(PP_PCLIPBOARDMONITORING) && IsClipboardFormatAvailable(CF_HDROP))
+		{
+			// get data from clipboard
+			OpenClipboard(NULL);
+			HANDLE handle=GetClipboardData(CF_HDROP);
+
+			UINT nCount=DragQueryFile(static_cast<HDROP>(handle), 0xffffffff, NULL, 0);
+
+			pTask = pData->m_pTasks->CreateTask();
+
+			for (UINT i=0;i<nCount;i++)
+			{
+				DragQueryFile(static_cast<HDROP>(handle), i, path, _MAX_PATH);
+				pEntry=new CClipboardEntry;
+				pEntry->SetPath(path);
+				pTask->AddClipboardData(pEntry);
+			}
+
+			if (IsClipboardFormatAvailable(nFormat))
+			{
+				handle=GetClipboardData(nFormat);
+				LPVOID addr=GlobalLock(handle);
+
+				DWORD dwData=((DWORD*)addr)[0];
+				if (dwData & DROPEFFECT_COPY)
+					pTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// copy
+				else if (dwData & DROPEFFECT_MOVE)
+					pTask->SetStatus(ST_MOVE, ST_OPERATION_MASK);	// move
+
+				GlobalUnlock(handle);
+			}
+			else
+				pTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// default - copy
+
+			EmptyClipboard();
+			CloseClipboard();
+
+			BUFFERSIZES bs;
+			bs.m_bOnlyDefault=rConfig.get_bool(PP_BFUSEONLYDEFAULT);
+			bs.m_uiDefaultSize=(UINT)rConfig.get_signed_num(PP_BFDEFAULT);
+			bs.m_uiOneDiskSize=(UINT)rConfig.get_signed_num(PP_BFONEDISK);
+			bs.m_uiTwoDisksSize=(UINT)rConfig.get_signed_num(PP_BFTWODISKS);
+			bs.m_uiCDSize=(UINT)rConfig.get_signed_num(PP_BFCD);
+			bs.m_uiLANSize=(UINT)rConfig.get_signed_num(PP_BFLAN);
+
+			pTask->SetBufferSizes(&bs);
+			pTask->SetPriority((int)rConfig.get_signed_num(PP_CMDEFAULTPRIORITY));
+
+			// get dest folder
+			CFolderDialog dlg;
+
+			const tchar_t* pszPath = NULL;
+			dlg.m_bdData.cvShortcuts.clear(true);
+			size_t stCount = rConfig.get_value_count(PP_SHORTCUTS);
+			for(size_t stIndex = 0; stIndex < stCount; stIndex++)
+			{
+				pszPath = rConfig.get_string(PP_SHORTCUTS, stIndex);
+				dlg.m_bdData.cvShortcuts.push_back(pszPath);
+			}
+
+			dlg.m_bdData.cvRecent.clear(true);
+			stCount = rConfig.get_value_count(PP_RECENTPATHS);
+			for(size_t stIndex = 0; stIndex < stCount; stIndex++)
+			{
+				pszPath = rConfig.get_string(PP_RECENTPATHS, stIndex);
+				dlg.m_bdData.cvRecent.push_back(pszPath);
+			}
+
+			dlg.m_bdData.bExtended=rConfig.get_bool(PP_FDEXTENDEDVIEW);
+			dlg.m_bdData.cx=(int)rConfig.get_signed_num(PP_FDWIDTH);
+			dlg.m_bdData.cy=(int)rConfig.get_signed_num(PP_FDHEIGHT);
+			dlg.m_bdData.iView=(int)rConfig.get_signed_num(PP_FDSHORTCUTLISTSTYLE);
+			dlg.m_bdData.bIgnoreDialogs=rConfig.get_bool(PP_FDIGNORESHELLDIALOGS);
+
+			dlg.m_bdData.strInitialDir=(dlg.m_bdData.cvRecent.size() > 0) ? dlg.m_bdData.cvRecent.at(0) : _T("");
+
+			int iStatus=pTask->GetStatus(ST_OPERATION_MASK);
+			if (iStatus == ST_COPY)
+				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLECOPY_STRING);
+			else if (iStatus == ST_MOVE)
+				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLEMOVE_STRING);
+			else
+				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLEUNKNOWNOPERATION_STRING);
+			dlg.m_bdData.strText=GetResManager().LoadString(IDS_MAINBROWSETEXT_STRING);
+
+			// set count of data to display
+			int iClipboardSize=pTask->GetClipboardDataSize();
+			int iEntries=(iClipboardSize > 3) ? 2 : iClipboardSize;
+			for (int i=0;i<iEntries;i++)
+				dlg.m_bdData.strText+=pTask->GetClipboardData(i)->GetPath()+_T("\n");
+
+			// add ...
+			if (iEntries < iClipboardSize)
+				dlg.m_bdData.strText+=_T("...");
+
+			// show window
+			int iResult=dlg.DoModal();
+
+			// set data to config
+			rConfig.clear_array_values(PP_SHORTCUTS);
+			for(char_vector::iterator it = dlg.m_bdData.cvShortcuts.begin(); it != dlg.m_bdData.cvShortcuts.end(); it++)
+			{
+				rConfig.set_string(PP_SHORTCUTS, (*it), icpf::property::action_add);
+			}
+
+			rConfig.clear_array_values(PP_RECENTPATHS);
+			for(char_vector::iterator it = dlg.m_bdData.cvRecent.begin(); it != dlg.m_bdData.cvRecent.end(); it++)
+			{
+				rConfig.set_string(PP_RECENTPATHS, (*it), icpf::property::action_add);
+			}
+
+			rConfig.set_bool(PP_FDEXTENDEDVIEW, dlg.m_bdData.bExtended);
+			rConfig.set_signed_num(PP_FDWIDTH, dlg.m_bdData.cx);
+			rConfig.set_signed_num(PP_FDHEIGHT, dlg.m_bdData.cy);
+			rConfig.set_signed_num(PP_FDSHORTCUTLISTSTYLE, dlg.m_bdData.iView);
+			rConfig.set_bool(PP_FDIGNORESHELLDIALOGS, dlg.m_bdData.bIgnoreDialogs);
+			rConfig.write(NULL);
+
+			if ( iResult != IDOK )
+				delete pTask;
+			else
+			{
+				// get dest path
+				CString strData;
+				dlg.GetPath(strData);
+				pTask->SetDestPath(strData);
+
+				// get the relationship between src and dst paths
+				for (int i=0;i<pTask->GetClipboard()->GetSize();i++)
+					pTask->GetClipboard()->GetAt(i)->CalcBufferIndex(pTask->GetDestPath());
+
+				// add task to a list of tasks and start
+				pData->m_pTasks->Add(pTask);
+
+				// write pTask to a file
+				pTask->Store(true);
+				pTask->Store(false);
+
+				// start processing
+				pTask->BeginProcessing();
+			}
+		}
+
+		// do we need to check for turning computer off
+		if (GetConfig().get_bool(PP_PSHUTDOWNAFTREFINISHED))
+		{
+			if (uiShutCounter == 0)
+			{
+				if (lFinished != pData->m_pTasks->m_lFinished)
+				{
+					bEnd=true;
+					lFinished=pData->m_pTasks->m_lFinished;
+				}
+
+				if (bEnd && pData->m_pTasks->IsFinished())
+				{
+					TRACE("Shut down windows\n");
+					bool bShutdown=true;
+					if (GetConfig().get_signed_num(PP_PTIMEBEFORESHUTDOWN) != 0)
+					{
+						CShutdownDlg dlg;
+						dlg.m_iOverallTime=(int)GetConfig().get_signed_num(PP_PTIMEBEFORESHUTDOWN);
+						if (dlg.m_iOverallTime < 0)
+							dlg.m_iOverallTime=-dlg.m_iOverallTime;
+						bShutdown=(dlg.DoModal() != IDCANCEL);
+					}
+
+					GetConfig().set_bool(PP_PSHUTDOWNAFTREFINISHED, false);
+					GetConfig().write(NULL);
+					if (bShutdown)
+					{
+						// adjust token privileges for NT
+						HANDLE hToken=NULL;
+						TOKEN_PRIVILEGES tp;
+						if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)
+							&& LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid))
+						{
+							tp.PrivilegeCount=1;
+							tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
+
+							AdjustTokenPrivileges(hToken, FALSE, &tp, NULL, NULL, NULL);
+						}
+
+						BOOL bExit=ExitWindowsEx(EWX_POWEROFF | EWX_SHUTDOWN | (GetConfig().get_bool(PP_PFORCESHUTDOWN) ? EWX_FORCE : 0), 0);
+						if (bExit)
+							return 1;
+						else
+						{
+							// some kind of error
+							ictranslate::CFormat fmt(GetResManager().LoadString(IDS_SHUTDOWNERROR_STRING));
+							fmt.SetParam(_t("%errno"), GetLastError());
+							AfxMessageBox(fmt, MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
+						}
+					}
+				}
+			}
+		}
+		else
+		{
+			bEnd=false;
+			lFinished=pData->m_pTasks->m_lFinished;
+		}
+
+		// sleep for some time
+		const int iSleepCount=200;
+		
+		if(WaitForSingleObject(pData->m_hKillEvent, iSleepCount) == WAIT_OBJECT_0)
+			break;
+		
+		uiCounter+=iSleepCount;
+		uiShutCounter+=iSleepCount;
+		if (uiCounter >= (UINT)GetConfig().get_signed_num(PP_PMONITORSCANINTERVAL))
+			uiCounter=0;
+		if (uiShutCounter >= 800)
+			uiShutCounter=0;
+	}
+
+	TRACE("Monitoring clipboard proc aborted...\n");
+
+	return 0;
+}
Index: src/ch/ClipboardMonitor.h
===================================================================
diff -u
--- src/ch/ClipboardMonitor.h	(revision 0)
+++ src/ch/ClipboardMonitor.h	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -0,0 +1,52 @@
+//******************************************************************************
+//   Copyright (C) 2001-2008 by Jozef Starosczyk
+//   ixen@copyhandler.com
+//
+//   This program is free software; you can redistribute it and/or modify
+//   it under the terms of the GNU Library General Public License
+//   (version 2) as published by the Free Software Foundation;
+//
+//   This program is distributed in the hope that it will be useful,
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//   GNU General Public License for more details.
+//
+//   You should have received a copy of the GNU Library General Public
+//   License along with this program; if not, write to the
+//   Free Software Foundation, Inc.,
+//   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+/// @file ClipboardMonitor.h
+/// @brief Contains clipboard monitoring package.
+//******************************************************************************
+#ifndef __CLIPBOARDMONITOR_H__
+#define __CLIPBOARDMONITOR_H__
+
+class CTaskArray;
+
+class CClipboardMonitor
+{
+public:
+	static bool StartMonitor(CTaskArray* pTasks);
+	static bool StopMonitor();
+
+	bool Start(CTaskArray* pTasks);
+	bool Stop();
+
+protected:
+	CClipboardMonitor();
+	~CClipboardMonitor();
+
+	static DWORD WINAPI ClipboardMonitorProc(LPVOID pParam);
+
+protected:
+	static CClipboardMonitor S_ClipboardMonitor;
+
+	CTaskArray* m_pTasks;
+
+	// thread control
+	HANDLE m_hThread;
+	HANDLE m_hKillEvent;
+};
+
+#endif
Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rbfe720fda9529e7a77b4fb6410b4d4945b69188b
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 449a5b399ab21ca0d06050b47b264f2f704af966)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -33,6 +33,7 @@
 #include "FeedbackHandler.h"
 #include "MiniviewDlg.h"
 #include "StatusDlg.h"
+#include "ClipboardMonitor.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -60,6 +61,22 @@
 
 /////////////////////////////////////////////////////////////////////////////
 // CMainWnd
+/////////////////////////////////////////////////////////////////////////////
+// CMainWnd construction/destruction
+CMainWnd::CMainWnd() :
+	m_pFeedbackFactory(CFeedbackHandlerFactory::CreateFactory()),
+	m_pdlgStatus(NULL),
+	m_pdlgMiniView(NULL),
+	m_dwLastTime(0)
+{
+}
+
+CMainWnd::~CMainWnd()
+{
+	if(m_pFeedbackFactory)
+		m_pFeedbackFactory->Delete();
+}
+
 // registers main window class
 ATOM CMainWnd::RegisterClass()
 {
@@ -132,268 +149,6 @@
 END_MESSAGE_MAP()
 
 /////////////////////////////////////////////////////////////////////////////
-// CMainWnd construction/destruction
-
-CMainWnd::CMainWnd() :
-	m_pFeedbackFactory(CFeedbackHandlerFactory::CreateFactory())
-{
-	m_pdlgStatus=NULL;
-	m_pdlgMiniView=NULL;
-	m_dwLastTime=0;
-}
-
-CMainWnd::~CMainWnd()
-{
-	if(m_pFeedbackFactory)
-		m_pFeedbackFactory->Delete();
-}
-
-UINT ClipboardMonitorProc(LPVOID pParam)
-{
-	volatile CLIPBOARDMONITORDATA* pData=static_cast<CLIPBOARDMONITORDATA *>(pParam);
-	ASSERT(pData->m_hwnd);
-
-	// bufor
-	TCHAR path[_MAX_PATH];
-//	UINT i;	// counter
-	CTask *pTask;	// ptr to a task
-	CClipboardEntry* pEntry=NULL;
-
-	// register clipboard format
-	UINT nFormat=RegisterClipboardFormat(_T("Preferred DropEffect"));
-	UINT uiCounter=0, uiShutCounter=0;;
-	LONG lFinished=0;
-	bool bEnd=false;
-
-	icpf::config& rConfig = GetConfig();
-	while (!pData->bKill)
-	{
-		if (uiCounter == 0 && rConfig.get_bool(PP_PCLIPBOARDMONITORING) && IsClipboardFormatAvailable(CF_HDROP))
-		{
-			// get data from clipboard
-			OpenClipboard(pData->m_hwnd);
-			HANDLE handle=GetClipboardData(CF_HDROP);
-
-			UINT nCount=DragQueryFile(static_cast<HDROP>(handle), 0xffffffff, NULL, 0);
-
-			pTask = pData->m_pTasks->CreateTask();
-
-			for (UINT i=0;i<nCount;i++)
-			{
-				DragQueryFile(static_cast<HDROP>(handle), i, path, _MAX_PATH);
-				pEntry=new CClipboardEntry;
-				pEntry->SetPath(path);
-				pTask->AddClipboardData(pEntry);
-			}
-			
-			if (IsClipboardFormatAvailable(nFormat))
-			{
-				handle=GetClipboardData(nFormat);
-				LPVOID addr=GlobalLock(handle);
-				
-				DWORD dwData=((DWORD*)addr)[0];
-				if (dwData & DROPEFFECT_COPY)
-					pTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// copy
-				else if (dwData & DROPEFFECT_MOVE)
-					pTask->SetStatus(ST_MOVE, ST_OPERATION_MASK);	// move
-
-				GlobalUnlock(handle);
-			}
-			else
-				pTask->SetStatus(ST_COPY, ST_OPERATION_MASK);	// default - copy
-
-			EmptyClipboard();
-			CloseClipboard();
-			
-			BUFFERSIZES bs;
-			bs.m_bOnlyDefault=rConfig.get_bool(PP_BFUSEONLYDEFAULT);
-			bs.m_uiDefaultSize=(UINT)rConfig.get_signed_num(PP_BFDEFAULT);
-			bs.m_uiOneDiskSize=(UINT)rConfig.get_signed_num(PP_BFONEDISK);
-			bs.m_uiTwoDisksSize=(UINT)rConfig.get_signed_num(PP_BFTWODISKS);
-			bs.m_uiCDSize=(UINT)rConfig.get_signed_num(PP_BFCD);
-			bs.m_uiLANSize=(UINT)rConfig.get_signed_num(PP_BFLAN);
-
-			pTask->SetBufferSizes(&bs);
-			pTask->SetPriority((int)rConfig.get_signed_num(PP_CMDEFAULTPRIORITY));
-
-			// get dest folder
-			CFolderDialog dlg;
-
-			const tchar_t* pszPath = NULL;
-			dlg.m_bdData.cvShortcuts.clear(true);
-			size_t stCount = rConfig.get_value_count(PP_SHORTCUTS);
-			for(size_t stIndex = 0; stIndex < stCount; stIndex++)
-			{
-				pszPath = rConfig.get_string(PP_SHORTCUTS, stIndex);
-				dlg.m_bdData.cvShortcuts.push_back(pszPath);
-			}
-
-			dlg.m_bdData.cvRecent.clear(true);
-			stCount = rConfig.get_value_count(PP_RECENTPATHS);
-			for(size_t stIndex = 0; stIndex < stCount; stIndex++)
-			{
-				pszPath = rConfig.get_string(PP_RECENTPATHS, stIndex);
-					dlg.m_bdData.cvRecent.push_back(pszPath);
-			}
-
-			dlg.m_bdData.bExtended=rConfig.get_bool(PP_FDEXTENDEDVIEW);
-			dlg.m_bdData.cx=(int)rConfig.get_signed_num(PP_FDWIDTH);
-			dlg.m_bdData.cy=(int)rConfig.get_signed_num(PP_FDHEIGHT);
-			dlg.m_bdData.iView=(int)rConfig.get_signed_num(PP_FDSHORTCUTLISTSTYLE);
-			dlg.m_bdData.bIgnoreDialogs=rConfig.get_bool(PP_FDIGNORESHELLDIALOGS);
-
-			dlg.m_bdData.strInitialDir=(dlg.m_bdData.cvRecent.size() > 0) ? dlg.m_bdData.cvRecent.at(0) : _T("");
-
-			int iStatus=pTask->GetStatus(ST_OPERATION_MASK);
-			if (iStatus == ST_COPY)
-				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLECOPY_STRING);
-			else if (iStatus == ST_MOVE)
-				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLEMOVE_STRING);
-			else
-				dlg.m_bdData.strCaption=GetResManager().LoadString(IDS_TITLEUNKNOWNOPERATION_STRING);
-			dlg.m_bdData.strText=GetResManager().LoadString(IDS_MAINBROWSETEXT_STRING);
-			
-			// set count of data to display
-			int iClipboardSize=pTask->GetClipboardDataSize();
-			int iEntries=(iClipboardSize > 3) ? 2 : iClipboardSize;
-			for (int i=0;i<iEntries;i++)
-				dlg.m_bdData.strText+=pTask->GetClipboardData(i)->GetPath()+_T("\n");
-
-			// add ...
-			if (iEntries < iClipboardSize)
-				dlg.m_bdData.strText+=_T("...");
-
-			// show window
-			int iResult=dlg.DoModal();
-
-			// set data to config
-			rConfig.clear_array_values(PP_SHORTCUTS);
-			for(char_vector::iterator it = dlg.m_bdData.cvShortcuts.begin(); it != dlg.m_bdData.cvShortcuts.end(); it++)
-			{
-				rConfig.set_string(PP_SHORTCUTS, (*it), icpf::property::action_add);
-			}
-
-			rConfig.clear_array_values(PP_RECENTPATHS);
-			for(char_vector::iterator it = dlg.m_bdData.cvRecent.begin(); it != dlg.m_bdData.cvRecent.end(); it++)
-			{
-				rConfig.set_string(PP_RECENTPATHS, (*it), icpf::property::action_add);
-			}
-
-			rConfig.set_bool(PP_FDEXTENDEDVIEW, dlg.m_bdData.bExtended);
-			rConfig.set_signed_num(PP_FDWIDTH, dlg.m_bdData.cx);
-			rConfig.set_signed_num(PP_FDHEIGHT, dlg.m_bdData.cy);
-			rConfig.set_signed_num(PP_FDSHORTCUTLISTSTYLE, dlg.m_bdData.iView);
-			rConfig.set_bool(PP_FDIGNORESHELLDIALOGS, dlg.m_bdData.bIgnoreDialogs);
-			rConfig.write(NULL);
-
-			if ( iResult != IDOK )
-				delete pTask;
-			else
-			{
-				// get dest path
-				CString strData;
-				dlg.GetPath(strData);
-				pTask->SetDestPath(strData);
-
-				// get the relationship between src and dst paths
-				for (int i=0;i<pTask->GetClipboard()->GetSize();i++)
-					pTask->GetClipboard()->GetAt(i)->CalcBufferIndex(pTask->GetDestPath());
-
-				// add task to a list of tasks and start
-				pData->m_pTasks->Add(pTask);
-
-				// write pTask to a file
-				pTask->Store(true);
-				pTask->Store(false);
-				
-				// start processing
-				pTask->BeginProcessing();
-			}
-		}
-		
-		// do we need to check for turning computer off
-		if (GetConfig().get_bool(PP_PSHUTDOWNAFTREFINISHED))
-		{
-			if (uiShutCounter == 0)
-			{
-				if (lFinished != pData->m_pTasks->m_lFinished)
-				{
-					bEnd=true;
-					lFinished=pData->m_pTasks->m_lFinished;
-				}
-				
-				if (bEnd && pData->m_pTasks->IsFinished())
-				{
-					TRACE("Shut down windows\n");
-					bool bShutdown=true;
-					if (GetConfig().get_signed_num(PP_PTIMEBEFORESHUTDOWN) != 0)
-					{
-						CShutdownDlg dlg;
-						dlg.m_iOverallTime=(int)GetConfig().get_signed_num(PP_PTIMEBEFORESHUTDOWN);
-						if (dlg.m_iOverallTime < 0)
-							dlg.m_iOverallTime=-dlg.m_iOverallTime;
-						bShutdown=(dlg.DoModal() != IDCANCEL);
-					}
-					
-					GetConfig().set_bool(PP_PSHUTDOWNAFTREFINISHED, false);
-					GetConfig().write(NULL);
-					if (bShutdown)
-					{
-						// we're killed
-						pData->bKilled=true;
-						
-						// adjust token privileges for NT
-						HANDLE hToken=NULL;
-						TOKEN_PRIVILEGES tp;
-						if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)
-							&& LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid))
-						{
-							tp.PrivilegeCount=1;
-							tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
-							
-							AdjustTokenPrivileges(hToken, FALSE, &tp, NULL, NULL, NULL);
-						}
-						
-						BOOL bExit=ExitWindowsEx(EWX_POWEROFF | EWX_SHUTDOWN | (GetConfig().get_bool(PP_PFORCESHUTDOWN) ? EWX_FORCE : 0), 0);
-						if (bExit)
-							return 1;
-						else
-						{
-							pData->bKilled=false;
-							
-							// some kind of error
-							ictranslate::CFormat fmt(GetResManager().LoadString(IDS_SHUTDOWNERROR_STRING));
-							fmt.SetParam(_t("%errno"), GetLastError());
-							AfxMessageBox(fmt, MB_ICONERROR | MB_OK | MB_SYSTEMMODAL);
-						}
-					}
-				}
-			}
-		}
-		else
-		{
-			bEnd=false;
-			lFinished=pData->m_pTasks->m_lFinished;
-		}
-		
-		// sleep for some time
-		const int iSleepCount=200;
-		Sleep(iSleepCount);
-		uiCounter+=iSleepCount;
-		uiShutCounter+=iSleepCount;
-		if (uiCounter >= (UINT)GetConfig().get_signed_num(PP_PMONITORSCANINTERVAL))
-			uiCounter=0;
-		if (uiShutCounter >= 800)
-			uiShutCounter=0;
-	}
-
-	pData->bKilled=true;
-	TRACE("Monitoring clipboard proc aborted...\n");
-
-	return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////
 // CMainWnd message handlers
 
 int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
@@ -420,12 +175,7 @@
 	m_tasks.TasksRetryProcessing();
 
 	// start clipboard monitoring
-	cmd.bKill=false;
-	cmd.bKilled=false;
-	cmd.m_hwnd=this->m_hWnd;
-	cmd.m_pTasks=&m_tasks;
-
-	AfxBeginThread(&ClipboardMonitorProc, static_cast<LPVOID>(&cmd), THREAD_PRIORITY_IDLE);
+	CClipboardMonitor::StartMonitor(&m_tasks);
 	
 	// start saving timer
 	SetTimer(1023, (UINT)GetConfig().get_signed_num(PP_PAUTOSAVEINTERVAL), NULL);
@@ -1112,9 +862,7 @@
 void CMainWnd::PrepareToExit()
 {
 	// kill thread that monitors clipboard
-	cmd.bKill=true;
-	while (!cmd.bKilled)
-		Sleep(10);
+	CClipboardMonitor::StopMonitor();
 
 	// kill all unfinished tasks - send kill request
 	for (int i=0;i<m_tasks.GetSize();i++)
Index: src/ch/MainWnd.h
===================================================================
diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rbfe720fda9529e7a77b4fb6410b4d4945b69188b
--- src/ch/MainWnd.h	(.../MainWnd.h)	(revision 449a5b399ab21ca0d06050b47b264f2f704af966)
+++ src/ch/MainWnd.h	(.../MainWnd.h)	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -38,7 +38,6 @@
 // Attributes
 public:
 	CTrayIcon m_ctlTray;
-	CLIPBOARDMONITORDATA cmd;
 	
 	CTaskArray m_tasks;
 	chcore::IFeedbackHandlerFactory* m_pFeedbackFactory;
Index: src/ch/Structs.h
===================================================================
diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rbfe720fda9529e7a77b4fb6410b4d4945b69188b
--- src/ch/Structs.h	(.../Structs.h)	(revision 449a5b399ab21ca0d06050b47b264f2f704af966)
+++ src/ch/Structs.h	(.../Structs.h)	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -27,16 +27,4 @@
 int IndexToPriorityClass(int iIndex);
 int PriorityClassToIndex(int iPriority);
 
-///////////////////////////////////////////////////////////////////////////
-// CLIPBOARDMONITORDATA
-class CTaskArray;
-
-struct CLIPBOARDMONITORDATA
-{
-	HWND m_hwnd;	// hwnd to window
-	CTaskArray *m_pTasks;
-
-	volatile bool bKill, bKilled;
-};
-
 #endif
\ No newline at end of file
Index: src/ch/ch.cpp
===================================================================
diff -u -raa6bff57279b9f9cfc276e9adab2763e2900878d -rbfe720fda9529e7a77b4fb6410b4d4945b69188b
--- src/ch/ch.cpp	(.../ch.cpp)	(revision aa6bff57279b9f9cfc276e9adab2763e2900878d)
+++ src/ch/ch.cpp	(.../ch.cpp)	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -84,7 +84,6 @@
 
 CCopyHandlerApp::CCopyHandlerApp() :
 	m_lfLog(),
-	m_cfgSettings(icpf::config::eIni),
 	m_piShellExtControl(NULL)
 {
 	m_pMainWindow=NULL;
@@ -122,18 +121,13 @@
 
 ictranslate::CResourceManager& GetResManager()
 {
-	return theApp.m_resManager;
+	return ictranslate::CResourceManager::Acquire();
 }
 
 chcore::engine_config& GetConfig()
 {
-	return theApp.m_cfgSettings;
+	return chcore::engine_config::Acquire();
 }
-/*
-CLogFile* GetLog()
-{
-	return &theApp.m_lfLog;
-}*/
 
 int MsgBox(UINT uiID, UINT nType, UINT nIDHelp)
 {
@@ -247,8 +241,11 @@
 	if (g_pscsShared == NULL) 
 		return FALSE; 
 	
+	chcore::engine_config& rConfig = chcore::engine_config::Acquire();
+	ictranslate::CResourceManager& rResManager = ictranslate::CResourceManager::Acquire();
+
 	// load configuration
-	m_cfgSettings.set_callback(ConfigPropertyChangedCallback, NULL);
+	rConfig.set_callback(ConfigPropertyChangedCallback, NULL);
 	CString strPath;
 	// note that the GetProgramDataPath() below should create a directory; ExpandPath() could
 	// depend on the directory to be created earlier
@@ -257,29 +254,29 @@
 		strPath += _T("\\ch.ini");
 		try
 		{
-			m_cfgSettings.read(strPath);
+			rConfig.read(strPath);
 		}
 		catch(...)
 		{
 		}
 	}
 
 	// set working dir for the engine
-	m_cfgSettings.set_base_path(strPath);
+	rConfig.set_base_path(strPath);
 	// register all properties
-	RegisterProperties(&m_cfgSettings);
+	RegisterProperties(&rConfig);
 
 	// set this process class
 	HANDLE hProcess=GetCurrentProcess();
-	::SetPriorityClass(hProcess, (DWORD)m_cfgSettings.get_signed_num(PP_PPROCESSPRIORITYCLASS));
+	::SetPriorityClass(hProcess, (DWORD)rConfig.get_signed_num(PP_PPROCESSPRIORITYCLASS));
 
 	// set current language
 	TCHAR szPath[_MAX_PATH];
-	m_resManager.Init(AfxGetInstanceHandle());
-	m_resManager.SetCallback(ResManCallback);
-	m_cfgSettings.get_string(PP_PLANGUAGE, szPath, _MAX_PATH);
+	rResManager.Init(AfxGetInstanceHandle());
+	rResManager.SetCallback(ResManCallback);
+	rConfig.get_string(PP_PLANGUAGE, szPath, _MAX_PATH);
 	TRACE(_T("Help path=%s\n"), szPath);
-	if (!m_resManager.SetLanguage(ExpandPath(szPath)))
+	if (!rResManager.SetLanguage(ExpandPath(szPath)))
 	{
 		TCHAR szData[2048];
 		_sntprintf(szData, 2048, _T("Couldn't find the language file specified in configuration file:\n%s\nPlease correct this path to point the language file to use.\nProgram will now exit."), szPath);
@@ -290,11 +287,11 @@
 	UpdateHelpPaths();
 
 	// for dialogs
-	ictranslate::CLanguageDialog::SetResManager(&m_resManager);
+	ictranslate::CLanguageDialog::SetResManager(&rResManager);
 
 	// initialize log file
-	m_cfgSettings.get_string(PP_LOGPATH, szPath, _MAX_PATH);
-	m_lfLog.init(ExpandPath(szPath), (int_t)m_cfgSettings.get_signed_num(PP_LOGMAXLIMIT), icpf::log_file::level_debug, false, false);
+	rConfig.get_string(PP_LOGPATH, szPath, _MAX_PATH);
+	m_lfLog.init(ExpandPath(szPath), (int_t)rConfig.get_signed_num(PP_LOGMAXLIMIT), icpf::log_file::level_debug, false, false);
 
 	// TODO: remove unused properties from configuration
 /*	m_lfLog.EnableLogging(m_cfgManager.GetBoolValue(PP_LOGENABLELOGGING));
@@ -305,7 +302,7 @@
 
 #ifndef _DEBUG		// for easier writing the program - doesn't collide with std CH
 	// set "run with system" registry settings
-	SetAutorun(m_cfgSettings.get_bool(PP_PRELOADAFTERRESTART));
+	SetAutorun(rConfig.get_bool(PP_PRELOADAFTERRESTART));
 #endif
 
 	// check instance - return false if it's the second one
@@ -369,8 +366,8 @@
 	{
 		// update language in resource manager
 		TCHAR szPath[_MAX_PATH];
-		m_cfgSettings.get_string(PP_PLANGUAGE, szPath, _MAX_PATH);
-		m_resManager.SetLanguage(ExpandPath(szPath));
+		GetConfig().get_string(PP_PLANGUAGE, szPath, _MAX_PATH);
+		GetResManager().SetLanguage(ExpandPath(szPath));
 	}
 }
 
Index: src/ch/ch.h
===================================================================
diff -u -raa6bff57279b9f9cfc276e9adab2763e2900878d -rbfe720fda9529e7a77b4fb6410b4d4945b69188b
--- src/ch/ch.h	(.../ch.h)	(revision aa6bff57279b9f9cfc276e9adab2763e2900878d)
+++ src/ch/ch.h	(.../ch.h)	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -70,9 +70,6 @@
 	HWND HHelp(HWND hwndCaller, LPCTSTR pszFile, UINT uCommand, DWORD dwData);
 
 public:
-	ictranslate::CResourceManager m_resManager;
-//	CConfigManager m_cfgManager;
-	chcore::engine_config m_cfgSettings;
 	icpf::log_file m_lfLog;
 
 	IShellExtControl* m_piShellExtControl;
Index: src/ch/ch.vc90.vcproj
===================================================================
diff -u -r49b67b7417f8b42ce581ebfe604f47df841f763b -rbfe720fda9529e7a77b4fb6410b4d4945b69188b
--- src/ch/ch.vc90.vcproj	(.../ch.vc90.vcproj)	(revision 49b67b7417f8b42ce581ebfe604f47df841f763b)
+++ src/ch/ch.vc90.vcproj	(.../ch.vc90.vcproj)	(revision bfe720fda9529e7a77b4fb6410b4d4945b69188b)
@@ -501,6 +501,14 @@
 					>
 				</File>
 				<File
+					RelativePath=".\ClipboardMonitor.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\ClipboardMonitor.h"
+					>
+				</File>
+				<File
 					RelativePath="..\common\FileSupport.cpp"
 					>
 				</File>