#include #include #include #include "wingui.h" //----------------------------------------------------------------- // グローバル変数定義 //----------------------------------------------------------------- HINSTANCE hAppInst; HWND hAppWnd; UINT iWidth,iHeight,iLength; UINT iSize,biSize,bmpLoad; UINT iOrgWidth,iOrgHeight; UINT iGHist[512]; LPBYTE lpOrgBMP,lpBMP; LPBITMAPINFO lpBInfo; extern MenuInfo MI[]; //----------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { LPCTSTR szClassName = "BMP画像処理"; // 初期化 bmpLoad = 0; iWidth = 300; iHeight = 200; //-------------------------------------------------- // ウィンドウ・クラスの登録 //-------------------------------------------------- if(!hPrevInst){ if(!InitApp(hCurInst,szClassName)) return 0; hAppInst = hCurInst; } //-------------------------------------------------- // ウィンドウ作成 //-------------------------------------------------- if(!InitInstance(hCurInst,szClassName,lpsCmdLine,nCmdShow)){ return 0; } // メッセージループ MSG msg; while(GetMessage(&msg,NULL,0,0)){ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //----------------------------------------------------------------- // ウィンドウ・クラスの登録 //----------------------------------------------------------------- BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; // プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; // インスタンス wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; // メニュー名 wc.lpszClassName = (LPCSTR)szClassName; return (RegisterClassEx(&wc)); } //----------------------------------------------------------------- // ウィンドウの生成 //----------------------------------------------------------------- BOOL InitInstance(HINSTANCE hInst,LPCSTR szClassName, LPSTR lpsCmdLine,int nCmdShow) { TCHAR lpStr[256]; LPSTR ifile; wsprintf(lpStr,"BMP画像処理"); //-------------------------------------------------- // ウィンドウの作成 //-------------------------------------------------- HWND hWnd; hWnd = CreateWindow(szClassName,lpStr, // タイトルバー WS_OVERLAPPEDWINDOW, // ウィンドウ CW_USEDEFAULT, // X座標 CW_USEDEFAULT, // Y座標 15+iWidth, // 幅 70+iHeight, // 高さ NULL, // 親ウィンドウのハンドル NULL, // メニューハンドル hInst, // インスタンスハンドル NULL); if(!hWnd) return FALSE; // ドラッグ&ドロップ受入 DragAcceptFiles(hWnd,TRUE); // ウィンドウを表示 ShowWindow(hWnd,nCmdShow); // 再描画 UpdateWindow(hWnd); // ウィンドウ設定 hAppWnd = hWnd; return TRUE; } //----------------------------------------------------------------- // メッセージ情報 //----------------------------------------------------------------- LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static HWND hwB1,hwB2,hwB3,hwSel; static UINT s,mi,mlen,mlen_max; TCHAR szFn[MAX_PATH]; HDC hdc; HDROP hDrop; PAINTSTRUCT ps; switch(iMsg){ case WM_CHAR: if(wParam=='q') SendMessage(hwnd,WM_DESTROY,NULL,NULL); break; case WM_CREATE: { InitCommonControls(); // ボタン作成 hwB1=CreateWindow("Button","開く", WS_CHILD | WS_VISIBLE, 5,5,60,25,hwnd,(HMENU)ID_OPEN,hAppInst,NULL); hwB2=CreateWindow("Button","保存", WS_CHILD | WS_VISIBLE, 65,5,60,25,hwnd,(HMENU)ID_SAVE,hAppInst,NULL); hwB3=CreateWindow("Button","実行", WS_CHILD | WS_VISIBLE, 125,5,60,25,hwnd,(HMENU)ID_IP,hAppInst,NULL); // 選択メニュー mi = mlen_max = 0; while(MI[mi].menu!=NULL){ if(mlen_max < strlen(MI[mi].menu)) mlen_max = strlen(MI[mi].menu); mi++; } mlen = 8*(mlen_max+1); hwSel=CreateWindow("COMBOBOX",NULL, WS_CHILD|WS_VISIBLE|CBS_DROPDOWN, 190,5,mlen,200,hwnd,(HMENU)0,hAppInst,NULL); mi = 0; while(MI[mi].menu!=NULL){ SendMessage(hwSel,CB_ADDSTRING,0,(LPARAM)MI[mi].menu); mi++; } SendMessage(hwSel,CB_SETCURSEL,0,1); } break; case WM_COMMAND: switch(LOWORD(wParam)){ case 'q': // 終了 SendMessage(hwnd,WM_DESTROY,NULL,NULL); break; case ID_OPEN: // 読み込みボタン if(OpenFile(hwnd,szFn)){ reLoadBMP(szFn); // 再読込み } break; case ID_SAVE: // 保存ボタン if(SaveFile(hwnd,szFn)){ SaveBMP(szFn,lpBInfo,lpBMP); } break; case ID_IP: // 画像処理ボタン if(bmpLoad){ s=SendMessage(hwSel,CB_GETCURSEL,0,0); MI[s].proc(); InvalidateRgn(hwnd,NULL,TRUE); UpdateWindow(hwnd); // 再描画 } break; } break; case WM_DROPFILES: // ファイルがドロップされた時の処理 // HDROPを取得 hDrop=(HDROP)wParam; DragQueryFile(hDrop,0,szFn,MAX_PATH); DragFinish(hDrop); // 再読込み reLoadBMP(szFn); break; case WM_PAINT: if(bmpLoad){ hdc=BeginPaint(hwnd,&ps); StretchDIBits(hdc,4,35,iWidth,iHeight, 0,0,iWidth,iHeight,lpBMP,lpBInfo, DIB_RGB_COLORS,SRCCOPY); // DIBを画面に描画 EndPaint(hwnd,&ps); } break; case WM_DESTROY: // メモリの解放 GlobalFree(lpBInfo); GlobalFree(lpOrgBMP); PostQuitMessage(0); break; } return DefWindowProc(hwnd,iMsg,wParam,lParam); } //----------------------------------------------------------------- // ウィンドウ位置の取得 //----------------------------------------------------------------- void GetWinPos(HWND hWnd,UINT *x,UINT *y) { WINDOWPLACEMENT wndpl; GetWindowPlacement(hWnd,&wndpl); *x = wndpl.rcNormalPosition.left; *y = wndpl.rcNormalPosition.top; return; } //----------------------------------------------------------------- // 画像情報の設定 //----------------------------------------------------------------- void set_image_size(LPBITMAPINFO bInfo) { iWidth = bInfo->bmiHeader.biWidth; iHeight = bInfo->bmiHeader.biHeight; iSize = iWidth*iHeight; iOrgWidth = iWidth; iOrgHeight = iHeight; // バッファの1ラインの長さを計算 if((iWidth*3)%4==0) iLength = iWidth*3; else iLength = iWidth*3+(4-(iWidth*3)%4); biSize = iHeight*iLength; // ビットマップの読込み完了 bmpLoad = 1; } // 画像処理範囲の変更 void set_ip_window(UINT xsize,UINT ysize) { if(xsize && ysize){ iWidth = xsize; iHeight = ysize; } else { if(xsize > iWidth) return; if(ysize > iHeight) return; iWidth = iOrgWidth; iHeight = iOrgHeight; } iSize = iWidth*iHeight; // バッファの1ラインの長さを計算 if((iWidth*3)%4==0) iLength = iWidth*3; else iLength = iWidth*3+(4-(iWidth*3)%4); biSize = iHeight*iLength; // ビットマップ情報 lpBInfo->bmiHeader.biWidth = iWidth; lpBInfo->bmiHeader.biHeight = iHeight; } //----------------------------------------------------------------- // [開く]ファイルの選択 //----------------------------------------------------------------- UINT OpenFile(HWND hWnd, LPTSTR lpFname) { static OPENFILENAME ofn; TCHAR szFn[MAX_PATH],szFt[MAX_PATH]; FillMemory(szFn,MAX_PATH,0); // ファイル[開く]ダイアログ設定 ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.hInstance = NULL; ofn.lpstrFilter = "Bitmap(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0"; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 1; // フィルタの初期位置 ofn.lpstrFile = szFn; // ファイル名用文字列バッファ ofn.nMaxFile = 255; // 文字列バッファのサイズ ofn.lpstrFileTitle = szFt; // タイトル用文字列バッファ ofn.nMaxFileTitle = 255; // 文字列バッファのサイズ ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = "Bitmap"; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = "bmp"; ofn.lCustData = 0; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; // ダイアログを開く if(!GetOpenFileName(&ofn)) return FALSE; wsprintf(lpFname,szFn); return TRUE; } //----------------------------------------------------------------- // [保存]ファイルの選択 //----------------------------------------------------------------- UINT SaveFile(HWND hWnd, LPTSTR lpFname) { static OPENFILENAME ofn; TCHAR szFn[MAX_PATH],szFt[MAX_PATH]; FillMemory(szFn,MAX_PATH,0); // ファイル[保存]ダイアログ設定 ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.hInstance = NULL; ofn.lpstrFilter = "Bitmap(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0"; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 1; // フィルタの初期位置 ofn.lpstrFile = szFn; // ファイル名用文字列バッファ ofn.nMaxFile = 255; // 文字列バッファのサイズ ofn.lpstrFileTitle = szFt; ofn.nMaxFileTitle = 255; // 文字列バッファのサイズ ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = "Bitmap"; ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = "bmp"; ofn.lCustData = 0; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; // ダイアログを開く if(!GetSaveFileName(&ofn)) return FALSE; wsprintf(lpFname,szFn); return TRUE; } //----------------------------------------------------------------- // ビットマップの読込み //----------------------------------------------------------------- UINT LoadBMP(LPCTSTR lpFname,LPBITMAPINFO& biBuf,LPBYTE& lpBuf) { HANDLE hdlBmp; // ファイルのハンドル BITMAPFILEHEADER bfhBmp; // ビットマップファイル情報の構造体 DWORD dwdFileSize =0; // 読み込んだサイズ DWORD dwdPixelsSize=0; // 色情報のサイズ // ファイルを開く hdlBmp=CreateFile(lpFname,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); if(hdlBmp==INVALID_HANDLE_VALUE){ MessageBox(NULL,"読込みに失敗しました",NULL,MB_OK); return FALSE; } // ファイル情報部分を読み込む ReadFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&dwdFileSize,NULL); // ビットマップ情報部分を読み込む biBuf=(LPBITMAPINFO)GlobalAlloc(GPTR,sizeof(BITMAPINFO)); ReadFile(hdlBmp,biBuf,sizeof(BITMAPINFOHEADER),&dwdFileSize,NULL); // 色情報を読み込む dwdPixelsSize=((biBuf->bmiHeader.biWidth+3)&0xfffffffc) * biBuf->bmiHeader.biHeight*3; lpBuf=(LPBYTE)GlobalAlloc(GPTR,dwdPixelsSize); ReadFile(hdlBmp,lpBuf,dwdPixelsSize,&dwdFileSize,NULL); // ファイルを閉じる CloseHandle(hdlBmp); // 24ビットの BMPでない場合、処理を終了する if(bfhBmp.bfType!='M'*256+'B' || biBuf->bmiHeader.biBitCount!=24){ // メモリ領域を解放 GlobalFree(biBuf); GlobalFree(lpBuf); MessageBox(NULL,"ファイルの種類が不正です",NULL,MB_OK); // 処理を中断 return FALSE; } return TRUE; } //----------------------------------------------------------------- // ビットマップの再読込み //----------------------------------------------------------------- UINT reLoadBMP(LPCTSTR lpFname) { UINT wx,wy; TCHAR lpStr[256]; // メモリの解放 GlobalFree(lpBInfo); GlobalFree(lpOrgBMP); GlobalFree(lpBMP); // ビットマップの読込み if(LoadBMP(lpFname,lpBInfo,lpOrgBMP)){ // 画像情報の設定 set_image_size(lpBInfo); // 複製 lpBMP=(LPBYTE)GlobalAlloc(GPTR,iLength*iHeight); CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight); // ウィンドウ幅の変更 GetWinPos(hAppWnd,&wx,&wy); MoveWindow(hAppWnd,wx,wy,15+iWidth,iHeight+70,TRUE); // タイトル wsprintf(lpStr,"%s %d*%d Pixel %dBit", lpFname,iWidth,iHeight,lpBInfo->bmiHeader.biBitCount); SetWindowText(hAppWnd,(LPSTR)lpStr); return TRUE; } return FALSE; } //----------------------------------------------------------------- // ビットマップの読込み //----------------------------------------------------------------- UINT SaveBMP(LPCTSTR lpFname,LPBITMAPINFO biBuf,LPBYTE lpBuf) { HANDLE hdlBmp; // ファイルのハンドル BITMAPFILEHEADER bfhBmp; // ビットマップファイル情報の構造体 LONG offset=14+40; // 画像データまでのオフセット DWORD dwdFileSize=0; // 書き込んだサイズ DWORD dwdPixelsSize=iHeight*iLength; // 色情報のサイズ // ファイルを開く hdlBmp=CreateFile(lpFname,GENERIC_WRITE,0,NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); if(hdlBmp==INVALID_HANDLE_VALUE){ MessageBox(NULL,"書込みに失敗しました",NULL,MB_OK); return FALSE; } bfhBmp.bfType ='M'*256+'B'; bfhBmp.bfSize = offset+dwdPixelsSize; bfhBmp.bfReserved1 = 0; bfhBmp.bfReserved2 = 0; bfhBmp.bfOffBits = offset; // ファイル情報部分を書き込む WriteFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&dwdFileSize,NULL); // ビットマップ情報部分を書き込む WriteFile(hdlBmp,biBuf,sizeof(BITMAPINFOHEADER),&dwdFileSize,NULL); // 色情報を書き込む WriteFile(hdlBmp,lpBuf,dwdPixelsSize,&dwdFileSize,NULL); // ファイルを閉じる CloseHandle(hdlBmp); return TRUE; } //----------------------------------------------------------------- // テンプレート画像の読込み //----------------------------------------------------------------- LPBYTE Load_template(UINT& sizex,UINT& sizey) { TCHAR szFn[MAX_PATH]; LPBYTE lpTempBMP; LPBITMAPINFO bInfo; // ファイル名の取得 if(!OpenFile(hAppWnd,szFn)) return NULL; // ビットマップの読込み if(!LoadBMP(szFn,bInfo,lpTempBMP)) return NULL; // 取得サイズの設定 sizex = bInfo->bmiHeader.biWidth; sizey = bInfo->bmiHeader.biHeight; return lpTempBMP; }