矩形で領域を選択


この画像は16色時代に MAG 形式で描かれた東京BBSのシカトミヨ氏の作品です。

画像を表示して、マウスのドラッグで矩形領域を選択します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. Image Object Class を使っています。
    ImgFile が表示する画像ファイルです。適当な画像を調達してきて下さい。
    bCap が矩形領域の設定が完了したフラグです。
    bBlock が矩形で領域を設定中のフラグで、マウスの移動によって矩形の大きさが変化します。
    beg, end, oldend は矩形の座標で、開始点,終了点,前回の座標です。
        IMAGE       *Img= NULL;             //IMAGE Object Class
        char        ImgFile[]= "c:\\data\\ffx2.jpg";
        BOOL        bCap=0;                 // 矩形が描画されている状態
        BOOL        bBlock=0;               // 矩形を描画中
        POINTS      beg, end, oldend;
        
  2. WinMain() はいつもと同じです。
  3. CALLBACK 関数です。
    WM_CREATE: で Image Object Class を初期化して画像を入力します。
        switch(msg)
        {   case WM_CREATE:
                Img= new IMAGE(hWnd);
                if (Img->LoadFile(ImgFile)==FALSE)
                {   SAFE_DELETE(Img);
                    PostMessage(hWnd,WM_CLOSE,0,0);
                }
                break;
        
  4. WM_PAINT: で画像を描画します。
    bCap が TRUE のときは画像に重ねて矩形を描画します。
            case WM_PAINT:
                hdc= BeginPaint(hWnd, &ps);
                if (Img)
                {   Img->Show(hdc);
                    if (bCap)   DrawRect(hWnd,beg,end);
                }
                EndPaint(hWnd, &ps);
                break;
        
  5. 左ボタンのクリックで矩形領域の設定を開始します。
    古い矩形が設定されているときは DrawRect() で消去してフラグをクリアします。
    DrawRect() は一度実行すると色を反転して矩形を描画し、同じ矩形をもう一度描くと元に戻ります。
    bBlock を TRUE にして矩形の設定を開始します。
    beg が矩形の開始座標です。
    SetCursor() で十字カーソルに設定してみました。
            case WM_LBUTTONDOWN:    // 左ボタンをクリック
                if (bCap)
                {   DrawRect(hWnd,beg,end); // 古い矩形を消す
                    bCap= FALSE;
                }
                bBlock = TRUE;
                beg = MAKEPOINTS(lParam);
                oldend = beg;
                DrawRect(hWnd, beg, oldend);
                SetCursor(LoadCursor(NULL, IDC_CROSS));
                break;
        
  6. WM_MOUSEMOVE: でマウスの移動に従い矩形を動かします。
    DrawRect(hWnd, beg, oldend); で古い矩形を消去して、DrawRect(hWnd, beg, end) で新しい矩形を描きます。
            case WM_MOUSEMOVE:
                if(bBlock)
                {   end = MAKEPOINTS(lParam);
                    DrawRect(hWnd, beg, oldend);
                    DrawRect(hWnd, beg, end);
                    oldend = end;
                }
                break;
        
  7. WM_LBUTTONUP で矩形を確定します。
    beg が矩形の開始座標で、end が矩形の終了座標です。
            case WM_LBUTTONUP:      // 矩形が確定
                if  (bBlock)
                {   bBlock= FALSE;
                    bCap= TRUE;
                    SetCursor(LoadCursor(NULL, IDC_ARROW));
                    end = MAKEPOINTS(lParam);
                    DrawRect(hWnd, beg, oldend);
                    DrawRect(hWnd, beg, end);
                    InvalidateRect(hWnd, NULL, TRUE);
                }
                break;
        
  8. 右ボタンのクリックで矩形を取り消します。
            case WM_RBUTTONDOWN:    // 右ボタンで矩形の取り消し
                bBlock= FALSE;
                bCap= FALSE;
                InvalidateRect(hWnd, NULL, TRUE);
                break;
        
  9. 矩形を描く DrawRect() 関数です。
    一度実行すると色を反転して矩形を描画し、同じ矩形をもう一度描くと元に戻ります。
    マウスで選択した範囲を拡大して描画するプログラムを Image Big に掲載しています。
        //★ 矩形を表示する
        void  DrawRect(HWND hWnd, POINTS beg, POINTS end)
        {   HDC     hdc;
            HPEN    hPen;
            int     old;
    
            hdc = GetDC(hWnd);
            old= SetROP2(hdc, R2_NOT);
            hPen = CreatePen(PS_SOLID,2,RGB(0,0,0));
            SelectObject(hdc, hPen);
            MoveToEx(hdc, beg.x, beg.y, NULL);
            LineTo(hdc, end.x, beg.y);
            LineTo(hdc, end.x, end.y);
            LineTo(hdc, beg.x, end.y);
            LineTo(hdc, beg.x, beg.y);
            DeleteObject(hPen);
            SetROP2(hdc, old);
            ReleaseDC(hWnd, hdc);
        }
        

超初心者のプログラム入門(Win32API C++)