Taking a screenshot from the selected area(QRubberBand) on Qt - c++

I am trying to create a Qt application to take screenshot from the selected area on screen. For now I am using QRubberBand to select an area of the screen.
It works like this.
When the Capture Button clicked an overlay transparent widget will popup(fullscreen but without frames)
I am using QRubberBand to select an area on the transparent widget.
Now I have to take the screenshot of the part which I selected.
I am thinking I have to pass the dimensions I get from selecting the QRubberBand to this:
screen->grabWindow( WId window, int x = 0, int y = 0, int width = -1, int height = -1 );
So how do I get the info I need from the QRubberBand?
I am stuck here, so someone please help me!

In your OnMouseRelease event you can get the rect of the QRubberBand using geometry(). Next using the QRect::getRect you can extract the position of the rectangle's top-left corner to x and y, and its dimensions to width and height. :
const QRect & selectRect = mRubberBand->geometry();
int x, y, width, height;
selectRect.getRect(&x, &y, &width, &height);

Related

How to shift the start coordinates of the client area on the window?

I have refereed below article to draw a custom frame area with DWM.
Custom Window Frame Using DWM
After removing the standard frame, non client area is not exist in the frame.
void CMainFrame::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
int nTHight = 30; /*The title bar height*/
RECT * rc;
RECT aRect;
RECT bRect;
RECT bcRect;
if(bCalcValidRects == TRUE)
{
CopyRect(&aRect,&lpncsp->rgrc[1]);
CopyRect(&bRect,&lpncsp->rgrc[0]);
bcRect.left = bRect.left;
bcRect.top = bRect.top - nTHight;
bcRect.right = bRect.right;
bcRect.bottom = bRect.bottom;
CopyRect(&lpncsp->rgrc[0],&bcRect);
CopyRect(&lpncsp->rgrc[1],&bRect);
CopyRect(&lpncsp->rgrc[2],&aRect);
}
else
{
rc = (RECT *)lpncsp;
rc->left = rc->left;
rc->top = rc->top - nTHight;
rc->right = rc->right;
rc->bottom = rc->bottom;
}
CFrameWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}
Because the entire window is client region, I have to adjust the UI control placement for the frame, but I don't know how to handle this problem.
For example, below red rectangle (all UI component) should be shifted into the original coordinate of the client area before removing the non client part.
CWnd::GetWindowRect gives you the rectangle of the window on screen. The dimensions of the caption, border, and scroll bars, if present, are included.
CWnd::GetClientRect gives you the client rectangel of the window. The left and top members will be 0. The right and bottom members will contain the width and height of the window.
CWnd::ScreenToClientand CWnd::ClientToScreen calculate a point or rectangle from the client area to screen coordinates and back to screen.
AdjustWindowRect calculates the required window rectangle, based on the client rectangle of the window.
Here is afunction which calcualtes the margins of a window:
void CalculateWndMargin( const CWnd &wnd, int &leftM, int &rightM , int &topM, int &bottomM )
{
CRect wndRect;
wnd.GetWindowRect( wndRect );
CRect screenRect;
wnd.GetClientRect( screenRect );
wnd.ClientToScreen( screenRect );
leftM = screenRect.left - wndRect.left;
rightM = wndRect.right - screenRect.right;
topM = screenRect.top - wndRect.top;
bottomM = wndRect.bottom - screenRect.bottom;
}

c++ Xlib don't want to resize my window in height

I want to resize a window with Xlib so I made a function (she is inside a class) :
int setSizeAndMove(int top, int left, int width, int height)
{
XMoveResizeWindow(m_display, m_window_terminal, top, left, width, height);
return 1;
}
This function works fine. I have another function who return the size of the current window :
Rect getWindowSize() const
{
XWindowAttributes size_win;
XGetWindowAttributes(m_display, m_window_terminal, &size_win);
Rect size_return;
size_return.X = size_win.width;
size_return.Y = size_win.height;
return size_return;
}
(Rect is just a structur that contain int X & int Y)
My problem is when I do something like this :
setSizeAndMove(0, 0, getWindowSize().X + 10, getWindowSize().Y + 10);
The window correctly add 10 pixel to width but not to height, why ?
//Additional question with 0,0 the window isn't in the top left but something like 5,5.
Thanks for help.

Get current coordinates of a window (C++)

I'm trying to get the x and y coordinates of a specific window relative to the screen (e.g. If the window's position on the screen is (100, 300) then I should retrieve an x-coordinate of 100 and a y-coordinate of 300). How can I achieve this so that I can assign the coordinates to some variables?
int x = /*Get x-coordinate*/;
int y = /*Get y-coordinate*/;
On Vista and later with Aero glass enabled, you have to use DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS) to account for glass padding.
Otherwise, you can use GetWindowRect() instead, which does not account for glass padding.
RECT rect;
GetWindowRect(window, &rect);
int x = rect.left;
int y = rect.top;

How to use grabWindow to take a screenshot of only a certain region of a window?

I am currently using the following code to take a screenshot of a window (handle is type HWND):
QPixmap::grabWindow((WId) handle).save("haystack.png", "png");
However, I only need to take a screenshot of a certain region (rectange) of the window.
In my case, the rectangle has the following vertices:
Top-left corner: (536, 535)
Bottom-right corner: (778, 592)
Right from the documentation:
QPixmap QPixmap::grabWindow( WId window,
int x = 0,
int y = 0,
int width = -1,
int height = -1 );

How do I set X coordinate of button without changing: y, width, height

I know I can use MoveWindow to move it but I only want to move the button on the x axis. Thanks.
I figured it out. You can get the button's (screen) position using GetWindowRect, then you can use ScreenToClient to get it's location in the form. Example:
RECT buttonScreenRect;
GetWindowRect(hwnd, &buttonScreenRect);
POINT buttonClientPoint;
buttonClientPoint.x = buttonScreenRect.left;
buttonClientPoint.y = buttonScreenRect.top;
ScreenToClient(hwnd, &buttonClientPoint);
MoveWindow(hwnd, 50, buttonClientPoint.y, buttonScreenRect.right - buttonScreenRect.left, buttonScreenRect.bottom - buttonScreenRect.top);
Hope it helps!