// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "PipeClient.h"
#include "Utility.h"

// 枚举屏幕上的所有顶级窗口
BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam)
{
	TCHAR szLog[MAX_PATH] = {0};
	DWORD dwCurrentProcessId = *((DWORD*)lParam);
	// 根据进程ID、窗口，获取当前窗口所在线程ID;
	DWORD dwWindProcessId = 0;
	DWORD dwThreadId = GetWindowThreadProcessId(hwnd, &dwWindProcessId);
	Utility::dprintf(_T("进程ID=%ld, 窗口进程ID=%ld\n"), dwCurrentProcessId, dwThreadId);
	if ( dwCurrentProcessId == dwWindProcessId && GetParent(hwnd) == NULL )   // GetParent==Null表示主窗口,本来就是找顶级的，有点多余?;
	{
		*((HWND*)lParam) = hwnd;
		// 回调函数调用SetLastError以获取有意义的错误代码，以返回给EnumWindows的调用方
		SetLastError(10086);
		// 停止枚举,返回FALSE;
		return FALSE;
	}

	// 继续枚举,返回TRUE;
	return TRUE;
}


HWND GetMainWnd()
{
	TCHAR szLog[MAX_PATH] = {0};
	// 获取当前DLL所在进程ID;
	DWORD dwCurrentProcessId = GetCurrentProcessId();
    Utility::g_WndInfo.dwProcessId = dwCurrentProcessId;
	// 枚举该进程窗口;
	EnumWindows(EnumWndProc, (LPARAM)&dwCurrentProcessId);
	DWORD dwError = GetLastError();
	if (dwError == 10086)
	{
		// 找到窗口句柄;
		return (HWND)dwCurrentProcessId;
	}

    Utility::dprintf(_T("进程ID=%ld, 没找到窗口,GetLastError=%ld\n"), dwCurrentProcessId, dwError);

	return NULL;
}

DWORD WINAPI WorkThreadProc(LPVOID lParam)
{
#if defined _DEBUG & !defined _CONSOLE
	Sleep(15000);
#endif
	TCHAR szLog[MAX_PATH] = {0};
	// 获取DLL所在窗口句柄;
	Utility::g_WndInfo.hWnd = GetMainWnd();
	if ( Utility::g_WndInfo.hWnd == NULL )
	{
		Utility::dprintf(_T("没有找到窗口句柄"));
		Utility::FreeLibraryAndExit();
		return 0;
	}

	// 得到窗口名称
	GetWindowText(Utility::g_WndInfo.hWnd, Utility::g_WndInfo.szWindowTitle, sizeof(Utility::g_WndInfo.szWindowTitle));
	Utility::dprintf(_T("找到窗口名称：%s\n"),  Utility::g_WndInfo.szWindowTitle);

	//是否名称是计算器
    if( _tcsstr(Utility::g_WndInfo.szWindowTitle, Utility::g_cfgCtx.szWindowTitel) )
	{
		Utility::dprintf(_T("找到指定窗口!!!"));
		// 2、创建后台线程;
		MessageBox(NULL, Utility::g_WndInfo.szWindowTitle, Utility::g_cfgCtx.szWindowTitel, MB_OK);
        if ( Utility::g_pPipeClient == NULL )
        {
            Utility::g_pPipeClient = new CPipeClient(Utility::g_cfgCtx.szPipeName);
            Utility::g_pPipeClient->StartWork();
        }
	}
	else
	{
		Utility::dprintf(_T("不满足条件,DLL自我卸载!!!"));
		// 如果不满足条件,DLL自我卸载;
		Utility::FreeLibraryAndExit();
	}

	return 0;
}

#ifndef _CONSOLE
BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		{
            Utility::g_hDLLModule = hModule;
            Utility::GetConfigContent();
			HANDLE hThreadProc = CreateThread(NULL, 0, WorkThreadProc, NULL, 0, NULL);
			CloseHandle(hThreadProc);
		}
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
#else
int main(int argc, char **argv)
{
    Utility::g_hDLLModule = GetModuleHandle(NULL);
    Utility::GetConfigContent();

    Utility::dprintf(_T("管道名称=%s, 窗口名称=%s, 窗口进程名称=%s"), Utility::g_cfgCtx.szPipeName, Utility::g_cfgCtx.szWindowTitel, Utility::g_cfgCtx.szWndProcessName);

    if ( Utility::g_pPipeClient == NULL )
    {
        Utility::g_pPipeClient = new CPipeClient(Utility::g_cfgCtx.szPipeName);
        Utility::g_pPipeClient->StartWork();
    }

    system("pause");

    return 0;
}
#endif