#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("DIB Section");
HWND hwnd;
MSG msg;
WNDCLASSEX wndclassex = {0};
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WndProc;
wndclassex.cbClsExtra = 0;
wndclassex.cbWndExtra = 0;
wndclassex.hInstance = hInstance;
wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclassex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wndclassex.lpszClassName = szAppName;
wndclassex.hIconSm = wndclassex.hIcon;
if (!RegisterClassEx (&wndclassex))
{
MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
szAppName,
TEXT ("DIB Section"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
//读入DIB文件并转换成DIB Section
HBITMAP CreateDibSectionFromDibFile(PTSTR szFileName)
{
BITMAPFILEHEADER bmfh;
BITMAPINFO *pbmi;
BYTE *pBits;
BOOL bSuccess;
DWORD dwInfoSize, dwBytesRead;
HANDLE hFile;
HBITMAP hBitmap;
//打开文件
hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
return NULL;
}
//读入DIB文件头
bSuccess = ReadFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
if (!bSuccess || (dwBytesRead != sizeof(BITMAPFILEHEADER)) || (bmfh.bfType != *(WORD *)"BM"))
{
CloseHandle(hFile);
return NULL;
}
//为DIB BITMAPINFO分配内存,并读入DIB数据
dwInfoSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
pbmi = malloc(dwInfoSize);
if (NULL == pbmi)
{
CloseHandle(hFile);
return NULL;
}
bSuccess = ReadFile(hFile, pbmi, dwInfoSize, &dwBytesRead, NULL);
if (!bSuccess || (dwBytesRead != dwInfoSize))
{
free(pbmi);
CloseHandle(hFile);
return NULL;
}
//创建DIB Section
hBitmap = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0);
free(pbmi);
if (NULL == hBitmap)
{
CloseHandle(hFile);
return NULL;
}
//读入位图数据到分配的DIB Section的Bits区(pBits指向)
bSuccess = ReadFile(hFile, pBits, bmfh.bfSize-bmfh.bfOffBits, &dwBytesRead, NULL);
CloseHandle(hFile);
if (!bSuccess || (dwBytesRead != (bmfh.bfSize-bmfh.bfOffBits)))
{
return NULL;
}
return hBitmap;
}
//如果有调色板则获得第一个调色板项
BOOL GetFirstColorTableItem(HBITMAP hBitmap, RGBQUAD *prgb)
{
HDC hdcMem;
int iNum;
hdcMem = CreateCompatibleDC(NULL);
SelectObject(hdcMem, hBitmap);
iNum = GetDIBColorTable(hdcMem, 0, 1, prgb);
DeleteDC(hdcMem);
return 0==iNum ? FALSE : TRUE;
}
//获得第一个调色板项
DWORD GetFirstMaskItem(HBITMAP hBitmap)
{
DIBSECTION ds;
GetObject(hBitmap, sizeof(DIBSECTION), &ds);
return ds.dsBitfields[0];
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmap;
static int cxClient, cyClient;
static OPENFILENAME ofn;
static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
static TCHAR szFilter[] = TEXT("Bitmap Files(*.BMP)\0*.BMP\0")
TEXT("All Files(*.*)\0*.*\0\0");
RGBQUAD rgb;
BITMAP bitmap;
HDC hdc, hdcMem;
PAINTSTRUCT ps;
TCHAR szBuffer[256];
switch (message)
{
case WM_CREATE:
//打开文件框设置
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.hInstance = NULL;
ofn.lpstrFilter = szFilter;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileName;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrInitialDir = TEXT(".\\Image\\");
ofn.lpstrTitle = NULL;
ofn.Flags = 0;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = TEXT("bmp");
ofn.lCustData = 0;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
return (0);
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return (0);
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_FILE_OPEN:
ofn.Flags = 0;
//打开文件对话框选择要打开的文件
if (!GetOpenFileName(&ofn))
{
return (0);
}
//删除前一次读入的图像数据
if (hBitmap)
{
DeleteObject(hBitmap);
hBitmap = NULL;
}
//加载要打开的文件
SetCursor(LoadCursor(NULL, IDC_WAIT));
ShowCursor(TRUE);
hBitmap = CreateDibSectionFromDibFile(szFileName);
SetCursor(LoadCursor(NULL, IDC_ARROW));
ShowCursor(FALSE);
InvalidateRect(hwnd, NULL, TRUE);
if (hBitmap == NULL)
{
MessageBox(hwnd, TEXT("加载DIB错误"), TEXT("错误"), MB_OK | MB_ICONERROR);
}
return (0);
case IDM_FILE_COLOR:
if (hBitmap && TRUE == GetFirstColorTableItem(hBitmap, &rgb))
{
wsprintf(szBuffer, TEXT("第一个调色板项为:%d-%d-%d\n"), rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
MessageBox(hwnd, szBuffer, TEXT("提示"), MB_OK);
}
return (0);
case IDM_FILE_MASK:
if (hBitmap)
{
wsprintf(szBuffer, TEXT("第一个掩码值为:%d\n"), GetFirstMaskItem(hBitmap));
MessageBox(hwnd, szBuffer, TEXT("提示"), MB_OK);
}
return (0);
}
break;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
if (hBitmap)
{
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBitmap);
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight,
hdcMem, 0, 0,
SRCCOPY);
DeleteDC(hdcMem);
}
EndPaint (hwnd, &ps);
return (0);
case WM_DESTROY:
if (hBitmap)
{
DeleteObject(hBitmap);
}
PostQuitMessage (0);
return (0);
}
return DefWindowProc (hwnd, message, wParam, lParam);
}