// 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;
}