#pragma once
class CDialogBase
{
public:
CDialogBase(DWORD idDlg, HWND hWndParent = NULL);
~CDialogBase();
HWND m_hDlg;
HWND m_hWndParent;
BOOL CreateDlg();
virtual LRESULT WndProc(UINT message, WPARAM wParam, LPARAM lParam);
LRESULT DoModal();
private:
LPCWSTR m_lpTemplateName;
#pragma pack(push,1)
typedef struct _StdCallThunk
{
DWORD m_mov; // = 0x042444C7
DWORD m_this; // = this
BYTE m_jmp; // = 0xe9
DWORD m_relproc; // = relative distance
} StdCallThunk;
#pragma pack(pop)
StdCallThunk *m_pStdthunk;
static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};
#include "stdafx.h"
#include "DialogBase.h"
CDialogBase::CDialogBase(DWORD idDlg, HWND hWndParent){
m_pStdthunk = (StdCallThunk *)VirtualAlloc(NULL, sizeof(StdCallThunk),
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
m_hWndParent = hWndParent;
m_lpTemplateName = MAKEINTRESOURCE(idDlg);
m_hDlg = NULL;
}
CDialogBase::~CDialogBase(){
VirtualFree(m_pStdthunk, sizeof(StdCallThunk), MEM_RELEASE);
}
BOOL CDialogBase::CreateDlg(){
m_hDlg = CreateDialog(GetModuleHandle(NULL), m_lpTemplateName, m_hWndParent, (DLGPROC)DefWindowProc);
if (m_hDlg == NULL)
{
return FALSE;
}
m_pStdthunk->m_mov = 0x042444c7;
m_pStdthunk->m_jmp = 0xe9;
m_pStdthunk->m_this = (DWORD)this;
m_pStdthunk->m_relproc = (DWORD)StaticWndProc - ((DWORD)m_pStdthunk + sizeof(StdCallThunk));
SetWindowLong(m_hDlg, GWL_WNDPROC, (LONG)m_pStdthunk);
return TRUE;
}
LRESULT CALLBACK CDialogBase::StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
return ((CDialogBase *)hWnd)->WndProc(message, wParam, lParam);
}
LRESULT CDialogBase::WndProc(UINT message, WPARAM wParam, LPARAM lParam){
return DefWindowProc(m_hDlg, message, wParam, lParam);
}
LRESULT CDialogBase::DoModal(){
if (m_hDlg == NULL)
{
CreateDlg();
}
EnableWindow(m_hWndParent, FALSE);
ShowWindow(m_hDlg, SW_SHOW);
UpdateWindow(m_hDlg);
return TRUE;
}