[HighGUI] On Windows: Support Ctrl+C to copy image to clipboard.
This commit is contained in:
@@ -1286,6 +1286,10 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|||||||
|
|
||||||
switch(uMsg)
|
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:
|
case WM_DESTROY:
|
||||||
|
|
||||||
icvRemoveWindow(window);
|
icvRemoveWindow(window);
|
||||||
@@ -1448,6 +1452,81 @@ static LRESULT CALLBACK HighGUIProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
|||||||
// Process the message
|
// Process the message
|
||||||
switch(uMsg)
|
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.
|
||||||
|
memBM && ::DeleteObject(memBM);
|
||||||
|
memDC && ::DeleteDC(memDC);
|
||||||
|
hDC && ::ReleaseDC(hwnd, hDC);
|
||||||
|
::CloseClipboard();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_WINDOWPOSCHANGING:
|
case WM_WINDOWPOSCHANGING:
|
||||||
{
|
{
|
||||||
LPWINDOWPOS pos = (LPWINDOWPOS)lParam;
|
LPWINDOWPOS pos = (LPWINDOWPOS)lParam;
|
||||||
@@ -1798,6 +1877,11 @@ cvWaitKey( int delay )
|
|||||||
is_processed = 1;
|
is_processed = 1;
|
||||||
return (int)(message.wParam << 16);
|
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:
|
default:
|
||||||
DispatchMessage(&message);
|
DispatchMessage(&message);
|
||||||
is_processed = 1;
|
is_processed = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user