#include #include"DIB8or24.h" #include"outline.h" #define APP_NAME TEXT("Sample_MainWindow") LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int i; static int select=0; //外側(複数)と内側(複数)の輪郭(0) //外側(複数)の輪郭(1) //外側(一つ)の輪郭(2) //ファイル static OPENFILENAME ofn; static char szFile[MAX_PATH]; static char szFileTitle[MAX_PATH]; //画像 static LPDWORD lpPixel; static BITMAPINFO bmpInfo; static int iWidth,iHeight; //背景色 static DWORD BackColor; //外側と内側の輪郭 static POINT lpPoints[0xFFFF]; static INT lpPolyCounts[0xF]; static int nCount; static LPBYTE mask; //リージョン static HRGN hRgn; switch(uMsg){ case WM_CREATE: //OPENFILENAME 構造体の初期化 ofn.lStructSize=sizeof(OPENFILENAME); ofn.hwndOwner=hWnd; ofn.lpstrFilter="8/24bitBMP(*.bmp)\0*.bmp\0"; ofn.lpstrFile=szFile; ofn.nMaxFile=MAX_PATH; ofn.lpstrFileTitle=szFileTitle; ofn.nMaxFileTitle=MAX_PATH; ofn.Flags=OFN_FILEMUSTEXIST; ofn.lpstrDefExt="bmp"; ofn.lpstrTitle="8/24ビットのBMPファイルを選択して下さい"; //ファイルを開くダイアログボックス表示 if(!GetOpenFileName(&ofn)){ MessageBox(hWnd,"8/24ビットのBMPファイルを選択して下さい","終了します",MB_OK); SendMessage(hWnd,WM_CLOSE,0,0); return 0; } //画像を読み込む lpPixel=BMP8or24toDIB(ofn.lpstrFile,&bmpInfo); if(lpPixel==NULL){ //非対応のファイル形式である MessageBox(hWnd,"非対応のファイル形式です","終了します",MB_OK); SendMessage(hWnd,WM_CLOSE,0,0); return 0; } iWidth=bmpInfo.bmiHeader.biWidth; iHeight=bmpInfo.bmiHeader.biHeight; //ウィンドウサイズを画像サイズに合わせる MoveWindow(hWnd,0,0,iWidth,iHeight,TRUE); //正しく準備された画像か? if((lpPixel[0]!=lpPixel[iWidth-1]) || (lpPixel[0]!=lpPixel[(iHeight-1)*iWidth]) || (lpPixel[0]!=lpPixel[iWidth-1+(iHeight-1)*iWidth])){ MessageBox(hWnd,"画像が不正です","終了します",MB_OK); SendMessage(hWnd,WM_CLOSE,0,0); return 0; } //背景色を取得 BackColor=lpPixel[0]; mask=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BYTE)*iWidth*iHeight); case WM_RBUTTONDOWN: switch(select){ case 0: //外側(複数)と内側(複数)の輪郭を取得 i=GetOutlineExPlus(lpPixel,iWidth,iHeight,BackColor, lpPoints,0xFFFF,lpPolyCounts,0xF,&nCount,mask,TRUE); break; case 1: //外側(複数)の輪郭を取得 i=GetOutlineExPlus(lpPixel,iWidth,iHeight,BackColor, lpPoints,0xFFFF,lpPolyCounts,0xF,&nCount,mask,FALSE); break; case 2: //外側(一つ)の輪郭を取得 i=GetOutline(lpPixel,iWidth,iHeight,BackColor,lpPoints,0xFFFF,&nCount); break; } if(i==-1){ //限界まで輪郭の座標を取得した MessageBox(hWnd,"輪郭が複雑すぎます","終了します",MB_OK); SendMessage(hWnd,WM_CLOSE,0,0); return 0; }else if(i==-2){ //輪郭がない MessageBox(hWnd,"輪郭がありません","終了します",MB_OK); SendMessage(hWnd,WM_CLOSE,0,0); return 0; } switch(select){ case 0: //外側(複数)と内側(複数)の輪郭を取得 hRgn=CreatePolyPolygonRgn(lpPoints,lpPolyCounts,nCount,ALTERNATE); break; case 1: //外側(複数)の輪郭を取得 hRgn=CreatePolyPolygonRgn(lpPoints,lpPolyCounts,nCount,ALTERNATE); break; case 2: //外側(一つ)の輪郭を取得 hRgn=CreatePolygonRgn(lpPoints,nCount,ALTERNATE); break; } select=(select+1)%3; //リージョン設定 SetWindowRgn(hWnd,hRgn,TRUE); return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); StretchDIBits(hdc,0,0,iWidth,iHeight, 0,0,iWidth,iHeight, lpPixel,&bmpInfo,DIB_RGB_COLORS,SRCCOPY); //終点1ピクセルは描画されない //Polyline(hdc,lpPoints,nCount); //PolyPolyline(hdc,lpPoints,(DWORD *)lpPolyCounts,nCount); EndPaint(hWnd,&ps); return 0; case WM_LBUTTONDOWN: PostMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,lParam); return 0; case WM_KEYDOWN: if(wParam==VK_ESCAPE) PostMessage(hWnd,WM_CLOSE,0,0); return 0; case WM_DESTROY: DeleteObject(hRgn); HeapFree(GetProcessHeap(),0,mask); FreeDIB(lpPixel); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR lpCmdLine,int nCmdShow) { WNDCLASS wc; MSG msg; wc.style =CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc =WindowProc; wc.cbClsExtra =0; wc.cbWndExtra =0; wc.hInstance =hInstance; wc.hIcon =LoadIcon(NULL,IDI_APPLICATION); wc.hCursor =LoadCursor(NULL,IDC_ARROW); wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName =NULL; wc.lpszClassName =APP_NAME; if(!RegisterClass(&wc)) return 0; if(CreateWindow( APP_NAME,TEXT(__FILE__), WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL)==NULL) return 0; while(GetMessage(&msg,NULL,0,0)>0){ DispatchMessage(&msg); } return (int)msg.wParam; }