Last active
December 15, 2015 18:09
-
-
Save ynkdir/5301490 to your computer and use it in GitHub Desktop.
drawcustom.dll: draw background image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* compile: cl /MD /LD drawcusotm.c user32.lib gdi32.lib | |
* usage: :echo libcall('C:\fullpath\to\drawcustom.dll', 'init', '/path/to/background-image.bmp') | |
* bmp is loaded with LoadImage() API. And it doesn't support BITMAPV4HEADER and above. | |
*/ | |
#include <windows.h> | |
#include <string.h> | |
typedef int (WINAPI *fFillRect)(HDC hDC, CONST RECT *lprc, HBRUSH hbr); | |
typedef BOOL (WINAPI *fExtTextOutA)(HDC, int, int, UINT, CONST RECT *, LPCSTR, UINT, CONST INT *); | |
typedef BOOL (WINAPI *fExtTextOutW)(HDC, int, int, UINT, CONST RECT *, LPCWSTR, UINT, CONST INT *); | |
typedef int (WINAPI *fScrollWindowEx)(HWND, int, int, CONST RECT *, CONST RECT *, HRGN, LPRECT, UINT); | |
int WINAPI MyFillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr); | |
BOOL WINAPI MyExtTextOutA(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCSTR lpString, UINT cbCount, CONST INT *lpDx); | |
BOOL WINAPI MyExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbCount, CONST INT *lpDx); | |
int WINAPI MyScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll, CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags); | |
BOOL LoadBitmapFromBMPFile( LPCTSTR szFileName, HBITMAP *phBitmap, HPALETTE *phPalette); | |
HDC create_image_dc(const char *szFileName); | |
BOOL install_hook(HINSTANCE hInst, const char *funcname, FARPROC* orig, FARPROC newfn); | |
void show_lasterr(); | |
__declspec(dllexport) const char *init(const char *args); | |
HINSTANCE hinstSelf = NULL; | |
HDC hdcimage = NULL; | |
fFillRect OrigFillRect = NULL; | |
fExtTextOutA OrigExtTextOutA = NULL; | |
fExtTextOutW OrigExtTextOutW = NULL; | |
fScrollWindowEx OrigScrollWindowEx = NULL; | |
int WINAPI | |
MyFillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr) | |
{ | |
int ret; | |
/* Fill with red. */ | |
//HBRUSH b = CreateSolidBrush(lprc->top % 0xFF); /* BBGGRR */ | |
//ret = OrigFillRect(hDC, lprc, b); | |
//DeleteObject(b); | |
//return ret; | |
BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top, hdcimage, lprc->left, lprc->top, SRCCOPY); | |
return TRUE; | |
} | |
/* ExtTextOutA is always used for ASCII text even if encoding=utf-8. */ | |
BOOL WINAPI | |
MyExtTextOutA(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCSTR lpString, UINT cbCount, CONST INT *lpDx) | |
{ | |
#if 0 | |
BOOL ret; | |
char *buf; | |
int i; | |
buf = strdup(lpString); | |
/* Swap X and Y */ | |
for (i = 0; i < cbCount; ++i) | |
{ | |
if (buf[i] == 'X') | |
buf[i] = 'Y'; | |
else if (buf[i] == 'Y') | |
buf[i] = 'X'; | |
} | |
ret = OrigExtTextOutA(hdc, X, Y, fuOptions, lprc, buf, cbCount, lpDx); | |
free(buf); | |
return ret; | |
#endif | |
return OrigExtTextOutA(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); | |
} | |
BOOL WINAPI | |
MyExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbCount, CONST INT *lpDx) | |
{ | |
return OrigExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); | |
} | |
int WINAPI | |
MyScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll, CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags) | |
{ | |
// return OrigScrollWindowEx(hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate, prcUpdate, flags); | |
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE); | |
return TRUE; | |
} | |
/* http://support.microsoft.com/kb/158898/ja */ | |
BOOL | |
LoadBitmapFromBMPFile( LPCTSTR szFileName, HBITMAP *phBitmap, HPALETTE *phPalette) | |
{ | |
BITMAP bm; | |
*phBitmap = NULL; | |
*phPalette = NULL; | |
// Use LoadImage() to get the image loaded into a DIBSection | |
*phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0, | |
LR_CREATEDIBSECTION | LR_LOADFROMFILE); | |
if( *phBitmap == NULL ) | |
return FALSE; | |
// Get the color depth of the DIBSection | |
GetObject(*phBitmap, sizeof(BITMAP), &bm ); | |
// If the DIBSection is 256 color or less, it has a color table | |
if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 ) | |
{ | |
HDC hMemDC; | |
HBITMAP hOldBitmap; | |
RGBQUAD rgb[256]; | |
LPLOGPALETTE pLogPal; | |
WORD i; | |
// Create a memory DC and select the DIBSection into it | |
hMemDC = CreateCompatibleDC( NULL ); | |
hOldBitmap = (HBITMAP)SelectObject( hMemDC, *phBitmap ); | |
// Get the DIBSection's color table | |
GetDIBColorTable( hMemDC, 0, 256, rgb ); | |
// Create a palette from the color tabl | |
pLogPal = (LOGPALETTE *)malloc( sizeof(LOGPALETTE) + (256*sizeof(PALETTEENTRY)) ); | |
pLogPal->palVersion = 0x300; | |
pLogPal->palNumEntries = 256; | |
for(i=0;i<256;i++) | |
{ | |
pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed; | |
pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen; | |
pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue; | |
pLogPal->palPalEntry[i].peFlags = 0; | |
} | |
*phPalette = CreatePalette( pLogPal ); | |
// Clean up | |
free( pLogPal ); | |
SelectObject( hMemDC, hOldBitmap ); | |
DeleteDC( hMemDC ); | |
} | |
else // It has no color table, so use a halftone palette | |
{ | |
HDC hRefDC; | |
hRefDC = GetDC( NULL ); | |
*phPalette = CreateHalftonePalette( hRefDC ); | |
ReleaseDC( NULL, hRefDC ); | |
} | |
return TRUE; | |
} | |
HDC | |
create_image_dc(const char *szFileName) | |
{ | |
PAINTSTRUCT ps; | |
HBITMAP hBitmap, hOldBitmap; | |
HPALETTE hPalette, hOldPalette; | |
HDC hDC, hMemDC; | |
BITMAP bm; | |
if (!LoadBitmapFromBMPFile( szFileName, &hBitmap, &hPalette)) | |
return NULL; | |
hDC = GetDC(NULL); | |
GetObject( hBitmap, sizeof(BITMAP), &bm ); | |
hMemDC = CreateCompatibleDC( hDC ); | |
hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap ); | |
/* hOldPalette = SelectPalette( hDC, hPalette, FALSE ); */ | |
/* RealizePalette( hDC ); */ | |
ReleaseDC(NULL, hDC); | |
return hMemDC; | |
/* | |
BitBlt( hDC, 0, 0, bm.bmWidth, bm.bmHeight, | |
hMemDC, 0, 0, SRCCOPY ); | |
SelectObject( hMemDC, hOldBitmap ); | |
DeleteObject( hBitmap ); | |
SelectPalette( hDC, hOldPalette, FALSE ); | |
DeleteObject( hPalette ); | |
*/ | |
} | |
BOOL | |
install_hook(HINSTANCE hInst, const char *funcname, FARPROC* orig, FARPROC newfn) | |
{ | |
PBYTE pImage = (PBYTE)hInst; | |
PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst; | |
PIMAGE_NT_HEADERS pPE; | |
PIMAGE_IMPORT_DESCRIPTOR pImpDesc; | |
PIMAGE_THUNK_DATA pIAT; /* Import Address Table */ | |
PIMAGE_THUNK_DATA pINT; /* Import Name Table */ | |
PIMAGE_IMPORT_BY_NAME pImpName; | |
if (pDOS->e_magic != IMAGE_DOS_SIGNATURE) | |
return FALSE; | |
pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew); | |
if (pPE->Signature != IMAGE_NT_SIGNATURE) | |
return FALSE; | |
pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage | |
+ pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] | |
.VirtualAddress); | |
for (; pImpDesc->FirstThunk; ++pImpDesc) | |
{ | |
if (!pImpDesc->OriginalFirstThunk) | |
continue; | |
pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk); | |
pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk); | |
for (; pIAT->u1.Function; ++pIAT, ++pINT) | |
{ | |
if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal)) | |
continue; | |
pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage | |
+ (UINT_PTR)(pINT->u1.AddressOfData)); | |
if (strcmp(pImpName->Name, funcname) == 0) | |
{ | |
FARPROC *ppfn = (FARPROC*)&pIAT->u1.Function; | |
DWORD dwDummy; | |
*orig = (FARPROC)(*ppfn); | |
if (!VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy)) | |
return FALSE; | |
if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &newfn, sizeof(newfn), NULL)) | |
return FALSE; | |
return TRUE; | |
} | |
} | |
} | |
return TRUE; | |
} | |
void | |
show_lasterr() | |
{ | |
LPVOID lpMessageBuffer; | |
FormatMessage( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
FORMAT_MESSAGE_FROM_SYSTEM, | |
NULL, | |
GetLastError(), | |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
(LPTSTR) &lpMessageBuffer, | |
0, | |
NULL ); | |
MessageBox(NULL, lpMessageBuffer, "Error", MB_OK); | |
LocalFree( lpMessageBuffer ); | |
} | |
__declspec(dllexport) | |
const char * | |
init(const char *bgimage) | |
{ | |
char buf[1024]; | |
GetModuleFileName(hinstSelf, buf, sizeof(buf)); | |
LoadLibrary(buf); | |
hdcimage = create_image_dc(bgimage); | |
if (hdcimage == NULL) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "FillRect", (FARPROC*)&OrigFillRect, (FARPROC)MyFillRect)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "ExtTextOutA", (FARPROC*)&OrigExtTextOutA, (FARPROC)MyExtTextOutA)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "ExtTextOutW", (FARPROC*)&OrigExtTextOutW, (FARPROC)MyExtTextOutW)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "ScrollWindowEx", (FARPROC*)&OrigScrollWindowEx, (FARPROC)MyScrollWindowEx)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
return "OK"; | |
} | |
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | |
{ | |
switch(fdwReason) | |
{ | |
case DLL_PROCESS_ATTACH: | |
hinstSelf = hinstDLL; | |
break; | |
case DLL_PROCESS_DETACH: | |
break; | |
case DLL_THREAD_ATTACH: | |
break; | |
case DLL_THREAD_DETACH: | |
break; | |
} | |
return TRUE; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* gdiplus version | |
* compile: cl /MD /LD drawcusotm.cpp user32.lib gdi32.lib gdiplus.lib | |
* usage: :echo libcall('C:\fullpath\to\drawcustom.dll', 'init', '/path/to/background-image.bmp') | |
* png and jpg also can be used. | |
*/ | |
#include <windows.h> | |
#include <gdiplus.h> | |
#include <string.h> | |
extern "C" { | |
typedef int (WINAPI *fFillRect)(HDC hDC, CONST RECT *lprc, HBRUSH hbr); | |
typedef BOOL (WINAPI *fExtTextOutA)(HDC, int, int, UINT, CONST RECT *, LPCSTR, UINT, CONST INT *); | |
typedef BOOL (WINAPI *fExtTextOutW)(HDC, int, int, UINT, CONST RECT *, LPCWSTR, UINT, CONST INT *); | |
typedef int (WINAPI *fScrollWindowEx)(HWND, int, int, CONST RECT *, CONST RECT *, HRGN, LPRECT, UINT); | |
int WINAPI MyFillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr); | |
BOOL WINAPI MyExtTextOutA(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCSTR lpString, UINT cbCount, CONST INT *lpDx); | |
BOOL WINAPI MyExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbCount, CONST INT *lpDx); | |
int WINAPI MyScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll, CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags); | |
wchar_t *mbtowide(const char *mb); | |
BOOL load_image(const char *filename, Gdiplus::Image **pimg); | |
BOOL install_hook(HINSTANCE hInst, const char *funcname, FARPROC* orig, FARPROC newfn); | |
void show_lasterr(); | |
__declspec(dllexport) const char *init(const char *args); | |
HINSTANCE hinstSelf = NULL; | |
HDC hdcimage = NULL; | |
Gdiplus::Image *bgimage; | |
fFillRect OrigFillRect = NULL; | |
fExtTextOutA OrigExtTextOutA = NULL; | |
fExtTextOutW OrigExtTextOutW = NULL; | |
fScrollWindowEx OrigScrollWindowEx = NULL; | |
int WINAPI | |
MyFillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr) | |
{ | |
#if 0 | |
/* drwaing scaled image is slow */ | |
Gdiplus::Graphics g(hDC); | |
double scale = g.GetDpiX() / bgimage->GetHorizontalResolution(); | |
Gdiplus::REAL x = lprc->left; | |
Gdiplus::REAL y = lprc->top; | |
Gdiplus::REAL srcx = lprc->left / scale; | |
Gdiplus::REAL srcy = lprc->top / scale; | |
Gdiplus::REAL srcwidth = (lprc->right - lprc->left) / scale; | |
Gdiplus::REAL srcheight = (lprc->bottom - lprc->top) / scale; | |
Gdiplus::GpUnit srcUnit = Gdiplus::UnitPixel; | |
g.DrawImage(bgimage, x, y, srcx, srcy, srcwidth, srcheight, srcUnit); | |
#else | |
BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top, hdcimage, lprc->left, lprc->top, SRCCOPY); | |
#endif | |
return TRUE; | |
} | |
/* ExtTextOutA is always used for ASCII text even if encoding=utf-8. */ | |
BOOL WINAPI | |
MyExtTextOutA(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCSTR lpString, UINT cbCount, CONST INT *lpDx) | |
{ | |
#if 0 | |
BOOL ret; | |
char *buf; | |
int i; | |
buf = strdup(lpString); | |
/* Swap X and Y */ | |
for (i = 0; i < cbCount; ++i) | |
{ | |
if (buf[i] == 'X') | |
buf[i] = 'Y'; | |
else if (buf[i] == 'Y') | |
buf[i] = 'X'; | |
} | |
ret = OrigExtTextOutA(hdc, X, Y, fuOptions, lprc, buf, cbCount, lpDx); | |
free(buf); | |
return ret; | |
#endif | |
return OrigExtTextOutA(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); | |
} | |
BOOL WINAPI | |
MyExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbCount, CONST INT *lpDx) | |
{ | |
return OrigExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); | |
} | |
int WINAPI | |
MyScrollWindowEx(HWND hWnd, int dx, int dy, CONST RECT *prcScroll, CONST RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags) | |
{ | |
//return OrigScrollWindowEx(hWnd, dx, dy, prcScroll, prcClip, hrgnUpdate, prcUpdate, flags); | |
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE); | |
return TRUE; | |
} | |
wchar_t * | |
mbtowide(const char *mb) | |
{ | |
DWORD len; | |
wchar_t *wc; | |
len = MultiByteToWideChar(CP_ACP, 0, mb, -1, NULL, 0); | |
if (len == 0) | |
return NULL; | |
wc = (wchar_t *)malloc(sizeof(wchar_t) * len); | |
if (wc == NULL) | |
return NULL; | |
if (MultiByteToWideChar(CP_ACP, 0, mb, -1, wc, len) != len) | |
return NULL; | |
return wc; | |
} | |
BOOL | |
load_image(const char *filename, Gdiplus::Image **pimg) | |
{ | |
wchar_t *wfilename; | |
wfilename = mbtowide(filename); | |
if (wfilename == NULL) | |
return FALSE; | |
*pimg = Gdiplus::Image::FromFile(wfilename, FALSE); | |
free(wfilename); | |
HDC screen = GetDC(NULL); | |
HDC hDC = CreateCompatibleDC(screen); | |
HBITMAP hBM = CreateCompatibleBitmap(screen, (*pimg)->GetWidth(), (*pimg)->GetHeight()); | |
SelectObject(hDC, hBM); | |
ReleaseDC(NULL, screen); | |
Gdiplus::Graphics g(hDC); | |
double scale = g.GetDpiX() / bgimage->GetHorizontalResolution(); | |
g.ScaleTransform(1.0 / scale, 1.0 / scale); | |
g.DrawImage(*pimg, 0, 0); | |
hdcimage = hDC; | |
*pimg = Gdiplus::Bitmap::FromHBITMAP(hBM, NULL); | |
return TRUE; | |
} | |
BOOL | |
install_hook(HINSTANCE hInst, const char *funcname, FARPROC* orig, FARPROC newfn) | |
{ | |
PBYTE pImage = (PBYTE)hInst; | |
PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst; | |
PIMAGE_NT_HEADERS pPE; | |
PIMAGE_IMPORT_DESCRIPTOR pImpDesc; | |
PIMAGE_THUNK_DATA pIAT; /* Import Address Table */ | |
PIMAGE_THUNK_DATA pINT; /* Import Name Table */ | |
PIMAGE_IMPORT_BY_NAME pImpName; | |
if (pDOS->e_magic != IMAGE_DOS_SIGNATURE) | |
return FALSE; | |
pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew); | |
if (pPE->Signature != IMAGE_NT_SIGNATURE) | |
return FALSE; | |
pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage | |
+ pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] | |
.VirtualAddress); | |
for (; pImpDesc->FirstThunk; ++pImpDesc) | |
{ | |
if (!pImpDesc->OriginalFirstThunk) | |
continue; | |
pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk); | |
pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk); | |
for (; pIAT->u1.Function; ++pIAT, ++pINT) | |
{ | |
if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal)) | |
continue; | |
pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage | |
+ (UINT_PTR)(pINT->u1.AddressOfData)); | |
if (strcmp((const char *)pImpName->Name, funcname) == 0) | |
{ | |
FARPROC *ppfn = (FARPROC*)&pIAT->u1.Function; | |
DWORD dwDummy; | |
*orig = (FARPROC)(*ppfn); | |
if (!VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy)) | |
return FALSE; | |
if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &newfn, sizeof(newfn), NULL)) | |
return FALSE; | |
return TRUE; | |
} | |
} | |
} | |
return TRUE; | |
} | |
void | |
show_lasterr() | |
{ | |
LPVOID lpMessageBuffer; | |
FormatMessage( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
FORMAT_MESSAGE_FROM_SYSTEM, | |
NULL, | |
GetLastError(), | |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
(LPTSTR) &lpMessageBuffer, | |
0, | |
NULL ); | |
MessageBox(NULL, (LPTSTR)lpMessageBuffer, "Error", MB_OK); | |
LocalFree( lpMessageBuffer ); | |
} | |
__declspec(dllexport) | |
const char * | |
init(const char *bgimagefile) | |
{ | |
char buf[1024]; | |
GetModuleFileName(hinstSelf, buf, sizeof(buf)); | |
LoadLibrary(buf); | |
if (!load_image(bgimagefile, &bgimage)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "FillRect", (FARPROC*)&OrigFillRect, (FARPROC)MyFillRect)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "ExtTextOutA", (FARPROC*)&OrigExtTextOutA, (FARPROC)MyExtTextOutA)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "ExtTextOutW", (FARPROC*)&OrigExtTextOutW, (FARPROC)MyExtTextOutW)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
if (!install_hook((HINSTANCE)GetModuleHandle(NULL), "ScrollWindowEx", (FARPROC*)&OrigScrollWindowEx, (FARPROC)MyScrollWindowEx)) | |
{ | |
show_lasterr(); | |
return "NG"; | |
} | |
return "OK"; | |
} | |
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | |
{ | |
Gdiplus::GdiplusStartupInput gdiplusStartupInput; | |
static ULONG_PTR gdiplusToken; | |
switch(fdwReason) | |
{ | |
case DLL_PROCESS_ATTACH: | |
hinstSelf = hinstDLL; | |
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); | |
break; | |
case DLL_PROCESS_DETACH: | |
Gdiplus::GdiplusShutdown(gdiplusToken); | |
break; | |
case DLL_THREAD_ATTACH: | |
break; | |
case DLL_THREAD_DETACH: | |
break; | |
} | |
return TRUE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment