Click here to Skip to main content
15,895,142 members
Articles / Desktop Programming / MFC

Auto-Task Tool for Web Game Travian

Rate me:
Please Sign up or sign in to vote.
4.84/5 (26 votes)
29 Oct 20075 min read 783.5K   7.1K   45  
Developing Auto-Task Tool for Web Game Travian
// FormTask.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "TravianAutoTask.h"
#include "FormTask.h"


// CFormTask

IMPLEMENT_DYNCREATE(CFormTask, CFormView)

CFormTask::CFormTask()
	: CFormView(CFormTask::IDD)
	, m_sUsr(_T(""))
	, m_sPwd(_T(""))
	, m_sSvr(_T(""))
	, m_sTaskFileName(_T(""))
	, m_pThread(NULL)
{

}

CFormTask::~CFormTask()
{
}

void CFormTask::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_USR, m_sUsr);
	DDX_Text(pDX, IDC_PWD, m_sPwd);
	DDX_Text(pDX, IDC_SVR, m_sSvr);
	DDX_Text(pDX, IDC_TASKFILENAME, m_sTaskFileName);
}

BEGIN_MESSAGE_MAP(CFormTask, CFormView)
	ON_UPDATE_COMMAND_UI(ID_FILE_OPEN,				&CFormTask::OnUpdateFileOpen)
	ON_COMMAND(ID_FILE_OPEN,						&CFormTask::OnFileOpen)
	ON_BN_CLICKED(IDC_BTN_BROWSE,					&CFormTask::OnBnClickedBtnBrowse)
	ON_BN_CLICKED(ID_BTN_START,						&CFormTask::OnBnClickedStart)
	ON_BN_CLICKED(IDC_RADIO_SHUTDOWN,				&CFormTask::OnBnClickedRadioShutdown)
	ON_BN_CLICKED(IDC_RADIO_CLOSE,					&CFormTask::OnBnClickedRadioClose)
	ON_MESSAGE (WM_USERMSG_TASK_SETPARAM_FINISHED,	&CFormTask::OnTaskSetParamFinished)
	ON_MESSAGE (WM_USERMSG_TASK_EXECSTATE,			&CFormTask::OnTaskExecState)
	ON_MESSAGE (WM_USERMSG_SCHEDULE_FINISHED,		&CFormTask::OnScheduleFinished)
	ON_WM_DRAWITEM()
	ON_WM_CTLCOLOR()
	ON_BN_CLICKED(IDC_RADIO_ACTIONNONE, &CFormTask::OnBnClickedRadioActionnone)
END_MESSAGE_MAP()


// CFormTask diagnostics

#ifdef _DEBUG
void CFormTask::AssertValid() const
{
	CFormView::AssertValid();
}

#ifndef _WIN32_WCE
void CFormTask::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif
#endif //_DEBUG


//
// CFormTask message handlers
//
void CFormTask::OnInitialUpdate()
{
	// TODO: Add your specialized code here and/or call the base class

	CFormView::OnInitialUpdate();
	GetDlgItem(IDC_SVR)->ModifyStyle(WS_SIZEBOX | WS_MAXIMIZEBOX, WS_BORDER);
	GetDlgItem(IDC_SVR)->ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE, 0, SWP_DRAWFRAME);

	GetDlgItem(IDC_USR)->ModifyStyle(WS_SIZEBOX | WS_MAXIMIZEBOX, WS_BORDER);
	GetDlgItem(IDC_USR)->ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE, 0, SWP_DRAWFRAME);

	GetDlgItem(IDC_PWD)->ModifyStyle(WS_SIZEBOX | WS_MAXIMIZEBOX, WS_BORDER);
	GetDlgItem(IDC_PWD)->ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE, 0, SWP_DRAWFRAME);

	GetDlgItem(IDC_TASKFILENAME)->ModifyStyle(WS_SIZEBOX | WS_MAXIMIZEBOX, WS_BORDER);
	GetDlgItem(IDC_TASKFILENAME)->ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE, 0, SWP_DRAWFRAME);

}

void DoGradientFill(CDC *pDC, CRect& rect, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	int nWidth = (rect.right) - (rect.left);
    int nHeight = (rect.bottom) - (rect.top);
	COLORREF cr[64];
	CRect r;
	int i;

	for(i=0; i<64; i++)
	{

		if(lpDrawItemStruct->itemState & ODS_HOTLIGHT)
		{
			if( lpDrawItemStruct->itemState & ODS_SELECTED ||
				lpDrawItemStruct->itemState & ODS_FOCUS	   ||
				lpDrawItemStruct->itemState & ODS_DEFAULT)
			{
				cr[i] = RGB(255-(i/4), 255-(i/4), 255-(i/3));
			}
			else
			{
				cr[i] = RGB(255-(i/4), 255-(i/4), 255-(i/5));
			}
		}
		else
		{
			if( lpDrawItemStruct->itemState & ODS_SELECTED ||
				lpDrawItemStruct->itemState & ODS_FOCUS	   ||
				lpDrawItemStruct->itemState & ODS_DEFAULT)
			{
				cr[i] = RGB(255-(i/3), 255-(i/3), 255-(i/4));
			}
			else
			{
				cr[i] = RGB(255-(i/3), 255-(i/3), 255-(i/5));
			}
		}

		//pDC->GradientFill(vert,2, &gRect,1, GRADIENT_FILL_RECT_V);
		//pDC->FillSolidRect(r, cr[i]);
	}

	for (i=rect.top; i<nHeight+2; i++) 
	{
		r.SetRect (rect.left, i, nWidth+2, i + 1);
		if (i==nHeight+1)
			pDC->FillSolidRect(r, cr[(( (i-1) * 63) / nHeight)]);
		else
			pDC->FillSolidRect(r, cr[((i * 63) / nHeight)]);
    }
	////GetSystemMetrics(SM_CXEDGE) is 2
	r.SetRect (rect.left+2, i, nWidth, i+1);
	pDC->FillSolidRect(&r, cr[(( (i-2) * 63) / nHeight)]);
}

struct BUTTON_PARAM
{
	CPen PenBoundry;
	CPen PenInsideBorder;
	CBrush BrushFillActive;
	CBrush BrushFillInactive;
	BUTTON_PARAM() {
		PenBoundry.CreatePen(PS_INSIDEFRAME|PS_SOLID, 1 ,RGB(0,0,0));
		//PenSel.CreatePen(PS_DOT, 1 ,RGB(0,0,0));
		PenInsideBorder.CreatePen(PS_SOLID,3,RGB(250,196,88));
		BrushFillActive.CreateSolidBrush( RGB(222,223,236) );
		BrushFillInactive.CreateSolidBrush( RGB(222,223,236) );
	};
	~BUTTON_PARAM() {
		PenBoundry.DeleteObject();
		PenInsideBorder.DeleteObject();
		BrushFillActive.DeleteObject();
		BrushFillInactive.DeleteObject();
	};
};
static BUTTON_PARAM btn_param;

void DrawInsideBorder(CDC *pDC, CRect& rect, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CPoint oldpoint = pDC->MoveTo(rect.left, rect.bottom-3);
	CPen* pOldPen = pDC->SelectObject(& (btn_param.PenInsideBorder) );
	
	pDC->LineTo(rect.left,rect.top+2);
	pDC->MoveTo(rect.right-1,rect.bottom-3);
	pDC->LineTo(rect.right-1,rect.top+2);
	pDC->MoveTo(rect.left+2,rect.top);
	pDC->LineTo(rect.right-2,rect.top);
	pDC->MoveTo(rect.left+2,rect.bottom-1);
	pDC->LineTo(rect.right-2,rect.bottom-1);

	pDC->SelectObject(pOldPen);	
	pDC->MoveTo(oldpoint);
}


void CFormTask::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	// TODO: Add your message handler code here and/or call default

	//if ( nIDCtrl != ID_BTN_START && nIDCtrl != IDC_BTN_BROWSE)
	if ( lpDrawItemStruct->CtlType != ODT_BUTTON)
		CFormView::OnDrawItem(nIDCtl, lpDrawItemStruct);


	CDC dc;
	dc.Attach(lpDrawItemStruct->hDC);
	CRect rect = lpDrawItemStruct->rcItem;
	CPoint pt;
	TCHAR szText[MAX_PATH];
	ZeroMemory(szText, MAX_PATH);
	::GetWindowText(lpDrawItemStruct->hwndItem, szText, MAX_PATH);
	CPen* pOldPen;
	CBrush* pOldBrush;
	
    // draw the control edges
	
	pt.x = 10;
	pt.y = 10;
	
	pOldPen = dc.SelectObject( &(btn_param.PenBoundry) );
	
	dc.RoundRect(rect, pt);
	//dc.Rectangle(rect);
    dc.SelectObject(pOldPen);
	// Deflate the drawing rect by the size of the button's edges
    rect.DeflateRect( CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));

	// Fill the interior color if necessary
	if (lpDrawItemStruct->itemState & ODS_HOTLIGHT)
	{
		pOldBrush = dc.SelectObject( &(btn_param.BrushFillActive) );   
		DoGradientFill(&dc, rect, lpDrawItemStruct);		
	}
	else
	{
		pOldBrush = dc.SelectObject( &(btn_param.BrushFillInactive) );   
		DoGradientFill(&dc, rect, lpDrawItemStruct);
	}
	dc.SelectObject(pOldBrush);

	POINT ptCursor;
	GetCursorPos (&ptCursor);
	if ( //!(lpDrawItemStruct->itemState & ODS_SELECTED) &&
		 //!(lpDrawItemStruct->itemState & ODS_FOCUS) &&
		 !(lpDrawItemStruct->itemState & ODS_DISABLED) &&
		 ::ScreenToClient(lpDrawItemStruct->hwndItem, &ptCursor) )	// mouse hover on this ctrl
	//if (lpDrawItemStruct->itemState & ODS_HOTLIGHT)
	{
		if (ptCursor.x >= rect.left &&
			ptCursor.y >= rect.top &&
			ptCursor.x <= rect.right &&
			ptCursor.y <= rect.bottom )		
			DrawInsideBorder(&dc, rect, lpDrawItemStruct);
	}

	if( lpDrawItemStruct->itemState & ODS_SELECTED ||
		lpDrawItemStruct->itemState & ODS_DEFAULT)
	{
		rect.DeflateRect(2, 2);
		dc.DrawFocusRect(&rect);
	}


	// Draw the text
	int nTextLen = _tcslen(szText);
    if ( nTextLen > 0 )
    {
        CSize Extent = dc.GetTextExtent( szText );
        CPoint ptText( rect.CenterPoint().x - Extent.cx/2, rect.CenterPoint().y - Extent.cy/2 );
		
        if (lpDrawItemStruct->itemState & ODS_SELECTED) 
		{
            ptText.Offset(1,1);
			rect.OffsetRect(1,1);
		}
		
        int nMode = dc.SetBkMode(TRANSPARENT);
		
        if (lpDrawItemStruct->itemState & ODS_DISABLED)
            dc.DrawState(ptText, Extent, szText, DSS_DISABLED, TRUE, nTextLen, (HBRUSH)NULL);
        else
            //dc.TextOut(ptText.x, ptText.y, szText);
			dc.DrawText(szText, nTextLen, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
		dc.SetBkMode(nMode);
    }


	dc.Detach();

	CFormView::OnDrawItem(nIDCtl, lpDrawItemStruct);
}


HBRUSH CFormTask::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  Change any attributes of the DC here

	if(nCtlColor==CTLCOLOR_LISTBOX)   
	{   
		//pDC->SetBkMode(TRANSPARENT);   
		pDC->SetTextColor(RGB(0,0,0));   
		pDC->SetBkColor( g_crBkgnd );   
		HBRUSH   b=CreateSolidBrush( g_crBkgnd );   
		return   b;   
	}   
	else   if(nCtlColor==CTLCOLOR_SCROLLBAR)   
	{   
		//pDC->SetBkMode(TRANSPARENT);   
		pDC->SetTextColor(RGB(0,0,0));   
		pDC->SetBkColor( g_crBkgnd );   
		HBRUSH   b=CreateSolidBrush( g_crBkgnd );   
		return   b;   
	}   
	else   if(nCtlColor==CTLCOLOR_EDIT)   
	{   
		pDC->SetBkMode(TRANSPARENT);   
		pDC->SetTextColor(RGB(0,0,0));   
		pDC->SetBkColor( g_crBkgnd );   
		HBRUSH   b=CreateSolidBrush( g_crBkgnd );   
		return   b;   
	}   
	else   if(nCtlColor==CTLCOLOR_STATIC)   
	{   
		pDC->SetTextColor(RGB(0,0,0));   
		pDC->SetBkColor( g_crBkgnd );   
		HBRUSH   b=CreateSolidBrush( g_crBkgnd );   
		return   b;   
	}
	// CButton (not ownerdraw style) is the only one ctrl that doesn't response to WM_CTRLCOLOR msg.
	else if (nCtlColor == CTLCOLOR_BTN)
	{
		pDC->SetBkMode(TRANSPARENT);   
		//pDC->SetTextColor(RGB(0,0,0));   
		//pDC->SetBkColor( g_crBkgnd );   
		//HBRUSH   b=CreateSolidBrush( g_crBkgnd );   
		//return   b;   
		HBRUSH   b=CreateSolidBrush( pDC->GetDCBrushColor() );   
		return   b;   
	}
	else   if(nCtlColor==CTLCOLOR_DLG)   
	{   
		pDC->SetTextColor(RGB(0,0,0));   
		pDC->SetBkColor( g_crBkgnd );   
		HBRUSH   b=CreateSolidBrush( g_crBkgnd );   
		return   b;   
	}  


	// TODO:  Return a different brush if the default is not desired
	return hbr;
}

void CFormTask::OnUpdateFileOpen(CCmdUI *pCmdUI)
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( GetDlgItem(ID_BTN_START)->IsWindowEnabled() );
}

void CFormTask::OnFileOpen()
{
	// TODO: Add your command handler code here

	OnBnClickedBtnBrowse();
}

void CFormTask::OnBnClickedBtnBrowse()
{
	// TODO: Add your control notification handler code here
	CFileDialog dlg(TRUE, _T("txt"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		_T("Text files(*.txt)|*.txt|All files(*.*)|*.*||"), NULL);

	BOOL bRet = FALSE;
	if (dlg.DoModal() == IDOK)
	{
		GetDlgItem(IDC_TASKFILENAME)->SetWindowText(dlg.GetPathName());
		UpdateData(TRUE);

		Tasks* pts = new Tasks();
		if (! CTravianTask::GetTasks(dlg.GetPathName(), *pts, g_TravianEvtLog) )
		{
			m_pViewTaskList->SetTasks(NULL);
			delete pts;
			return;
		}

		m_pViewTaskList->SetTasks(pts);
	}
}


void CFormTask::OnBnClickedStart()
{
	if (NULL == m_pViewTaskList->GetTasks() &&
		m_sTaskFileName.GetLength() == 0)
	{
		MessageBox(_T("Please select tasks file first."), _T("Error"), MB_ICONSTOP);
		return;
	}
	if (m_pViewTaskList->GetTasks()->size() ==0)
	{
		MessageBox(_T("Tasks queue empty!"), _T("Error"), MB_ICONSTOP);
		return;
	}

	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if (m_sSvr.GetLength() <=0 || m_sUsr.GetLength() <=0 || m_sPwd.GetLength() <=0 ||
		m_sTaskFileName.GetLength() <=0 )
	{
		AfxMessageBox(_T("Please input server, task file name, user name and password!"), MB_OK | MB_ICONERROR);
		return;
	}

	bool bInit = false;
	if (!m_pThread)
	{
		bInit = true;

		// Create schedule thread. The thread is created suspended so that we can
		// set variables in CThreadSchedule before it starts executing.
		m_pThread = (CThreadSchedule*)AfxBeginThread(RUNTIME_CLASS(CThreadSchedule), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
		if (!m_pThread)
		{
			AfxMessageBox(_T("Could not create connection thread\n"), MB_ICONSTOP);
			return;
		}
		
		//if (!m_pThread->InitSchedule(&g_TravianEvtLog, m_hWnd, m_sSvr, m_sUsr, m_sPwd, m_sTaskFileName))
		//{
		//	PostQuitMessage(0);
		//	return ;
		//}
		m_pThread->ResumeThread();
		m_dwThreadID = m_pThread->m_nThreadID;	// stores schedule thread id, so we can post WM_QUIT to it in case that we don't know whether this thread ends.
		m_hThread = m_pThread->m_hThread;
	}

	CThreadSchedule::ScheduleParam* pParam = new CThreadSchedule::ScheduleParam();
	pParam->SetWnd(this->m_hWnd);
	pParam->SetEventLog(&g_TravianEvtLog);
	pParam->SetSvr(m_sSvr);
	pParam->SetUserPwd(m_sUsr, m_sPwd);
	//pParam->SetTaskFileName(m_sTaskFileName);
	pParam->SetTasks(*m_pViewTaskList->GetTasks());
	if ( ((CButton*)(GetDlgItem(IDC_RADIO_SHUTDOWN)))->GetCheck() == BST_CHECKED )
		pParam->SetAction(E_ACTION_SHUTDOWN);
	if (  ((CButton*)(GetDlgItem(IDC_RADIO_CLOSE)))->GetCheck() == BST_CHECKED )
		pParam->SetAction(E_ACTION_EXIT);
	if (  ((CButton*)(GetDlgItem(IDC_RADIO_ACTIONNONE)))->GetCheck() == BST_CHECKED )
		pParam->SetAction(E_ACTION_NONE);

	if (bInit)
		::PostThreadMessage(m_pThread->m_nThreadID, WM_THREADMSG_SCHEDULE_INIT, 0, 0);
	::PostThreadMessage(m_pThread->m_nThreadID, WM_THREADMSG_SCHEDULE_SETPARAM, 0, (LPARAM)pParam);

	GetDlgItem(IDC_USER)->EnableWindow(FALSE);
	GetDlgItem(IDC_PWD)->EnableWindow(FALSE);
	GetDlgItem(IDC_SVR)->EnableWindow(FALSE);
	GetDlgItem(IDC_TASKFILENAME)->EnableWindow(FALSE);
	GetDlgItem(IDC_BTN_BROWSE)->EnableWindow(FALSE);
	GetDlgItem(ID_BTN_START)->EnableWindow(FALSE);


	return ;  // return TRUE unless you set the focus to a control
}
void CFormTask::OnBnClickedRadioShutdown()
{
	if (!m_pThread) return;
	if ( ((CButton*)(GetDlgItem(IDC_RADIO_SHUTDOWN)))->GetCheck() != BST_CHECKED ) return;

	// TODO: Add your control notification handler code here
	CThreadSchedule::ScheduleParam* pParam = new CThreadSchedule::ScheduleParam();
	pParam->SetAction(E_ACTION_SHUTDOWN);

	::PostThreadMessage(m_pThread->m_nThreadID, WM_THREADMSG_SCHEDULE_SETPARAM, 0, (LPARAM)pParam);

}

void CFormTask::OnBnClickedRadioClose()
{
	if (!m_pThread) return;
	if ( ((CButton*)(GetDlgItem(IDC_RADIO_CLOSE)))->GetCheck() != BST_CHECKED ) return;

	// TODO: Add your control notification handler code here
	CThreadSchedule::ScheduleParam* pParam = new CThreadSchedule::ScheduleParam();
	pParam->SetAction(E_ACTION_EXIT);

	::PostThreadMessage(m_pThread->m_nThreadID, WM_THREADMSG_SCHEDULE_SETPARAM, 0, (LPARAM)pParam);

}

void CFormTask::OnBnClickedRadioActionnone()
{
	// TODO: Add your control notification handler code here
	if (!m_pThread) return;
	if ( ((CButton*)(GetDlgItem(IDC_RADIO_ACTIONNONE)))->GetCheck() != BST_CHECKED ) return;

	CThreadSchedule::ScheduleParam* pParam = new CThreadSchedule::ScheduleParam();
	pParam->SetAction(E_ACTION_NONE);

	::PostThreadMessage(m_pThread->m_nThreadID, WM_THREADMSG_SCHEDULE_SETPARAM, 0, (LPARAM)pParam);
}

LRESULT CFormTask::OnTaskSetParamFinished(WPARAM wParam, LPARAM lParam)
{
	// wParam indicates whether tasks parameter set successful(1) or failed(0). 
	// LPARAM is the pointer of returned Tasks object, user needs to delete this object if he doesn't use it. 
	// This message only sent when set tasks file name parameter instead of other parameters. 
	if (wParam)
	{
		if (lParam)	// because here we use directly setting Tasks object method instead of passing tasks file name, so this message never sent.
		{
			Tasks* pts = (Tasks*)lParam;
			m_pViewTaskList->SetTasks(pts);
		}
		::PostThreadMessage(m_pThread->m_nThreadID, WM_THREADMSG_SCHEDULE_START, 0, 0);
	}
	else
	{
		AfxMessageBox(_T("Task file parsing failed."), MB_ICONSTOP);
		
		GetDlgItem(IDC_USR)->EnableWindow(TRUE);
		GetDlgItem(IDC_PWD)->EnableWindow(TRUE);
		GetDlgItem(IDC_SVR)->EnableWindow(TRUE);
		GetDlgItem(IDC_TASKFILENAME)->EnableWindow(TRUE);
		GetDlgItem(IDC_BTN_BROWSE)->EnableWindow(TRUE);
		GetDlgItem(IDOK)->EnableWindow(TRUE);
	}
	return 0;
}

LRESULT CFormTask::OnScheduleFinished (WPARAM wParam, LPARAM lParam)
{
	DWORD nThreadID = (DWORD)lParam;

	GetDlgItem(IDC_USR)->EnableWindow(TRUE);
	GetDlgItem(IDC_PWD)->EnableWindow(TRUE);
	GetDlgItem(IDC_SVR)->EnableWindow(TRUE);
	GetDlgItem(IDC_TASKFILENAME)->EnableWindow(TRUE);
	GetDlgItem(IDC_BTN_BROWSE)->EnableWindow(TRUE);
	GetDlgItem(ID_BTN_START)->EnableWindow(TRUE);

	g_TravianEvtLog.AddEvt(EVTLEVEL_INFO, _T("Tasks execution finished."), true, false);

	return 0;
}

LRESULT CFormTask::OnTaskExecState(WPARAM wParam, LPARAM lParam)
{

	// wParam is the task order index, numbered from 0, LPARAM is the executing state.
	m_pViewTaskList->SetTaskState((int)wParam, (eTaskExecState)lParam);

	return 0;
}





By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions