Live window resizing on Windows
Custom implementation for resizing (GHOST_SizerWin32) Some things still don't work: * esc cancel * max windows size * aero (sizing) snap on win7 hbrBackground = 0 to disable clear screen. Thanks to dfelinto for help in finding of root cause.
This commit is contained in:
@@ -296,6 +296,7 @@ elseif(WIN32)
|
|||||||
intern/GHOST_SystemPathsWin32.cpp
|
intern/GHOST_SystemPathsWin32.cpp
|
||||||
intern/GHOST_WindowWin32.cpp
|
intern/GHOST_WindowWin32.cpp
|
||||||
intern/GHOST_DropTargetWin32.cpp
|
intern/GHOST_DropTargetWin32.cpp
|
||||||
|
intern/GHOST_SizerWin32.cpp
|
||||||
|
|
||||||
intern/GHOST_DisplayManagerWin32.h
|
intern/GHOST_DisplayManagerWin32.h
|
||||||
intern/GHOST_DropTargetWin32.h
|
intern/GHOST_DropTargetWin32.h
|
||||||
@@ -303,6 +304,7 @@ elseif(WIN32)
|
|||||||
intern/GHOST_SystemPathsWin32.h
|
intern/GHOST_SystemPathsWin32.h
|
||||||
intern/GHOST_WindowWin32.h
|
intern/GHOST_WindowWin32.h
|
||||||
intern/GHOST_TaskbarWin32.h
|
intern/GHOST_TaskbarWin32.h
|
||||||
|
intern/GHOST_SizerWin32.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WITH_INPUT_NDOF)
|
if(WITH_INPUT_NDOF)
|
||||||
|
202
intern/ghost/intern/GHOST_SizerWin32.cpp
Normal file
202
intern/ghost/intern/GHOST_SizerWin32.cpp
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Alexandr Kuznetsov
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file ghost/intern/GHOST_SizerWin32.cpp
|
||||||
|
* \ingroup GHOST
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GHOST_SIZERWIN32_CPP__
|
||||||
|
#define __GHOST_SIZERWIN32_CPP__
|
||||||
|
|
||||||
|
|
||||||
|
#include "GHOST_SizerWin32.h"
|
||||||
|
#include <Windowsx.h>
|
||||||
|
|
||||||
|
#define T_NONE (0)
|
||||||
|
#define T_SIZE (1)
|
||||||
|
#define T_MOVE (2)
|
||||||
|
#define T_MOVESIZE (3)
|
||||||
|
|
||||||
|
|
||||||
|
static void RectCopyH(RECT * t, RECT * f)
|
||||||
|
{
|
||||||
|
t->left = f->left;
|
||||||
|
t->right = f->right;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RectCopyV(RECT * t, RECT * f)
|
||||||
|
{
|
||||||
|
t->top = f->top;
|
||||||
|
t->bottom = f->bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RectCopy(RECT * t, RECT * f)
|
||||||
|
{
|
||||||
|
RectCopyH(t,f);
|
||||||
|
RectCopyV(t,f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GHOST_SizerWin32::GHOST_SizerWin32(void)
|
||||||
|
{
|
||||||
|
hortransf = vertransf = 0;
|
||||||
|
minsize[0] = minsize[1] = 0;
|
||||||
|
hwnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GHOST_SizerWin32::~GHOST_SizerWin32(void)
|
||||||
|
{
|
||||||
|
if(isWinChanges())
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_SizerWin32::setMinSize(int minx, int miny)
|
||||||
|
{
|
||||||
|
minsize[0] = minx;
|
||||||
|
minsize[1] = miny;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GHOST_SizerWin32::isWinChanges(void)
|
||||||
|
{
|
||||||
|
return hortransf||vertransf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GHOST_SizerWin32::startSizing(unsigned short type)
|
||||||
|
{
|
||||||
|
//SetCapture(hwnd);
|
||||||
|
POINT coord;
|
||||||
|
|
||||||
|
switch(type & 0xf)
|
||||||
|
{
|
||||||
|
|
||||||
|
case WMSZ_LEFT: hortransf = T_MOVESIZE;
|
||||||
|
vertransf = T_NONE; break;
|
||||||
|
case WMSZ_RIGHT: hortransf = T_SIZE;
|
||||||
|
vertransf = T_NONE; break;
|
||||||
|
case WMSZ_TOP: hortransf = T_NONE;
|
||||||
|
vertransf = T_MOVESIZE; break;
|
||||||
|
case WMSZ_TOPLEFT: hortransf = T_MOVESIZE;
|
||||||
|
vertransf = T_MOVESIZE; break;
|
||||||
|
case WMSZ_TOPRIGHT: hortransf = T_SIZE;
|
||||||
|
vertransf = T_MOVESIZE; break;
|
||||||
|
case WMSZ_BOTTOM: hortransf = T_NONE;
|
||||||
|
vertransf = T_SIZE; break;
|
||||||
|
case WMSZ_BOTTOMLEFT: hortransf = T_MOVESIZE;
|
||||||
|
vertransf = T_SIZE; break;
|
||||||
|
case WMSZ_BOTTOMRIGHT: hortransf = T_SIZE;
|
||||||
|
vertransf = T_SIZE; break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
POINT mp;
|
||||||
|
GetCursorPos(&mp);
|
||||||
|
startpos[0]=mp.x;
|
||||||
|
startpos[1]=mp.y;
|
||||||
|
|
||||||
|
GetWindowRect(hwnd, &initrect);
|
||||||
|
initrect.bottom-=initrect.top;
|
||||||
|
initrect.right-=initrect.left;
|
||||||
|
RectCopy(&goodrect,&initrect);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_SizerWin32::setHWND(HWND hWnd)
|
||||||
|
{
|
||||||
|
this->hwnd = hWnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GHOST_SizerWin32::updateWindowSize(void)
|
||||||
|
{
|
||||||
|
if(!isWinChanges())
|
||||||
|
return;
|
||||||
|
if(hortransf||vertransf){
|
||||||
|
POINT mp;
|
||||||
|
GetCursorPos(&mp);
|
||||||
|
int hordelta = mp.x-startpos[0];
|
||||||
|
int verdelta = mp.y-startpos[1];
|
||||||
|
|
||||||
|
RECT newrect;
|
||||||
|
RectCopy(&newrect, &initrect);
|
||||||
|
|
||||||
|
switch(hortransf)
|
||||||
|
{
|
||||||
|
case T_SIZE:
|
||||||
|
newrect.right+=hordelta;
|
||||||
|
break;
|
||||||
|
case T_MOVESIZE:
|
||||||
|
newrect.right-=hordelta;
|
||||||
|
case T_MOVE:
|
||||||
|
newrect.left+=hordelta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(vertransf)
|
||||||
|
{
|
||||||
|
case T_SIZE:
|
||||||
|
newrect.bottom+=verdelta;
|
||||||
|
break;
|
||||||
|
case T_MOVESIZE:
|
||||||
|
newrect.bottom-=verdelta;
|
||||||
|
case T_MOVE:
|
||||||
|
newrect.top+=verdelta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(newrect.right<minsize[0])
|
||||||
|
RectCopyH(&newrect,&goodrect);
|
||||||
|
if(newrect.bottom<minsize[1])
|
||||||
|
RectCopyV(&newrect,&goodrect);
|
||||||
|
|
||||||
|
SetWindowPos(hwnd,0,newrect.left, newrect.top,
|
||||||
|
newrect.right, newrect.bottom,
|
||||||
|
0);
|
||||||
|
|
||||||
|
RectCopy(&goodrect, &newrect);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_SizerWin32::cancel(void)
|
||||||
|
{
|
||||||
|
accept();
|
||||||
|
SetWindowPos(hwnd,0,initrect.left, initrect.top,
|
||||||
|
initrect.right, initrect.bottom, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_SizerWin32::accept(void)
|
||||||
|
{
|
||||||
|
hortransf=vertransf=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GHOST_SIZERWIN32_CPP__*/
|
61
intern/ghost/intern/GHOST_SizerWin32.h
Normal file
61
intern/ghost/intern/GHOST_SizerWin32.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Alexandr Kuznetsov
|
||||||
|
*
|
||||||
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \file ghost/intern/GHOST_SizerWin32.h
|
||||||
|
* \ingroup GHOST
|
||||||
|
*/
|
||||||
|
#ifndef __GHOST_SIZERWIN32_H__
|
||||||
|
#define __GHOST_SIZERWIN32_H__
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
class GHOST_SizerWin32
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HWND hwnd;
|
||||||
|
int startpos[2];
|
||||||
|
int minsize[2];
|
||||||
|
RECT initrect;
|
||||||
|
RECT goodrect;
|
||||||
|
unsigned char hortransf, vertransf;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
GHOST_SizerWin32(void);
|
||||||
|
~GHOST_SizerWin32(void);
|
||||||
|
|
||||||
|
bool isWinChanges(void);
|
||||||
|
void startSizing(unsigned short type);
|
||||||
|
void updateWindowSize(void);
|
||||||
|
|
||||||
|
void setHWND(HWND hWnd);
|
||||||
|
void setMinSize(int minx, int miny);
|
||||||
|
|
||||||
|
void cancel(void);
|
||||||
|
void accept(void);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*#ifndef __GHOST_SIZERWIN32_H__*/
|
@@ -400,7 +400,7 @@ GHOST_TSuccess GHOST_SystemWin32::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
WNDCLASSW wc;
|
WNDCLASSW wc = {0};
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
wc.lpfnWndProc = s_wndProc;
|
wc.lpfnWndProc = s_wndProc;
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
@@ -412,7 +412,7 @@ GHOST_TSuccess GHOST_SystemWin32::init()
|
|||||||
::LoadIcon(NULL, IDI_APPLICATION);
|
::LoadIcon(NULL, IDI_APPLICATION);
|
||||||
}
|
}
|
||||||
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
|
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
|
||||||
wc.hbrBackground = (HBRUSH) ::GetStockObject(BLACK_BRUSH);
|
wc.hbrBackground = 0;
|
||||||
wc.lpszMenuName = 0;
|
wc.lpszMenuName = 0;
|
||||||
wc.lpszClassName = L"GHOST_WindowClass";
|
wc.lpszClassName = L"GHOST_WindowClass";
|
||||||
|
|
||||||
@@ -979,7 +979,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
* maximize, minimize or close the window are triggered. Also it is sent when ALT
|
* maximize, minimize or close the window are triggered. Also it is sent when ALT
|
||||||
* button is press for menu. To prevent this we must return preventing DefWindowProc.
|
* button is press for menu. To prevent this we must return preventing DefWindowProc.
|
||||||
*/
|
*/
|
||||||
if (wParam == SC_KEYMENU) return 0;
|
if (wParam == SC_KEYMENU)
|
||||||
|
{
|
||||||
|
eventHandled = true;
|
||||||
|
} else
|
||||||
|
if((wParam&0xfff0)==SC_SIZE)
|
||||||
|
{
|
||||||
|
window->registerMouseClickEvent(0);
|
||||||
|
window->m_wsh.startSizing(wParam);
|
||||||
|
eventHandled = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Tablet events, processed
|
// Tablet events, processed
|
||||||
@@ -1017,6 +1026,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
break;
|
break;
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
window->registerMouseClickEvent(1);
|
window->registerMouseClickEvent(1);
|
||||||
|
if(window->m_wsh.isWinChanges())
|
||||||
|
window->m_wsh.accept();
|
||||||
|
else
|
||||||
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
|
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
|
||||||
break;
|
break;
|
||||||
case WM_MBUTTONUP:
|
case WM_MBUTTONUP:
|
||||||
@@ -1037,6 +1049,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
|
if(window->m_wsh.isWinChanges())
|
||||||
|
window->m_wsh.updateWindowSize();
|
||||||
|
else
|
||||||
event = processCursorEvent(GHOST_kEventCursorMove, window);
|
event = processCursorEvent(GHOST_kEventCursorMove, window);
|
||||||
break;
|
break;
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
@@ -1105,6 +1120,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
|
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
|
||||||
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
|
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
|
||||||
* will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
* will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
||||||
|
if(LOWORD(wParam)==WA_INACTIVE)
|
||||||
|
window->lostMouseCapture();
|
||||||
|
|
||||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1235,6 +1253,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
* In GHOST, we let DefWindowProc call the timer callback.
|
* In GHOST, we let DefWindowProc call the timer callback.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
case WM_CANCELMODE:
|
||||||
|
if(window->m_wsh.isWinChanges())
|
||||||
|
window->m_wsh.cancel();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -272,6 +272,9 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
|||||||
// Store a pointer to this class in the window structure
|
// Store a pointer to this class in the window structure
|
||||||
::SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG_PTR) this);
|
::SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG_PTR) this);
|
||||||
|
|
||||||
|
m_wsh.setHWND(m_hWnd);
|
||||||
|
m_wsh.setMinSize(320, 240);
|
||||||
|
|
||||||
// Store the device context
|
// Store the device context
|
||||||
m_hDC = ::GetDC(m_hWnd);
|
m_hDC = ::GetDC(m_hWnd);
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
#include "GHOST_Window.h"
|
#include "GHOST_Window.h"
|
||||||
|
#include "GHOST_SizerWin32.h"
|
||||||
#include "GHOST_TaskbarWin32.h"
|
#include "GHOST_TaskbarWin32.h"
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||||
@@ -280,6 +281,8 @@ public:
|
|||||||
|
|
||||||
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
|
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
|
||||||
|
|
||||||
|
GHOST_SizerWin32 m_wsh;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
|
GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user