Главная / FAQ по Builder'у / 27 Как нарисовать на чьей либо...

27 Как нарисовать на чьей либо форме(программе)?


Я на основе чьего-то примера сделал прогу.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#include <windowsx.h>
#pragma hdrstop
#include "unit1.h"
#include "IPC.h"//Здесь класс для share ресурсов. В следующем сообщении кину
#include <comctrls.hpp>
#include <stdio.h>
#include <sysutils.hpp>
#define WM_OLEG WM_USER+3000//пользоват. сообщение

//Исправленный взломщик сообщений
//этот макрос позволяет отработать стандартной процедуре
//так как в нем убран return
//но после его вызова в switch надо ставить break;
#define HANDLE_MSGOS(hwnd, message, fn)    \
    case (message): HANDLE_##message((hwnd), (wParam), (lParam), (fn))

// Глобальные переменные
static HHOOK g_hHook = NULL;//Хэндл на ловушку
static DWORD g_dwThreadId = 0;// захученый поток
static HINSTANCE g_hinstDLL = NULL;// Handle на эту DLL
static CIPC g_obIPC;// Файл в памяти (разделяемый ресурс) для передачи данных от ехе сюда
//Сообщение инициализации (уникальное)
static UINT g_wmScanPassword = RegisterWindowMessage(IPC_CUSTOM_MSG);
WNDPROC  oldProc;
WNDPROC  oldEdit;
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*
lpReserved)
{

    switch(reason)
    {
    case DLL_PROCESS_ATTACH:

        g_hinstDLL = hinst;
        DisableThreadLibraryCalls(GetModuleHandle(PWDSPY_HOOK_DLL));
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
        return 1;
}

//---------------------------------------------------------------------------
//***********************************************
extern "C" __declspec(dllexport) bool InstallHook(const DWORD dwThreadId)
{
    // Вызывается из exe модуля
    bool bSuccess = false;
    try
    {
        //Попытка захучить захученный поток
        if(g_dwThreadId == dwThreadId)
            return true;
         
        // Попытка захучить другой поток, сначала отхучить прежний хук
                //Мы еще в адр. пространстве нашего exe
                  if(g_dwThreadId != dwThreadId && g_hHook != NULL)
            RemoveHook();
	
        // Сохранить ид-р потока, если он не 0
        if((g_dwThreadId = dwThreadId) != 0)
        {   
            // Заблокировать разделяемый ресурс (Установить mutex)
            g_obIPC.Lock();
            g_obIPC.CreateIPCMMF();//Создать файл в памяти
		
                        //Установить ловушку
            g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc,
g_hinstDLL,
g_dwThreadId);
            if(g_hHook != NULL)
            {
                // Сохранить handle ловушки в разделяемый ресурс.
                DWORD dwData = (DWORD)g_hHook;
                g_obIPC.WriteIPCMMF((LPBYTE)&dwData, sizeof(dwData));
                bSuccess = true;
		
                //Послать сообщение, чтобы ловушка установилась и взяла вызов
                PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
            }
        }
    }
    catch(...) {}

    // Разблокировать ресурсы
    g_obIPC.Unlock();
    return bSuccess;
}

//***********************************************
void OnDestroy(HWND hwnd);
bool WINAPI RemoveHook(void)
{
       //Вызывается из нашего exe
    bool bSuccess = false;
    try
    {
        if(g_hHook != NULL)
        {
            bSuccess = UnhookWindowsHookEx(g_hHook) ? true : false;
            g_hHook = NULL;
            g_dwThreadId = 0;
        }
    }
    catch(...) {}
    return bSuccess;
}

//***********************************************
bool WINAPI ScanPassword(const HWND hWnd, const HWND hPwdSpyWnd)
{
    bool bSuccess = false;

    try
    {
        if(g_dwThreadId != 0 && hWnd != NULL && hPwdSpyWnd != NULL)
        {
            PostThreadMessage(g_dwThreadId, g_wmScanPassword, (WPARAM)hWnd,
(LPARAM)hPwdSpyWnd);
            bSuccess = true;
        }
    }
    catch(...) {}

    return bSuccess;
}

//***********************************************
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    // Вызывается ТОЛЬКО из  захученного процесса
    try
    {
        if(g_hHook == NULL)
        {   // Считать данные из разделяемых ресурсов
                        //получить ид-р ловушки
            DWORD dwData = 0, dwSize = sizeof(dwData);
            g_obIPC.Lock();
            g_obIPC.OpenIPCMMF();
            g_obIPC.ReadIPCMMF((LPBYTE)&dwData, dwSize);
            g_obIPC.Unlock();
            g_hHook = (HHOOK)dwData;
        }
	
        //Игнорировать сообщения меньше 0. Hужны только для счит. данных
        if(nCode >= 0)
        {
            HWND hWnd = NULL;       // Handle на окно с паролем
            HWND hPwdSpyWnd = NULL; // Handle куда отправить информацию в наш exe
            MSG *pMsg = (MSG*)lParam;
		
            // Hаше сообщение?
            if(pMsg->message == g_wmScanPassword)
            {
                hWnd = (HWND)pMsg->wParam;
                hPwdSpyWnd = (HWND)pMsg->lParam;
                ExtractPassword(hWnd, hPwdSpyWnd);
            }
        }
    }
    catch(...) {}
        return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
//Пользовательские функции
//Hа разрушение - все возвернуть взад
 void OnDestroy(HWND hwnd)
  {
   SetWindowLong(hwnd,GWL_WNDPROC,LONG(oldProc));
   PostQuitMessage(0);
  }

 void OnPaint(HWND hwnd)
  {
  //Пример из Win32 sdk
  //Рисунок будет съезжать при скроллинге,но это  не всегда помеха
  //Hа крайняк надо отлавливать WM_H(V)SCROLL, и если используется
  // не SolidBrush, получить MapMode и установить
  // LPtoDP и SetBrushOrgEx()
   HDC hdc;
   RECT rc;
   POINT aptStar[6] = {50,2, 2,98, 98,33, 2,33, 98,98, 50,2};
   hdc = GetDC(hwnd);
   GetClientRect(hwnd, &rc);
   SetMapMode(hdc, MM_ANISOTROPIC);
   SetWindowExtEx(hdc, 100, 100, NULL);
   SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);
   Polyline(hdc, aptStar, 6);
   TextOut(hdc,10,10,"А вот и я!",10);
   ReleaseDC(hwnd,hdc);
  }

//Hовая процедура обработки сообщений окна (со взломщиком)
LRESULT  CALLBACK NewWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM
lParam)
 {
    switch(message)
     {
//      HANDLE_MSGOS(hwnd,WM_COMMAND,OnMenu); return 1;
       case WM_DESTROY: OnDestroy(hwnd); break;
       case WM_PAINT:
        {
          //Дать старому отрисоваться (можно и не давать)
         LRESULT r=CallWindowProc((FARPROC)oldProc, hwnd,message,
wParam,lParam);
         OnPaint(hwnd);
         return r;
        }
     }
    return CallWindowProc((FARPROC)oldProc, hwnd,message, wParam,lParam);
 }

//Эта функция может рассматриваться как WinMain
//Т.к. до нее прошли все подготовительные операции
void ExtractPassword(const HWND hWnd, const HWND hPwdSpyWnd)
{
   try
    {
         static HWND f=0;
         //Чтобы 2 раза одно окно не хучить
         if(f==hWnd) return;else f=hWnd;
        //Подсунуть новую процедурку (т.е. создать подкласс окна)
         oldProc= (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC);
         LONG m;
         m = SetWindowLong(hWnd,GWL_WNDPROC,LONG(NewWndProc));
         if(m)//процедура установилась нормально
          {
           AnsiString s ="Хук установлен";
           COPYDATASTRUCT cds = {0};
       cds.dwData = (DWORD)hWnd;
       cds.cbData = s.Length()+1;
       cds.lpData = s.c_str();
           //Отправить в установщик
       SendMessage(hPwdSpyWnd , WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
          }
      }

       catch(...)
       {
         AnsiString h="Какой-то дикий трабл";
         HDC dc1= GetDC(0);
         TextOut(dc1,10,40,h.c_str(),h.Length());
         ReleaseDC(0,dc1);
       }
}
И з этой dll делаешь lib и статически подключаешь его к exe-модулю. Hу а потом из exe вызываешь
InstallHook(GetWindowThreadProcessId(hWnd, NULL));//Hwnd - исслед. форма
ScanPassword(hWnd, Handle);
Vasiutin Oleg (Васютин Олег) 2:5020/400 infomar@cityline.ru

Предыдущий вопрос   |  Список вопросов   |   Следующий вопрос

источник      На главную      by jenyok
Copyright © 2003 JTSOFT
Сайт управляется системой uCoz