window_w32.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 1,334 行 · 第 1/3 页

SVN-BASE
1,334
字号
    CV_FUNCNAME( "cvShowImage" );

    __BEGIN__;
    
    CvWindow* window;
    SIZE size = { 0, 0 };
    int channels = 0;
    void* dst_ptr = 0;
    const int channels0 = 3;
    int origin = 0;
    CvMat stub, dst, *image;

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name" );

    window = icvFindWindowByName(name);
    if( !window || !arr )
        EXIT; // keep silence here.

    if( CV_IS_IMAGE_HDR( arr ))
        origin = ((IplImage*)arr)->origin;

    CV_CALL( image = cvGetMat( arr, &stub ));

    if( window->image )
        icvGetBitmapData( window, &size, &channels, &dst_ptr );

    if( size.cx != image->width || size.cy != image->height || channels != channels0 )
    {
        uchar buffer[sizeof(BITMAPINFO) + 255*sizeof(RGBQUAD)];
        BITMAPINFO* binfo = (BITMAPINFO*)buffer;
        
        DeleteObject( SelectObject( window->dc, window->image ));
        window->image = 0;

        size.cx = image->width;
        size.cy = image->height;
        channels = channels0;

        FillBitmapInfo( binfo, size.cx, size.cy, channels*8, 1 );

        window->image = SelectObject( window->dc, CreateDIBSection(window->dc, binfo,
                                      DIB_RGB_COLORS, &dst_ptr, 0, 0));
    }

    cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3,
                     dst_ptr, (size.cx * channels + 3) & -4 );
    cvConvertImage( image, &dst, origin == 0 );
    
    icvUpdateWindowPos(window);
    InvalidateRect(window->hwnd, 0, 0);
    UpdateWindow(window->hwnd);

    __END__;
}


HIGHGUI_IMPL void cvResizeWindow(const char* name, int width, int height )
{
    CV_FUNCNAME( "cvResizeWindow" );

    __BEGIN__;
    
    int i;
    CvWindow* window;
    RECT rmw, rw, rect;

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name" );

    window = icvFindWindowByName(name);
    if(!window)
        EXIT;

    // Repeat two times because after the first resizing of the mainhWnd window
    // toolbar may resize too
    for(i = 0; i < (window->toolbar.toolbar ? 2 : 1); i++)
    {
        rw = icvCalcWindowRect(window);
        MoveWindow(window->hwnd, rw.left, rw.top,
            rw.right - rw.left + 1, rw.bottom - rw.top + 1, FALSE);
        GetClientRect(window->hwnd, &rw);
        GetWindowRect(window->frame, &rmw);
        // Resize the mainhWnd window in order to make the bitmap fit into the child window
        MoveWindow(window->frame, rmw.left, rmw.top,
            rmw.right - rmw.left + width - rw.right + rw.left,
            rmw.bottom  - rmw.top + height - rw.bottom + rw.top, TRUE);
    }

    rect = icvCalcWindowRect(window);
    MoveWindow(window->hwnd, rect.left, rect.top,
        rect.right - rect.left + 1, rect.bottom - rect.top + 1, TRUE);

    __END__;
}


HIGHGUI_IMPL void cvMoveWindow( const char* name, int x, int y )
{
    CV_FUNCNAME( "cvMoveWindow" );

    __BEGIN__;

    CvWindow* window;
    RECT rect;

    if( !name )
        CV_ERROR( CV_StsNullPtr, "NULL name" );

    window = icvFindWindowByName(name);
    if(!window)
        EXIT;

    GetWindowRect( window->frame, &rect );
    MoveWindow( window->frame, x, y, rect.right - rect.left, rect.bottom - rect.top, FALSE );

    __END__;
}


static LRESULT CALLBACK
MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    CvWindow* window = icvWindowByHWND( hwnd );
    if( !window )
        return DefWindowProc(hwnd, uMsg, wParam, lParam);

    switch(uMsg)
    {
    case WM_DESTROY:
        icvRemoveWindow(window);
        // Do nothing!!!
        //PostQuitMessage(0);
        break;

    case WM_GETMINMAXINFO:
        if( !(window->flags & HG_AUTOSIZE) )
        {
            MINMAXINFO* minmax = (MINMAXINFO*)lParam;
            RECT rect;
            LRESULT retval = DefWindowProc(hwnd, uMsg, wParam, lParam);

            minmax->ptMinTrackSize.y = 100;
            minmax->ptMinTrackSize.x = 100;

            if( window->toolbar.first )
            {
                GetWindowRect( window->toolbar.first->hwnd, &rect );
                minmax->ptMinTrackSize.y += window->toolbar.rows*(rect.bottom - rect.top);
                minmax->ptMinTrackSize.x = rect.right - rect.left + HG_BUDDY_WIDTH;
            }
            return retval;
        }
        break;

    case WM_WINDOWPOSCHANGED:
        {
            WINDOWPOS* pos = (WINDOWPOS*)lParam;

            // Update the toolbar position/size
            if(window->toolbar.toolbar)
            {
                RECT rect;
                GetWindowRect(window->toolbar.toolbar, &rect);
                MoveWindow(window->toolbar.toolbar, 0, 0, pos->cx, rect.bottom - rect.top, TRUE);
            }

            if(!(window->flags & HG_AUTOSIZE))
                icvUpdateWindowPos(window);
            
            break;
        }

    case WM_ACTIVATE:
        if(LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
            SetFocus(window->hwnd);
        break;

    case WM_ERASEBKGND:
        {
            RECT cr, tr, wrc;
            HRGN rgn, rgn1, rgn2;
            int ret;
            HDC hdc = (HDC)wParam;
            GetWindowRect(window->hwnd, &cr);
            icvScreenToClient(window->frame, &cr);
            if(window->toolbar.toolbar)
            {
                GetWindowRect(window->toolbar.toolbar, &tr);
                icvScreenToClient(window->frame, &tr);
            }
            else
                tr.left = tr.top = tr.right = tr.bottom = 0;

            GetClientRect(window->frame, &wrc);

            rgn = CreateRectRgn(0, 0, wrc.right, wrc.bottom);
            rgn1 = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
            rgn2 = CreateRectRgn(tr.left, tr.top, tr.right, tr.bottom);
            ret = CombineRgn(rgn, rgn, rgn1, RGN_DIFF);
            ret = CombineRgn(rgn, rgn, rgn2, RGN_DIFF);

            if(ret != NULLREGION && ret != ERROR)
                FillRgn(hdc, rgn, (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND));
        }
        return 1;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}


static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    CvWindow* window = icvWindowByHWND(hwnd);
    if( !window )
        // This window is not mentioned in HighGUI storage
        // Actually, this should be error except for the case of calls to CreateWindow
        return DefWindowProc(hwnd, uMsg, wParam, lParam);

    // Process the message
    switch(uMsg)
    {
    case WM_WINDOWPOSCHANGING:
        {
            LPWINDOWPOS pos = (LPWINDOWPOS)lParam;
            RECT rect = icvCalcWindowRect(window);
            pos->x = rect.left;
            pos->y = rect.top;
            pos->cx = rect.right - rect.left + 1;
            pos->cy = rect.bottom - rect.top + 1;
        }
        break;

    case WM_LBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
    case WM_RBUTTONDBLCLK:
    case WM_MBUTTONDBLCLK:
    case WM_LBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MBUTTONUP:
    case WM_MOUSEMOVE:
        if( window->on_mouse )
        {
            POINT pt;
            RECT rect;
            SIZE size;

            int flags = (wParam & MK_LBUTTON ? CV_EVENT_FLAG_LBUTTON : 0)|
                        (wParam & MK_RBUTTON ? CV_EVENT_FLAG_RBUTTON : 0)|
                        (wParam & MK_MBUTTON ? CV_EVENT_FLAG_MBUTTON : 0)|
                        (wParam & MK_CONTROL ? CV_EVENT_FLAG_SHIFTKEY : 0)|
                        (wParam & MK_SHIFT ? CV_EVENT_FLAG_CTRLKEY : 0)|
                        (GetKeyState(VK_MENU) < 0 ? CV_EVENT_FLAG_ALTKEY : 0);
            int event = uMsg == WM_LBUTTONDOWN ? CV_EVENT_LBUTTONDOWN :
                        uMsg == WM_RBUTTONDOWN ? CV_EVENT_RBUTTONDOWN :
                        uMsg == WM_MBUTTONDOWN ? CV_EVENT_MBUTTONDOWN :
                        uMsg == WM_LBUTTONUP ? CV_EVENT_LBUTTONUP :
                        uMsg == WM_RBUTTONUP ? CV_EVENT_RBUTTONUP :
                        uMsg == WM_MBUTTONUP ? CV_EVENT_MBUTTONUP :
                        uMsg == WM_LBUTTONDBLCLK ? CV_EVENT_LBUTTONDBLCLK :
                        uMsg == WM_RBUTTONDBLCLK ? CV_EVENT_RBUTTONDBLCLK :
                        uMsg == WM_MBUTTONDBLCLK ? CV_EVENT_MBUTTONDBLCLK :
                                                   CV_EVENT_MOUSEMOVE;
            if( uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN )
                SetCapture( hwnd );
            if( uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_MBUTTONUP )
                ReleaseCapture();

            pt.x = LOWORD( lParam );
            pt.y = HIWORD( lParam );

            GetClientRect( window->hwnd, &rect );
            icvGetBitmapData( window, &size, 0, 0 );
            
            window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1),
                                     pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags );
        }
        break;

    case WM_PAINT:
        if(window->image != 0)
        {
            int nchannels = 3;
            SIZE size;
            PAINTSTRUCT paint;
            HDC hdc;
            RGBQUAD table[256];

            // Determine the bitmap's dimensions
            icvGetBitmapData( window, &size, &nchannels, 0 );

            BeginPaint(hwnd, &paint);
            hdc = paint.hdc;
            SetStretchBltMode(hdc, COLORONCOLOR);

            if( nchannels == 1 )
            {
                int i;
                for(i = 0; i < 256; i++)
                {
                    table[i].rgbBlue = (unsigned char)i;
                    table[i].rgbGreen = (unsigned char)i;
                    table[i].rgbRed = (unsigned char)i;
                }
                SetDIBColorTable(window->dc, 0, 255, table);
            }

            if(window->flags & HG_AUTOSIZE)
            {
                BitBlt( hdc, 0, 0, size.cx, size.cy, window->dc, 0, 0, SRCCOPY );
            }
            else
            {
                RECT rect;
                GetClientRect(window->hwnd, &rect);
                StretchBlt( hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
                            window->dc, 0, 0, size.cx, size.cy, SRCCOPY );
            }
            DeleteDC(hdc);
            EndPaint(hwnd, &paint);
        }
        else
        {
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
        }
        return 0;

    case WM_ERASEBKGND:
        if(window->image)
            return 0;
        break;
        
    case WM_DESTROY:
        icvRemoveWindow(window);
        // Do nothing!!!
        //PostQuitMessage(0);
        break;

    case WM_SETCURSOR:
        SetCursor((HCURSOR)GetClassLong(hwnd, GCL_HCURSOR));
        return 0;

    case WM_KEYDOWN:
        window->last_key = (int)wParam;
        return 0;
    }
    
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
};


static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    int ret;
    
    if( hg_on_preprocess )
    {
        int was_processed = 0;
        int ret = hg_on_preprocess(hwnd, uMsg, wParam, lParam, &was_processed);
        if(was_processed)
            return ret;
    }
    
    ret = HighGUIProc(hwnd, uMsg, wParam, lParam);
    if(hg_on_postprocess)
    {
        int was_processed = 0;
        int ret = hg_on_postprocess(hwnd, uMsg, wParam, lParam, &was_processed);
        if(was_processed)
            return ret;
    }
    
    return ret;
}


static void icvUpdateTrackbar( CvTrackbar* trackbar, int pos )
{
    const int max_name_len = 10;
    const char* suffix = "";
    char pos_text[32];
    int name_len;

    if( trackbar->data )
        *trackbar->data = pos;

    if( trackbar->pos != pos )
    {
        trackbar->pos = pos;
        if( trackbar->notify )
            trackbar->notify(pos);

        name_len = strlen(trackbar->name);

        if( name_len > max_name_len )
        {
            int start_len = max_name_len*2/3;
            int end_len = max_name_len - start_len - 2;
            memcpy( pos_text, trackbar->name, start_len );
            memcpy( pos_text + start_len, "...", 3 );
            memcpy( pos_text + start_len + 3, trackbar->name + name_len - end_len, end_len + 1 );
        }
        else
        {
            memcpy( pos_text, trackbar->name, name_len + 1);
        }

        sprintf( pos_text + strlen(pos_text), "%s: %d\n", suffix, pos );
        SetWindowText( trackbar->buddy, pos_text );
    }
}


static LRESULT CALLBACK HGToolbarProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    CvWindow* window = icvWindowByHWND( hwnd );
    if(!window)
        return DefWindowProc(hwnd, uMsg, wParam, lParam);

    // Control messages processing
    switch(uMsg)
    {
    // Slider processing
    case WM_HSCROLL:
        {
            HWND slider = (HWND)lParam;
            int pos = SendMessage(slider, TBM_GETPOS, 0, 0);
            CvTrackbar* trackbar = icvTrackbarByHWND( slider );

            if( trackbar )
            {
                if( trackbar->pos != pos )
                    icvUpdateTrackbar( trackbar, pos );
            }

            SetFocus( window->hwnd );
            return 0;
        }

    case WM_NCCALCSIZE:
        {
            LRESULT ret = CallWindowProc(window->toolbar.toolBarProc, hwnd, uMsg, wParam, lParam);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?