window_w32.cpp.svn-base

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

SVN-BASE
1,334
字号
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "_highgui.h"

#ifdef WIN32

#if _MSC_VER >= 1200
#pragma warning( disable: 4710 )
#endif

#include "commctrl.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

struct CvWindow;

typedef struct CvTrackbar
{
    int signature;
    HWND hwnd;
    char* name;
    CvTrackbar* next;
    CvWindow* parent;
    HWND buddy;
    int* data;
    int pos;
    int maxval;
    void (*notify)(int);
    int id;
}
CvTrackbar;


typedef struct CvWindow
{
    int signature;
    HWND hwnd;
    char* name;
    CvWindow* prev;
    CvWindow* next;
    HWND frame;

    HDC dc;
    HGDIOBJ image;
    int last_key;
    int flags;

    CvMouseCallback on_mouse;

    struct
    {
        HWND toolbar;
        int pos;
        int rows;
        WNDPROC toolBarProc;
        CvTrackbar* first;
    }
    toolbar;
}
CvWindow;


void  FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp, int origin )
{
    assert( bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));

    BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);

    memset( bmih, 0, sizeof(*bmih));
    bmih->biSize = sizeof(BITMAPINFOHEADER); 
    bmih->biWidth = width;
    bmih->biHeight = origin ? abs(height) : -abs(height);
    bmih->biPlanes = 1; 
    bmih->biBitCount = (unsigned short)bpp;
    bmih->biCompression = BI_RGB;

    if( bpp == 8 )
    {
        RGBQUAD* palette = bmi->bmiColors;
        int i;
        for( i = 0; i < 256; i++ )
        {
            palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
            palette[i].rgbReserved = 0;
        }
    }
}


#define HG_BUDDY_WIDTH  130

#ifndef TBIF_SIZE
    #define TBIF_SIZE  0x40
#endif

#ifndef TB_SETBUTTONINFO
    #define TB_SETBUTTONINFO (WM_USER + 66)
#endif

#ifndef TBM_GETTOOLTIPS
    #define TBM_GETTOOLTIPS  (WM_USER + 30)
#endif

static LRESULT CALLBACK HighGUIProc(  HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WindowProc(  HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK MainWindowProc(  HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static void icvUpdateWindowPos( CvWindow* window );

static CvWindow* hg_windows = 0;
static CvWin32WindowCallback hg_on_preprocess = 0, hg_on_postprocess = 0;
static HINSTANCE hg_hinstance = 0;

HIGHGUI_IMPL int cvInitSystem( int, char** )
{
    static int wasInitialized = 0;    

    // check initialization status
    if( !wasInitialized )
    {
        // Initialize the stogare
        hg_windows = 0;
        
        // Register the class
        WNDCLASS wndc;
        wndc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
        wndc.lpfnWndProc = WindowProc;
        wndc.cbClsExtra = 0;
        wndc.cbWndExtra = 0;
        wndc.hInstance = hg_hinstance;
        wndc.lpszClassName = "HighGUI class";
        wndc.lpszMenuName = "HighGUI class";
        wndc.hIcon = LoadIcon(0, IDI_APPLICATION); 
        wndc.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_CROSS));
        wndc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);  

        RegisterClass(&wndc);

        wndc.lpszClassName = "Main HighGUI class";
        wndc.lpszMenuName = "Main HighGUI class";
        wndc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
        wndc.lpfnWndProc = MainWindowProc;

        RegisterClass(&wndc);

        wasInitialized = 1;
    }

    return HG_OK;
}

static CvWindow* icvFindWindowByName( const char* name )
{
    CvWindow* window = hg_windows;

    for( ; window != 0 && strcmp( name, window->name) != 0; window = window->next )
        ;

    return window;
}

static CvWindow* icvWindowByHWND( HWND hwnd )
{
    CvWindow* window = (CvWindow*)GetWindowLong( hwnd, GWL_USERDATA );
    return window != 0 && window->signature == HG_WINDOW_SIGNATURE ? window : 0;
}


static CvTrackbar* icvTrackbarByHWND( HWND hwnd )
{
    CvTrackbar* trackbar = (CvTrackbar*)GetWindowLong( hwnd, GWL_USERDATA );
    return trackbar != 0 && trackbar->signature == HG_TRACKBAR_SIGNATURE &&
           trackbar->hwnd == hwnd ? trackbar : 0;    
}



HIGHGUI_IMPL int cvNamedWindow( const char* name, int flags )
{
    int result = 0;
    CV_FUNCNAME( "cvNamedWindow" );

    __BEGIN__;

    HWND hWnd, mainhWnd;
    CvWindow* window;
    DWORD defStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
    int len;

    cvInitSystem(0,0);

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

    // Check the name in the storage
    if( icvFindWindowByName( name ) != 0 )
    {
        result = 1;
        EXIT;
    }

    if( (flags & HG_AUTOSIZE) == 0 )
        defStyle |= WS_SIZEBOX;

    mainhWnd = CreateWindow( "Main HighGUI class", name, defStyle | WS_OVERLAPPED,
                             CW_USEDEFAULT, 0, 320, 320, 0, 0, hg_hinstance, 0 );
    if( !mainhWnd )
        CV_ERROR( CV_StsError, "Frame window can not be created" );

    ShowWindow(mainhWnd, SW_SHOW);

    hWnd = CreateWindow("HighGUI class", "", defStyle | WS_CHILD | WS_SIZEBOX, 
                        CW_USEDEFAULT, 0, 320, 320, mainhWnd, 0, hg_hinstance, 0);
    if( !hWnd )
        CV_ERROR( CV_StsError, "Frame window can not be created" );

    ShowWindow(hWnd, SW_SHOW);

    len = strlen(name);
    CV_CALL( window = (CvWindow*)cvAlloc(sizeof(CvWindow) + len + 1));

    window->signature = HG_WINDOW_SIGNATURE;
    window->hwnd = hWnd;
    window->frame = mainhWnd;
    window->name = (char*)(window + 1);
    memcpy( window->name, name, len + 1 );
    window->flags = flags;
    window->image = 0;
    window->dc = CreateCompatibleDC(0);
    window->last_key = 0;
    
    window->on_mouse = 0;

    memset( &window->toolbar, 0, sizeof(window->toolbar));

    window->next = hg_windows;
    window->prev = 0;
    if( hg_windows )
        hg_windows->prev = window;
    hg_windows = window;
    SetWindowLong( hWnd, GWL_USERDATA, (long)window );
    SetWindowLong( mainhWnd, GWL_USERDATA, (long)window );

    // Recalculate window position
    icvUpdateWindowPos( window );

    result = 1;
    __END__;

    return result;
}


static void icvRemoveWindow( CvWindow* window )
{
    CvTrackbar* trackbar;

    SetWindowLong( window->hwnd, GWL_USERDATA, (long)0 );
    SetWindowLong( window->frame, GWL_USERDATA, (long)0 );
    
    if( window->prev )
        window->prev->next = window->next;
    else
        hg_windows = window->next;

    if( window->next )
        window->next->prev = window->prev;

    window->prev = window->next = 0;

    if( window->image )
        DeleteObject(SelectObject(window->dc,window->image));

    if( window->dc )
        DeleteDC(window->dc);

    for( trackbar = window->toolbar.first; trackbar != 0; )
    {
        CvTrackbar* next = trackbar->next;
        cvFree( (void**)&trackbar );
        trackbar = next;
    }

    cvFree( (void**)&window );
}


HIGHGUI_IMPL void cvDestroyWindow( const char* name )
{
    CV_FUNCNAME( "cvDestroyWindow" );
    
    __BEGIN__;

    CvWindow* window;
    HWND mainhWnd;

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

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

    mainhWnd = window->frame;
    SendMessage(window->hwnd, WM_CLOSE, 0, 0);
    SendMessage( mainhWnd, WM_CLOSE, 0, 0);
    // Do NOT call _remove_window -- CvWindow list will be updated automatically ...

    __END__;
}


static void icvScreenToClient( HWND hwnd, RECT* rect )
{
    POINT p;
    p.x = rect->left;
    p.y = rect->top;
    ScreenToClient(hwnd, &p);
    OffsetRect( rect, p.x - rect->left, p.y - rect->top );
}


/* Calculatess the window coordinates relative to the upper left corner of the mainhWnd window */
static RECT icvCalcWindowRect( CvWindow* window )
{
    const int gutter = 1;
    RECT crect, trect, rect;

    assert(window);

    GetClientRect(window->frame, &crect);
    if(window->toolbar.toolbar)
    {
        GetWindowRect(window->toolbar.toolbar, &trect);
        icvScreenToClient(window->frame, &trect);
        SubtractRect( &rect, &crect, &trect);
    }
    else
        rect = crect;

    rect.top += gutter;
    rect.left += gutter;
    rect.bottom -= gutter;
    rect.right -= gutter;

    return rect;
}


static void icvGetBitmapData( CvWindow* window, SIZE* size, int* channels, void** data )
{
    BITMAP bmp;
    GetObject( GetCurrentObject( window->dc, OBJ_BITMAP ), sizeof(bmp), &bmp );

    if( size )
    {
        size->cx = abs(bmp.bmWidth);
        size->cy = abs(bmp.bmHeight);
    }

    if( channels )
        *channels = bmp.bmBitsPixel/8;

    if( data )
        *data = bmp.bmBits;
}


static void icvUpdateWindowPos( CvWindow* window )
{
    RECT rect;
    assert(window);

    if( (window->flags & HG_AUTOSIZE) && window->image )
    {
        int i;
        SIZE size;
        icvGetBitmapData( window, &size, 0, 0 );

        // 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++)
        {
            RECT rmw, 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 + size.cx - rw.right + rw.left, 
                rmw.bottom  - rmw.top + size.cy - 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 );
}


HIGHGUI_IMPL void
cvShowImage( const char* name, const CvArr* arr )
{

⌨️ 快捷键说明

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