@ -1286,6 +1286,10 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
switch ( uMsg )
{
case WM_COPY :
: : WindowProc ( hwnd , uMsg , wParam , lParam ) ; // call highgui proc. There may be a better way to do this.
break ;
case WM_DESTROY :
icvRemoveWindow ( window ) ;
@ -1448,6 +1452,81 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
// Process the message
switch ( uMsg )
{
case WM_COPY :
{
if ( ! : : OpenClipboard ( hwnd ) )
break ;
HDC hDC = 0 ;
HDC memDC = 0 ;
HBITMAP memBM = 0 ;
// We'll use a do-while(0){} scope as a single-run breakable scope
// Upon any error we can jump out of the single-time while scope to clean up the resources.
do
{
if ( ! : : EmptyClipboard ( ) )
break ;
if ( ! window - > image )
break ;
// Get window device context
if ( 0 = = ( hDC = : : GetDC ( hwnd ) ) )
break ;
// Create another DC compatible with hDC
if ( 0 = = ( memDC = : : CreateCompatibleDC ( hDC ) ) )
break ;
// Determine the bitmap's dimensions
int nchannels = 3 ;
SIZE size = { 0 , 0 } ;
icvGetBitmapData ( window , & size , & nchannels , 0 ) ;
// Create bitmap to draw on and it in the new DC
if ( 0 = = ( memBM = : : CreateCompatibleBitmap ( hDC , size . cx , size . cy ) ) )
break ;
if ( ! : : SelectObject ( memDC , memBM ) )
break ;
// Begin drawing to DC
if ( ! : : SetStretchBltMode ( memDC , COLORONCOLOR ) )
break ;
RGBQUAD table [ 256 ] ;
if ( 1 = = nchannels )
{
for ( int i = 0 ; i < 256 ; + + i )
{
table [ i ] . rgbBlue = ( unsigned char ) i ;
table [ i ] . rgbGreen = ( unsigned char ) i ;
table [ i ] . rgbRed = ( unsigned char ) i ;
}
if ( ! : : SetDIBColorTable ( window - > dc , 0 , 255 , table ) )
break ;
}
// The image copied to the clipboard will be in its original size, regardless if the window itself was resized.
// Render the image to the dc/bitmap (at original size).
if ( ! : : BitBlt ( memDC , 0 , 0 , size . cx , size . cy , window - > dc , 0 , 0 , SRCCOPY ) )
break ;
// Finally, set bitmap to clipboard
: : SetClipboardData ( CF_BITMAP , memBM ) ;
} while ( 0 , 0 ) ; // (0,0) instead of (0) to avoid MSVC compiler warning C4127: "conditional expression is constant"
//////////////////////////////////////////////////////////////////////////
// if handle is allocated (i.e. != 0) then clean-up.
if ( memBM ) : : DeleteObject ( memBM ) ;
if ( memDC ) : : DeleteDC ( memDC ) ;
if ( hDC ) : : ReleaseDC ( hwnd , hDC ) ;
: : CloseClipboard ( ) ;
break ;
}
case WM_WINDOWPOSCHANGING :
{
LPWINDOWPOS pos = ( LPWINDOWPOS ) lParam ;
@ -1798,6 +1877,11 @@ cvWaitKey( int delay )
is_processed = 1 ;
return ( int ) ( message . wParam < < 16 ) ;
}
// Intercept Ctrl+C for copy to clipboard
if ( ' C ' = = message . wParam & & ( : : GetKeyState ( VK_CONTROL ) > > 15 ) )
: : PostMessage ( message . hwnd , WM_COPY , 0 , 0 ) ;
default :
DispatchMessage ( & message ) ;
is_processed = 1 ;