hook实例小记

dll部分:

/////xxx.h

#ifndef HOOK_API
#define HOOK_API __declspec(dllimport)
#endif

HOOK_API BOOL WINAPI SetDIPSHook(DWORD dwThreadId);

 

/////xxx.cpp

#define HOOK_API __declspec(dllexport)
#include "hook.h"
#include <Windows.h>
#include "resource.h"
#include <fstream>

using namespace std;

#pragma data_seg("shared")
HHOOK g_hhook = NULL;
DWORD g_dwThreadIdDIPS = 0;
#pragma data_seg()


#pragma comment(linker, "/section:shared,rws")

LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);

INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

HINSTANCE g_hinstDll = NULL;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    switch (ul_reason_for_call) {

      case DLL_PROCESS_ATTACH:
          // DLL is attaching to the address space of the current process.
          g_hinstDll = hModule;
          break;

      case DLL_THREAD_ATTACH:
          // A new thread is being created in the current process.
          break;

      case DLL_THREAD_DETACH:
          // A thread is exiting cleanly.
          break;

      case DLL_PROCESS_DETACH:
          // The calling process is detaching the DLL from its address space.
          break;
    }
    return TRUE;
}


BOOL WINAPI SetDIPSHook(DWORD dwThreadId)
{
    BOOL fOk = FALSE;

    if (dwThreadId != 0) {

        // Save our thread ID in a shared variable so that our GetMsgProc
        // function can post a message back to to thread when the server
        // window has been created.
        g_dwThreadIdDIPS = GetCurrentThreadId();

        // Install the hook on the specified thread
        g_hhook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDll,
            dwThreadId);

        fOk = (g_hhook != NULL);
        if (fOk) {
            // The hook was installed successfully; force a benign message to
            // the thread's queue so that the hook function gets called.
            fOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
        }
    } else {

        // Make sure that a hook has been installed.
        fOk = UnhookWindowsHookEx(g_hhook);
        g_hhook = NULL;
    }

    return(fOk);
}

LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {

    static BOOL fFirstTime = TRUE;

    if (fFirstTime) {
        // The DLL just got injected.
        fFirstTime = FALSE;

        // Uncomment the line below to invoke the debugger
        // on the process that just got the injected DLL.
        // ForceDebugBreak();

        // Create the DTIS Server window to handle the client request.
        CreateDialog(g_hinstDll, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlg_Proc);

        // Tell the DIPS application that the server is up
        // and ready to handle requests.
        PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0);
    }

    return(CallNextHookEx(g_hhook, nCode, wParam, lParam));
}


///////////////////////////////////////////////////////////////////////////////


void Dlg_OnClose(HWND hwnd) {

    DestroyWindow(hwnd);
}


///////////////////////////////////////////////////////////////////////////////


static const TCHAR g_szRegSubKey[] =
TEXT("Software//Richter//Desktop Item Position Saver");


///////////////////////////////////////////////////////////////////////////////


void SaveListViewItemPositions(HWND hwndLV) {
    /*

    int nMaxItems = ListView_GetItemCount(hwndLV);

    // When saving new positions, delete the old position
    // information that is currently in the registry.
    LONG l = RegDeleteKey(HKEY_CURRENT_USER, g_szRegSubKey);

    // Create the registry key to hold the info
    HKEY hkey;
    l = RegCreateKeyEx(HKEY_CURRENT_USER, g_szRegSubKey, 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL);
    chASSERT(l == ERROR_SUCCESS);

    for (int nItem = 0; nItem < nMaxItems; nItem++) {

        // Get the name and position of a ListView item.
        TCHAR szName[MAX_PATH];
        ListView_GetItemText(hwndLV, nItem, 0, szName, chDIMOF(szName));

        POINT pt;
        ListView_GetItemPosition(hwndLV, nItem, &pt);

        // Save the name and position in the registry.
        l = RegSetValueEx(hkey, szName, 0, REG_BINARY, (PBYTE) &pt, sizeof(pt));
        chASSERT(l == ERROR_SUCCESS);
    }
    RegCloseKey(hkey);
    */
    ofstream fout("e:/1.txt");
    fout<<"save";
    fout.close();

}


///////////////////////////////////////////////////////////////////////////////


void RestoreListViewItemPositions(HWND hwndLV) {
    /*
    HKEY hkey;
    LONG l = RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegSubKey,
        0, KEY_QUERY_VALUE, &hkey);
    if (l == ERROR_SUCCESS) {

        // If the ListView has AutoArrange on, temporarily turn it off.
        DWORD dwStyle = GetWindowStyle(hwndLV);
        if (dwStyle & LVS_AUTOARRANGE)
            SetWindowLong(hwndLV, GWL_STYLE, dwStyle & ~LVS_AUTOARRANGE);

        l = NO_ERROR;
        for (int nIndex = 0; l != ERROR_NO_MORE_ITEMS; nIndex++) {
            TCHAR szName[MAX_PATH];
            DWORD cbValueName = chDIMOF(szName);

            POINT pt;
            DWORD cbData = sizeof(pt), nItem;

            // Read a value name and position from the registry.
            DWORD dwType;
            l = RegEnumValue(hkey, nIndex, szName, &cbValueName,
                NULL, &dwType, (PBYTE) &pt, &cbData);

            if (l == ERROR_NO_MORE_ITEMS)
                continue;

            if ((dwType == REG_BINARY) && (cbData == sizeof(pt))) {
                // The value is something that we recognize; try to find
                // an item in the ListView control that matches the name.
                LV_FINDINFO lvfi;
                lvfi.flags = LVFI_STRING;
                lvfi.psz = szName;
                nItem = ListView_FindItem(hwndLV, -1, &lvfi);
                if (nItem != -1) {
                    // We found a match; change the item's position.
                    ListView_SetItemPosition(hwndLV, nItem, pt.x, pt.y); 
                }
            }
        }
        // Turn AutoArrange back on if it was originally on.
        SetWindowLong(hwndLV, GWL_STYLE, dwStyle);
        RegCloseKey(hkey);
    }
    */
    ofstream fout("e:/1.txt");
    fout<<"load";
    fout.close();
}


///////////////////////////////////////////////////////////////////////////////


INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

    switch (uMsg) {

      case WM_APP:
          // Uncomment the line below to invoke the debugger
          // on the process that just got the injected DLL.
          // ForceDebugBreak();

          if (lParam==1)
              SaveListViewItemPositions((HWND) wParam);
          else
              RestoreListViewItemPositions((HWND) wParam);
          break;
    }

    return(FALSE);
}

 

 

 

 

exe测试部分:

    HWND hwndLV = ::GetFirstChild(::GetFirstChild(::FindWindow("ProgMan",NULL)));

    if(hwndLV==NULL)
        AfxMessageBox("zfq");

    SetDIPSHook(GetWindowThreadProcessId(hwndLV, NULL));

    // Wait for the DIPS server window to be created.
    MSG msg;
    GetMessage(&msg, NULL, 0, 0);

    // Find the handle of the hidden dialog box window.
    hwndDIPS = ::FindWindow(NULL, "HookServer");


    // Tell the DIPS window which ListView window to manipulate
    // and whether the items should be saved or restored.
    ::SendMessage(hwndDIPS, WM_APP, (WPARAM) hwndLV, 0);

    // Tell the DIPS window to destroy itself. Use SendMessage
    // instead of PostMessage so that we know the window is
    // destroyed before the hook is removed.
    ::SendMessage(hwndDIPS, WM_CLOSE, 0, 0);


    // Unhook the DLL, removing the DIPS dialog box procedure
    // from the Explorer's address space.
    SetDIPSHook(0); 

你可能感兴趣的:(thread,ListView,null,dll,hook,winapi)