c – 以编程方式调用Snap / Aero最大化
有没有一种方法可以使用C或C以特定的窗口/窗口ID以编程方式调用Aera最大化效果?
例如: 要么 enter link description here http://www.thebuzzmedia.com/wp-content/uploads/2009/05/windows-7-aero-snap-to-edge-effect.png 我使用的是无边框Qt窗口,Qt有一个用于获取窗口ID的API.我想以编程方式触发Windows效果而不使用已知的触发器. 解决方法
我不想谈论实现这种效果所涉及的每一个细节,不仅有很多事情发生,而且你还提到你理解将窗口放在特定位置的逻辑.在这个答案中,我将解决我认为的两个主要挑战:
>如何接收和处理最大化事件? 为了回答第一个问题,我们必须分析窗口最大化时触发的event handlers: void resizeEvent(QResizeEvent* evt); // Invoked first,void paintEvent(QPaintEvent* event); // then second,void changeEvent(QEvent* evt); // and at last. 首先通知Qt应用程序resizeEvent(),然后使用paintEvent()绘制窗口(或窗口小部件),并且只有在显示所有内容之后,才会调用changeEvent()以告知窗口小部件已最大化(也许接收这样的通知有点晚了,我不知道). 在所有这些中,我们唯一关心的是resizeEvent().此事件处理程序通知可用于与桌面大小进行比较的新窗口/窗口小部件大小,从而允许我们知道事件是否实际上是最大化请求.一旦我们确定了最大化请求,我们就可以确定应用程序是否应该最大化(并锚定)到屏幕的右侧,左侧或中心. 这将是创建aero snap小部件并将其作为用户视觉线索放置在屏幕上的时间. 要回答第二个问题,我认为无法调用本机Windows API并礼貌地请求它在您的窗口上执行此效果.唯一合乎逻辑的选择是编写一个自己近似于这种效果的代码. 可以通过绘制带阴影边框的透明窗口来复制视觉外观.在下面的源代码中演示的方法,创建并自定义QWidget,使其行为和看起来像一个航空快照窗口: 我知道,这不是世界上最美丽的事物.此演示为用户创建一个常规窗口进行交互,一旦最大化,它就会将自己置于屏幕左侧.对于正确尺寸的屏幕,它会显示类似于航空快照窗口的内容(如上所示). aero snap小部件背后的想法非常简单:具有透明背景和自定义绘制过程的QWidget.换句话说,它是一个透明的窗口,它绘制一个带阴影的圆角矩形,就是这样. 为了使它更逼真,你应该添加一些动画来逐渐调整小部件的大小. for循环可能会起作用,但如果你需要一些花哨的东西,你最终会使用定时器.如果你拿look here,你可以看到最快的&使用Qt执行动画的最脏的方法,以及处理动画的更好方法.但是,对于像这样的简单任务,请坚持使用frame-based animation. main.cpp中: #include "window.h" #include <QApplication> int main(int argc,char* argv[]) { QApplication app(argc,argv); Window window; window.show(); return app.exec(); } 在window.h: #pragma once #include "snapwindow.h" #include <QMainWindow> #include <QEvent> class Window : public QMainWindow { public: Window(); void resizeEvent(QResizeEvent* evt); //void paintEvent(QPaintEvent* event); void changeEvent(QEvent* evt); private: SnapWindow* _sw; }; window.cpp: #include "window.h" #include "snapwindow.h" #include <QDebug> #include <QWindowStateChangeEvent> #include <QApplication> #include <QDesktopWidget> Window::Window() { setWindowTitle("AeroSnap"); resize(300,300); _sw = new SnapWindow(this); _sw->hide(); } void Window::changeEvent(QEvent* evt) { if (evt->type() == QEvent::WindowStateChange) { QWindowStateChangeEvent* event = static_cast<QWindowStateChangeEvent*>(evt); if (event->oldState() == Qt::WindowNoState && windowState() == Qt::WindowMaximized) { qDebug() << "changeEvent: window is now maximized!"; } } } // resizeEvent is triggered before window_maximized event void Window::resizeEvent(QResizeEvent* evt) { qDebug() << "resizeEvent: request to resize window to: " << evt->size(); QSize desktop_sz = QApplication::desktop()->size(); //qDebug() << "resizeEvent: desktop sz " << desktop_sz.width() << "x" << desktop_sz.height(); // Apparently,the maximum size a window can have in my system (1920x1080) // is actually 1920x990. I suspect this happens because the taskbar has 90px of height: desktop_sz.setHeight(desktop_sz.height() - 90); // If this not a request to maximize the window,don't do anything crazy. if (desktop_sz.width() != evt->size().width() || desktop_sz.height() != evt->size().height()) return; // Alright,now we known it's a maximize request: qDebug() << "resizeEvent: maximize this window to the left"; // so we update the window geometry (i.e. size and position) // to what we think it's appropriate: half width to the left int new_width = evt->size().width(); int new_height = evt->size().height(); int x_offset = 10; setGeometry(x_offset,45,new_width/2,new_height-45); // y 45 and height -45 are due to the 90px problem /* Draw aero snap widget */ _sw->setGeometry(new_width/2-x_offset,new_height); _sw->show(); // paintEvent() will be called automatically after this method ends,// and will draw this window with the appropriate geometry. } snapwindow.h: #pragma once #include <QWidget> class SnapWindow : public QWidget { public: SnapWindow(QWidget* parent = 0); void paintEvent(QPaintEvent *event); }; snapwindow.cpp: #include "snapwindow.h" #include <QPainter> #include <QGraphicsDropShadowEffect> SnapWindow::SnapWindow(QWidget* parent) : QWidget(parent) { // Set this widget as top-level (i.e. owned by user) setParent(0); /* Behold: the magic of creating transparent windows */ setWindowFlags(Qt::Widget | Qt::FramelessWindowHint); setStyleSheet("background:transparent;"); setAttribute(Qt::WA_NoSystemBackground,true); // speed up drawing by removing unnecessary background initialization setAttribute(Qt::WA_TranslucentBackground); //setAutoFillBackground(true); /* Use Qt tricks to paint stuff with shadows */ QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect(); effect->setBlurRadius(12); effect->setOffset(0); effect->setColor(QColor(0,255)); setGraphicsEffect(effect); } void SnapWindow::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); /* Lazy way of painting a shadow */ QPainter painter(this); QPen pen(QColor(180,180,200)); pen.setWidth(3); painter.setPen(pen); // Offset 6 and 9 pixels so the shadow shows up properly painter.drawRoundedRect(QRect(6,6,(width()-1)-9,(height()-1)-9),18,18); } 这只是一个快速演示,可以指出您正确的方向.它绝不是您正在寻找的效果的完整实现. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |