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 -#include -#include - - -class CursorRenderer -{ -public: - void DrawCursor(HDC hdc, HCURSOR cursor, int x, int y); - -private: - struct CursorCache - { - CImage img; - POINT hotSpot; - }; - - std::map m_cursorCache; - - - CursorCache& GetCursorCache(HCURSOR cursor); - bool GetCursorImage(ICONINFO& info, CImage& img); - bool GetCursorColorImage(HBITMAP color, HBITMAP mask, CImage& img); - bool GetCursorMonoImage(HBITMAP mask, CImage& img); - - bool GetBmpData(HBITMAP hbmp, BITMAP& bmp, std::unique_ptr& data); - int GetMonoBmpBit(const BYTE* data, int index); -}; diff --git a/Plugin/WIMC/WIMC.cpp b/Plugin/WIMC/WIMC.cpp index f91737f..5f0f3d2 100644 --- a/Plugin/WIMC/WIMC.cpp +++ b/Plugin/WIMC/WIMC.cpp @@ -30,23 +30,16 @@ bool WIMC::OnPostDrawIcon(HDC& hdc) if (!GetCursorInfo(&info)) return true; - /*DrawIconEx(hdc, 0, 0, info.hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_DEFAULTSIZE); - DrawIconEx(hdc, 0, 50, info.hCursor, 0, 0, 0, NULL, DI_IMAGE | DI_DEFAULTSIZE); - DrawIconEx(hdc, 0, 100, info.hCursor, 0, 0, 0, NULL, DI_MASK | DI_DEFAULTSIZE); - - ICONINFO iconInfo; - GetIconInfo(info.hCursor, &iconInfo); - CImage tmp; - tmp.Attach(iconInfo.hbmMask); - tmp.Draw(hdc, 0, 150);*/ - POINT& pos = info.ptScreenPos; float distance = sqrtf(float((pos.x - m_cursorOrigin.x) * (pos.x - m_cursorOrigin.x) + (pos.y - m_cursorOrigin.y) * (pos.y - m_cursorOrigin.y))); float angle = atan2f(float(pos.y - m_cursorOrigin.y), float(pos.x - m_cursorOrigin.x)); + int width = GetSystemMetrics(SM_CXCURSOR); + int height = GetSystemMetrics(SM_CYCURSOR); + for (auto& i : m_fakeCursors) - i.Draw(hdc, info.hCursor, distance, angle, m_renderer); + i.Draw(hdc, info.hCursor, distance, angle, width, height); return true; } @@ -61,14 +54,15 @@ WIMC::FakeCursor::FakeCursor() { SIZE size; cd::GetDesktopSize(size); - origin.x = (int)GetRandomFloat(-size.cx / 2.0f, size.cx * 1.5f); - origin.y = (int)GetRandomFloat(-size.cy / 2.0f, size.cy * 1.5f); + origin.x = (int)GetRandomFloat(-size.cx * 0.75f, size.cx * 1.75f); + origin.y = (int)GetRandomFloat(-size.cy * 0.75f, size.cy * 1.75f); angle = GetRandomFloat(0.0f, 2.0f * float(M_PI)); } -void WIMC::FakeCursor::Draw(HDC hdc, HCURSOR cursor, float cursorDistance, float cursorAngle, CursorRenderer& renderer) +void WIMC::FakeCursor::Draw(HDC hdc, HCURSOR cursor, float cursorDistance, float cursorAngle, int width, int height) { int x = int(origin.x + cursorDistance * cosf(cursorAngle + angle)); int y = int(origin.y + cursorDistance * sinf(cursorAngle + angle)); - renderer.DrawCursor(hdc, cursor, x, y); + // 没有对准热点,不过没什么影响 + DrawIconEx(hdc, x, y, cursor, width, height, 0, NULL, DI_NORMAL); } diff --git a/Plugin/WIMC/WIMC.h b/Plugin/WIMC/WIMC.h index 6bcd1b0..4717c9f 100644 --- a/Plugin/WIMC/WIMC.h +++ b/Plugin/WIMC/WIMC.h @@ -1,6 +1,5 @@ #pragma once #include -#include "CursorRenderer.h" class WIMC final @@ -22,11 +21,10 @@ class WIMC final FakeCursor(); // 参数:真实鼠标的极坐标 - void Draw(HDC hdc, HCURSOR cursor, float cursorDistance, float cursorAngle, CursorRenderer& renderer); + void Draw(HDC hdc, HCURSOR cursor, float cursorDistance, float cursorAngle, int width, int height); }; // 真实鼠标的极坐标原点 POINT m_cursorOrigin; std::vector m_fakeCursors; - CursorRenderer m_renderer; }; diff --git a/Plugin/WIMC/WIMC.vcxproj b/Plugin/WIMC/WIMC.vcxproj index e3a9e8c..50a1ad6 100644 --- a/Plugin/WIMC/WIMC.vcxproj +++ b/Plugin/WIMC/WIMC.vcxproj @@ -148,13 +148,11 @@ - - false false diff --git a/Plugin/WIMC/WIMC.vcxproj.filters b/Plugin/WIMC/WIMC.vcxproj.filters index 3f25646..aae8036 100644 --- a/Plugin/WIMC/WIMC.vcxproj.filters +++ b/Plugin/WIMC/WIMC.vcxproj.filters @@ -27,9 +27,6 @@ 头文件 - - 头文件 - @@ -44,8 +41,5 @@ 源文件 - - 源文件 - \ No newline at end of file