PDA

View Full Version : Resizing a maximized, custom-frame window



Claymore
19th February 2007, 18:59
I have an application that uses a custom window frame that is implemented by hiding the main application frame (via Qt::FramelessWindowHint) and giving it an appropriate mask.

Everything is working properly, except when I try to maximize the application. When maximized, the top border of the custom window is offset by the height of the masked Windows frame titlebar. I've tried using the setGeometry() command on the main window to offset the custom window frame slightly when maximized, but for some reason it doesn't want to set the new geometry if an x-coordinate of less than 5 is given (I'd like to keep the x coordinate at 0 and have the y coordinate be the negative of whatever the masked Windows frame titlebar is).

Any help on this is greatly appreciated. :)

wysota
19th February 2007, 19:22
AFAIK you can't move a window outside the screen in Windows, so if the frame still is there, you won't be able to move it. You may set your widget to full screen mode, maybe that helps (there will be no border at all then). But why do you need the mask? Doesn't the frameless window hint disable the decoration?

Claymore
19th February 2007, 20:15
You are correct, the frameless window removes the window decoration, but I have a custom window decoration that is setup in a 3x3 grid in the main window. The mask is then applied to give the window a curved look on the edges instead of it being a big rectangle.

I've tried using the full-screen method, but doing this causes the context menu on the Windows taskbar to disable the "Restore" option that restores the application back to its original size.

Also, I noticed that if I make the following call:

setGeometry(rect());
updateGeometry();

It will correctly shift the application window up to the top of the screen, but it will leave a space below the application. Attempting to manually set the height to a different value will cause the window to shift back down again. This call is in the resizeEvent() method of my main window, and I have a boolean variable that gets set to avoid an infinite loop in resizing the window.

One thing I'm noticing is that something else is receiving the maximized signal before my QMainWindow. Does Windows handle this event and attempt a resize before it notifies the application? If I can intercept this call, then maybe I can redefine how the application can handle it before any resize is attempted. By the time resizeEvent() is called in my code, the application already thinks it's maximized.

wysota
19th February 2007, 21:54
Maybe you could just
setGeometry(QDesktopWidget().availableGeometry()); ?

Claymore
19th February 2007, 22:21
Ok, this worked:


showFullScreen();
setGeometry(qApp->desktop()->availableGeometry());
updateGeometry();

However, when you right-click on the application button in the Windows taskbar it doesn't have the "Restore" option highlighted... Is there any way to manually enable those options? :)

Also, it would be a lot easier if I blocked the call for maximizing the application right when the application receives it and before any resize takes place; but for some reason I can't ignore the event. Here's the code I have in place that catches the maximize attempt:


bool MyMainWindow::event(QEvent* e)
{
if(e->type() == QEvent::WindowStateChange && windowState() == Qt::WindowMaximized)
{
// Manually resize the GUI using the above method.
e->ignore();
return false;
}
else
return QWidget::event(e);
}
Even though I specify that the event should be ignored, the window still tries to maximize which causes a brief moment of window resizing up, then down, then back up to full-screen. Is there something else I need to do to ignore the event?

Thanks!

wysota
19th February 2007, 22:48
However, when you right-click on the application button in the Windows taskbar it doesn't have the "Restore" option highlighted...
Because it's not maximized. "Maximized" doesn't mean every situation when a widget fills the whole available space. Maximizing is done by the window manager and any change to the geometry causes the window to leave the maximized state.


Is there any way to manually enable those options? :)
I don't think so.


Also, it would be a lot easier if I blocked the call for maximizing the application right when the application receives it and before any resize takes place; but for some reason I can't ignore the event.

State change events are just a notification, they are spontaneous events.


Even though I specify that the event should be ignored, the window still tries to maximize which causes a brief moment of window resizing up, then down, then back up to full-screen. Is there something else I need to do to ignore the event?
I don't think you can ignore the event.

Do you really need that "restore" option enabled? Can't you just have a button or something?

Claymore
19th February 2007, 23:25
Do you really need that "restore" option enabled? Can't you just have a button or something?
It's not so much my preference but more the preference of the customers involved, in this case a marketing department ;). I'll keep chugging away at this and see if I can't find some sort of solution. The reason why I think this should be possible (or at least I hope it is :)) is that other applications such as Windows Media Player seem to use this similar method of hiding the window frame and masking off specific areas of the window, but somehow they can handle going to fullscreen just fine.

wysota
19th February 2007, 23:29
Fullscreen or maximize? These two differ you know...

And I think you don't have any problem maximizing the window and having "restore" enabled, the problem is you want to move the window then. Maybe try focusing on how to obtain the effect you need (whatever it is) without manipulating the geometry of the window once it is maximized?

Claymore
19th February 2007, 23:55
You are correct - I meant maximized, not full screen (head's becoming frazzled from trying to get this working properly :p).

Boo Boo
24th November 2010, 19:17
You could intercept win messages, overrride winEvent() in your window. This will let you set the width/height for system "maximize" function, so you could make it fullscreen.

In the comments are provided links to msdn where you can read more about the MINMAXINFO structure and its variables.


#include <windows.h>

bool MainWindow::winEvent ( MSG * message, long * result )
{
switch (message->message)
{
case WM_GETMINMAXINFO: {

// GetSysemMetrics(): http://msdn.microsoft.com/en-us/library/ms724385(VS.85).aspx
// ptMinTrackSize - The minimum tracking width/height of a window, in pixels.
// The user cannot drag the window frame to a size smaller than these dimensions.
// ptMaxTrackSize - The default maximum width/height of a window that has a caption
// and sizing borders, in pixels. This metric refers to the entire desktop. The user cannot
// drag the window frame to a size larger than these dimensions.

// WM_GETMINMAXINFO: http://msdn.microsoft.com/en-us/library/ms632626(VS.85).aspx
// MINMAXINFO structure: http://msdn.microsoft.com/en-us/library/ms632605(VS.85).aspx

MINMAXINFO *mmi = (MINMAXINFO*) (message->lParam);

QDesktopWidget desktopWidget;
QRect desktop = desktopWidget.availableGeometry();

mmi->ptMaxSize.x = desktop.width();
mmi->ptMaxSize.y = desktop.height();

mmi->ptMaxPosition.x = desktop.x();
mmi->ptMaxPosition.y = desktop.y();

mmi->ptMinTrackSize.x = this->minWidth; // minimum width for your window
mmi->ptMinTrackSize.y = this->minHeight; // minimum height for your window

mmi->ptMaxTrackSize.x = desktop.width();
mmi->ptMaxTrackSize.y = desktop.height();

result = 0;

return true;
break;
}
return false;
}