// Host.cpp - a plugin-based image viewer
// In this version the host manually binds to all plugins through their GetParser function
//
// Part of the Plugin System tutorial
//
///////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <Shlwapi.h>
#include <stdio.h>
#include "ImageParser.h"
// a prototype for the GetParser function
typedef IImageParser *(*TGetParser)( void );
// the currently displayed bitmap
static HBITMAP g_Bitmap=NULL;
// a global list with all parsers
const int MAX_PARSERS=100;
IImageParser *g_Parsers[MAX_PARSERS];
int g_NumParsers=0;
// Adds the parser to the g_Parsers list
void AddParser( IImageParser *parser )
{
g_Parsers[g_NumParsers++]=parser;
}
// Loads all plugins in the same folder as the EXE
void LoadPlugins( void )
{
char path[_MAX_PATH];
GetModuleFileName(NULL,path,_MAX_PATH);
*PathFindFileName(path)=0;
char spec[_MAX_PATH];
sprintf(spec,"%s*.imp",path);
WIN32_FIND_DATA data;
// find all DLLs
HANDLE h=FindFirstFile(spec,&data);
if (h!=INVALID_HANDLE_VALUE) {
do {
char fname[_MAX_PATH];
sprintf(fname,"%s%s",path,data.cFileName);
HMODULE hModule=LoadLibrary(fname);
if (hModule) {
// get the parser pointer and add it to the parsers list
TGetParser getparser=(TGetParser)GetProcAddress(hModule,"GetParser");
if (getparser)
AddParser(getparser());
}
} while (FindNextFile(h,&data));
FindClose(h);
}
}
// Loads an image file
void LoadImage( const char *fname )
{
// find the parser for that type and load the image
char ext[_MAX_EXT];
_splitpath(fname,NULL,NULL,NULL,ext);
for (int i=0;i<g_NumParsers;i++)
if (g_Parsers[i]->SupportsType(ext)) {
g_Bitmap=g_Parsers[i]->ParseFile(fname);
break;
}
}
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if (uMsg==WM_DESTROY)
PostQuitMessage(0);
if (uMsg==WM_PAINT) {
// paints the window
// if a bitmap is loaded - draw the bitmap
// otherwise draw a text prompt
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hwnd,&ps);
if (g_Bitmap) {
HDC hsrc=CreateCompatibleDC(hdc);
SelectObject(hsrc,g_Bitmap);
BITMAP bmp;
GetObject(g_Bitmap,sizeof(bmp),&bmp);
BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hsrc,0,0,SRCCOPY);
DeleteDC(hsrc);
}
else {
SelectObject(hdc,GetStockObject(DEFAULT_GUI_FONT));
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,0xFFFFFF);
const char *s="Drop an image file here";
TextOut(hdc,0,0,s,strlen(s));
}
EndPaint(hwnd,&ps);
return 0;
}
if (uMsg==WM_DROPFILES) {
// destroy the previous image
if (g_Bitmap) DeleteObject(g_Bitmap);
g_Bitmap=NULL;
// get the file name
HDROP hDrop=(HDROP)wParam;
char fname[_MAX_PATH];
DragQueryFile(hDrop,0,fname,_MAX_PATH);
DragFinish(hDrop);
// load the image file
LoadImage(fname);
InvalidateRect(hwnd,NULL,TRUE);
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// Create main window
WNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.style=CS_VREDRAW|CS_HREDRAW;
wc.lpfnWndProc=WindowProc;
wc.hInstance=hInstance;
wc.hCursor=LoadCursor(NULL,IDC_CROSS);
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszClassName="ImageViewer";
RegisterClass(&wc);
HWND main=CreateWindowEx(WS_EX_APPWINDOW,"ImageViewer","ImageViewer",WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_CLIPCHILDREN,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
DragAcceptFiles(main,TRUE);
LoadPlugins();
// Process messages
while (1) {
MSG msg;
if (!GetMessage(&msg,0,0,0)) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}