diff --git a/CustomDesktop/CustomDesktop.vcxproj b/CustomDesktop/CustomDesktop.vcxproj
index c309bcd..05b0279 100644
--- a/CustomDesktop/CustomDesktop.vcxproj
+++ b/CustomDesktop/CustomDesktop.vcxproj
@@ -165,7 +165,6 @@
-
@@ -192,7 +191,6 @@
-
Create
diff --git a/CustomDesktop/CustomDesktop.vcxproj.filters b/CustomDesktop/CustomDesktop.vcxproj.filters
index a145bca..af9c128 100644
--- a/CustomDesktop/CustomDesktop.vcxproj.filters
+++ b/CustomDesktop/CustomDesktop.vcxproj.filters
@@ -72,9 +72,6 @@
头文件\Module
-
- 头文件\Helper
-
头文件\Module
@@ -104,9 +101,6 @@
源文件\Module
-
- 源文件\Helper
-
源文件\Module
diff --git a/CustomDesktop/InlineHook.cpp b/CustomDesktop/InlineHook.cpp
deleted file mode 100644
index 58a66cd..0000000
--- a/CustomDesktop/InlineHook.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "stdafx.h"
-#include "InlineHook.h"
-
-
-namespace cd
-{
- namespace
- {
-#pragma pack(push)
-#pragma pack(1)
- struct JmpCode
- {
- private:
-#ifndef _WIN64
- const BYTE jmpCode = 0xE9; // JMP指令的机器码,近跳转为E9,可跳至同一个段的范围内的地址
- uintptr_t relativeAddress; // 相对地址 = 目标地址 - 下一条指令地址 = 目标地址 - 当前地址 - JMP指令长度
-#else
- const BYTE rexPrefix = 0x48;
- const BYTE movRax = 0xB8;
- uintptr_t address; // 绝对地址
- const BYTE jmp = 0xFF;
- const BYTE jmpRax = 0xE0;
-#endif
-
- public:
- JmpCode(void* srcAddr, void* dstAddr)
- {
- setAddress(srcAddr, dstAddr);
- }
-
-#ifndef _WIN64
- void setAddress(void* srcAddr, void* dstAddr)
- {
- relativeAddress = (uintptr_t)dstAddr - (uintptr_t)srcAddr - sizeof(JmpCode); // JMP指令长度 = sizeof(JmpCode) = 5 (32位)
- }
-#else
- void setAddress(void* srcAddr, void* dstAddr)
- {
- address = (uintptr_t)dstAddr;
- }
-#endif
- };
-#pragma pack(pop)
- }
-
- InlineHook::InlineHook(void* originalFunction, void* hookFunction, bool enable) :
- m_originalFunction(originalFunction),
- m_hookFunction(hookFunction),
- m_newEntry(VirtualAlloc(NULL, sizeof(JmpCode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE))
- {
- if (m_newEntry == NULL)
- return;
-
- // 保存originalFunction开头前sizeof(JmpCode)字节
- memcpy(m_newEntry, m_originalFunction, sizeof(JmpCode));
-
- if (enable)
- Enable();
- }
-
- InlineHook::InlineHook(InlineHook& other) :
- m_originalFunction(other.m_originalFunction),
- m_hookFunction(other.m_hookFunction),
- m_newEntry(other.m_newEntry)
- {
- (void*&)other.m_originalFunction = NULL;
- (void*&)other.m_hookFunction = NULL;
- (void*&)other.m_newEntry = NULL;
- }
-
- InlineHook::~InlineHook()
- {
- Disable();
-
- // 释放newEntry
- if (m_newEntry != NULL)
- VirtualFree(m_newEntry, 0, MEM_RELEASE);
- }
-
- bool InlineHook::Enable()
- {
- if (m_newEntry == NULL)
- return false;
- if (m_isEnabled)
- return true;
-
- // 改变虚拟内存保护,使originalFunction开头可写,用WriteProcessMemory写内存的话好像不用改保护
- DWORD oldProtect, oldProtect2;
- if (!VirtualProtect(m_originalFunction, sizeof(JmpCode), PAGE_EXECUTE_READWRITE, &oldProtect))
- return false;
-
- // 从originalFunction开头跳到hookFunction开头的指令
- JmpCode code(m_originalFunction, m_hookFunction);
- // 修改originalFunction开头的指令
- memcpy(m_originalFunction, &code, sizeof(code));
-
- // 恢复虚拟内存保护
- VirtualProtect(m_originalFunction, sizeof(JmpCode), oldProtect, &oldProtect2);
-
- m_isEnabled = true;
- return true;
- }
-
- bool InlineHook::Disable()
- {
- if (m_newEntry == NULL)
- return false;
- if (!m_isEnabled)
- return true;
-
- // 改变虚拟内存保护,使originalFunction开头可写
- DWORD oldProtect, oldProtect2;
- if (!VirtualProtect(m_originalFunction, sizeof(JmpCode), PAGE_EXECUTE_READWRITE, &oldProtect))
- return false;
-
- // 恢复originalFunction开头的指令
- memcpy(m_originalFunction, m_newEntry, sizeof(JmpCode));
-
- // 恢复虚拟内存保护
- VirtualProtect(m_originalFunction, sizeof(JmpCode), oldProtect, &oldProtect2);
-
- m_isEnabled = false;
- return true;
- }
-
- bool InlineHook::IsEnabled()
- {
- return m_isEnabled;
- }
-}
diff --git a/CustomDesktop/InlineHook.h b/CustomDesktop/InlineHook.h
deleted file mode 100644
index 699debc..0000000
--- a/CustomDesktop/InlineHook.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-
-namespace cd
-{
- class InlineHook final
- {
- private:
- void* const m_newEntry = NULL;
- void* const m_hookFunction;
- bool m_isEnabled = false;
- public:
- void* const m_originalFunction;
-
- InlineHook(void* originalFunction, void* hookFunction, bool enable = true);
- InlineHook(InlineHook& other);
- ~InlineHook();
-
- bool Enable();
- bool Disable();
-
- bool IsEnabled();
- };
-}
diff --git a/Data/WIMC.ini b/Data/WIMC.ini
index 8fa2fb4..cc4b6bc 100644
--- a/Data/WIMC.ini
+++ b/Data/WIMC.ini
@@ -1,4 +1,4 @@
[WIMC]
;
-NumberOfCursors = 50
+NumberOfCursors = 500
diff --git a/Plugin/WIMC/Config.cpp b/Plugin/WIMC/Config.cpp
index fe9ed74..154b8cc 100644
--- a/Plugin/WIMC/Config.cpp
+++ b/Plugin/WIMC/Config.cpp
@@ -14,4 +14,8 @@ Config::Config()
void Config::LoadConfig(LPCWSTR path)
{
m_nCursors = GetPrivateProfileIntW(APPNAME, L"NumberOfCursors", m_nCursors, path);
+ if (m_nCursors < 0)
+ m_nCursors = 0;
+ else if (m_nCursors > 10000)
+ m_nCursors = 10000;
}
diff --git a/Plugin/WIMC/Config.h b/Plugin/WIMC/Config.h
index b92601d..949cbbc 100644
--- a/Plugin/WIMC/Config.h
+++ b/Plugin/WIMC/Config.h
@@ -6,7 +6,7 @@ static const TCHAR APPNAME[] = _T("WIMC");
class Config final
{
public:
- int m_nCursors = 50;
+ int m_nCursors = 500;
Config();
diff --git a/Plugin/WIMC/CursorRenderer.cpp b/Plugin/WIMC/CursorRenderer.cpp
deleted file mode 100644
index c0f569b..0000000
--- a/Plugin/WIMC/CursorRenderer.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#include "stdafx.h"
-#include "CursorRenderer.h"
-
-
-void CursorRenderer::DrawCursor(HDC hdc, HCURSOR cursor, int x, int y)
-{
- auto& cache = GetCursorCache(cursor);
- if (!cache.img.IsNull())
- cache.img.AlphaBlend(hdc, x - cache.hotSpot.x, y - cache.hotSpot.y);
-}
-
-CursorRenderer::CursorCache& CursorRenderer::GetCursorCache(HCURSOR cursor)
-{
- auto it = m_cursorCache.find(cursor);
- if (it != m_cursorCache.end() && !it->second.img.IsNull())
- return it->second;
-
- // 没有缓存,创建一个
- auto& cache = m_cursorCache[cursor];
-
- ICONINFO info;
- GetIconInfo(cursor, &info);
- cache.hotSpot = { info.xHotspot, info.yHotspot };
-
- GetCursorImage(info, cache.img);
-
- if (info.hbmColor != NULL)
- DeleteObject(info.hbmColor);
- if (info.hbmMask != NULL)
- DeleteObject(info.hbmMask);
- return cache;
-}
-
-bool CursorRenderer::GetCursorImage(ICONINFO& info, CImage& img)
-{
- CImage bufferImg;
- // 先尝试彩色图
- if (!GetCursorColorImage(info.hbmColor, info.hbmMask, bufferImg))
- {
- // 单色图
- if (!GetCursorMonoImage(info.hbmMask, bufferImg))
- return false;
- }
-
- int width = GetSystemMetrics(SM_CXCURSOR);
- int height = GetSystemMetrics(SM_CYCURSOR);
- img.Create(width, height, 32, CImage::createAlphaChannel);
- bufferImg.AlphaBlend(img.GetDC(), 0, 0, width, height, 0, 0, bufferImg.GetWidth(), bufferImg.GetHeight());
- img.ReleaseDC();
- return true;
-}
-
-bool CursorRenderer::GetCursorColorImage(HBITMAP color, HBITMAP mask, CImage& img)
-{
- BITMAP colorBmp;
- std::unique_ptr colorData;
- // color必须是32位图
- if (color == NULL || !GetBmpData(color, colorBmp, colorData) || colorBmp.bmBitsPixel != 32)
- return false;
-
- BITMAP maskBmp;
- std::unique_ptr maskData;
- // 有掩码
- if (GetBmpData(mask, maskBmp, maskData))
- {
- // 判断color有没有alpha通道
- int colorSize = colorBmp.bmWidth * colorBmp.bmHeight;
- for (int i = 0; i < colorSize; i++)
- {
- if (colorData[i * 4 + 3] != 0)
- goto NoMask;
- }
- // 没有alpha通道则用mask(与掩码)当alpha通道
- for (int i = 0; i < colorSize; i++)
- colorData[i * 4 + 3] = (GetMonoBmpBit(maskData.get(), i) != 0 ? 255 : 0);
- }
-
-NoMask:
- // 复制到img
- img.Create(colorBmp.bmWidth, colorBmp.bmHeight, 32, CImage::createAlphaChannel);
- for (int y = 0; y < colorBmp.bmHeight; y++)
- {
- BYTE* imgData = (BYTE*)img.GetPixelAddress(0, y);
- memcpy(imgData, &colorData[y * colorBmp.bmWidthBytes], colorBmp.bmWidthBytes);
- }
-
- return true;
-}
-
-bool CursorRenderer::GetCursorMonoImage(HBITMAP mask, CImage& img)
-{
- BITMAP maskBmp;
- std::unique_ptr maskData;
- if (mask == NULL || !GetBmpData(mask, maskBmp, maskData))
- return false;
-
- // 单色图标mask上半部分是与掩码,下半部分是异或掩码
- maskBmp.bmHeight /= 2;
- BYTE* xorMask = maskData.get() + maskBmp.bmHeight * maskBmp.bmWidthBytes;
-
- img.Create(maskBmp.bmWidth, maskBmp.bmHeight, 32, CImage::createAlphaChannel);
- for (int y = 0; y < maskBmp.bmHeight; y++)
- {
- BYTE* imgData = (BYTE*)img.GetPixelAddress(0, y);
- for (int x = 0; x < maskBmp.bmWidth; x++)
- {
- if (GetMonoBmpBit(maskData.get(), x * y) == 0)
- {
- // 与掩码为0,变黑
- // 异或掩码为0则不变(变黑),异或掩码为1则反相(变白)
- *(DWORD*)&imgData[x * 4] = (GetMonoBmpBit(xorMask, x * y) == 0 ? 0xFF000000 : 0xFFFFFFFF);
- }
- else
- {
- // 与掩码为1,不变
- // 异或掩码为0则不变(alpha=0),异或掩码为1则反相(无法用alpha模拟)
- *(DWORD*)&imgData[x * 4] = (GetMonoBmpBit(xorMask, x * y) == 0 ? 0x00000000 : 0xFF7F7F7F);
- }
- }
- }
-
- return true;
-}
-
-bool CursorRenderer::GetBmpData(HBITMAP hbmp, BITMAP& bmp, std::unique_ptr& data)
-{
- if (GetObject(hbmp, sizeof(bmp), &bmp) == 0)
- return false;
-
- LONG size = bmp.bmWidth * bmp.bmHeight * bmp.bmBitsPixel / 8;
- data.reset(new BYTE[size]);
- GetBitmapBits(hbmp, size, data.get());
- return true;
-}
-
-int CursorRenderer::GetMonoBmpBit(const BYTE* data, int index)
-{
- // 单色图一位代表一个像素
- return data[index / 8] >> (7 - index % 8) & 1;
-}
diff --git a/Plugin/WIMC/CursorRenderer.h b/Plugin/WIMC/CursorRenderer.h
deleted file mode 100644
index fa7d534..0000000
--- a/Plugin/WIMC/CursorRenderer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include