显示拖放(或在命令行中指定)的图象。
把拖放的文件名或在 [开始]-[运行] 中启动的参数传递给 WinMain() 函数的第三个形参(pCmdLine)。
检测传递给 pCmdLine 的图象文件,根据这个图象的大小调整窗口大小。
决定窗口大小的函数是 CreateWindowedDisplay() ,这个函数是在创建 Surface(表面) 之前执行的,所以我们需要在 CreateWindowedDisplay() 函数执行之前知道图象的大小。
执行顺序如下:
1.
把拖放或在命令行中指定的文件名传递给 WinMain() 函数的第三个形参(pCmdLine)。
2.
检测由第三形参 pCmdLine 的文件名所指定的图象文件的大小:
SIZE
BmpSize;
:
if (GetBmpSize(pCmdLine,&BmpSize)==S_FALSE)
{
ERMSG("Bmp File Not Found");
return
FALSE;
}
3.
根据这个图象的大小设定窗口大小:
if (FAILED(hr = g_pDisplay-CreateWindowedDisplay(hWnd,BmpSize.cx,BmpSize.cy)))
{
ERMSG("Failed initializing DirectDraw");
return hr;
}
4.
创建图象 Surface :
if (FAILED(hr = g_pDisplay-CreateSurfaceFromBitmap(&g_pBmpSurface,Bmpfile,0,0)))
return hr;
5.
在窗口中描绘图象:
g_pDisplay-Blt(0,0,g_pBmpSurface,NULL);
if (FAILED(hr= g_pDisplay-Present())) return hr;
6.
改变窗口大小时相应调整图象大小。
检测 BMP 图象大小的代码。
BMP 文件中依次记载 BitMapFileHeader 、 BitMapInfoHeader 、调色板和图象信息,图象大小记载在 BitMapInfoHeader 。
BMP 文件的详细格式,有机会再讲吧。
HANDLE
hFile;
DWORD
dwBytes;
struct
//BMP 文件结构体
{
BITMAPFILEHEADER
g_Bf;
BITMAPINFOHEADER
g_Bi;
}
g_Bmp;
:
SetFilePointer(hFile,0,0,FILE_BEGIN);
ReadFile(hFile, &g_Bmp.g_Bf, sizeof(BITMAPFILEHEADER), &dwBytes, NULL);
ReadFile(hFile, &g_Bmp.g_Bi, sizeof(BITMAPINFOHEADER), &dwBytes, NULL);
bmpsize-cx = g_Bmp.g_Bi.biWidth;
bmpsize-cy = g_Bmp.g_Bi.biHeight;
源程序没有多大改变,启动方法跟过去的就大大不同了。还象以前那样编译并执行的话,会出现下面的错误信息,提示找不到文件,确认后退出:
这个程序的启动方法:
先编译并执行,在工程文件夹的 Debug 目录下生成可执行文件(我的是Cmdline.exe) 。
通过拖放 BMP 文件来启动。
先在桌面上创建 Cmdline.exe 的快捷方式,然后把 BMP 文件拖上去:
通过命令行键入 BMP 文件名来启动。
从 [开始]-[运行] 中键入 "路径\cmdline 路径\*.bmp" :
源程序:
/*********************************************/
/*★ 拖放显示图象
2001-01-25
前田 稔 ★*/
/*********************************************/
#define NAME
"Command Line"
#define
STRICT
#include
// Defines, constants, and global variables
CDisplay*
g_pDisplay
= NULL;
CSurface*
g_pBmpSurface = NULL;
BOOL
g_bActive
= FALSE;
SIZE
BmpSize;
// Function-prototypes
int
PASCAL
WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
LRESULT
CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT
InitDraw(HWND hWnd, LPSTR Bmpfile);
HRESULT
GetBmpSize(LPSTR Bmpfile, SIZE *bmpsize);
HRESULT
DisplayFrame();
void
FreeDraw();
//★ Windows Main
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow)
{
MSG
msg;
WNDCLASS wc = { CS_CLASSDC,WndProc,0L,0L,hInst,
NULL,NULL,NULL,NULL,NAME };
if (RegisterClass(&wc)==0)
return FALSE;
HWND hWnd = CreateWindow(NAME,NAME,WS_OVERLAPPEDWINDOW,50,50,0,0,
GetDesktopWindow(),NULL,wc.hInstance,NULL);
if (hWnd==NULL)
return FALSE;
if (GetBmpSize(pCmdLine,&BmpSize)==S_FALSE)
{
ERMSG("Bmp File Not Found");
return
FALSE;
}
if (FAILED(InitDraw(hWnd,pCmdLine)))
{
if (g_pDisplay)
g_pDisplay-GetDirectDraw()-SetCooperativeLevel(NULL, DDSCL_NORMAL);
ERMSG("DirectDraw init failed. The sample will now exit.");
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (0 == GetMessage(&msg, NULL, 0, 0))
return (int)msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (g_bActive)
{
if (FAILED(DisplayFrame()))
{
SAFE_DELETE(g_pDisplay);
ERMSG("Displaying the next frame failed");
return FALSE;
}
}
else
WaitMessage();
}
}
}
//★ 处理消息的 CallBack 函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
PostMessage(hWnd,WM_CLOSE,0,0);
return 0L;
case WM_PAINT:
if (g_pDisplay)
{
if (DisplayFrame() == DDERR_SURFACELOST)
{
PostMessage(hWnd,WM_CLOSE,0,0);
}
}
break;
case WM_MOVE:
if (g_pDisplay)
g_pDisplay-UpdateBounds();
return 0L;
case WM_SIZE:
if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam)
g_bActive= FALSE;
else
g_bActive= TRUE;
if (g_pDisplay)
g_pDisplay-UpdateBounds();
break;
case WM_DESTROY:
FreeDraw();
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//★ InitDraw()
HRESULT InitDraw(HWND hWnd, LPSTR Bmpfile)
{
HRESULT
hr;
g_pDisplay = new CDisplay();
if (FAILED(hr = g_pDisplay-CreateWindowedDisplay(hWnd,BmpSize.cx,BmpSize.cy)))
{
ERMSG("Failed initializing DirectDraw");
return hr;
}
if (FAILED(hr = g_pDisplay-CreateSurfaceFromBitmap(&g_pBmpSurface,Bmpfile,0,0)))
return hr;
return S_OK;
}
//★ DisplayFrame()
HRESULT DisplayFrame()
{
HRESULT hr;
g_pDisplay-Clear(0);
g_pDisplay-Blt(0,0,g_pBmpSurface,NULL);
if (FAILED(hr= g_pDisplay-Present())) return hr;
return S_OK;
}
//★ FreeDraw()
VOID FreeDraw()
{
SAFE_DELETE(g_pBmpSurface);
SAFE_DELETE(g_pDisplay);
}
//★ 获取位图图象的大小
HRESULT GetBmpSize(LPSTR Bmpfile, SIZE *bmpsize)
{
HANDLE
hFile;
DWORD
dwBytes;
struct
//BMP 文件结构体
{
BITMAPFILEHEADER
g_Bf;
BITMAPINFOHEADER
g_Bi;
}
g_Bmp;
hFile= CreateFile(Bmpfile, GENERIC_READ, 0, 0, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile==INVALID_HANDLE_VALUE)
return
S_FALSE;
SetFilePointer(hFile,0,0,FILE_BEGIN);
ReadFile(hFile, &g_Bmp.g_Bf, sizeof(BITMAPFILEHEADER), &dwBytes, NULL);
ReadFile(hFile, &g_Bmp.g_Bi, sizeof(BITMAPINFOHEADER), &dwBytes, NULL);
bmpsize-cx = g_Bmp.g_Bi.biWidth;
bmpsize-cy = g_Bmp.g_Bi.biHeight;
CloseHandle(hFile);
return S_OK;
}