Mouse Pointer Highlight

Mouse Pointer Highlightは、マウスカーソルを強調する円を表示するアプリです
フリーソフトウェアです

ダウンロード

MousePointerHighlight-20240311.zip
MousePointerHighlight-20231227.zip
MousePointerHighlight-20231222.zip
MousePointerHighlight-20231206.zip

ソースコード


//MousePointerHighlight

#define _WIN32_WINNT _WIN32_WINNT_WIN7

#include <windows.h>
#include <windowsx.h>
#include <shlwapi.h>
#include <gdiplus.h>
#include <xmllite.h>

using namespace Gdiplus;

HWND g_hwndHighlight = NULL;
HHOOK g_hHook = NULL;
HDC g_hdc = NULL;
HBITMAP g_hBitmapOld = NULL;

typedef struct tagCONFIG
{
	Color highlight_color;
	int highlight_width;
	int highlight_diameter;
	BOOL left_enable;
	Color left_color;
	BOOL right_enable;
	Color right_color;
	BOOL middle_enable;
	Color middle_color;
	BOOL wheelup_enable;
	Color wheelup_color;
	BOOL wheeldown_enable;
	Color wheeldown_color;
} CONFIG, *LPCONFIG;

CONFIG g_config;
const int margin = 2;

DWORD state = 0;

enum
{
	lbutton = 0x01,
	rbutton = 0x02,
	mbutton = 0x04,
	wheelup = 0x08,
	wheeldown = 0x10,
	x1button = 0x20,
	x2button = 0x40,
};

static const GUID guid = {0x2478cb6b, 0xba23, 0x4338, {0x9e, 0x22, 0xca, 0xb5, 0x26, 0x2e, 0x78, 0xa3}};
#define WM_NOTIFYICON (WM_APP + 1)

HICON g_hIcon;

//--------
BOOL writeValueString(IXmlWriter *pWriter, LPCWSTR attribute, LPCWSTR value)
{
	pWriter->WriteAttributeString(NULL, attribute, NULL, value);
	return TRUE;
}

BOOL writeValueInt(IXmlWriter *pWriter, LPCWSTR attribute, INT value)
{
	WCHAR buffer[1024];
	wsprintf(buffer, L"%d", value);
	pWriter->WriteAttributeString(NULL, attribute, NULL, buffer);
	return TRUE;
}

void onWrite(IXmlWriter *pWriter)
{
	pWriter->SetProperty(XmlWriterProperty_Indent, TRUE);
	pWriter->WriteStartDocument(XmlStandalone_Omit); // 

	pWriter->WriteStartElement(NULL, L"config", NULL);

	pWriter->WriteStartElement(NULL, L"highlight", NULL);
	writeValueInt(pWriter, L"red", g_config.highlight_color.GetR());
	writeValueInt(pWriter, L"green", g_config.highlight_color.GetG());
	writeValueInt(pWriter, L"blue", g_config.highlight_color.GetB());
	writeValueInt(pWriter, L"alpha", g_config.highlight_color.GetA());
	writeValueInt(pWriter, L"width", g_config.highlight_width);
	writeValueInt(pWriter, L"diameter", g_config.highlight_diameter);
	pWriter->WriteFullEndElement(); // highlight

	pWriter->WriteStartElement(NULL, L"left", NULL);
	writeValueInt(pWriter, L"enable", g_config.left_enable);
	writeValueInt(pWriter, L"red", g_config.left_color.GetR());
	writeValueInt(pWriter, L"green", g_config.left_color.GetG());
	writeValueInt(pWriter, L"blue", g_config.left_color.GetB());
	writeValueInt(pWriter, L"alpha", g_config.left_color.GetA());
	pWriter->WriteFullEndElement(); // left

	pWriter->WriteStartElement(NULL, L"right", NULL);
	writeValueInt(pWriter, L"enable", g_config.right_enable);
	writeValueInt(pWriter, L"red", g_config.right_color.GetR());
	writeValueInt(pWriter, L"green", g_config.right_color.GetG());
	writeValueInt(pWriter, L"blue", g_config.right_color.GetB());
	writeValueInt(pWriter, L"alpha", g_config.right_color.GetA());
	pWriter->WriteFullEndElement(); // right

	pWriter->WriteStartElement(NULL, L"middle", NULL);
	writeValueInt(pWriter, L"enable", g_config.middle_enable);
	writeValueInt(pWriter, L"red", g_config.middle_color.GetR());
	writeValueInt(pWriter, L"green", g_config.middle_color.GetG());
	writeValueInt(pWriter, L"blue", g_config.middle_color.GetB());
	writeValueInt(pWriter, L"alpha", g_config.middle_color.GetA());
	pWriter->WriteFullEndElement(); // middle

	pWriter->WriteStartElement(NULL, L"wheelup", NULL);
	writeValueInt(pWriter, L"enable", g_config.wheelup_enable);
	writeValueInt(pWriter, L"red", g_config.wheelup_color.GetR());
	writeValueInt(pWriter, L"green", g_config.wheelup_color.GetG());
	writeValueInt(pWriter, L"blue", g_config.wheelup_color.GetB());
	writeValueInt(pWriter, L"alpha", g_config.wheelup_color.GetA());
	pWriter->WriteFullEndElement(); // wheelup

	pWriter->WriteStartElement(NULL, L"wheeldown", NULL);
	writeValueInt(pWriter, L"enable", g_config.wheeldown_enable);
	writeValueInt(pWriter, L"red", g_config.wheeldown_color.GetR());
	writeValueInt(pWriter, L"green", g_config.wheeldown_color.GetG());
	writeValueInt(pWriter, L"blue", g_config.wheeldown_color.GetB());
	writeValueInt(pWriter, L"alpha", g_config.wheeldown_color.GetA());
	pWriter->WriteFullEndElement(); // wheeldown

	pWriter->WriteFullEndElement(); // config
}

void xmlWrite(LPCWSTR path)
{
	IStream *pStream;
	if (S_OK == SHCreateStreamOnFile(path, STGM_CREATE | STGM_WRITE, &pStream))
	{
		IXmlWriter *pWriter;
		if (S_OK == CreateXmlWriter(__uuidof(IXmlWriter), (void **)&pWriter, NULL))
		{
			pWriter->SetOutput(pStream);
			onWrite(pWriter);
			pWriter->Flush();
			pWriter->Release();
		}
		pStream->Release();
	}
}

BOOL getValueString(IXmlReader *pReader, LPCWSTR attribute, LPCWSTR *value)
{
	if (S_OK == pReader->MoveToAttributeByName(attribute, NULL) &&
		S_OK == pReader->GetValue(value, NULL))
	{
		return TRUE;
	}
	return FALSE;
}

BOOL getValueInt(IXmlReader *pReader, LPCWSTR attribute, LPINT value)
{
	LPCWSTR p;
	if (S_OK == pReader->MoveToAttributeByName(attribute, NULL) &&
		S_OK == pReader->GetValue(&p, NULL))
	{
		*value = StrToInt(p);
		return TRUE;
	}
	return FALSE;
}

void onRead(IXmlReader *pReader, LPCWSTR element)
{
	int r, g, b, a, value;

	if (!StrCmpI(element, L"highlight"))
	{
		if (getValueInt(pReader, L"red", &r) &&
			getValueInt(pReader, L"green", &g) &&
			getValueInt(pReader, L"blue", &b) &&
			getValueInt(pReader, L"alpha", &a))
		{
			g_config.highlight_color = Color(a, r, g, b);
		}
		if (getValueInt(pReader, L"width", &value))
			g_config.highlight_width = value;
		if (getValueInt(pReader, L"diameter", &value))
			g_config.highlight_diameter = value;
	}
	if (!StrCmpI(element, L"left"))
	{
		if (getValueInt(pReader, L"enable", &value))
			g_config.left_enable = value;
		if (getValueInt(pReader, L"red", &r) &&
			getValueInt(pReader, L"green", &g) &&
			getValueInt(pReader, L"blue", &b) &&
			getValueInt(pReader, L"alpha", &a))
		{
			g_config.left_color = Color(a, r, g, b);
		}
	}
	if (!StrCmpI(element, L"right"))
	{
		if (getValueInt(pReader, L"enable", &value))
			g_config.right_enable = value;
		if (getValueInt(pReader, L"red", &r) &&
			getValueInt(pReader, L"green", &g) &&
			getValueInt(pReader, L"blue", &b) &&
			getValueInt(pReader, L"alpha", &a))
		{
			g_config.right_color = Color(a, r, g, b);
		}
	}
	if (!StrCmpI(element, L"middle"))
	{
		if (getValueInt(pReader, L"enable", &value))
			g_config.middle_enable = value;
		if (getValueInt(pReader, L"red", &r) &&
			getValueInt(pReader, L"green", &g) &&
			getValueInt(pReader, L"blue", &b) &&
			getValueInt(pReader, L"alpha", &a))
		{
			g_config.middle_color = Color(a, r, g, b);
		}
	}
	if (!StrCmpI(element, L"wheelup"))
	{
		if (getValueInt(pReader, L"enable", &value))
			g_config.wheelup_enable = value;
		if (getValueInt(pReader, L"red", &r) &&
			getValueInt(pReader, L"green", &g) &&
			getValueInt(pReader, L"blue", &b) &&
			getValueInt(pReader, L"alpha", &a))
		{
			g_config.wheelup_color = Color(a, r, g, b);
		}
	}
	if (!StrCmpI(element, L"wheeldown"))
	{
		if (getValueInt(pReader, L"enable", &value))
			g_config.wheeldown_enable = value;
		if (getValueInt(pReader, L"red", &r) &&
			getValueInt(pReader, L"green", &g) &&
			getValueInt(pReader, L"blue", &b) &&
			getValueInt(pReader, L"alpha", &a))
		{
			g_config.wheeldown_color = Color(a, r, g, b);
		}
	}
}

void xmlRead(LPCWSTR path)
{
	IStream *pStream;
	if (S_OK == SHCreateStreamOnFile(path, STGM_READ, &pStream))
	{
		IXmlReader *pReader;
		if (S_OK == CreateXmlReader(__uuidof(IXmlReader), (void **)&pReader, NULL))
		{
			pReader->SetInput(pStream);
			XmlNodeType nodeType;
			while (S_OK == pReader->Read(&nodeType))
			{
				switch (nodeType)
				{
				case XmlNodeType_Element:
					LPCWSTR pwszLocalName;
					pReader->GetLocalName(&pwszLocalName, NULL);
					onRead(pReader, pwszLocalName);
					break;
				}
			}
			pReader->Release();
		}
		pStream->Release();
	}
}

void SaveConfig()
{
	xmlWrite(L"config.xml");
}

void LoadConfig()
{
	// デフォルトの設定
	g_config.highlight_color = Color(0xC0FF0000);
	g_config.highlight_width = 20;
	g_config.highlight_diameter = 160;
	g_config.left_enable = TRUE;
	g_config.left_color = Color(0xFF00FF00);
	g_config.right_enable = TRUE;
	g_config.right_color = Color(0xFF00FF00);
	g_config.middle_enable = TRUE;
	g_config.middle_color = Color(0xFF00FF00);
	g_config.wheelup_enable = TRUE;
	g_config.wheelup_color = Color(0xFF0000FF);
	g_config.wheeldown_enable = TRUE;
	g_config.wheeldown_color = Color(0xFF0000FF);

	xmlRead(L"config.xml");
}

//--------
HBITMAP CreateBitmap32bit(LONG width, LONG height)
{
	HBITMAP hBitmap;
	BITMAPINFO bmi;
	DWORD *bits = NULL;
	HDC hdc;

	ZeroMemory(&bmi, sizeof(BITMAPINFO));
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = width;
	bmi.bmiHeader.biHeight = height;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 32;
	bmi.bmiHeader.biCompression = BI_RGB;

	hdc = GetDC(NULL);
	hBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (VOID **)&bits, NULL, 0);
	ReleaseDC(NULL, hdc);
	return hBitmap;
}

//--------
void DrawHighlight()
{
	Graphics graphics(g_hdc);

	// アンチエイリアス有効
	graphics.SetSmoothingMode(SmoothingModeAntiAlias);

	// 背景を透明度100%で描画
	graphics.Clear(Color(0, 0, 0, 0));

	// 円の描画位置とサイズ
	int x, y, width, height;
	x = g_config.highlight_width / 2;
	y = g_config.highlight_width / 2;
	width = g_config.highlight_diameter;
	height = g_config.highlight_diameter;

	// 円
	Pen pen(g_config.highlight_color, g_config.highlight_width);
	graphics.DrawEllipse(&pen, x, y, width, height);

	// ホイールアップ
	if (g_config.wheelup_enable && (state & wheelup))
	{
		Pen pen(g_config.wheelup_color, g_config.highlight_width);
		graphics.DrawArc(&pen, x, y, width, height, 210, 120);
	}
	// ホイールダウン
	if (g_config.wheeldown_enable && (state & wheeldown))
	{
		Pen pen(g_config.wheeldown_color, g_config.highlight_width);
		graphics.DrawArc(&pen, x, y, width, height, 30, 120);
	}
	// 左クリック
	if (g_config.left_enable && (state & lbutton))
	{
		Pen pen(g_config.left_color, g_config.highlight_width);
		graphics.DrawArc(&pen, x, y, width, height, 150, 60);
	}
	// 右クリック
	if (g_config.right_enable && (state & rbutton))
	{
		Pen pen(g_config.right_color, g_config.highlight_width);
		graphics.DrawArc(&pen, x, y, width, height, 330, 60);
	}
	// 中クリック
	if (g_config.middle_enable && (state & mbutton))
	{
		Pen pen(g_config.middle_color, g_config.highlight_width);
		graphics.DrawArc(&pen, x, y, width, height, 240, 60);
	}
}

void UpdateHighlight(HWND hwnd)
{
	// ハイライトウインドウを描画
	DrawHighlight();

	// UpdateLayeredWindow
	HDC hdcDst = GetDC(NULL);
	SIZE size = {
		g_config.highlight_width + g_config.highlight_diameter + margin,
		g_config.highlight_width + g_config.highlight_diameter + margin};
	POINT ptSrc = {0, 0};
	BLENDFUNCTION blend = {AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA};
	UpdateLayeredWindow(
		hwnd, hdcDst, NULL, &size, g_hdc, &ptSrc, 0, &blend, ULW_ALPHA);
	ReleaseDC(NULL, hdcDst);
}

void UnloadHighlightConfig()
{
	HBITMAP hBitmap;
	// ビットマップ破棄
	hBitmap = (HBITMAP)SelectObject(g_hdc, g_hBitmapOld);
	DeleteObject(hBitmap);
}

void LoadHighlightConfig()
{
	HBITMAP hBitmap;
	// ビットマップ作成
	// アンチエイリアス有効にすると直径より少し大きくなるので少し大きくしておこう
	hBitmap = CreateBitmap32bit(
		g_config.highlight_width + g_config.highlight_diameter + margin,
		g_config.highlight_width + g_config.highlight_diameter + margin);
	g_hBitmapOld = (HBITMAP)SelectObject(g_hdc, hBitmap);
}

//--------
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	UINT msg = (UINT)wParam;
	LPMSLLHOOKSTRUCT pMouseHookStruct = (LPMSLLHOOKSTRUCT)lParam;

	if (nCode < 0)
		return CallNextHookEx(g_hHook, nCode, wParam, lParam);

	switch (msg)
	{
	case WM_MOUSEMOVE:
	{
		int x = pMouseHookStruct->pt.x - ((g_config.highlight_width + g_config.highlight_diameter) / 2);
		int y = pMouseHookStruct->pt.y - ((g_config.highlight_width + g_config.highlight_diameter) / 2);
		// ハイライトを移動
		SetWindowPos(g_hwndHighlight, NULL,
					 x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
		UpdateHighlight(g_hwndHighlight);
		break;
	}
	case WM_LBUTTONDOWN:
		if (!(state & lbutton))
			state += lbutton;
		UpdateHighlight(g_hwndHighlight);
		break;
	case WM_LBUTTONUP:
		if ((state & lbutton))
			state -= lbutton;
		UpdateHighlight(g_hwndHighlight);
		break;
	case WM_RBUTTONDOWN:
		if (!(state & rbutton))
			state += rbutton;
		UpdateHighlight(g_hwndHighlight);
		break;
	case WM_RBUTTONUP:
		if ((state & rbutton))
			state -= rbutton;
		UpdateHighlight(g_hwndHighlight);
		break;
	case WM_MBUTTONDOWN:
		if (!(state & mbutton))
			state += mbutton;
		UpdateHighlight(g_hwndHighlight);
		break;
	case WM_MBUTTONUP:
		if ((state & mbutton))
			state -= mbutton;
		UpdateHighlight(g_hwndHighlight);
		break;
	case WM_MOUSEWHEEL:
	{
		short delta = (short)HIWORD(pMouseHookStruct->mouseData);
		if (delta > 0)
		{
			if (!(state & wheelup))
				state = state + wheelup;
			KillTimer(g_hwndHighlight, wheelup);
			SetTimer(g_hwndHighlight, wheelup, 500, NULL);
		}
		else
		{
			if (!(state & wheeldown))
				state = state + wheeldown;
			KillTimer(g_hwndHighlight, wheeldown);
			SetTimer(g_hwndHighlight, wheeldown, 500, NULL);
		}
		UpdateHighlight(g_hwndHighlight);
		break;
	}
	}
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

//--------
void OnTimer(HWND hwnd, UINT id)
{
	switch (id)
	{
	case wheelup:
		state = state - wheelup;
		KillTimer(hwnd, wheelup);
		UpdateHighlight(g_hwndHighlight);
		break;
	case wheeldown:
		state = state - wheeldown;
		KillTimer(hwnd, wheeldown);
		UpdateHighlight(g_hwndHighlight);
		break;
	}
}

void OnDestroy(HWND hwnd)
{
	// ローレベルマウスフックアンインストール
	UnhookWindowsHookEx(g_hHook);
	g_hHook = NULL;

	UnloadHighlightConfig();

	// デバイスコンテキスト破棄
	DeleteDC(g_hdc);
}

BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
	HDC hdc;

	// デバイスコンテキスト作成
	hdc = GetDC(NULL);
	g_hdc = CreateCompatibleDC(hdc);
	ReleaseDC(NULL, hdc);

	LoadHighlightConfig();

	// ローレベルマウスフックインストール
	g_hHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, lpCreateStruct->hInstance, 0);

	return TRUE;
}

LRESULT CALLBACK WndProcHighlight(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CREATE:
		return (OnCreate(hwnd, (LPCREATESTRUCT)lParam) ? 0 : -1);
	case WM_DESTROY:
		OnDestroy(hwnd);
		break;
	case WM_TIMER:
		OnTimer(hwnd, (UINT)wParam);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

//--------
HWND CreateHighlightWindow(HINSTANCE hInstance)
{
	return CreateWindowEx(
		WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TRANSPARENT,
		L"Highlight", L"Highlight",
		WS_VISIBLE,
		0, 0, 0, 0,
		NULL, NULL, hInstance, NULL);
}

//--------
void AddNotifyIcon(HWND hwnd)
{
	NOTIFYICONDATA nid = {0};
	nid.cbSize = sizeof(NOTIFYICONDATA);
	nid.hWnd = hwnd;
	//	nid.uID = 0;
	nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_GUID | NIF_SHOWTIP;
	nid.uCallbackMessage = WM_NOTIFYICON;
	nid.hIcon = g_hIcon;
	lstrcpyn(nid.szTip, L"Mouse Pointer Highlight", 64);
	nid.guidItem = guid;
	nid.uVersion = NOTIFYICON_VERSION_4;

	Shell_NotifyIcon(NIM_ADD, &nid);

	Shell_NotifyIcon(NIM_SETVERSION, &nid);
}

void DeleteNotifyIcon()
{
	NOTIFYICONDATA nid = {0};
	nid.cbSize = sizeof(NOTIFYICONDATA);
	nid.uFlags = NIF_GUID;
	nid.guidItem = guid;
	Shell_NotifyIcon(NIM_DELETE, &nid);
}

//--------
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static HINSTANCE s_hInstance;
	static UINT s_uTaskbarRestart;
	switch (msg)
	{
	case WM_CREATE:
	{
		WNDCLASS wc;
		MSG msg;

		s_hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
		s_uTaskbarRestart = RegisterWindowMessage(L"TaskbarCreated");

		// アイコンを動的に作成する
		Bitmap bitmap(32, 32);
		Graphics graphics(&bitmap);
		graphics.SetSmoothingMode(SmoothingModeAntiAlias);
		graphics.Clear(Color(0, 0, 0, 0));
		Pen pen(Color(255, 255, 0, 0), 8);
		graphics.DrawEllipse(&pen, 4, 4, 23, 23);
		bitmap.GetHICON(&g_hIcon);

		// タスクトレイにアイコンを追加
		AddNotifyIcon(hwnd);

		wc.style = 0;
		wc.lpfnWndProc = WndProcHighlight;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = s_hInstance;
		wc.hIcon = NULL;
		wc.hCursor = LoadCursor(NULL, IDC_ARROW);
		wc.hbrBackground = NULL;
		wc.lpszMenuName = NULL;
		wc.lpszClassName = L"Highlight";
		if (!RegisterClass(&wc))
		{
			return 0;
		}

		LoadConfig();

		g_hwndHighlight = CreateHighlightWindow(s_hInstance);
		break;
	}
	case WM_DESTROY:
	{
		DestroyWindow(g_hwndHighlight);

		SaveConfig();

		UnregisterClass(L"Highlight", s_hInstance);

		// タスクトレイのアイコンを削除
		DeleteNotifyIcon();

		// アイコンを破棄
		DestroyIcon(g_hIcon);

		PostQuitMessage(0);
		break;
	}
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case 40000:
			// 終了
			PostMessage(hwnd, WM_CLOSE, 0, 0);
			break;
		case 40001:
			// ハイライトウインドウの表示/非表示
			SetWindowPos(g_hwndHighlight, NULL, 0, 0, 0, 0,
						 (IsWindowVisible(g_hwndHighlight) ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) |
							 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
			break;
		case 40002:
			// 設定再読み込み
			DestroyWindow(g_hwndHighlight);
			LoadConfig();
			g_hwndHighlight = CreateHighlightWindow(s_hInstance);
			break;
		}
		break;

	case WM_NOTIFYICON:
		switch (LOWORD(lParam))
		{
		case NIN_SELECT:
			// 左クリック
			break;
		case NIN_KEYSELECT:
		case NIN_BALLOONSHOW:
		case NIN_BALLOONHIDE:
		case NIN_BALLOONTIMEOUT:
		case NIN_BALLOONUSERCLICK:
		case NIN_POPUPOPEN:
		case NIN_POPUPCLOSE:
			break;
		case WM_CONTEXTMENU:
		{
			// 右クリック
			HMENU hMenu = CreatePopupMenu();
			AppendMenu(hMenu, MF_STRING, 40001, L"enable Highlight");
			AppendMenu(hMenu, MF_STRING, 40002, L"reload config");
			AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
			AppendMenu(hMenu, MF_STRING, 40000, L"exit");
			if (IsWindowVisible(g_hwndHighlight))
				CheckMenuItem(hMenu, 40001, MF_BYCOMMAND | MF_CHECKED);
			SetForegroundWindow(hwnd);
			TrackPopupMenuEx(hMenu, 0, GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam), hwnd, 0);
			DestroyMenu(hMenu);
			PostMessage(hwnd, WM_NULL, 0, 0);
			break;
		}
		}
		break;
	default:
		if (msg == s_uTaskbarRestart)
			AddNotifyIcon(hwnd);
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

int AppMain(HINSTANCE hInstance)
{
	HANDLE hMutex;
	ULONG_PTR token;
	GdiplusStartupInput input;
	WNDCLASS wc;
	HWND hwnd = NULL;
	MSG msg;

	hMutex = CreateMutex(NULL, FALSE, TEXT("MousePointerHighlight"));
	if (GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(hMutex);
		return 0;
	}

	GdiplusStartup(&token, &input, NULL);

	wc.style = 0;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = L"MousePointerHighlight";
	if (!RegisterClass(&wc))
	{
		return 0;
	}

	hwnd = CreateWindow(
		L"MousePointerHighlight", L"Mouse Pointer Highlight",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, 320, 240,
		NULL, NULL, hInstance, NULL);
	if (hwnd == NULL)
	{
		return 0;
	}

	while (GetMessage(&msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	GdiplusShutdown(token);

	CloseHandle(hMutex);

	return msg.wParam;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	return AppMain(hInstance);
}

inserted by FC2 system