#define UNICODE
#include <windows.h>
typedef void(WINAPI * PSAVECALLWND) (HWND); // Kiểu hàm trong Dll
#define WM_NOTEPADKEYDOWN (WM_USER + 1) // Thông điệp thống nhất số hiệu với bên Dll
LPCTSTR g_AppName = L"HookNotepad";
class CLibrary
{
private:
HMODULE m_hModule;
HOOKPROC m_HookProc;
HHOOK m_hHook;
public:
// Khởi dựng - hủy
CLibrary() : m_hModule(NULL), m_HookProc(NULL), m_hHook(NULL) {}
~CLibrary()
{
if (m_hHook)
UnhookWindowsHookEx(m_hHook);
if (m_hModule)
FreeLibrary(m_hModule);
}
bool Initialize(HWND hwnd)
{
// Kiểm tra cửa sổ Notepad
HWND hParent = FindWindow(L"Notepad", L"Untitled - Notepad");
if (!hParent)
{
MessageBox(hwnd, L"Không tìm thấy cửa sổ Notepad, hoặc tiêu đề đã thay đổi !!!", g_AppName, MB_OK | MB_ICONERROR);
return false;
}
HWND hChild = FindWindowEx(hParent, NULL, L"Edit", L"");
if (!hChild)
{
MessageBox(hwnd, L"Notepad đã thay đổi tên lớp soạn thảo, hoặc nội dung đã thay đổi !!!", g_AppName, MB_OK | MB_ICONERROR);
return false;
}
//
DWORD processId;
DWORD threadId = GetWindowThreadProcessId(hChild, &processId);
// Kiểm tra thư viện
m_hModule = LoadLibrary(L"HookNotepadDll.dll");
if (!m_hModule)
{
MessageBox(hwnd, L"Không tìm thấy thư viện HookNotepadDll.dll !!!", g_AppName, MB_OK | MB_ICONERROR);
return false;
}
m_HookProc = (HOOKPROC)GetProcAddress(m_hModule, "KeyboardProc");
if (!m_HookProc)
{
MessageBox(hwnd, L"Thư viện HookNotepadDll.dll đã sai hỏng !!!", g_AppName, MB_OK | MB_ICONERROR);
return false;
}
// Phần mã cộng thêm nếu muốn xử lý hook dài
PSAVECALLWND pSave = (PSAVECALLWND)GetProcAddress(m_hModule, "SaveCallWnd");
if (!pSave)
{
MessageBox(hwnd, L"Thư viện HookNotepadDll.dll đã sai hỏng !!!", g_AppName, MB_OK | MB_ICONERROR);
return false;
}
pSave(hwnd); // Thư viện sẽ lưu thẻ cửa sổ chương trình từ hàm này
// Bắt đầu Hook
m_hHook = SetWindowsHookEx(WH_KEYBOARD, m_HookProc, m_hModule, threadId);
return true;
}
};
class CMainWnd
{
private:
HINSTANCE m_hInst = NULL;
HWND m_hWnd = NULL;
HWND m_hbtBegin = NULL;
HWND m_hbtEnd = NULL;
CLibrary * m_pLibrary = NULL;
// Thủ tục Window
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = reinterpret_cast<LPCREATESTRUCT>(lparam);
CMainWnd * p = reinterpret_cast<CMainWnd*>(pcs->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(p));
return p->OnCreate(pcs->hInstance, hwnd);
}
CMainWnd * p = reinterpret_cast<CMainWnd*>(static_cast<LONG_PTR>(GetWindowLongPtr(hwnd, GWLP_USERDATA)));
if (p)
{
switch (message)
{
case WM_SIZE: return p->OnSize(lparam);
case WM_COMMAND: return p->OnCommand(wparam, lparam);
case WM_DESTROY: return p->OnDestroy();
case WM_NOTEPADKEYDOWN: return p->OnNotepadKeydown(wparam, lparam); // Thông điệp từ Dll
}
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
// Các bộ xử lý thông điệp
LRESULT OnCreate(HINSTANCE hInst, HWND hwnd)
{
m_hInst = hInst;
m_hWnd = hwnd;
// Tạo các button
m_hbtBegin = CreateWindow(L"button", L"Begin", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,
reinterpret_cast<HMENU>(static_cast<UINT_PTR>(1001)), hInst, NULL);
m_hbtEnd = CreateWindow(L"button", L"End", WS_CHILD | WS_VISIBLE | WS_DISABLED, 0, 0, 0, 0, hwnd,
reinterpret_cast<HMENU>(static_cast<UINT_PTR>(1002)), hInst, NULL);
return 0;
}
LRESULT OnSize(LPARAM lparam)
{
int xCenter = LOWORD(lparam) / 2;
int yCenter = HIWORD(lparam) / 2;
// Di chuyển các Button
MoveWindow(m_hbtBegin, xCenter - 90, yCenter - 11, 80, 22, TRUE);
MoveWindow(m_hbtEnd, xCenter + 10, yCenter - 11, 80, 22, TRUE);
return 0;
}
LRESULT OnCommand(WPARAM wparam, LPARAM lparam)
{
switch (LOWORD(wparam))
{
case 1001: // Button Begin
m_pLibrary = new CLibrary();
if (!m_pLibrary->Initialize(m_hWnd))
{
delete m_pLibrary;
m_pLibrary = NULL;
return 0;
}
// On/Off cho phép các button
EnableWindow(m_hbtBegin, FALSE);
EnableWindow(m_hbtEnd, TRUE);
return 0;
case 1002: // Button End
if (m_pLibrary)
{
delete m_pLibrary;
m_pLibrary = NULL;
}
// On/Off cho phép các button
EnableWindow(m_hbtBegin, TRUE);
EnableWindow(m_hbtEnd, FALSE);
return 0;
}
return DefWindowProc(m_hWnd, WM_COMMAND, wparam, lparam);
}
LRESULT OnDestroy()
{
if (m_pLibrary)
delete m_pLibrary;
PostQuitMessage(0);
return 0;
}
LRESULT OnNotepadKeydown(WPARAM wparam, LPARAM lparam)
{
MessageBox(m_hWnd, L"Notepad - Keydown", g_AppName, MB_OK | MB_ICONINFORMATION);
return 0;
}
public:
int Create(HINSTANCE hInst, int nShow)
{
// Đăng ký lớp
WNDCLASS w;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
w.hCursor = LoadCursor(NULL, IDC_ARROW);
w.hIcon = LoadIcon(NULL, IDI_APPLICATION);
w.hInstance = hInst;
w.lpfnWndProc = WndProc;
w.lpszClassName = g_AppName;
w.lpszMenuName = NULL;
w.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&w))
return 0;
// Tạo cửa sổ
HWND hwnd = CreateWindow(g_AppName, g_AppName, WS_OVERLAPPEDWINDOW, 400, 400, 260, 80, NULL, NULL, hInst, this);
if (!hwnd)
return 0;
ShowWindow(hwnd, nShow);
UpdateWindow(hwnd);
// Vòng lặp thông điệp
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
};
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
CMainWnd wnd;
return wnd.Create(hInst, nShow);
}