めいくりぷとのブログ

技術的なことをまったりと。

MT4 ウィンドウ #1

カテゴリにインディケーター入れてるけど、インディケーターではありません。
MT4のチャートウィンドウを個別ウィンドウとして表示出来たら便利だなーと・・・。
探せばそういうのあるのかもしれない・・・。
C++で作れるらしいけど、まだ囓ってすら無いので、ゴリ押しヨ。

std::vector<HWND> vList;

VOID Detour_SetWindowPos()
{
	static decltype(&SetWindowPos) _SetWindowPos = SetWindowPos;

	decltype(&SetWindowPos) SetWindowPos_Hook = [](
		_In_     HWND hWnd,
		_In_opt_ HWND hWndInsertAfter,
		_In_     int  X,
		_In_     int  Y,
		_In_     int  cx,
		_In_     int  cy,
		_In_     UINT uFlags) -> BOOL
	{
		// call on clicked minimize button
		if (uFlags == SWP_SHOWWINDOW)
		{
			for (auto hwnd : vList)
			{
				if (hwnd == hWnd)
				{
					SetParent(hWnd, NULL);
					return _SetWindowPos(hWnd, NULL, X, Y, cx, cy, uFlags | SWP_NOSENDCHANGING);
				}
			}
		}

		return _SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
	};

	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_SetWindowPos), SetWindowPos_Hook);
}

VOID Detour_RegisterClassA()
{
	static decltype(&RegisterClassA) _RegisterClassA = RegisterClassA;

	decltype(&RegisterClassA) RegisterClassA_Hook = [](
		_In_ const WNDCLASSA *lpWndClass) -> ATOM
	{
		WNDPROC WindowProc;

		if (lpWndClass != NULL && 
			lpWndClass->lpszClassName != NULL &&
			lpWndClass->hInstance == GetModuleHandle(NULL)) // termial.exe
		{
			WindowProc = lpWndClass->lpfnWndProc;
			if (WindowProc != NULL)
			{
				if (!strcmp(lpWndClass->lpszClassName, "AfxFrameOrView140s"))
				{
					Detour_WindowProc(WindowProc);
				}
			}
		}

		return _RegisterClassA(lpWndClass);
	};

	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_RegisterClassA), RegisterClassA_Hook);
}

VOID Detour_DestroyWindow()
{
	static decltype(&DestroyWindow) _DestroyWindow = DestroyWindow;

	decltype(&DestroyWindow) DestroyWindow_Hook = [](
		_In_ HWND hWnd) -> BOOL
	{
		for (int i = 0; i < vList.size(); i++)
		{
			if (vList[i] == hWnd)
			{
				vList.erase(vList.begin() + i + 1);
				break;
			}
		}

		return _DestroyWindow(hWnd);
	};

	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_DestroyWindow), DestroyWindow_Hook);
}

VOID Detour_CreateWindowExA()
{
	static decltype(&CreateWindowExA) _CreateWindowExA = CreateWindowExA;

	decltype(&CreateWindowExA) CreateWindowExA_Hook = [](
		_In_     DWORD     dwExStyle,
		_In_opt_ LPCSTR    lpClassName,
		_In_opt_ LPCSTR    lpWindowName,
		_In_     DWORD     dwStyle,
		_In_     int       x,
		_In_     int       y,
		_In_     int       nWidth,
		_In_     int       nHeight,
		_In_opt_ HWND      hWndParent,
		_In_opt_ HMENU     hMenu,
		_In_opt_ HINSTANCE hInstance,
		_In_opt_ LPVOID    lpParam) -> HWND
	{
		HWND hWnd = _CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);

		if (lpClassName != NULL)
		{
			if (!strcmp(lpClassName, "AfxFrameOrView140s"))
			{
				vList.push_back(hWnd);			
			}
		}

		return hWnd;
	};

	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_CreateWindowExA), CreateWindowExA_Hook);
}