提交 9d227641 编写于 作者: A Alexander Alekhin

Merge pull request #19411 from crackwitz:highgui-pollkey

...@@ -348,23 +348,34 @@ The function waitKey waits for a key event infinitely (when \f$\texttt{delay}\le ...@@ -348,23 +348,34 @@ The function waitKey waits for a key event infinitely (when \f$\texttt{delay}\le
milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the
function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is
running on your computer at that time. It returns the code of the pressed key or -1 if no key was running on your computer at that time. It returns the code of the pressed key or -1 if no key was
pressed before the specified time had elapsed. pressed before the specified time had elapsed. To check for a key press but not wait for it, use
#pollKey.
@note @note The functions #waitKey and #pollKey are the only methods in HighGUI that can fetch and handle
GUI events, so one of them needs to be called periodically for normal event processing unless
This function is the only method in HighGUI that can fetch and handle events, so it needs to be HighGUI is used within an environment that takes care of event processing.
called periodically for normal event processing unless HighGUI is used within an environment that
takes care of event processing.
@note @note The function only works if there is at least one HighGUI window created and the window is
active. If there are several HighGUI windows, any of them can be active.
The function only works if there is at least one HighGUI window created and the window is active.
If there are several HighGUI windows, any of them can be active.
@param delay Delay in milliseconds. 0 is the special value that means "forever". @param delay Delay in milliseconds. 0 is the special value that means "forever".
*/ */
CV_EXPORTS_W int waitKey(int delay = 0); CV_EXPORTS_W int waitKey(int delay = 0);
/** @brief Polls for a pressed key.
The function pollKey polls for a key event without waiting. It returns the code of the pressed key
or -1 if no key was pressed since the last invocation. To wait until a key was pressed, use #waitKey.
@note The functions #waitKey and #pollKey are the only methods in HighGUI that can fetch and handle
GUI events, so one of them needs to be called periodically for normal event processing unless
HighGUI is used within an environment that takes care of event processing.
@note The function only works if there is at least one HighGUI window created and the window is
active. If there are several HighGUI windows, any of them can be active.
*/
CV_EXPORTS_W int pollKey();
/** @brief Displays an image in the specified window. /** @brief Displays an image in the specified window.
The function imshow displays an image in the specified window. If the window was created with the The function imshow displays an image in the specified window. If the window was created with the
...@@ -384,11 +395,12 @@ If the window was not created before this function, it is assumed creating a win ...@@ -384,11 +395,12 @@ If the window was not created before this function, it is assumed creating a win
If you need to show an image that is bigger than the screen resolution, you will need to call namedWindow("", WINDOW_NORMAL) before the imshow. If you need to show an image that is bigger than the screen resolution, you will need to call namedWindow("", WINDOW_NORMAL) before the imshow.
@note This function should be followed by cv::waitKey function which displays the image for specified @note This function should be followed by a call to cv::waitKey or cv::pollKey to perform GUI
milliseconds. Otherwise, it won't display the image. For example, **waitKey(0)** will display the window housekeeping tasks that are necessary to actually show the given image and make the window respond
infinitely until any keypress (it is suitable for image display). **waitKey(25)** will display a frame to mouse and keyboard events. Otherwise, it won't display the image and the window might lock up.
for 25 ms, after which display will be automatically closed. (If you put it in a loop to read For example, **waitKey(0)** will display the window infinitely until any keypress (it is suitable
videos, it will display the video frame-by-frame) for image display). **waitKey(25)** will display a frame and wait approximately 25 ms for a key
press (suitable for displaying a video frame-by-frame). To remove the window, use cv::destroyWindow.
@note @note
......
...@@ -297,6 +297,8 @@ int cv::waitKey(int delay) ...@@ -297,6 +297,8 @@ int cv::waitKey(int delay)
return (code != -1) ? (code & 0xff) : -1; return (code != -1) ? (code & 0xff) : -1;
} }
// NOTE: cv::pollKey has no C API equivalent. it is implemented in each backend source file.
int cv::createTrackbar(const String& trackbarName, const String& winName, int cv::createTrackbar(const String& trackbarName, const String& winName,
int* value, int count, TrackbarCallback callback, int* value, int count, TrackbarCallback callback,
void* userdata) void* userdata)
......
...@@ -382,6 +382,13 @@ CV_IMPL int cvWaitKey(int delay) ...@@ -382,6 +382,13 @@ CV_IMPL int cvWaitKey(int delay)
} }
int cv::pollKey()
{
CV_TRACE_FUNCTION();
// fallback. please implement a proper polling function
return cvWaitKey(1);
}
//Yannick Verdie //Yannick Verdie
//This function is experimental and some functions (such as cvSet/getWindowProperty will not work) //This function is experimental and some functions (such as cvSet/getWindowProperty will not work)
//We recommend not using this function for now //We recommend not using this function for now
......
...@@ -632,6 +632,13 @@ CV_IMPL int cvWaitKey (int maxWait) ...@@ -632,6 +632,13 @@ CV_IMPL int cvWaitKey (int maxWait)
return returnCode; return returnCode;
} }
int cv::pollKey()
{
CV_TRACE_FUNCTION();
// fallback. please implement a proper polling function
return cvWaitKey(1);
}
CvRect cvGetWindowRect_COCOA( const char* name ) CvRect cvGetWindowRect_COCOA( const char* name )
{ {
CvRect result = cvRect(-1, -1, -1, -1); CvRect result = cvRect(-1, -1, -1, -1);
......
...@@ -1950,6 +1950,13 @@ CV_IMPL int cvWaitKey( int delay ) ...@@ -1950,6 +1950,13 @@ CV_IMPL int cvWaitKey( int delay )
return last_key; return last_key;
} }
int cv::pollKey()
{
CV_TRACE_FUNCTION();
// fallback. please implement a proper polling function
return cvWaitKey(1);
}
#endif // HAVE_GTK #endif // HAVE_GTK
#endif // _WIN32 #endif // _WIN32
......
...@@ -2064,6 +2064,97 @@ static void showSaveDialog(CvWindow* window) ...@@ -2064,6 +2064,97 @@ static void showSaveDialog(CvWindow* window)
} }
} }
/*
* message received. check if it belongs to our windows (frame, hwnd).
* returns true (and value in keyCode) if a key was pressed.
* otherwise returns false (indication to continue event loop).
*/
static bool handleMessage(MSG& message, int& keyCode)
{
// whether we have to call translate and dispatch yet
// otherwise the message was handled specifically
bool is_processed = false;
for (CvWindow* window = hg_windows; window != 0 && is_processed == 0; window = window->next)
{
if (!(window->hwnd == message.hwnd || window->frame == message.hwnd))
continue;
is_processed = true;
switch (message.message)
{
case WM_DESTROY:
case WM_CHAR:
DispatchMessage(&message);
keyCode = (int)message.wParam;
return true;
case WM_SYSKEYDOWN:
if (message.wParam == VK_F10)
{
is_processed = true;
keyCode = (int)(message.wParam << 16);
return true;
}
break;
case WM_KEYDOWN:
TranslateMessage(&message);
if ((message.wParam >= VK_F1 && message.wParam <= VK_F24) ||
message.wParam == VK_HOME || message.wParam == VK_END ||
message.wParam == VK_UP || message.wParam == VK_DOWN ||
message.wParam == VK_LEFT || message.wParam == VK_RIGHT ||
message.wParam == VK_INSERT || message.wParam == VK_DELETE ||
message.wParam == VK_PRIOR || message.wParam == VK_NEXT)
{
DispatchMessage(&message);
is_processed = true;
keyCode = (int)(message.wParam << 16);
return true;
}
// Intercept Ctrl+C for copy to clipboard
if ('C' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15))
::SendMessage(message.hwnd, WM_COPY, 0, 0);
// Intercept Ctrl+S for "save as" dialog
if ('S' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15))
showSaveDialog(window);
default:
DispatchMessage(&message);
is_processed = true;
break;
}
}
if (!is_processed)
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return false; // no value to return, keep processing
}
/*
* process until queue is empty but don't wait.
*/
int cv::pollKey()
{
CV_TRACE_FUNCTION();
for(;;)
{
MSG message;
if (PeekMessage(&message, 0, 0, 0, PM_REMOVE) == FALSE)
return -1;
int keyCode = -1;
if (handleMessage(message, keyCode))
return keyCode;
}
}
CV_IMPL int CV_IMPL int
cvWaitKey( int delay ) cvWaitKey( int delay )
{ {
...@@ -2072,9 +2163,7 @@ cvWaitKey( int delay ) ...@@ -2072,9 +2163,7 @@ cvWaitKey( int delay )
for(;;) for(;;)
{ {
CvWindow* window;
MSG message; MSG message;
int is_processed = 0;
if( (delay <= 0) && hg_windows) if( (delay <= 0) && hg_windows)
GetMessage(&message, 0, 0, 0); GetMessage(&message, 0, 0, 0);
...@@ -2087,61 +2176,9 @@ cvWaitKey( int delay ) ...@@ -2087,61 +2176,9 @@ cvWaitKey( int delay )
continue; continue;
} }
for( window = hg_windows; window != 0 && is_processed == 0; window = window->next ) int keyCode = -1;
{ if (handleMessage(message, keyCode))
if( window->hwnd == message.hwnd || window->frame == message.hwnd ) return keyCode;
{
is_processed = 1;
switch(message.message)
{
case WM_DESTROY:
case WM_CHAR:
DispatchMessage(&message);
return (int)message.wParam;
case WM_SYSKEYDOWN:
if( message.wParam == VK_F10 )
{
is_processed = 1;
return (int)(message.wParam << 16);
}
break;
case WM_KEYDOWN:
TranslateMessage(&message);
if( (message.wParam >= VK_F1 && message.wParam <= VK_F24) ||
message.wParam == VK_HOME || message.wParam == VK_END ||
message.wParam == VK_UP || message.wParam == VK_DOWN ||
message.wParam == VK_LEFT || message.wParam == VK_RIGHT ||
message.wParam == VK_INSERT || message.wParam == VK_DELETE ||
message.wParam == VK_PRIOR || message.wParam == VK_NEXT )
{
DispatchMessage(&message);
is_processed = 1;
return (int)(message.wParam << 16);
}
// Intercept Ctrl+C for copy to clipboard
if ('C' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
::SendMessage(message.hwnd, WM_COPY, 0, 0);
// Intercept Ctrl+S for "save as" dialog
if ('S' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
showSaveDialog(window);
default:
DispatchMessage(&message);
is_processed = 1;
break;
}
}
}
if( !is_processed )
{
TranslateMessage(&message);
DispatchMessage(&message);
}
} }
} }
......
...@@ -205,6 +205,14 @@ CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name) ...@@ -205,6 +205,14 @@ CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name)
/********************************** Not YET implemented API ****************************************************/ /********************************** Not YET implemented API ****************************************************/
int cv::pollKey()
{
CV_TRACE_FUNCTION();
CV_WINRT_NO_GUI_ERROR("cvPollKey");
// TODO: implement appropriate logic here
}
CV_IMPL int cvWaitKey(int delay) CV_IMPL int cvWaitKey(int delay)
{ {
CV_WINRT_NO_GUI_ERROR("cvWaitKey"); CV_WINRT_NO_GUI_ERROR("cvWaitKey");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册