OpenCVでWindowを作成し、画面の端に近づけると、勝手にスナップします。
微妙な位置に配置したい時など困りますので、この余計な機能を消してしまいましょう。
ソースを修正する
問題の個所は、「sources/modules/highgui/src/window_w32.cpp」にあります。
window_w32.cpp
case WM_WINDOWPOSCHANGING:
{
// Snap window to screen edges with multi-monitor support. // Adi Shavit
LPWINDOWPOS pos = (LPWINDOWPOS)lParam;
RECT rect;
GetWindowRect(window->frame, &rect);
HMONITOR hMonitor;
hMonitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
MONITORINFO mi;
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi);
const int SNAP_DISTANCE = 15;
if (abs(pos->x - mi.rcMonitor.left) <= SNAP_DISTANCE)
pos->x = mi.rcMonitor.left; // snap to left edge
else
if (abs(pos->x + pos->cx - mi.rcMonitor.right) <= SNAP_DISTANCE)
pos->x = mi.rcMonitor.right - pos->cx; // snap to right edge
if (abs(pos->y - mi.rcMonitor.top) <= SNAP_DISTANCE)
pos->y = mi.rcMonitor.top; // snap to top edge
else
if (abs(pos->y + pos->cy - mi.rcMonitor.bottom) <= SNAP_DISTANCE)
pos->y = mi.rcMonitor.bottom - pos->cy; // snap to bottom edge
}
画面の上下左右15pixel以内になると「0」にしてしまうという力技を見せてくれています。
こんな処理は、さくっとコメントアウトしてしまいましょう。
window_w32.cpp
case WM_WINDOWPOSCHANGING:
// {
// // Snap window to screen edges with multi-monitor support. // Adi Shavit
// LPWINDOWPOS pos = (LPWINDOWPOS)lParam;
//
// RECT rect;
// GetWindowRect(window->frame, &rect);
//
// HMONITOR hMonitor;
// hMonitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
//
// MONITORINFO mi;
// mi.cbSize = sizeof(mi);
// GetMonitorInfo(hMonitor, &mi);
//
// const int SNAP_DISTANCE = 15;
//
// if (abs(pos->x - mi.rcMonitor.left) <= SNAP_DISTANCE)
// pos->x = mi.rcMonitor.left; // snap to left edge
// else
// if (abs(pos->x + pos->cx - mi.rcMonitor.right) <= SNAP_DISTANCE)
// pos->x = mi.rcMonitor.right - pos->cx; // snap to right edge
//
// if (abs(pos->y - mi.rcMonitor.top) <= SNAP_DISTANCE)
// pos->y = mi.rcMonitor.top; // snap to top edge
// else
// if (abs(pos->y + pos->cy - mi.rcMonitor.bottom) <= SNAP_DISTANCE)
// pos->y = mi.rcMonitor.bottom - pos->cy; // snap to bottom edge
// }
※一応イベントは受け取り、下の処理(アクティブならフォーカスを当てる)を実行出来るよう、breakしたりはしません
余談
Windows10ではOSが余計なことをしてくれるそうですが、そちらは設定で変更できるようです。
まとめ
「小さな親切、大きなお世話」ということで、将来のバージョンでは削除されていることを祈ります。