001: #include <stdio.h>
002: #include <windows.h>
003: #include <wingdi.h>
004: #include <commctrl.h>
005: #include "wingui.h"
006: 
007: //-----------------------------------------------------------------
008: // グローバル変数定義
009: //-----------------------------------------------------------------
010: HINSTANCE hAppInst;
011: HWND hAppWnd;
012: UINT iWidth,iHeight,iLength,iSize,bmpLoad;
013: LPBYTE lpOrgBMP,lpBMP;
014: UINT iGHist[512];
015: LPBITMAPINFO lpInfo;
016: extern MenuInfo MI[];
017: //-----------------------------------------------------------------
018: 
019: int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
020:                    LPSTR lpsCmdLine, int nCmdShow)
021: {
022:     LPCTSTR szClassName = "BMP画像処理"; // 初期化
023:     bmpLoad = 0; iWidth = 300; iHeight = 200;
024:     //--------------------------------------------------
025:     // ウィンドウ・クラスの登録
026:     //--------------------------------------------------
027:     if(!hPrevInst){
028:         if(!InitApp(hCurInst,szClassName)) return 0;
029:         hAppInst = hCurInst;
030:     }
031:     //--------------------------------------------------
032:     // ウィンドウ作成
033:     //--------------------------------------------------
034:     if(!InitInstance(hCurInst,szClassName,lpsCmdLine,nCmdShow)){
035:         return 0;
036:     }
037:     // メッセージループ
038:     MSG msg;
039:     while(GetMessage(&msg,NULL,0,0)){
040:         TranslateMessage(&msg);
041:         DispatchMessage(&msg);
042:     }
043:     return msg.wParam;
044: }
045: //-----------------------------------------------------------------
046: // ウィンドウ・クラスの登録
047: //-----------------------------------------------------------------
048: BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName)
049: {
050:     WNDCLASSEX wc;
051:     wc.cbSize      = sizeof(wc);
052:     wc.style       = CS_HREDRAW | CS_VREDRAW;
053:     wc.lpfnWndProc = WndProc; // プロシージャ名
054:     wc.cbClsExtra  = 0;
055:     wc.cbWndExtra  = 0;
056:     wc.hInstance   = hInst;   // インスタンス
057:     wc.hIcon       = LoadIcon(NULL,IDI_APPLICATION);
058:     wc.hCursor     = LoadCursor(NULL,IDC_ARROW);
059:     wc.hIconSm     = LoadIcon(NULL,IDI_APPLICATION);
060:     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
061:     wc.lpszMenuName = NULL;   // メニュー名 
062:     wc.lpszClassName = (LPCSTR)szClassName;
063:     return (RegisterClassEx(&wc));
064: }
065: //-----------------------------------------------------------------
066: // ウィンドウの生成
067: //-----------------------------------------------------------------
068: BOOL InitInstance(HINSTANCE hInst,LPCSTR szClassName,
069:                   LPSTR lpsCmdLine,int nCmdShow)
070: {
071:     TCHAR lpStr[256]; LPSTR ifile;
072:     //--------------------------------------------------
073:     // ビットマップファイルオープン 
074:     //--------------------------------------------------
075:     if(strlen(lpsCmdLine)) {
076:         ifile = lpsCmdLine;
077:         // ビットマップの読込み 
078:         if(!LoadBMP(ifile,lpInfo,lpOrgBMP)){
079:             MessageBox(NULL,"読込み失敗",NULL,MB_OK); return 0;
080:         }
081:         // 複製 
082:         lpBMP=(LPBYTE)GlobalAlloc(GPTR,iLength*iHeight);
083:         CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight);
084:     }
085:     // ビットマップの情報表示
086:     if(bmpLoad) wsprintf(lpStr,"%s %d*%d Pixel %dBit",
087:                          ifile,iWidth,iHeight,
088:                          lpInfo->bmiHeader.biBitCount);
089:     else wsprintf(lpStr,"BMP画像処理");
090:     //--------------------------------------------------
091:     // ウィンドウの作成 
092:     //--------------------------------------------------
093:     HWND hWnd;
094:     hWnd = CreateWindow(szClassName,lpStr,   // タイトルバー
095:                         WS_OVERLAPPEDWINDOW, // ウィンドウ
096:                         CW_USEDEFAULT,       // X座標
097:                         CW_USEDEFAULT,       // Y座標
098:                         15+iWidth,           // 幅
099:                         70+iHeight,          // 高さ
100:                         NULL,                // 親ウィンドウのハンドル
101:                         NULL,                // メニューハンドル 
102:                         hInst,               // インスタンスハンドル
103:                         NULL);
104:     if(!hWnd) return FALSE;
105:     // ドラッグ&ドロップ受入 
106:     DragAcceptFiles(hWnd,TRUE);
107:     // ウィンドウを表示 
108:     ShowWindow(hWnd,nCmdShow);
109:     // 再描画
110:     UpdateWindow(hWnd);
111:     // ウィンドウ設定 
112:     hAppWnd = hWnd;
113:     return TRUE;
114: }
115: //-----------------------------------------------------------------
116: // メッセージ情報
117: //-----------------------------------------------------------------
118: LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
119:                          WPARAM wParam, LPARAM lParam)
120: {
121:     static HWND hwB1,hwB2,hwB3,hwSel;
122:     static UINT s,mi,mlen,mlen_max;
123:     TCHAR szFn[MAX_PATH];
124:     HDC hdc; HDROP hDrop; PAINTSTRUCT ps;
125:     switch(iMsg){
126:     case WM_CHAR:
127:         if(wParam=='q') SendMessage(hwnd,WM_DESTROY,NULL,NULL); break;
128:     case WM_CREATE: {
129:         InitCommonControls();
130:         // ボタン作成 
131:         hwB1=CreateWindow("Button","開く", WS_CHILD | WS_VISIBLE,
132:                           5,5,60,25,hwnd,(HMENU)ID_OPEN,hAppInst,NULL);
133:         hwB2=CreateWindow("Button","保存", WS_CHILD | WS_VISIBLE,
134:                           65,5,60,25,hwnd,(HMENU)ID_SAVE,hAppInst,NULL); 
135:         hwB3=CreateWindow("Button","実行", WS_CHILD | WS_VISIBLE,
136:                           125,5,60,25,hwnd,(HMENU)ID_IP,hAppInst,NULL);
137:         // 選択メニュー
138:         mi = mlen_max = 0;
139:         while(MI[mi].menu!=NULL){
140:             if(mlen_max < strlen(MI[mi].menu))
141:                 mlen_max = strlen(MI[mi].menu);
142:             mi++;
143:         }
144:         mlen = 8*(mlen_max+1);
145:         hwSel=CreateWindow("COMBOBOX",NULL,
146:                            WS_CHILD|WS_VISIBLE|CBS_DROPDOWN,
147:                            190,5,mlen,200,hwnd,(HMENU)0,hAppInst,NULL);
148:         mi = 0;
149:         while(MI[mi].menu!=NULL){
150:             SendMessage(hwSel,CB_ADDSTRING,0,(LPARAM)MI[mi].menu);
151:             mi++;
152:         }
153:         SendMessage(hwSel,CB_SETCURSEL,0,1);
154:     } break;
155:     case WM_COMMAND:
156:         switch(LOWORD(wParam)){
157:         case 'q':     // 終了
158:             SendMessage(hwnd,WM_DESTROY,NULL,NULL); break;
159:         case ID_OPEN: // 読み込みボタン
160:             if(OpenFile(hwnd,szFn)){
161:                 reLoadBMP(szFn); // 再読込み
162:             }
163:             break;
164:         case ID_SAVE: // 保存ボタン
165:             if(SaveFile(hwnd,szFn)){
166:                 SaveBMP(szFn,lpInfo,lpBMP);
167:             }
168:             break;
169:         case ID_IP:   // 画像処理ボタン 
170:             if(bmpLoad){
171:                 s=SendMessage(hwSel,CB_GETCURSEL,0,0);
172:                 MI[s].proc();
173:                 InvalidateRgn(hAppWnd,NULL,FALSE);
174:                 UpdateWindow(hAppWnd); // 再描画
175:             }
176:             break;
177:         }
178:         break;
179:     case WM_DROPFILES: // ファイルがドロップされた時の処理
180:         // HDROPを取得
181:         hDrop=(HDROP)wParam;
182:         DragQueryFile(hDrop,0,szFn,MAX_PATH);
183:         DragFinish(hDrop);
184:         // 再読込み
185:         reLoadBMP(szFn);
186:         break;
187:     case WM_PAINT:
188:         if(bmpLoad){
189:             hdc=BeginPaint(hwnd,&ps);
190:             StretchDIBits(hdc,4,35,iWidth,iHeight,
191:                           0,0,iWidth,iHeight,lpBMP,lpInfo,
192:                           DIB_RGB_COLORS,SRCCOPY); // DIBを画面に描画 
193:             EndPaint(hwnd,&ps);
194:         }
195:         break;
196:     case WM_DESTROY: // メモリの解放
197:         GlobalFree(lpInfo);
198:         GlobalFree(lpOrgBMP);
199:         PostQuitMessage(0);
200:         break;
201:     }
202:     return DefWindowProc(hwnd,iMsg,wParam,lParam);
203: }
204: //-----------------------------------------------------------------
205: // ウィンドウ位置の取得
206: //-----------------------------------------------------------------
207: void GetWinPos(HWND hWnd,UINT *x,UINT *y)
208: {
209:     WINDOWPLACEMENT wndpl;
210:     GetWindowPlacement(hWnd,&wndpl);
211:     *x = wndpl.rcNormalPosition.left;
212:     *y = wndpl.rcNormalPosition.top;
213:     return;
214: }
215: //-----------------------------------------------------------------
216: // [開く]ファイルの選択
217: //-----------------------------------------------------------------
218: UINT OpenFile(HWND hWnd, LPTSTR lpFname)
219: {
220:     static OPENFILENAME ofn;
221:     TCHAR szFn[MAX_PATH],szFt[MAX_PATH];
222:     FillMemory(szFn,MAX_PATH,0);
223:     // ファイル[開く]ダイアログ設定
224:     ofn.lStructSize       = sizeof(OPENFILENAME);
225:     ofn.hwndOwner         = hWnd;
226:     ofn.hInstance         = NULL;
227:     ofn.lpstrFilter       =
228:         "Bitmap(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0";
229:     ofn.lpstrCustomFilter = NULL;
230:     ofn.nMaxCustFilter    = 0;
231:     ofn.nFilterIndex      = 1;    // フィルタの初期位置
232:     ofn.lpstrFile         = szFn; // ファイル名用文字列バッファ
233:     ofn.nMaxFile          = 255;  // 文字列バッファのサイズ
234:     ofn.lpstrFileTitle    = szFt; // タイトル用文字列バッファ
235:     ofn.nMaxFileTitle     = 255;  // 文字列バッファのサイズ
236:     ofn.lpstrInitialDir   = NULL;
237:     ofn.lpstrTitle        = "Bitmap";
238:     ofn.Flags             = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
239:     ofn.nFileOffset       = 0;
240:     ofn.nFileExtension    = 0;
241:     ofn.lpstrDefExt       = "bmp";
242:     ofn.lCustData         = 0;
243:     ofn.lpfnHook          = NULL;
244:     ofn.lpTemplateName    = NULL;
245:     // ダイアログを開く
246:     if(!GetOpenFileName(&ofn)) return FALSE;
247:     wsprintf(lpFname,szFn);
248:     return TRUE;
249: }
250: //-----------------------------------------------------------------
251: // [保存]ファイルの選択
252: //-----------------------------------------------------------------
253: UINT SaveFile(HWND hWnd, LPTSTR lpFname)
254: {
255:     static OPENFILENAME ofn;
256:     TCHAR szFn[MAX_PATH],szFt[MAX_PATH];
257:     FillMemory(szFn,MAX_PATH,0);
258:     // ファイル[保存]ダイアログ設定
259:     ofn.lStructSize       = sizeof(OPENFILENAME);
260:     ofn.hwndOwner         = hWnd;
261:     ofn.hInstance         = NULL;
262:     ofn.lpstrFilter       =
263:         "Bitmap(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0";
264:     ofn.lpstrCustomFilter = NULL;
265:     ofn.nMaxCustFilter    = 0;
266:     ofn.nFilterIndex      = 1;    // フィルタの初期位置
267:     ofn.lpstrFile         = szFn; // ファイル名用文字列バッファ
268:     ofn.nMaxFile          = 255;  // 文字列バッファのサイズ
269:     ofn.lpstrFileTitle    = szFt;
270:     ofn.nMaxFileTitle     = 255;  // 文字列バッファのサイズ
271:     ofn.lpstrInitialDir   = NULL;
272:     ofn.lpstrTitle        = "Bitmap";
273:     ofn.Flags             = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
274:     ofn.nFileOffset       = 0;
275:     ofn.nFileExtension    = 0;
276:     ofn.lpstrDefExt       = "bmp";
277:     ofn.lCustData         = 0;
278:     ofn.lpfnHook          = NULL;
279:     ofn.lpTemplateName    = NULL;
280:     // ダイアログを開く
281:     if(!GetSaveFileName(&ofn)) return FALSE;
282:     wsprintf(lpFname,szFn);
283:     return TRUE;
284: }
285: //-----------------------------------------------------------------
286: // ビットマップの読込み
287: //-----------------------------------------------------------------
288: UINT LoadBMP(LPCTSTR lpFname,LPBITMAPINFO& biBuf,LPBYTE& lpBuf)
289: {
290:     HANDLE hdlBmp;           // ファイルのハンドル
291:     BITMAPFILEHEADER bfhBmp; // ビットマップファイル情報の構造体
292:     DWORD dwdFileSize=0;     // 読み込んだサイズ
293:     DWORD dwdPixelsSize=0;   // 色情報のサイズ
294:     // ファイルを開く
295:     hdlBmp=CreateFile(lpFname,GENERIC_READ,0,NULL,OPEN_EXISTING,
296:                       FILE_ATTRIBUTE_NORMAL,NULL);
297:     if(hdlBmp==INVALID_HANDLE_VALUE){
298:         MessageBox(NULL,"読込みに失敗しました",NULL,MB_OK);
299:         return FALSE;
300:     }
301:     // ファイル情報部分を読み込む
302:     ReadFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&dwdFileSize,NULL);
303:     // ビットマップ情報部分を読み込む
304:     biBuf=(LPBITMAPINFO)GlobalAlloc(GPTR,sizeof(BITMAPINFO));
305:     ReadFile(hdlBmp,biBuf,sizeof(BITMAPINFOHEADER),&dwdFileSize,NULL);
306:     // 色情報を読み込む
307:     dwdPixelsSize=((biBuf->bmiHeader.biWidth+3)&0xfffffffc) *
308:         biBuf->bmiHeader.biHeight*3;
309:     lpBuf=(LPBYTE)GlobalAlloc(GPTR,dwdPixelsSize);
310:     ReadFile(hdlBmp,lpBuf,dwdPixelsSize,&dwdFileSize,NULL);
311:     // ファイルを閉じる
312:     CloseHandle(hdlBmp);
313:     // 24ビットの BMPでない場合、処理を終了する
314:     if(bfhBmp.bfType!='M'*256+'B' || biBuf->bmiHeader.biBitCount!=24){
315:         // メモリ領域を解放
316:         GlobalFree(biBuf);
317:         GlobalFree(lpBuf);
318:         MessageBox(NULL,"ファイルの種類が不正です",NULL,MB_OK);
319:         // 処理を中断
320:         return FALSE;
321:     }
322:     // 正常終了
323:     iWidth =biBuf->bmiHeader.biWidth;
324:     iHeight=biBuf->bmiHeader.biHeight;
325:     // バッファの1ラインの長さを計算
326:     if((iWidth*3)%4==0) iLength=iWidth*3;
327:     else iLength=iWidth*3+(4-(iWidth*3)%4);
328:     iSize=iWidth*iHeight;
329:     // ビットマップの読込み完了
330:     bmpLoad = 1;
331:     return TRUE;
332: }
333: //-----------------------------------------------------------------
334: // ビットマップの再読込み
335: //-----------------------------------------------------------------
336: UINT reLoadBMP(LPCTSTR lpFname)
337: {
338:     UINT wx,wy; TCHAR lpStr[256];
339:     // メモリの解放
340:     GlobalFree(lpInfo);
341:     GlobalFree(lpOrgBMP);
342:     GlobalFree(lpBMP);
343:     // ビットマップの読込み
344:     if(LoadBMP(lpFname,lpInfo,lpOrgBMP)){
345:         // 複製
346:         lpBMP=(LPBYTE)GlobalAlloc(GPTR,iLength*iHeight);
347:         CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight);
348:         // ウィンドウ幅の変更
349:         GetWinPos(hAppWnd,&wx,&wy);
350:         MoveWindow(hAppWnd,wx,wy,15+iWidth,iHeight+70,TRUE);
351:         // タイトル
352:         wsprintf(lpStr,"%s %d*%d Pixel %dBit",
353:                  lpFname,iWidth,iHeight,lpInfo->bmiHeader.biBitCount);
354:         SetWindowText(hAppWnd,(LPSTR)lpStr);
355:         return TRUE;
356:     }
357:     return FALSE;
358: }
359: //-----------------------------------------------------------------
360: // ビットマップの読込み
361: //-----------------------------------------------------------------
362: UINT SaveBMP(LPCTSTR lpFname,LPBITMAPINFO biBuf,LPBYTE lpBuf)
363: {
364:     HANDLE hdlBmp;           // ファイルのハンドル
365:     BITMAPFILEHEADER bfhBmp; // ビットマップファイル情報の構造体
366:     LONG  offset=14+40;      // 画像データまでのオフセット
367:     DWORD dwdFileSize=0;     // 書き込んだサイズ
368:     DWORD dwdPixelsSize=iHeight*iLength; // 色情報のサイズ
369:     // ファイルを開く
370:     hdlBmp=CreateFile(lpFname,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
371:                       FILE_ATTRIBUTE_NORMAL,NULL);
372:     if(hdlBmp==INVALID_HANDLE_VALUE){
373:         MessageBox(NULL,"書込みに失敗しました",NULL,MB_OK);
374:         return FALSE;
375:     }
376:     bfhBmp.bfType ='M'*256+'B';
377:     bfhBmp.bfSize = offset+dwdPixelsSize;
378:     bfhBmp.bfReserved1 = 0;
379:     bfhBmp.bfReserved2 = 0;
380:     bfhBmp.bfOffBits   = offset;
381:     // ファイル情報部分を書き込む
382:     WriteFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&dwdFileSize,NULL);
383:     // ビットマップ情報部分を書き込む
384:     WriteFile(hdlBmp,biBuf,sizeof(BITMAPINFOHEADER),&dwdFileSize,NULL);
385:     // 色情報を書き込む
386:     WriteFile(hdlBmp,lpBuf,dwdPixelsSize,&dwdFileSize,NULL);
387:     // ファイルを閉じる
388:     CloseHandle(hdlBmp);
389:     return TRUE;
390: }
inserted by FC2 system