ホーム > カテゴリ > C/C++ >

グラフィックエフェクト- 90/180/270℃回転(C/C++版)

グラフィックエフェクト- 90/180/270℃回転のサンプルです。

サンプルの実行画面

ソースコード

[Sample96.c]

//--------------------------------------------------------------------------------------
//  ■グラフィックエフェクト- 90/180/270℃回転 -■ Sample NO.96
//
//--------------------------------------------------------------------------------------

#include <windows.h>

#define IDM_MENU  101
#define IDM_NONE  103
#define IDM_END   104
#define IDM_90    500
#define IDM_180   501
#define IDM_270   502

//ウインドウを中央にする為にX座標(LEFT)とY座標(TOP)算出するマクロ
#define ScreenCenterX(Width) ((0)<((int)((GetSystemMetrics(SM_CXSCREEN)- Width) / 2)) ? ((int)((GetSystemMetrics(SM_CXSCREEN)- Width) / 2)) :(0))
#define ScreenCenterY(Height) ((0)<((int)((GetSystemMetrics(SM_CYSCREEN)- Height) / 2)) ? ((int)((GetSystemMetrics(SM_CYSCREEN)- Height) / 2)) :(0))

LRESULT CALLBACK  WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
int  WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow);
void AllOff(HWND hwnd);
void Turn(HWND hwnd);

HBITMAP hBitmap;     //ビットマップのハンドル
HBITMAP hTempBMP[3]; //テンポラリビットマップのハンドル
HDC     hTempMem[3]; //テンポラリメモリデバイスコンテキスト
BYTE    Ok[4];       //フラグ    

 
/////////////////////////////////////////////////////////////////////////////
//
//  Turn  
//         VBレベルの手法なので遅いです(^^;  
//         高速に処理したい人はGetDIBits()APIなどを使いましょう。
//
void Turn(HWND hwnd)
{
  BITMAP  BMPINFO;   
  HDC     hMem,hDC; 
  int     X,Y;

  DWORD   RGBColor;
 
  hDC=GetDC(hwnd);
  GetObject(hBitmap, sizeof(BITMAP), &BMPINFO);
  //メモリビットマップ作成
  hMem    = CreateCompatibleDC(hDC);
  SelectObject(hMem, hBitmap);
  //テンポラリメモリビットマップ作成(90)
  hTempMem[0] = CreateCompatibleDC(hDC);
  hTempBMP[0] = CreateCompatibleBitmap(hDC, BMPINFO.bmHeight, BMPINFO.bmWidth);
  SelectObject(hTempMem[0], hTempBMP[0]);
  //テンポラリメモリビットマップ作成(180)
  hTempMem[1] = CreateCompatibleDC(hDC);
  hTempBMP[1] = CreateCompatibleBitmap(hDC, BMPINFO.bmWidth, BMPINFO.bmHeight);
  SelectObject(hTempMem[1], hTempBMP[1]);
  //テンポラリメモリビットマップ作成(270)
  hTempMem[2] = CreateCompatibleDC(hDC);
  hTempBMP[2] = CreateCompatibleBitmap(hDC, BMPINFO.bmHeight, BMPINFO.bmWidth);
  SelectObject(hTempMem[2], hTempBMP[2]);
   
  for (Y=0;Y<BMPINFO.bmHeight;Y++)
  {
   for (X=0;X<BMPINFO.bmWidth;X++)
   {   
      RGBColor=GetPixel(hMem, X, Y);
      
      //90
      SetPixelV(hTempMem[0],BMPINFO.bmHeight-1-Y,X,RGBColor) ;
      //180
      SetPixelV(hTempMem[1],BMPINFO.bmWidth-1-X,BMPINFO.bmHeight-1-Y,RGBColor);
      //270
      SetPixelV(hTempMem[2], Y,BMPINFO.bmWidth-1- X, RGBColor);
   }  
  }   
  DeleteDC(hMem);    
  ReleaseDC(hwnd,hDC);
}

/////////////////////////////////////////////////////////////////////////////
//
//  AllOff 
//
void AllOff(HWND hwnd)
{
  CheckMenuItem(GetMenu(hwnd),IDM_90,MF_BYCOMMAND |MF_UNCHECKED);
  CheckMenuItem(GetMenu(hwnd),IDM_180,MF_BYCOMMAND |MF_UNCHECKED);
  CheckMenuItem(GetMenu(hwnd),IDM_270,MF_BYCOMMAND |MF_UNCHECKED);
  CheckMenuItem(GetMenu(hwnd),IDM_NONE,MF_BYCOMMAND |MF_UNCHECKED);
  ZeroMemory(Ok,4);
}

/////////////////////////////////////////////////////////////////////////////
//
//  WinMain 
//
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
   MSG      msg;
   HWND     hWnd;         
   WNDCLASS myClass;  

    ZeroMemory(&myClass,sizeof(WNDCLASS));

    myClass.style         =CS_HREDRAW | CS_VREDRAW;    //ウインドウスタイルを設定 
    myClass.lpfnWndProc   =(WNDPROC)WindowProc;        //コールバックプロシージャへのポインタ
    myClass.hInstance     =hInstance;                  //インスタンスハンドルを設定
    myClass.hCursor       =LoadCursor(NULL, IDC_ARROW);//カーソルの設定(Windows標準リソースを使用)  
    myClass.hbrBackground =(HBRUSH)COLOR_WINDOW;       //ウインドウの背景を設定(デフォルトカラー)
    myClass.lpszClassName ="Programming Library";      //クラス名の設定  
    myClass.hIcon         =NULL;                       //アイコンの指定
    myClass.lpszMenuName  =MAKEINTRESOURCE(IDM_MENU);  //メニューの設定

    //ウィンドウ クラスを登録
    RegisterClass(&myClass); 

    //メインウインドウの生成
    hWnd=CreateWindowEx(
           WS_EX_CONTROLPARENT | WS_EX_WINDOWEDGE, //拡張ウインドウスタイル
           "Programming Library",                  //登録されたクラス名のアドレス 
           "グラフィックエフェクト- 90/180/270℃回転 -",     //ウインドウ名
           WS_OVERLAPPEDWINDOW,                    //ウインドウスタイルを設定
           ScreenCenterX(300),                     //X座標の位置設定
           ScreenCenterY(300),                     //Y座標の位置設定
           300,                                    //横幅を設定
           300,                                    //縦幅を設定
           NULL,                                   //親ウインドウを設定
           NULL,                                   //メニューを設定
           hInstance,                              //インスタンスを識別
           NULL);                                  //作成したウインドウに渡すデータへのポインタ
 
  //ウインドウの表示(表示方法はnCmdShowに従う)
  ShowWindow(hWnd, nCmdShow);

  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    TranslateMessage(&msg); 
    DispatchMessage(&msg);   
  } 
 return (msg.wParam);
}

/////////////////////////////////////////////////////////////////////////////
//
//  WindowProc 
//
LRESULT CALLBACK  WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{  
  int i;
  
  switch (uMsg)
    {
  case WM_CREATE:
         //ビットマップのロード
         hBitmap =(HBITMAP)LoadImage((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),"Sample96.bmp",IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); 
         if (hBitmap==NULL)
         {
          MessageBox(hwnd,"Sample96.bmpがありません。","エラー",MB_OK);
          PostQuitMessage(0);
         }
         else
         {
          //画像にエフェクトを施す 
          Turn(hwnd);         
         }
         break;
  case WM_PAINT:
        { 
          BITMAP      BMPINFO;    
          HDC         hMem,hDC;   
          HBRUSH      hBrush;
          RECT        Rect;
        
          //背景塗りつぶし
          hDC=GetDC(hwnd);
          hBrush=CreateSolidBrush(RGB(128,128,128));
          GetClientRect(hwnd,&Rect); 
          FillRect(hDC,&Rect,hBrush);
          DeleteObject(hBrush);
                  
                  if (Ok[0]==255)
                  {
                   //90℃回転を表示
                   GetObject(hTempBMP[0], sizeof(BITMAP), &BMPINFO);
                   BitBlt(hDC,0,0, BMPINFO.bmWidth,BMPINFO.bmHeight, hTempMem[0], 0, 0, SRCCOPY);
                  }
                  else if (Ok[1]==255)
                  {  
                   //180℃回転を表示
                   GetObject(hTempBMP[1], sizeof(BITMAP), &BMPINFO);
                   BitBlt(hDC,0,0, BMPINFO.bmWidth,BMPINFO.bmHeight, hTempMem[1], 0, 0, SRCCOPY);
                  }
                  else if (Ok[2]==255)
                  {  
                   //270℃回転を表示
                   GetObject(hTempBMP[2], sizeof(BITMAP), &BMPINFO);
                   BitBlt(hDC,0,0, BMPINFO.bmWidth,BMPINFO.bmHeight, hTempMem[2], 0, 0, SRCCOPY);
                  }
                  else
                  {
                   //ノーマル画像表示
                   GetObject(hBitmap, sizeof(BITMAP), &BMPINFO);
                   hMem = CreateCompatibleDC(hDC);
                   SelectObject(hMem, hBitmap);
                   BitBlt(hDC,0,0, BMPINFO.bmWidth,BMPINFO.bmHeight, hMem, 0, 0, SRCCOPY);
                   DeleteDC(hMem);    
                  }                  

                  ReleaseDC(hwnd,hDC);
                  return(DefWindowProc(hwnd, uMsg, wParam, lParam)); 
                  break;
        }
   case WM_COMMAND:
             switch(LOWORD(wParam))
             {
               case IDM_90 : 
                   AllOff(hwnd);
                   CheckMenuItem(GetMenu(hwnd),IDM_90,MF_BYCOMMAND |MF_CHECKED);
                   Ok[0]=255;
                   SendMessage(hwnd,WM_PAINT,0,0);
                   break;
              case IDM_180 : 
                   AllOff(hwnd);
                   CheckMenuItem(GetMenu(hwnd),IDM_180,MF_BYCOMMAND |MF_CHECKED);
                   Ok[1]=255;
                   SendMessage(hwnd,WM_PAINT,0,0);
                   break;
              case IDM_270 : 
                   AllOff(hwnd);
                   CheckMenuItem(GetMenu(hwnd),IDM_270,MF_BYCOMMAND |MF_CHECKED);
                   Ok[2]=255;
                   SendMessage(hwnd,WM_PAINT,0,0);
                   break;
               case IDM_NONE:
                   AllOff(hwnd);
                   CheckMenuItem(GetMenu(hwnd),IDM_NONE,MF_BYCOMMAND |MF_CHECKED);
                   Ok[3]=255;
                   SendMessage(hwnd,WM_PAINT,0,0);
                   break;
               case IDM_END:  
                   DeleteObject(hBitmap);    
                   for (i=0;i<3;i++)
                   {
                     DeleteObject(hTempBMP[i]);
                     DeleteObject(hTempMem[i]);
                   }
                   PostQuitMessage(0);
                   break;
               default :return(DefWindowProc(hwnd, uMsg, wParam, lParam)); 
             }
             break;      
   case WM_DESTROY:
             DeleteObject(hBitmap);
             for (i=0;i<3;i++)
             {
               DeleteObject(hTempBMP[i]);
               DeleteObject(hTempMem[i]);
             }             
             PostQuitMessage(0);
             break;
   default:return(DefWindowProc(hwnd, uMsg, wParam, lParam)); 
    }
  return (0);
}

ソースコード一式のダウンロード

capi_sample96.zip 37,454 バイト

動作環境

このサンプルは 「Windows98」及び「Microsoft Visual C++5.0」「Borland C++ Compiler 5.5」で確認しております。環境が異なる場合は正常に動作しない場合もございますのでご了承下さい。

Visual C++5.0でのコンパイル

VC5.0でサンプルをコンパイルする場合は新規プロジェクト(Win32Application)を作成後、各ファイルを追加してビルドしてください。

Borland C++ Compiler 5.5でのコンパイル

BCC5.5でサンプルをコンパイルする場合は「bcc32.exe」で*.c又は*.cppファイルをコンパイルします。リソースがある場合は「brc32.exe」で*resファイルを付与してください。

サンプルについて

このWindows APIサンプル集(C/C++版)は2000年頃にC/C++言語の学習の為に作成したものです。コードはエレガントではなく「初心者レベルのコーディング」です。仕事などの業務で利用する際にはエラー処理やメモリ解放などの再確認を必ずして下さい。





関連記事



公開日:2015年03月19日
記事NO:00552