⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hook.cpp

📁 C++Builder深度历险配套源码 C++Builder深度历险配套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
          // 重绘按钮区域的桌面
          R = ConfigButton->BoundsRect;
          InvalidateRect(Window, &R, false);

          // 成功处理此讯息
          return 0;
        }
      }
    }
  }

  return CallWindowProc((FARPROC)g_Data->OrigWndProc, Window, AMessage, WPARAM, LPARAM);
}

LRESULT _stdcall ParentWndProc(HWND Window, UINT AMessage, Longint WPARAM , Longint LPARAM)
{
  PNMHdr NMHdr;
  TRect RSrc, RDst;

  switch (AMessage) {
    case WM_NOTIFY:

      NMHdr = PNMHdr(LPARAM);
      switch (NMHdr->code) {
        // ListView 视窗进行绘制时会先送给其父视窗 WM_NOTIFY 讯息
        // 动作代码为 NM_CUSTOMDRAW
        case NM_CUSTOMDRAW:
          // 若矩形区域改变, 则变更 BackBits 大小
          if (DynDisplay.BackBits->Width != DynDisplay.CurRect.Right - DynDisplay.CurRect.Left || DynDisplay.BackBits->Height != DynDisplay.CurRect.Bottom - DynDisplay.CurRect.Top) {
            DynDisplay.BackBits->Width = DynDisplay.CurRect.Right - DynDisplay.CurRect.Left;
            DynDisplay.BackBits->Height = DynDisplay.CurRect.Bottom - DynDisplay.CurRect.Top;
          }

          RSrc = Rect(0, 0, DynDisplay.BackBits->Width, DynDisplay.BackBits->Height);

          if (g_Data->ShowDesktopWallPaper) { // 若要显示桌布
            // 先将背景拷贝到 DynDisplay.BackBits
            RDst = RSrc;
            OffsetRect(&RDst, DynDisplay.Position.x + g_Data->WorkAreaRect.Left, DynDisplay.Position.y + g_Data->WorkAreaRect.Top);
            DynDisplay.BackBits->Canvas->CopyRect(RSrc, DynDisplay.DesktopBits->Canvas, RDst);
          }

          // 若要显示桌布, 采透明贴字
          if (g_Data->ShowDesktopWallPaper)
            DynDisplay.BackBits->Canvas->Brush->Style = bsClear;
          else {
            // 否则将影像填满背景色
            DynDisplay.BackBits->Canvas->Brush->Style = bsSolid;
            DynDisplay.BackBits->Canvas->Brush->Color = clBackground;
          }

          // 先在 DynDisplay.BackBits 上绘出时间字串
          DynDisplay.BackBits->Canvas->TextRect(RSrc, 0, 0, DynDisplay.DisplayString);

          // 最後将 DynDisplay.BackBits 贴到桌面上
          BitBlt(PNMLVCustomDraw(NMHdr)->nmcd.hdc, DynDisplay.Position.x, DynDisplay.Position.y, DynDisplay.BackBits->Width, DynDisplay.BackBits->Height,
              DynDisplay.BackBits->Canvas->Handle, 0, 0, SRCCOPY);

          // 进行正常的绘制动作
          return CDRF_DODEFAULT;
      }
    break;
  }

  return CallWindowProc((FARPROC)g_Data->OrigParentWndProc, Window, AMessage, WPARAM, LPARAM);
}

LRESULT _stdcall GetMsgProc(int Code, Longint WPARAM , Longint LPARAM)
{
  static bool bFirstCalled = true;
  HANDLE hEvent;

  if (Code == HC_ACTION) { // 动作代码为 HC_ACTION 时才处理
    if (bFirstCalled) { // 第一次呼叫时进行 subclassing

      bFirstCalled = false;

      // subclass 背景视窗
      g_Data->OrigWndProc = (WNDPROC)SetWindowLong(g_Data->Wnd, GWL_WNDPROC, (long)WndProc);

      // subclass 背景视窗的父视窗
      g_Data->ParentWnd = GetParent(g_Data->Wnd);
      g_Data->OrigParentWndProc = (WNDPROC)SetWindowLong(g_Data->ParentWnd, GWL_WNDPROC, (long)ParentWndProc);

      // 告知背景视窗, 已被 subclass
      PostMessage(g_Data->Wnd, WM_SUBCLASSED, 0, 0);

      InvalidateRect(g_Data->Wnd, NULL, true); // 重绘 ListView 视窗

      // 告知 hook 程序完成
      PostThreadMessage(PMsg(LPARAM)->wParam, WM_MYHOOK, 0, 0);

      // 尝试开启保护 hook handle 的 event
      hEvent = OpenEvent(SYNCHRONIZE, false, HOOK_EVENT_NAME);
      if (hEvent) { // 如果开启成功, 表示 hook handle 尚未被写入
        WaitForSingleObject(hEvent, INFINITE); // 等待 hook handle 确定下来
        CloseHandle(hEvent); // 关闭 event
      }
    } else if (PMsg(LPARAM)->message == WM_MYHOOK) {
      // 通知背景视窗, 将要 unsubclass
      SendMessage(g_Data->Wnd, WM_BEFORE_UNSUBCLASS, 0, 0);

      // unsubclass 背景视窗
      SetWindowLong(g_Data->Wnd, GWL_WNDPROC, (long)g_Data->OrigWndProc);
      // unsubclass 背景视窗的父视窗
      SetWindowLong(g_Data->ParentWnd, GWL_WNDPROC, (long)g_Data->OrigParentWndProc);

      InvalidateRect(g_Data->Wnd, NULL, true); // 重绘 ListView 视窗

      // 告知 unhook 程序完成
      PostThreadMessage(PMsg(LPARAM)->wParam, WM_MYHOOK, 0, 0);
    }
  }

  // 呼叫下一个 hook 函式
  return CallNextHookEx(g_Data->HHOOK, Code, WPARAM, LPARAM);
}

EXTERN bool _stdcall SetDeskHook(HWND Wnd)
{
  DWORD ThreadId;
  TMsg Msg;
  HANDLE hEvent;

  if (Wnd != 0) {
    if (g_Data->HHOOK != 0) return false;

    // 取得视窗的执行绪 ID
    g_Data->Wnd = Wnd;
    ThreadId = GetWindowThreadProcessId(g_Data->Wnd, NULL);

    // 建立保护 hook handle 的 event
    hEvent = CreateEvent(NULL, true, false, HOOK_EVENT_NAME);
    // 安装 WH_GETMESSAGE hook
    g_Data->HHOOK = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hinstDLL, ThreadId);
    // 将 event 设为 signaled 状态, 若 hook 函式正在等待, 等於通知它,
    // hook handle 已经 ready
    SetEvent(hEvent);
    // 关闭 event
    CloseHandle(hEvent);

    if (g_Data->HHOOK != 0) { // 若 hook 安装成功
      // 丢一个无用讯息过去, 确认 hook 函式被呼叫
      // 同时 subclass 背景视窗及其父视窗
      PostThreadMessage(ThreadId, WM_NULL, GetCurrentThreadId(), 0);

      // 等待 Hook 装设完成, 由 Hook 程序送回 WM_MYHOOK 讯息通知
      do {
         GetMessage(&Msg, 0, 0, 0);
      } while (Msg.message != WM_MYHOOK);

      return true;
    }
  } else {
    if (g_Data->HHOOK != 0) {
      ThreadId = GetWindowThreadProcessId(g_Data->Wnd, NULL);
      // 告知 hook 函式, 请先 unsubclass, 准备要 unhook 了
      PostThreadMessage(ThreadId, WM_MYHOOK, GetCurrentThreadId(), 0);

      // 确定 GetMsgProc 已将背景视窗及其父视窗 unsubclassing 後..
      do {
        GetMessage(&Msg, 0, 0, 0);
      } while (Msg.message != WM_MYHOOK);

      // 取消 hook 函式
      UnhookWindowsHookEx(g_Data->HHOOK);

      g_Data->HHOOK = 0;

      return true;
    }
  }

  return true;
}

EXTERN void _stdcall SetMainWindow(HWND Wnd)
{
  g_Data->MainWnd = Wnd;
}

EXTERN void _stdcall SetShowDesktopWallPaper(bool Value)
{
  g_Data->ShowDesktopWallPaper = Value;
  InvalidateRect(g_Data->Wnd, NULL, true);
}

EXTERN void _stdcall SetEssay(int index, char* Str)
{
  if (index < MAX_ESSAY_LINE)
    strncpy(g_Data->Essay[index], Str, MAX_ESSAY_CHAR - 1);
}

#define MIN(a,b) ((a)<(b)?(a):(b))

EXTERN void _stdcall SetEssayCount(int Count)
{
  g_Data->Essay_LineCount = MIN(Count, MAX_ESSAY_LINE);
  InvalidateRect(g_Data->Wnd, NULL, true);
}

EXTERN void _stdcall SetEssayFont(PLogFont LF)
{
  memcpy(&g_Data->Essay_Font, LF, sizeof(TLogFont));
  InvalidateRect(g_Data->Wnd, NULL, true);
}

void _stdcall SetEssayColor(COLORREF SepColor, COLORREF TextColor)
{
  g_Data->SeperatorColor = SepColor;
  g_Data->Essay_Color = TextColor;

  InvalidateRect(g_Data->Wnd, NULL, true);
}

HANDLE MapGlobalData(const AnsiString MapName, int Size, LPVOID &P)
{
  HANDLE ret = CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, Size, MapName.c_str());

  if (ret == 0) {
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
      ret = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, MapName.c_str());
      if (ret == 0) return ret;
    } else
      return ret;
  }

  P = (LPVOID)MapViewOfFile(ret, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  if (P == NULL) {
    CloseHandle(ret);
    ret = 0;
  }

  return ret;
}

void ReleaseGlobalData(HANDLE handle, void* &Ptr)
{
  if (Ptr) {
    UnmapViewOfFile(Ptr);
    Ptr = NULL;
  }

  if (handle != 0) {
    CloseHandle(handle);
    handle = 0;
  }
}

void DebugStr(AnsiString S)
{
  S = S + "\n";
  OutputDebugString(S.c_str());
}

#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
  char buf[256];

  GetModuleFileName(0, buf, sizeof(buf));
  switch (fwdreason) {
    case DLL_PROCESS_ATTACH:
      g_hinstDLL = hinstDLL;
      DebugStr(Format("DLL_PROCESS_ATTACH: %d %s", OPENARRAY(TVarRec, ((int)hinstDLL, buf))));
      MapHandle = MapGlobalData(GLOBAL_DATA_MAPNAME, sizeof(TGlobalData), Pointer(g_Data));
      break;

    case DLL_PROCESS_DETACH:
      DebugStr(Format("DLL_PROCESS_DETACH: %d %s", OPENARRAY(TVarRec, ((int)g_hinstDLL, buf))));
      ReleaseGlobalData(MapHandle, Pointer(g_Data));
      break;

    case DLL_THREAD_ATTACH:;
      break;

    case DLL_THREAD_DETACH:;
      break;
  }

  return 1;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -