
// InjectDLLDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "InjectDLL.h"
#include "InjectDLLDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// OGC Tool无序句柄;
HWND g_hWnd_SN = NULL;
HWND g_hWnd_SN_Combobox = NULL;
HWND g_hWnd_Tester = NULL;
HWND g_hWnd_FWVersion = NULL;
HWND g_hWnd_Channel = NULL;

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CInjectDLLDlg 对话框




CInjectDLLDlg::CInjectDLLDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CInjectDLLDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CInjectDLLDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, COMBO_PROCESS, m_cbProcess);
	DDX_Control(pDX, COMBOX_BTN_NAME, m_cbBtnName);
}

BEGIN_MESSAGE_MAP(CInjectDLLDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
    ON_BN_CLICKED(BTN_INJECT, &CInjectDLLDlg::OnBnClickedInject)
    ON_BN_CLICKED(BTN_EJECT, &CInjectDLLDlg::OnBnClickedEject)
    ON_BN_CLICKED(BTN_REFLESH, &CInjectDLLDlg::OnBnClickedReflesh)
    ON_BN_CLICKED(BTN_HIDE_WND, &CInjectDLLDlg::OnBnClickedHideWnd)
    ON_BN_CLICKED(BTN_SHOW_WND, &CInjectDLLDlg::OnBnClickedShowWnd)
	ON_BN_CLICKED(BTN_TEST, &CInjectDLLDlg::OnBnClickedTest)
	ON_BN_CLICKED(BTN_SETDATA, &CInjectDLLDlg::OnBnClickedSetdata)
END_MESSAGE_MAP()


// CInjectDLLDlg 消息处理程序

BOOL CInjectDLLDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
    InitCommbox();

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CInjectDLLDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CInjectDLLDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CInjectDLLDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CInjectDLLDlg::OnBnClickedInject()
{
    // TODO: 在此添加控件通知处理程序代码
    CString strInjectDLL = OpenInectDLL();
    INT nCurSel = m_cbProcess.GetCurSel();
    if ( nCurSel == CB_ERR )
    {
        MessageBox(_T("请选择要注入的进程"), _T("提醒"), MB_ICONWARNING);
        return;
    }

    ProInfo *ptr = (ProInfo*)m_cbProcess.GetItemDataPtr(nCurSel);
    if ( ptr )
    {
        if ( m_Inject.GetInjectProcess() )
        {
            m_Inject.EjectDynamicLibrary();
        }

        m_Inject.setInjectionObj(ptr->dwProId, strInjectDLL.GetString());
        m_Inject.InjectDynamicLibrary();
    }
}

void CInjectDLLDlg::OnBnClickedEject()
{
    // TODO: 在此添加控件通知处理程序代码
    if ( m_Inject.GetInjectProcess() )
    {
        m_Inject.EjectDynamicLibrary();
    }
}


void CInjectDLLDlg::InitCommbox()
{
    m_vtProInfo.clear();
    m_cbProcess.ResetContent();
	m_wndData.vtWndInfo.clear();
    // 获取全部进程到Commbox;
    FindAllProcess(m_vtProInfo);

    int nIndex = 0;
    TCHAR szName[MAX_PATH] = {0};
    for (std::vector<ProInfo>::iterator it = m_vtProInfo.begin(); it != m_vtProInfo.end(); it++ )
    {
        _stprintf(szName, _T("%s %ld"), it->strProName.c_str(),it->dwProId);
        nIndex = m_cbProcess.AddString(szName);
        m_cbProcess.SetItemDataPtr(nIndex, &*it);
#ifdef _DEBUG
        TRACE3("%ld-%s:%p\n", it->dwProId, it->strProName.c_str(), *it);
#endif
	}

	if ( (nIndex = m_cbProcess.SelectString(0, _T("Demo"))) != -1 )
	{
		ProInfo *ptr = (ProInfo*)m_cbProcess.GetItemDataPtr(nIndex);
		if ( ptr )
		{
			m_wndData.dwPid = ptr->dwProId;
			EnumProcessAllWnd(&m_wndData);
			for (std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
			{
				if ( _tcscmp(it->szClassName, _T("TButton")) == 0 )
				{
					m_cbBtnName.AddString(it->szWndTitle);
				}
			}
		}
	}

	FetchOGCWnd();
}

CString CInjectDLLDlg::OpenInectDLL()
{
    CString strInjectDLL = _T("");
    CFileDialog dlg(TRUE, _T("DLL"), _T("*.DLL"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("要注入的DLL (*.dll)|*.dll||"));
    if ( dlg.DoModal() == IDOK )
    {
        strInjectDLL = dlg.GetPathName();
    }
        
    return strInjectDLL;
}

void CInjectDLLDlg::OnBnClickedReflesh()
{
    // TODO: 在此添加控件通知处理程序代码
    InitCommbox();
}

BOOL ShowInTaskbar(HWND hWnd, BOOL bShow)
{
    HRESULT hr; 
    ITaskbarList* pTaskbarList;
    hr = CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,  
        IID_ITaskbarList, (void**)&pTaskbarList );
    if(SUCCEEDED(hr))
    {
        pTaskbarList->HrInit();
        if(bShow)
            pTaskbarList->AddTab(hWnd);
        else
            pTaskbarList->DeleteTab(hWnd);
        pTaskbarList->Release();
        return TRUE;
    }

    return FALSE;
}

HWND g_hCurrentProWnd = NULL;
HWND g_hCurrentProWnd2 = NULL;
void CInjectDLLDlg::OnBnClickedHideWnd()
{
    // TODO: 在此添加控件通知处理程序代码
    INT nCurSel = m_cbProcess.GetCurSel();
    if ( nCurSel == CB_ERR )
    {
        MessageBox(_T("请选择要隐藏窗口的进程"), _T("提醒"), MB_ICONWARNING);
        return;
    }

	HWND hWnd = NULL;
	if ( hWnd = FindWindow(_T("TfrmDemo")) )
		::ShowWindow(hWnd, SW_HIDE);

	if ( hWnd = FindWindow(_T("TApplication")) )
		::ShowWindow(hWnd, SW_HIDE);

}

HWND CInjectDLLDlg::FindWindow(LPCTSTR lpClassName)
{
	HWND hWnd = NULL;
	if ( lpClassName == NULL || lpClassName[0] == '\0' )
		return hWnd;

	for (std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
	{
		// 返回第一个找到的类名;
		if ( _tcscmp(lpClassName, it->szClassName) == 0 )
		{
			hWnd = it->hWnd;
			break;
		}
	}

	return hWnd;
}

void CInjectDLLDlg::OnBnClickedShowWnd()
{
    // TODO: 在此添加控件通知处理程序代码
    INT nCurSel = m_cbProcess.GetCurSel();
    if ( nCurSel == CB_ERR )
    {
        MessageBox(_T("请选择要显示窗口的进程"), _T("提醒"), MB_ICONWARNING);
        return;
    }

	HWND hWnd = NULL;
	if ( hWnd = FindWindow(_T("TfrmDemo")) )
		::ShowWindow(hWnd, SW_SHOW);

	if ( hWnd = FindWindow(_T("TApplication")) )
		::ShowWindow(hWnd, SW_SHOW);
}

void CInjectDLLDlg::OnBnClickedTest()
{
	TCHAR szBtnName[MAX_PATH] = {0};
	INT nCurSel = m_cbBtnName.GetCurSel();
	if ( nCurSel == CB_ERR )
	{
		MessageBox(_T("请选择要测试的按钮名称"), _T("提醒"), MB_ICONWARNING);
		return;
	}

	m_cbBtnName.GetLBText(nCurSel, szBtnName);

	// TODO: 在此添加控件通知处理程序代码
	HWND hWnd = NULL;
	for ( std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
	{
		if ( _tcscmp(it->szWndTitle, szBtnName) == 0 )
		{
			hWnd = it->hWnd;
			break;
		}
	}

	if ( hWnd )
	{
		::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
		Sleep(20);
		::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
	}
	else
	{
		AfxMessageBox(_T("没有找到控件句柄"));
	}
}

void CInjectDLLDlg::OnBnClickedSetdata()
{
	// TODO: 在此添加控件通知处理程序代码
	UINT dwAddr = GetDlgItemInt(TX_ID);
	TCHAR szData[MAX_PATH] =  {0};
	GetDlgItemText(TX_DATA, szData, MAX_PATH);
	BOOL bIsDropList = ((CButton*)GetDlgItem(CH_DROPLIST))->GetCheck();

	if ( dwAddr != -1 )
	{
		//WNDINFO &info = m_wndData.vtWndInfo.at(nID);
	
		//::SetWindowText(info.hWnd, szData);	// 此方法：设置句柄文本失败;
		//::SendMessage(info.hWnd, WM_SETTEXT, 0, (LPARAM)&szData);	// 此方法：设置句柄文本成功;
		if ( bIsDropList )
			::SendMessage(HWND(dwAddr), CB_SELECTSTRING, 0, (LPARAM)&szData);	// 此方法：设置句柄文本成功;
		else
			::SendMessage(HWND(dwAddr), WM_SETTEXT, 0, (LPARAM)&szData);	// 此方法：设置句柄文本成功;
	}
}

void CInjectDLLDlg::FetchOGCWnd()
{
	// SN Combobox;
	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
	{
		if ( _tcscmp(_T("TfrmDemo"), it->szClassName) == 0 )
		{
			g_hWnd_SN_Combobox = (++it)->hWnd;
			break;
		}
	}

	// SN Edit && Tester;
	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
	{
		if ( !_tcscmp(_T("OCC"), it->szWndTitle) &&  !_tcscmp(_T("TCheckBox"), it->szClassName) )
		{
			g_hWnd_SN = (--it)->hWnd;
			g_hWnd_Tester = (--it)->hWnd;
			break;
		}
	}

	// Channel Edit;
	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
	{
		if ( !_tcscmp(_T("Connect CA310"), it->szWndTitle) &&  !_tcscmp(_T("TButton"), it->szClassName) )
		{
			g_hWnd_Channel = (--it)->hWnd;
			break;
		}
	}

	// FW Version;
	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
	{
		if ( !_tcscmp(_T("FS2"), it->szWndTitle) &&  !_tcscmp(_T("TCheckBox"), it->szClassName) )
		{
			g_hWnd_FWVersion = (--it)->hWnd;
			break;
		}
	}

#ifdef _DEBUG
	TCHAR szMsg[MAX_PATH] = {0};
	//_stprintf(szMsg, _T("Channel=%08X, SN=%08X, Combobox=%08X, Tester=%08X, FWVersion=%08X\n"), g_hWnd_Channel, g_hWnd_SN, g_hWnd_SN_Combobox, g_hWnd_Tester, g_hWnd_FWVersion);
	_stprintf(szMsg, _T("Channel=%ld, SN=%ld, Combobox=%ld, Tester=%ld, FWVersion=%ld\n"), g_hWnd_Channel, g_hWnd_SN, g_hWnd_SN_Combobox, g_hWnd_Tester, g_hWnd_FWVersion);
	//TRACE(szMsg);
	WriteTextLog(szMsg);
#endif
}