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 + -
显示快捷键?