Maybe someone find this useful.
First the include file, i named miniGdiPlus.h :
#ifndef _MINIGDIPLUS_H
#define _MINIGDIPLUS_H
typedef struct tagIMAGE
{
HBITMAP hBitmap ;
int w ;
int h ;
}
IMAGE;
void DeleteThisImge(IMAGE *_image){if(_image->hBitmap){ DeleteObject(_image->hBitmap); _image->w=0; _image->h=0;}}
IMAGE LoadThisImge(wchar_t *file)
{
typedef void (__stdcall *DebugEventProc)(int level, char *message);
typedef struct tagGdiplusStartupInput
{
UINT32 GdiplusVersion ;
DebugEventProc DebugEventCallback ;
BOOL SuppressBackgroundThread ;
BOOL SuppressExternalCodecs ;
}
_GdiplusStartupInput;
typedef struct tag_gImage { int unused; } gImage;
typedef struct tag_Image { gImage *nativeImage; int lastResult; } Image;
typedef struct tag_gGraphics { int unused; } gGraphics;
typedef struct tag_Graphics { gGraphics * nativeGraphics; int lastResult; } Graphics;
HINSTANCE gdiplusDll;
#ifdef UNICODE
gdiplusDll = LoadLibrary(L"gdiplus.dll");
#else
gdiplusDll = LoadLibrary("gdiplus.dll");
#endif
typedef int (__stdcall *_GdiplusStartup)( ULONG_PTR * , _GdiplusStartupInput * , void * );
_GdiplusStartup GdiplusStartup = (_GdiplusStartup)GetProcAddress( gdiplusDll , "GdiplusStartup" );
typedef void (__stdcall *_GdiplusShutdown)( ULONG_PTR ) ;
_GdiplusShutdown GdiplusShutdown = (_GdiplusShutdown)GetProcAddress( gdiplusDll , "GdiplusShutdown" );
typedef int (__stdcall *_GdipLoadImageFromFile)( wchar_t * , gImage ** );
_GdipLoadImageFromFile GdipLoadImageFromFile = (_GdipLoadImageFromFile)GetProcAddress( gdiplusDll , "GdipLoadImageFromFile" );
typedef int (__stdcall *_GdipGetImageWidth)( gImage * , unsigned int * );
_GdipGetImageWidth GdipGetImageWidth = (_GdipGetImageWidth)GetProcAddress( gdiplusDll , "GdipGetImageWidth" );
typedef int (__stdcall *_GdipGetImageHeight)( gImage * , unsigned int * );
_GdipGetImageHeight GdipGetImageHeight = (_GdipGetImageHeight)GetProcAddress( gdiplusDll , "GdipGetImageHeight" );
typedef int (__stdcall *_GdipCreateFromHDC)( HDC , gGraphics ** );
_GdipCreateFromHDC GdipCreateFromHDC = (_GdipCreateFromHDC)GetProcAddress( gdiplusDll , "GdipCreateFromHDC" );
typedef int (__stdcall *_GdipDrawImageRectI)( gGraphics * , gImage * , int ,int ,int ,int );
_GdipDrawImageRectI GdipDrawImageRectI = (_GdipDrawImageRectI)GetProcAddress( gdiplusDll , "GdipDrawImageRectI" );
typedef int (__stdcall *_GdipDeleteGraphics)( gGraphics * );
_GdipDeleteGraphics GdipDeleteGraphics = (_GdipDeleteGraphics)GetProcAddress( gdiplusDll , "GdipDeleteGraphics" );
typedef int (__stdcall *_GdipDisposeImage)( gImage * );
_GdipDisposeImage GdipDisposeImage = (_GdipDisposeImage)GetProcAddress( gdiplusDll , "GdipDisposeImage" );
typedef int (__stdcall *_GdipGetImageDimension)( gImage * , float * , float * );
_GdipGetImageDimension GdipGetImageDimension = (_GdipGetImageDimension)GetProcAddress( gdiplusDll , "GdipGetImageDimension" );
float x=0.0;
float y=0.0;
unsigned int nWidth =0;
unsigned int nHeight=0;
Image thisImage;
gGraphics *graphics = NULL ;
Graphics this ;
ULONG_PTR gdiplusToken;
IMAGE _img;
_GdiplusStartupInput GdiplusStartupInput;
GdiplusStartupInput.GdiplusVersion = 1 ;
GdiplusStartupInput.DebugEventCallback = NULL ;
GdiplusStartupInput.SuppressBackgroundThread = FALSE;
GdiplusStartupInput.SuppressExternalCodecs = FALSE;
GdiplusStartup (&gdiplusToken, &GdiplusStartupInput, NULL);
GdipLoadImageFromFile(file, &thisImage.nativeImage);
HDC hdc =GetDC(NULL);
if( file[lstrlenW(file)-3]=='w' || file[lstrlenW(file)-3]=='W')
{
GdipGetImageDimension( thisImage.nativeImage,&x,&y) ;
nWidth =MulDiv(x, GetDeviceCaps(hdc, LOGPIXELSX), 2540) ;
nHeight= MulDiv(y, GetDeviceCaps(hdc, LOGPIXELSY), 2540);
}
else
{
GdipGetImageWidth ( thisImage.nativeImage, &nWidth );
GdipGetImageHeight( thisImage.nativeImage, &nHeight );
}
_img.w=nWidth;
_img.h=nHeight;
HDC hdcMem =CreateCompatibleDC(hdc);
_img.w=nWidth;
_img.h=nHeight;
_img.hBitmap=CreateCompatibleBitmap(hdc,_img.w,_img.h);
SelectObject(hdcMem,_img.hBitmap);
this.lastResult = GdipCreateFromHDC(hdcMem, & graphics);
this.nativeGraphics = graphics;
this.lastResult = GdipDrawImageRectI(this.nativeGraphics, thisImage.nativeImage,0,0,_img.w,_img.h);
GdipDisposeImage(thisImage.nativeImage);
GdipDeleteGraphics(graphics);
DeleteDC(hdcMem);
ReleaseDC(NULL,hdc);
GdiplusShutdown(gdiplusToken);
FreeLibrary(gdiplusDll);
return _img;
}
#endif
And for test testGdiPlusDll.c :
#include <windows.h>
#include "miniGdiPlus.h"
HWND hwnd;
HINSTANCE G_hInstance;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
MSG msg ;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszClassName = "WindowClassName";
wc.hInstance = hInstance ; G_hInstance=wc.hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClass(&wc);
hwnd = CreateWindow( wc.lpszClassName,
"gdiplus.dll",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 500, 150,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);
while( GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static BOOL WeNeedToPaintTheWindow = FALSE;
static IMAGE img;
switch(msg)
{
case WM_LBUTTONDOWN:
{
wchar_t fileName[MAX_PATH]=L"\x0000";
OPENFILENAMEW ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter =
L"All supported graphic formats (*.bmp,*.dib,*.rle,*.ico,*.jpg,*.jpeg,*.jpe,*.jfif,*.gif,*.tif,*.tiff,*.png,*.emf,*.wmf)"
L"\0*.bmp;*.dib;*.rle;*.ico;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif;*.tif;*.tiff;*.png;*.emf;*.wmf\0\0";
ofn.lpstrFile = fileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if(GetOpenFileNameW(&ofn))
{
SetWindowTextW(hwnd,fileName);
DeleteThisImge( &img );
img = LoadThisImge( fileName );
WeNeedToPaintTheWindow = TRUE;
InvalidateRect(hwnd,NULL,TRUE);
}
} break;
case WM_ERASEBKGND:return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
GetClientRect(hwnd,&rc);
HDC hdc=BeginPaint(hwnd,&ps);
HDC hdcMem=CreateCompatibleDC(hdc);
if( WeNeedToPaintTheWindow == FALSE )
{
HBITMAP dummy=CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
SelectObject(hdcMem,dummy);
PatBlt(hdcMem,0,0,rc.right,rc.bottom,WHITENESS);
DrawText(hdcMem,"click me",-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
BitBlt(hdc,0,0,rc.right,rc.bottom,hdcMem,0,0,SRCCOPY);
DeleteObject(dummy) ;
DeleteDC(hdcMem);
}
else
{
SelectObject(hdcMem,img.hBitmap);
SetStretchBltMode(hdc,HALFTONE);
StretchBlt(hdc,0,0,rc.right,rc.bottom,hdcMem,0,0,img.w,img.h,SRCCOPY);
DeleteDC(hdcMem);
}
EndPaint(hwnd,&ps);
} break;
case WM_DESTROY:{PostQuitMessage(0);return 0;}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Laur