动态链接库的学习

1. 近来分析tightVnc 开源项目的时候学到不少东西.比如ScreenHooks 动态链接库 提供出来的时候,
在头文件只提供外部需要调用到的函数, 至于其他内部间调用的函数,即使是预定义也把它放在.cpp 文件里.

2. 个人想法:至于要提供整个类的时候,比如要提供A类的公有接口出来, 但是一般类中在头文件定义的时候,
会有私有函数和成员变量等在一起,但是其实外部调用都不太需要这些.. 个人的做法是从A 类中派生出一个B类,
在B类中只提供一些外部要调用的接口(此时接口也只是简单的调用父类的同名函数即可).

 

 

以下是开源项目的节省代码

ScreenHooks.h

#ifndef __SCREENHOOKS_H__
#define __SCREENHOOKS_H__

#include "util/CommonHeader.h"

extern "C"
{
  __declspec(dllexport) bool setHook(HWND targedWinHwnd);
  __declspec(dllexport) bool unsetHook();
}

#endif // __SCREENHOOKS_H__

 

 

ScreenHooks.cpp

#include "ScreenHooks.h"
#include "util/CommonHeader.h"
#include "tvnserver-app/NamingDefs.h"
#include "region/Point.h"
#include "region/Region.h"

// Pre-definition:
LRESULT CALLBACK callWndRetProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK getMsgProc(int code, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK sysMsgProc(int code, WPARAM wParam, LPARAM lParam);
void processMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void sendRect(const Rect *rect);
void sendClientRect(HWND hwnd);
void sendNClientRegion(HWND hwnd);
Rect getWindowRect(HWND hwnd);
Rect getClientRect(HWND hwnd);

// Per-instance variables:
HMODULE g_hModule = 0;

#pragma comment(linker, "/section:.shared,RWS")
#pragma data_seg(".shared")
HHOOK g_callWndProcH = 0;
HHOOK g_getMessageH = 0;
HHOOK g_sysMessageH = 0;
HWND g_targetWinHwnd = 0;
#pragma data_seg()

BOOL APIENTRY DllMain(HMODULE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved)
{
  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
    g_hModule = hModule;
    break;
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
    break;
  }
  return TRUE;
}

__declspec(dllexport) bool setHook(HWND targedWinHwnd)
{
  g_targetWinHwnd = targedWinHwnd;
  g_callWndProcH = SetWindowsHookEx(WH_CALLWNDPROCRET,
                                    callWndRetProc,
                                    g_hModule,
                                    0);

  g_getMessageH = SetWindowsHookEx(WH_GETMESSAGE,
                                   getMsgProc,
                                   g_hModule,
                                   0);

  g_sysMessageH = SetWindowsHookEx(WH_SYSMSGFILTER,
                                   sysMsgProc,
                                   g_hModule,
                                   0);

  return g_callWndProcH != 0 && g_getMessageH != 0 && g_sysMessageH != 0;
}

__declspec(dllexport) bool unsetHook()
{
  bool result = UnhookWindowsHookEx(g_callWndProcH) != 0;
  result = result && UnhookWindowsHookEx(g_getMessageH) != 0;
  return result;
}

LRESULT CALLBACK callWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
{
  if (nCode == HC_ACTION) {
    CWPRETSTRUCT *cpwS = (CWPRETSTRUCT *)lParam;
    processMessage(cpwS->hwnd, cpwS->message, cpwS->wParam, cpwS->lParam);
  }
  return CallNextHookEx(g_callWndProcH, nCode, wParam, lParam);
}

LRESULT CALLBACK getMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
  if (code == MSGF_DIALOGBOX || code == MSGF_MENU || code == MSGF_SCROLLBAR) {
    MSG *msg = (MSG *)lParam;
    processMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam);
  }
  return CallNextHookEx(g_getMessageH, code, wParam, lParam);
}

LRESULT CALLBACK sysMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
  if (code == MSGF_DIALOGBOX || code == MSGF_MENU || code == MSGF_SCROLLBAR) {
    MSG *msg = (MSG *)lParam;
    processMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam);
  }
  return CallNextHookEx(g_sysMessageH, code, wParam, lParam);
}

void processMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message) {
  case WM_PAINT:
    //FIXME: Process a region that folowing with WM_PAINT.
  case WM_CTLCOLOREDIT:
  case WM_ACTIVATE:
  case WM_ERASEBKGND:
    sendClientRect(hwnd);
    break;
  case WM_NCPAINT:
  case WM_NCACTIVATE:
  case WM_HSCROLL:
  case WM_VSCROLL:
    sendNClientRegion(hwnd);
    break;
  case 0x0092: // Menu
    sendClientRect(hwnd);
    sendNClientRegion(hwnd);
    break;
  case WM_DRAWITEM:
    if (lParam != 0) {
      DRAWITEMSTRUCT *dts = (DRAWITEMSTRUCT *)lParam;
      HWND ctlHwnd = dts->hwndItem;
      if (wParam == 0) { // it is a menu control
      } else {
        sendRect(&getWindowRect(ctlHwnd));
      }
    }
    break;
  }
}

void sendRect(const Rect *rect)
{
  INT16 left   = (INT16)rect->left;
  INT16 top    = (INT16)rect->top;
  INT16 right  = (INT16)rect->right;
  INT16 bottom = (INT16)rect->bottom;
  PostMessage(g_targetWinHwnd, HookDefinitions::SPEC_IPC_CODE,
              MAKEWPARAM(top, left),
              MAKELPARAM(bottom, right));
}

void sendClientRect(HWND hwnd)
{
  Rect clientRect = getClientRect(hwnd);
  sendRect(&clientRect);
}

void sendNClientRegion(HWND hwnd)
{
  Region ncRegion(&getWindowRect(hwnd));
  Region cRegion(&getClientRect(hwnd));

  ncRegion.subtract(&cRegion);

  std::vector<Rect> rects;
  std::vector<Rect>::iterator iRect;
  ncRegion.getRectVector(&rects);
  for (iRect = rects.begin(); iRect < rects.end(); iRect++) {
    sendRect(&(*iRect));
  }
}

Rect getWindowRect(HWND hwnd)
{
  Point offset;
  offset.x = GetSystemMetrics(SM_XVIRTUALSCREEN);
  offset.y = GetSystemMetrics(SM_YVIRTUALSCREEN);

  RECT clientRect;
  Rect resultRect;
  if (GetWindowRect(hwnd, &clientRect) != 0) {
    resultRect.fromWindowsRect(&clientRect);
    resultRect.move(offset.x, offset.y);
  }
  return resultRect;
}

Rect getClientRect(HWND hwnd)
{
  Rect resultRect;
  RECT clientRect;
  if (GetClientRect(hwnd, &clientRect) != 0) {
    POINT offset;
    offset.x = 0;
    offset.y = 0;

    ClientToScreen(hwnd, &offset);
    offset.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
    offset.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
    resultRect.fromWindowsRect(&clientRect);
    resultRect.move(offset.x, offset.y);
  }
  return resultRect;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值