Zoom the picture within the picturebox of Visual Studio C++ - c++

I have a problem about zooming into the picture displayed in a picturebox Picture Control. The expected result is similar to the following link: A scrollable, zoomable, and scalable picture box. The picture is zoomed in within the picturebox. Note the picturebox is zoomed in.
However, this can be implemented in .NET Framework 2.0. I have searched some information on the Internet, but none used C/C++ Windows API of Visual Studio. How can I zoom a picture within a the picturebox Picture Control when I work on Windows Forms of Visual Studio C++ 2010. Thank you for anyone's reply.

I have faced the same issue and I searched a lot but didn't get the solution in cpp(freely available in c# and VB).
So finally i decided to implement it by my own. If your Image size is bigger than the picture box then only 1 level of zoom(original size of image) you can do with my implementation.
I will help you with the implementation. In current implementation
if you do left click of mouse it will ZoomIn and
if you do right click of mouse it will ZoomOut.
Assuming you have read the image file(.png, .jpg, .bmp, ...) in bmpPicture.
Bitmap ^bmpPicture = gcnew Bitmap(strFilename);// if not it can help
private: System::Void pictureBox1_Click(System::Object^ sender, System::EventArgs^ e) {
MouseEventArgs ^ms = (MouseEventArgs^)e;
if (ms->Button == System::Windows::Forms::MouseButtons::Left)
{
int pbx = ms->X;
int pby = ms->Y;
int img_x = (pbx * mwidth / pbwidth * 1.0f);
int img_y = (pby * mheight / pbheight * 1.0f);
pictureBox1->Location = System::Drawing::Point(pbx - img_x, pby - img_y);
pictureBox1->SizeMode = PictureBoxSizeMode::AutoSize;
pictureBox1->Image = bmpPicture;
}
else if(ms->Button == System::Windows::Forms::MouseButtons::Right)
{
int pbx = ms->X;
int pby = ms->Y;
pictureBox1->Location = System::Drawing::Point(0, 0);
pictureBox1->SizeMode = PictureBoxSizeMode::StretchImage;
pictureBox1->Image = bmpPicture;
}
}
Hope this will help you...

Without any source code, it is difficult to comment.
StackOverflow is for problem solving; we can troubleshoot your starting code and get it working and during the course of which we can also fine tune design.
Anyway, I would like to give some pointers:
One or two picture boxes: entirely depends on your UI requirement.
Showing full or partial region of an image: StretchBlt is a powerful
API that can be used to achieve. See MSDN documentation for details.
Which class to use for picture box: if MFC is being used, then
derive a class from CStatic, overload the OnPaint() and use
StretchBlt to paint the image.
Classes to use for image: CBitmap, CImage, Gdiplus::Image.
Each have their own pros and cons.
If transparent images/PNGs are to be suported, better go for CImage or Gdiplus::Image.
You can get enough info here: CBitmap CImage Gdiplus::Image
Hope this would give you some starter.

Related

Taking Screenshot of Full Desktop with Qt5

I figured out how to take a screenshot of the desktop today with Qt5 from an included example which gets the primary screen, grabs it, and then saves it.
I'm translating the code from Python without testing so if there's a small syntax error, then yeah you know. So I can easily take a screenshot of the primary screen with:
QApplication a(argv, argc);
QScreen *screen = a.primaryScreen();
QPixmap screenshot = screen->grabWindow(0);
screenshot.save('screenshot.png', 'png');
This will (obviously) take a screenshot of the primary monitor. The problem is I need to take a screenshot of all of the monitors. So I came up with this:
QList<QScreen*> screens = a.screens();
QScreen *screen;
QPixmap screenshot;
for(int i = 0; i < screens.length(); i++){
screen = screens.at(i);
screenshot = screen->grabWindow(0);
screenshot.save(QString::number(i) + ".png", 'png');
}
//takes and saves two screenshots on my end
This finds both of my monitors but the saved images are all a screenshot of the primary monitor and I can't figure out how to get the others. I've been playing with this for a few hours now and still can't figure it out. So can someone help me out?
I figured out a simple fix for this problem. When I was looking through the documentation recently, I found that the 'getWindow' method had default parameters of
(x = 0, y = 0, width = -1, height = -1)
So no matter what screen I called the getWindow method with, it kept giving me the same geometry. So to fix this, it's simply:
//Screen geometry
QRect g = screen->geometry();
//Take the screenshot using the geometry of the screen
QPixmap screenShot = screen->grabWindow(0, g.x(), g.y(), g.width(), g.height());

Visual C++ Transparent BackColor of Button

I know this question has been already asked quite some times, but i would like to specify it. I got an image, which displays a circle blue X and I would like to make my own exit button in a Windows application form.
To do that, i added a button in the form and loaded the image on the button. However, the backcolor of the button ruins the image as it is grey. So i have tried:
private: System::Void button1_Paint(System::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e) {
this->TransparencyKey = BackColor;
}
This doesn't work at all (The backcolor is still grey). So i have tried this:
private: System::Void button1_Paint(System::Object^ sender,
System::Windows::Forms::PaintEventArgs^ e) {
this->BackColor = System::Drawing::Color::Transparent;
}
Here i got a message: This control doesn't support transparent colors
Ok, so how am i gonna do this?
thanks
In WPF as well as win32, controls or child windows in general can't have color transparency.
But they can have a non rectangular region. Any shape, including holes.
Use the control's region property to change it's region. There's an example in this link on how to draw a round button.
FYI, pixels that are outside the region are NOT receiving any messages/notifications.
Examples of crazy shaped controls:
Button shaped like a person's head.
Spiral shape.
3 triangles that do not touch each other.
Chess board - every 2nd pixel is transparent.
Also, a region is dynamic, can be changed after object creation, so your button can grow and shrink...
It's also pretty fast.
Limitations:
No alpha blending - either opaque or fully transparent.
I wrote a function (C++/win32) that takes a control and a BMP, both have the same size, scan the BMP for a "tranparent" color (you decide which color) and remove all pixels in that color from the region of the control. This is about half a screen of code.
Set the Background-property to Transparent:
btn->Background = System::Drawing::Color::Transparent;
By the way, don't do this in the Paint-Handler. Instead, do it in the constructor or any initialization function.
Update:
Ok, got it - it's a Windows Forms application. See this C# Windows Form Application Transparent button link for some solutions for your problem.
Another possibility (that I have used in projects before) would be to use a PictureBox instead and listen to the MouseClick-event.

Is it possible to determine screen orientation in a native Windows 8.1 Desktop App?

I need to account for the different orientations a device can be in. Aka landscape, landscape flipped, portrait, or portrait flipped. My app is written in native C++ and is running on Windows 8.1 as a desktop app (cross platform is not a requirement in any way).
I know that I can determine if the device is in portrait or landscape using methods outlined by Microsoft here: http://msdn.microsoft.com/en-us/library/ms812142.aspx
However, there's no way to discern between landscape and landscape flipped (or portrait and portrait flipped).
I could get exactly what I need by checking the DisplayInformation.CurrentOrientation property but it's a WinRT API. Which means if I wanted to use it, my app would have to use CLR, which is a non-starter.
Also I'd really like to keep my app as a single executable and I don't think there's a clean way to do that and call managed APIs at the same time. But then again, I'm very inexperienced with native + managed code integration.
So, does anyone know of any way of figuring out display orientation using only native code in Windows?
I figured this out. It's actually a lot easier than I thought. EnumDisplaySettings() doesn't populate the dmDisplayOrientation field in the DEVMODE struct, but EnumDisplaySettingsEx() does. So it's actually really easy :)
There's a good example here.
Detect window SizeChanged in the XAML:
<Page x:Class="ClockCpp.MainPage"
Loaded="Page_Loaded"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ClockCpp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="black"
SizeChanged="Page_SizeChanged">
Then use is to toggle between portrait or landscape:
Boolean t46 = true;
void ClockCpp::MainPage::Page_SizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
if (t46 == true)
{
t46 = false; // portrait
timetext->FontSize = 120; // 2/3 of 180
Othercontrols->Visibility = Windows::UI::Xaml::Visibility::Visible;
}
else
{
t46 = true; // landscape
timetext->FontSize = 180;
Othercontrols->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
}
You could also compare the screen height and width. If the width value was more higher then it's landscape and vice versa..
#include <windows.h>
int theScreenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int theScreenHeight = GetSystemMetrics(SM_CYFULLSCREEN);
if (theScreenWidth > theScreenHeight)
MessageBox(NULL,"Run in landscape.","Landscape",MB_OK);
else
MessageBox(NULL,"Run in portrait.","Portrait",MB_OK);

How to save to a bitmap in MFC C++ application?

I am just starting with MFC so please be tolerant ;).
I have wrote (it was mostly generated to be honest) a simple application which should do the Paint chores: drawing lines, rectangulars, ellipses, changing a color of object to be drawn etc.
I need to save what has been drawn on the screen into a bmp file. Any ideas how can I achieve this ?
I do not know if that's relevant but I am drawing objects on the screen without the use of any CBitmaps or things like that. Here is a part of code responsible for drawing :
CPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
Anchor.x=point.x;
Anchor.y=point.y;
OldPoint.x=Anchor.x;
OldPoint.y=Anchor.y;
if(pDoc->shapeCount>=MAX_SHAPES) return;
pDoc->shapeCount++;
if(bFreehand)
{
pDoc->m_shape[pDoc->shapeCount-1] = new Shape;
pDoc->m_shape[pDoc->shapeCount-1]->shape = ePoint;
}
if(bLine)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CLine;
pDoc->m_shape[pDoc->shapeCount-1]->shape = eLine;
}
if(bRectangle)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CRectangle;
pDoc->m_shape[pDoc->shapeCount-1]->shape = eRectangle;
}
if(bEllipse)
{
pDoc->m_shape[pDoc->shapeCount-1] = new CEllipse;
pDoc->m_shape[pDoc->shapeCount-1]->shape=eEllipse;
}
pDoc->m_shape[pDoc->shapeCount-1]->x=point.x;
pDoc->m_shape[pDoc->shapeCount-1]->y=point.y;
pDoc->m_shape[pDoc->shapeCount-1]->x2=point.x;
pDoc->m_shape[pDoc->shapeCount-1]->y2=point.y;
pDoc->m_shape[pDoc->shapeCount-1]->Pen=CurrentPen;
pDoc->m_shape[pDoc->shapeCount-1]->Brush=CurrentBrush;
bButtonDown=true;
SetCapture();
I have found this way to do it but I don't know how to obtain screen width and height to fill it in the CreateBitmap parameter's list
CBitmap *bitmap;
bitmap.CreateBitmap(desktopW, desktopH, 1, 32, rgbData);
CImage image;
image.Attach(bitmap);
image.Save(_T("C:\\test.bmp"), Gdiplus::ImageFormatBMP);
The CreateBitmap call only requires the desktop width and height if the image you wish to save is actually the entire size of the screen. If that's indeed your intent, you can use CWnd::GetDesktopWindow() to get a CWnd object that you can query for its width and height:
http://msdn.microsoft.com/en-us/library/bkxb36k8(v=VS.80).aspx
That gets dodgy in general...if for no other reason than multi-monitor scenarios...so I'd recommend against it unless you really feel like writing a screen capture app.
What you probably want to do isn't to take a full screen shot, but just save the contents of your program's window. Typically you'd do this by breaking out the drawing logic of your program so that in the paint method you call a helper function that is written to take a CDC device context. Then you can either call that function on the window-based DC you get in the paint call or on a DC you create from the bitmap to do your save. Note that you can use a CBitmap in CDC::SelectObject:
http://msdn.microsoft.com/en-us/library/432f18e2(v=VS.71).aspx
(Though let me pitch you on not using MFC. Try Qt instead. Way better.)

Manually drawing gradients for buttons, toolbars, tabs etc?

I would like to update some toolbar-like code we have to have a Vista/Win7 gradient roundedness to them.
Currently, the buttons have the Windows 2000 look & feel: blocky, single-tone.
I've played around with the XP themes, and using DrawThemeBackground, DrawThemeEdge, etc.; but I'm very dissatisfied with the theme drawing mechanics (the buttons are large, and the theme draws them as 2-tone, top half and bottom half, which looks okay when the buttons are small - it gives them a halfway decent appearance of being a gradient or having a rounded quality to them. But as large as these buttons are, they look stupid.
Experimenting by simply observing how many of the controls are drawn in various apps and controls, I can see that most of them seem to use gradients - where the top of the control appears a light color and fades to the bottom to a darker color - OR - where it is a lighter color than the background at the top, increases towards near-white at the middle, then fades back to a darker color towards the bottom.
I'm not really sure where to go from here. DrawThemeXXX seem to be inadequate. I don't really want to replace the entire control with a new one that has improved drawing but would require that I swap out some of the code for how the current custom control works, and risk various problems with some other library. I'd rather just have a way to draw arbitrary objects in the style of the current version of Windows that I'm running on. I would have thought that the theme drawing functions would have covered this. But they're fairly brain damaged, as I described.
Can someone point me towards 'How are modern C++ applications supposed to draw custom GUI elements so that they might reasonably expect a graceful appearance under XP, Vista, and Windows 7?'
We use MFC, Gdiplus, and raw Win32 APIs in our code, currently.
Here's to hoping someone knows a great deal about drawing modern GUIs under Windows from C++!
Just so that this isn't a wall of text, here's the current version of the paint handler, which draws the button with an etched border when 'hot-tracking' and both an etched border and the icon + text "depressed" (shifted by 1,1) when in a pressed state:
void CPlacesButton::PaintButton(CDC & dc, CRect & rcClient)
{
const int kLabelHeight = 8;
COLORREF clrHiLt = GetSysColor(COLOR_BTNHIGHLIGHT);
COLORREF clrShdo = GetSysColor(COLOR_BTNSHADOW);
COLORREF clrText = GetSysColor(COLOR_BTNTEXT);
COLORREF clrFace = GetSysColor(COLOR_BTNFACE);
// draw the button's background & border
if (m_bPressed || m_bDrawPressed || m_bMouseOnButton)
{
COLORREF clrDarkened = Darken(clrFace, -0.01f);
dc.FillRect(rcClient, &CBrush(clrDarkened));
//dc.Draw3dRect(rcClient, clrShdo, clrHiLt);
//dc.RoundRect(&rcClient, CPoint(10,10));
dc.DrawEdge(&rcClient, EDGE_ETCHED, BF_RECT|BF_FLAT);
//dc.DrawFrameControl(&rcClient, DFC_BUTTON, DFCS_BUTTONPUSH|DFCS_PUSHED);
}
// else if (m_bMouseOnButton) // hot draw
// //dc.Draw3dRect(rcClient, clrShdo, clrHiLt);
// dc.DrawEdge(&rcClient, EDGE_ETCHED, BF_RECT);
// //dc.RoundRect(&rcClient, CPoint(10,10));
else
dc.FillRect(rcClient, &CBrush(clrFace));
// use transparent mode for everything that follows
dc.SetBkMode(TRANSPARENT);
// center icon
CPoint ptIcon((rcClient.Width() - m_nIconSize) / 2, ((rcClient.Height() - m_nIconSize) / 2) - kLabelHeight);
if (m_bPressed || m_bDrawPressed)
ptIcon.Offset(1, 1);
// determine the state to draw ourselves in
const UINT nState = DST_ICON | (IsEnabled() ? DSS_NORMAL : DSS_DISABLED);
// draw our icon
dc.DrawState(ptIcon, CSize(m_nIconSize, m_nIconSize), m_hIcon, nState, (HBRUSH)NULL);
// create & select the font to use for the button's label
CFont guiFont;
VERIFY(guiFont.CreateStockObject(DEFAULT_GUI_FONT));
AutoSelectGDIObject select_font(dc, guiFont);
// determine clipping rect for label
CRect rcText(0, ptIcon.y+m_nIconSize+kLabelHeight, rcClient.Width(), ptIcon.y+m_nIconSize+kLabelHeight);
rcText.InflateRect(0,20);
if (m_bPressed || m_bDrawPressed)
rcText.OffsetRect(1, 1);
dc.SetTextColor(clrText);
if (IsEnabled())
dc.DrawText(m_strCaption, rcText, DT_VCENTER|DT_SINGLELINE|DT_CENTER);
else
dc.GrayString(NULL, NULL, (LPARAM)(LPCTSTR)m_strCaption, 0, rcText.TopLeft().x, rcText.TopLeft().y, rcText.Width(), rcText.Height());
}
I left some of the commented out variations in the code to indicate some hints as to what other possibilities I've tried. However, they're just a hint, as the complete alternate examples are not present.
Actually duplicating the look of the various flavors of Windows is ridiculously difficult, especially if your app can run on more than one version of windows.
I think that they intended to give you the api's to do this back in the Win2k/Win95 days, but then WinXP came along with shading and overlays, and the old API was completely inadequate.
So they came up with the theme stuff, which isn't really even an API so much as an API and a set of graphical primitives all jammed together. But they didn't follow through and allow the set of graphical primitives to be extended or replaced, so themes only works when your controls are a close match to the standard set.
So, for Win9x/Win2k. You use
DrawFrameControl
DrawEdge
For WinXP
DrawTheme
For WinVista/7
DrawTheme
DwmXXX functions
GradientFill ??
Now I suspect that Windows isn't actually using GradientDraw. I suspect it's actually using some DX10 shaders that are built in to the window manager code, but I don't know how to get at that, s I've been using GradientDraw instead. This code will give you a linear fade from the top of the control to the bottom.
INLINE void SetTrivertex(TRIVERTEX & vtx, int x, int y, COLORREF cr)
{
vtx.x = x;
vtx.y = y;
vtx.Red = (SHORT)(GetRValue(cr) * 256L);
vtx.Green = (SHORT)(GetGValue(cr) * 256L);
vtx.Blue = (SHORT)(GetBValue(cr) * 256L);
vtx.Alpha = (SHORT)(255 * 256L);
}
...
// fill the interior from the top down with a gradient that starts at crTop
// and ends with the crBottom
TRIVERTEX vtx[2];
SetTrivertex (vtx[0], prc->left+1, prc->top+1, crTop);
SetTrivertex (vtx[1], prc->right-1, prc->bottom-1, crBottom);
GRADIENT_RECT gRect = { 0, 1 };
GradientFill(hdc, vtx, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
You never mentioned the MFC Feature Pack. Have you taken a look at it yet? Download for VS2008, included with VS2008 SP1. The CDrawingManager has lots of special effects. It has great support for application themes.
MFC alone isn't exactly skinning friendly. Apart from using another GUI (Qt is great for custom skinning) you can look at solutions like SkinCrafter.