Comments (4)
@jiakuan I believe you can show these system menu using shortcut "Alt+Space". But I‘m not sure how to add the same support using mouse right click.
from qt-nice-frameless-window.
Hi there!
When we click the top left corner of a standard application window, it normally shows a system menu like this:
...
... But I‘m not sure how to add the same support using mouse right click.
I think the OP was talking about the menu displayed when we left click the top left corner.
from qt-nice-frameless-window.
Howdy All.
@jiakuan @Bringer-of-Light
Here is my findings on this one.
Looking at the General WinAPI For Custom Framing, there looks to be a message case called WM_NCRBUTTONDOWN.
using this allows us to receive a Right click when working in the window.
As a simple example of using this could be
// End case WM_NCHITTEST
case WM_NCRBUTTONDOWN:
{
// Get Mouse pos
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
// Support highdpi
double dpr = this->devicePixelRatioF();
QPoint pos = m_titlebar->mapFromGlobal(QPoint(x / dpr, y / dpr));
// Is the mouse within the titlebar pos?
if (!m_titlebar->rect().contains(pos))
return false;
// Get Win Handle
HWND pHndl = HWND(winId());
// Get SysMenu handle
HMENU pSysMenu = ::GetSystemMenu(pHndl, FALSE);
// If it exists
if (pSysMenu)
{
// Open the system menu, Aligning menu to the top left corner, at mouse pos.
TrackPopupMenu(pSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, x, y, NULL, pHndl, 0);
}
return false;
}
This is a simple Case and does not support the MenuControls such as 'Close' or other functions.
This also has a bug that allows the user to display the menu even when in resize area.
Fixing this bug should be a simple fix but requires more editing of the already implamented functions.
Adding in a bool m_bInBorder and setting this bool to true when the Cursor changes,
Then setting the bool back to false when not changing the Cursor can fix this issue.
i.e.
//top border
if (y >= winrect.top && y < winrect.top + border_width)
{
m_bInBorder = true;
*result = HTTOP;
}
with this we can now check to see if the cursor is 'm_bInBorder'.
And if it is NOT we can continue to process the above, like so:
//end case WM_NCHITTEST
case WM_NCRBUTTONDOWN:
{
// Check if the mouse is NOT within the Resize area.
if (!m_bInBorder)
{
// Get Mouse pos
long x = GET_X_LPARAM(msg->lParam);
long y = GET_Y_LPARAM(msg->lParam);
// Support highdpi - Needed for determining the pos of mouse, reletive to the dpi/monitor.
double dpr = this->devicePixelRatioF();
QPoint pos = m_titlebar->mapFromGlobal(QPoint(x / dpr, y / dpr));
// Is the mouse within the titlebar pos?
if (!m_titlebar->rect().contains(pos))
return false;
// Get Win Handle
HWND pHndl = HWND(winId());
// Get SysMenu handle
HMENU pSysMenu = ::GetSystemMenu(pHndl, FALSE);
// If it exists
if (pSysMenu)
{
// Open the system menu, Aligning menu to the top left corner, at mouse pos (dpi not included here).
TrackPopupMenu(pSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON, x, y, NULL, pHndl, 0);
}
return false;
}
}
Now all that is needed is to connect the Functions of the Menu..
This is a bit of a tougher case.
It looks like I was able to find a Solution for the SysMenu buttons too, after a bit of digging.
Following along with the WinAPI it looks like the message Case WM_COMMAND is the message used to receive the menuInputs.
Filtering the wParam of this message will determine the case used.
For Example, adding the below under the above code will allow you to 'Close' the Popup Dialog and Debug print to console.
//end case WM_NCRBUTTONDOWN
case WM_COMMAND: // "Sent when the user selects a command item from a menu" - https://learn.microsoft.com/en-us/windows/win32/menurc/wm-command
{
// Check if the wParam is the Close Param
if (msg->wParam == SC_CLOSE)
{
// If so Debug and Close Popup.
qDebug() << "Test";
::EndDialog(HWND(winId()), TRUE);
return false;
}
}
From here you can simply close the Widget Window itself.
There may be a need to do further troubleshooting on this as I have not fully tested the menu Functions.
Like for instance it seems the 'Restore' button has issues with detecting if fullscreen or not, but this can be fixed by troubleshooting.
More info can be found via:
https://learn.microsoft.com/en-us/windows/win32/menurc/wm-syscommand
https://learn.microsoft.com/en-us/windows/win32/dwm/customframe#appendix-c-hittestnca-function
I hope this helps anyone that comes across this :)
from qt-nice-frameless-window.
@jiakuan
If you wish to make the prompt appear when selecting an Icon or Button then just place the before mentioned code into a button signal.
Just make sure this is OS dependent.
from qt-nice-frameless-window.
Related Issues (20)
- MAC: titlebar show again when I put QTabWidget in widget.
- system min/max/close button show on Windows 7 when click custom title bar HOT 1
- 可以在qml里面使用吗
- 父窗口不能接收到WM_GETMINMAXINFO、WM_NCCALCSIZE、WM_NCHITTEST HOT 1
- Setting fixed size on MainWindow makes the window undraggable. macOS. Qt 5.14.2 HOT 1
- Can't show any view in macOS 10.15 HOT 2
- 如何在win10下将窗口裁剪为圆角
- Macos title遗留白边
- menuBar 使用疑问 HOT 1
- Can't move window to second screen HOT 9
- 双屏情况下,从这个屏幕移动到另一个屏幕上,会出现大黑边 HOT 3
- problem in window with Round corners
- win+down无法最小化
- Vertical bar on secondary screen when window is maximized HOT 3
- win7下会依旧会显示系统按钮及边框
- Err msg: QMainWindow::getContentsMargins(left,top,right,bottom); HOT 1
- undefined reference to `DwmExtendFrameIntoClientArea' HOT 2
- 这个方式Win10下面窗口能设置圆角吗
- Why params.rgrc[0].top -= 1; ? HOT 1
- Cleanup non issue
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from qt-nice-frameless-window.