From: http://blog.csdn.net/kfbyj/article/details/9284923
Summarize the problems encountered in the recent project.
Sometimes we think that the title bar and button of the system are too ugly and too rigid. We need to create our own title bar and maximize, minimize, and close the menu button.
[CPP]
View plaincopyprint?
- Setwindowflags (QT: framelesswindowhint );
setWindowFlags(Qt::FramelessWindowHint);
However, after that, we cannot drag the window to change its position or drag the edge to change the window size.
There are two solutions to handle this situation:
1. Handle events such as mousemoveevent, mousepressevent, and mousereleaseevent on your own.
2. QT can process Windows messages. Implement bool winevent (MSG * message, long * result) again; (here I feel the Nb of QT again)
I just started to implement it using the first method. It is easy to move the window. You can check this, but it has fewer problems than other versions on the Internet.
Http://blog.csdn.net/aqtata/article/details/8902889
It is troublesome to change the window size by pressing and dragging the mouse at the edge of the window.
I did this:
Set m_bpressed to true when pressing mousepressevent.
In mousemoveevent, m_bpressed is true and event-> X () is at the edge of the window, and the increment of mouse movement is processed, and then the window is continuously resize.
As for how to determine the edge, you can set a difference. If the window Edge contains 4 PX, the resize will be processed even at the edge.
This method has many disadvantages. 1. It can't be quickly dragged, and it is easy to exceed the difference value. 2. The window jitter is so bad that it has been resize. 3. Too many situations need to be processed.
In view of the disadvantages of appeal, Baidu and Google are everywhere. The second method is available:
The second method is very useful, and the effect is the same as that of the header border program ~~~
Qt can process Windows messages ..
Here we need to re-implement winevent (MSG * message, long * result)
This virtual function can be implemented in qwidget, qwizard, qsizegrip, and their subclasses.
If you want to stop QT from processing messages, true is returned, and the result is set to the value you want to save and returned to window for processing. Otherwise, false is returned.
Here we mainly want to process the wm_nchittest message.
TheWm_nchittestMessage is sent to a window in order to determine what part of the window corresponds to a participant screen coordinate. this can happen, for example, when the cursor moves, when a mouse button is pressed or released, or
In response to a call to a function such
Windowfrompoint. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse.
A window waits es this message through its
WindowprocFunction.
The message response function of wm_nchittest determines which part of the window the mouse hits based on the current coordinate of the mouse. the return value of the message response function indicates the part. For example, it may return htcaption, or htclient. (There are many return values. Please refer to msdn ).
Knowing this is fine, we still need to determine the position of the mouse, and then save it to the result to the window for processing.
In fact, our program can not send these messages without borders. We will tell it to Windows, and then windows will help us with the drag and resize effects. So the effect is the same as that of the program with a title on the border.
Header file declaration:
[CPP]
View plaincopyprint?
- Class mainwindow:
Public qmainwindow
- {
- Q_object
- Public:
- Mainwindow (qwidget * parent = 0 );
- ~ Mainwindow ();
- Protected:
- Bool winevent (MSG * message,
Long * result );
- };
class MainWindow : public QMainWindow{ Q_OBJECTpublic: MainWindow(QWidget *parent = 0); ~MainWindow();protected: bool winEvent(MSG *message, long *result);};
CPP implementation
[CPP]
View plaincopyprint?
- Bool mainwindow: winevent (MSG * message,
Long * result)
- {
- Switch (Message-> message)
- {
- Case wm_nchittest:
- Int xpos = get_x_lparam (Message-> lparam )-
This-> framegeometry (). X ();
- Int ypos = get_y_lparam (Message-> lparam )-
This-> framegeometry (). Y ();
- If (this-> childat (xpos, ypos) = 0)
- {
- * Result = htcaption;
- } Else {
- Return false;
- }
- If (xpos> 18 & xpos <22)
- * Result = htleft;
- If (xpos> (this-> width ()-22) & xpos <(this-> width ()-18 ))
- * Result = htright;
- If (ypos> 18 & ypos <22)
- * Result = httop;
- If (ypos> (this-> height ()-22) & ypos <(this-> height ()-18 ))
- * Result = htbottom;
- If (xpos> 18 & xpos <22 & ypos> 18 & ypos <22)
- * Result = httopleft;
- If (xpos> (this-> width ()-22) & xpos <(this-> width ()-18) & ypos> 18 & ypos <22)
- * Result = httopright;
- If (xpos> 18 & xpos <22 & ypos> (this-> height ()-22) & ypos <(this-> height ()-18 ))
- * Result = htbottomleft;
- If (xpos> (this-> width ()-22) & xpos <(this-> width ()-18) & ypos> (this-> height ()
-22) & ypos <(this-> height ()-18 ))
- * Result = htbottomright;
- Return true;
- }
- Return false;
- }
bool MainWindow::winEvent(MSG *message, long *result){ switch(message->message) { case WM_NCHITTEST: int xPos = GET_X_LPARAM(message->lParam) - this->frameGeometry().x(); int yPos = GET_Y_LPARAM(message->lParam) - this->frameGeometry().y(); if(this->childAt(xPos,yPos) == 0) { *result = HTCAPTION; }else{ return false; } if(xPos > 18 && xPos < 22) *result = HTLEFT; if(xPos > (this->width() - 22) && xPos < (this->width() - 18)) *result = HTRIGHT; if(yPos > 18 && yPos < 22) *result = HTTOP; if(yPos > (this->height() - 22) && yPos < (this->height() - 18)) *result = HTBOTTOM; if(xPos > 18 && xPos < 22 && yPos > 18 && yPos < 22) *result = HTTOPLEFT; if(xPos > (this->width() - 22) && xPos < (this->width() - 18) && yPos > 18 && yPos < 22) *result = HTTOPRIGHT; if(xPos > 18 && xPos < 22 && yPos > (this->height() - 22) && yPos < (this->height() - 18)) *result = HTBOTTOMLEFT; if(xPos > (this->width() - 22) && xPos < (this->width() - 18) && yPos > (this->height() - 22) && yPos < (this->height() - 18)) *result = HTBOTTOMRIGHT; return true; } return false;}
Saving the various boundary conditions to the result for Windows processing saves a lot of things. I think windows is definitely much better than what we implement.
The 18 and 22 above are the scope of my judgment on the edge of the program.
Because
I made a border shadow. The shadow border is set to 20px.
[CPP]
View plaincopyprint?
- Xpos> 18 & xpos <22 is actually our hypothetical border.
Xpos> 18 & xpos <22 is actually our hypothetical border.
[CPP]
View plaincopyprint?