提交 00263dd6 编写于 作者: V Vadim Pisarevsky

Merge pull request #2179 from adishavit:feature-SupportClipboardCopyOnWindows

......@@ -83,6 +83,9 @@ If window was created with OpenGL support, ``imshow`` also support :ocv:class:`o
.. note:: This function should be followed by ``waitKey`` function which displays the image for specified milliseconds. Otherwise, it won't display the image. For example, ``waitKey(0)`` will display the window infinitely until any keypress (it is suitable for image display). ``waitKey(25)`` will display a frame for 25 ms, after which display will be automatically closed. (If you put it in a loop to read videos, it will display the video frame-by-frame)
.. note::
[Windows Backend Only] Pressing Ctrl+C will copy the image to the clipboard.
namedWindow
---------------
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册