how to make a picture fit in a static control vc++ win32 - c++

can you tell me how to make a picture fit in a static control, i mean like if you create a static control for viewing pictures and if the picture quality or size of picture is bigger than control then it re size the static control with the size of picture. i could create the control and set the picture to it alright. but i don't know how to make it fit on control. this is how i create control and set picture to it.
Code:
HWND static_con(HWND hWnd, HINSTANCE hInst){
HWND Static_Pic;
Profile_Pic = CreateWindow("STATIC", NULL, SS_BITMAP|WS_CHILD|WS_VISIBLE|WS_TABSTOP, 5,5,33,33, hWnd, NULL, hInst, NULL);
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "camera1.jpg", IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(hBmp == NULL){
MessageBox(NULL, "Error while loading image", "Error", MB_OK|MB_ICONERROR);
}
SendMessage(Static_Pic, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
return 0;
}
and then i call the function in WM_CREATE handler which creates it successfully and now i don't know how to make it fit on control, i really appreciate if you could tell me how to make the picture fit on control.

You can use SS_REALSIZECONTROL
From Microsoft's documentation.
SS_REALSIZECONTROL - Adjusts the bitmap to fit the size of the static control.
You can also manually scale the image. Get the size of the control where image is to go by using GetWindowRect(), then by using StretchBlt() scale the image so that its dimensions match that of the source, then do STM_SETIMAGE.

Related

raw data image is not displayed in picture control using StretchDIBits

I made a picture control (ID= IDC_PICTURE) to display raw data using StretchDIBits().
HWND hDlg,hWndCtl;
hWndCtl =::GetDlgItem(hDlg,IDC_PICTURE);
hdc =:: GetDC(hWndCtl);
::StretchDIBits(hdc,0,0,width,height,0,0,width,height,raw_image,m_pBitMapInfo,DIB_RGB_COLORS,SRCCOPY);
But images is displayed on my desktop screen not inside picture control I made. How can I solve this problem? Thank you very much.
In the following line ...
hWndCtl =::GetDlgItem(hDlg,IDC_PICTURE);
... you haven't initialised hDlg, so it is probably failing and hWndCtl is being returned as NULL.
Then this line ...
hdc =:: GetDC(hWndCtl);
... is effectively GetDC(NULL) which gives you the DC of the desktop.
So, to fix the problem, make sure you pass the HWND of your dialog to GetDlgItem or, as you are using MFC, use the CWnd version of GetDlgItem from within your CDialog derived class like this:
CWnd *pWnd = GetDlgItem(IDC_PICTURE); // add error checking here for NULL return
HDC hdc =::GetDC(pWnd->GetSafeHwnd()); // use the HWND of the control to get the DC
// ... do the blit ...

Changing taskbar icon programmatically (Win32,C++) [duplicate]

This question already has an answer here:
Is there a Windows API for adding badges to taskbar icons?
(1 answer)
Closed 9 years ago.
I have a C++ win32 program, and I'd like to edit the taskbar icon at runtime to display alerts, etc about the program, however I'm not too experienced with the win32 api, and I haven't been able to find anything online. The closest I've found is http://www.windows-tech.info/17/52a5bfc45dac0ade.php which tells how to load the icon off the disc at runtime and change it.
I would like to do what they do in this question: Create an icon in memory with win32 in python but in C++ and without an external library.
I would like to do what they do in this question: Create an icon in memory with win32 in python but in C++ and without an external library
Since the accepted answer uses the wxWidgets library, which is just a wrapper of the Win32 API, the solution translates pretty nicely.
All you need to do is create a bitmap in memory using the CreateCompatibleBitmap function. Then you can draw into that bitmap using the standard GDI drawing functions. Finally, you create the icon using the CreateIconIndirect function.
The hardest part is keeping track of your resources and making sure that you free them all when you're finished to prevent memory leaks. It's way better if it's all wrapped up in a library that makes use of RAII to ensure the objects are properly freed, but if you're writing C code in C++, it would look like this:
HICON CreateSolidColorIcon(COLORREF iconColor, int width, int height)
{
// Obtain a handle to the screen device context.
HDC hdcScreen = GetDC(NULL);
// Create a memory device context, which we will draw into.
HDC hdcMem = CreateCompatibleDC(hdcScreen);
// Create the bitmap, and select it into the device context for drawing.
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, width, height);
HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp);
// Draw your icon.
//
// For this simple example, we're just drawing a solid color rectangle
// in the specified color with the specified dimensions.
HPEN hpen = CreatePen(PS_SOLID, 1, iconColor);
HPEN hpenOld = (HPEN)SelectObject(hdcMem, hpen);
HBRUSH hbrush = CreateSolidBrush(iconColor);
HBRUSH hbrushOld = (HBRUSH)SelectObject(hdcMem, hbrush);
Rectangle(hdcMem, 0, 0, width, height);
SelectObject(hdcMem, hbrushOld);
SelectObject(hdcMem, hpenOld);
DeleteObject(hbrush);
DeleteObject(hpen);
// Create an icon from the bitmap.
//
// Icons require masks to indicate transparent and opaque areas. Since this
// simple example has no transparent areas, we use a fully opaque mask.
HBITMAP hbmpMask = CreateCompatibleBitmap(hdcScreen, width, height);
ICONINFO ii;
ii.fIcon = TRUE;
ii.hbmMask = hbmpMask;
ii.hbmColor = hbmp;
HICON hIcon = CreateIconIndirect(&ii);
DeleteObject(hbmpMask);
// Clean-up.
SelectObject(hdcMem, hbmpOld);
DeleteObject(hbmp);
DeleteDC(hdcMem);
ReleaseDC(NULL, hdcScreen);
// Return the icon.
return hIcon;
}
Adding the error checking and the code to draw something interesting onto the bitmap is left as an exercise for the reader.
As I said in a comment above, once you have created the icon, you can set the icon for a window by sending it a WM_SETICON message and passing the HICON as the LPARAM:
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
You can also specify ICON_SMALL in order to set the window's small icon. If you set only a big icon, it will be scaled down to create the small icon automatically. However, if you set only the small icon, the window will continue to use the default icon as its big icon. Big icons typically have a dimension of 32x32, while small icons typically have a dimension of 16x16. This is not, however, guaranteed, so do not hardcode these values. If you need to determine them, call the GetSystemMetrics function with SM_CXICON and SM_CYICON to retrieve the width and height of big icons, or SM_CXSMICON and SM_CYSMICON to retrieve the width and height of small icons.
A fairly good tutorial on drawing in Windows using GDI is available here. I recommend reading it thoroughly if this is your first time doing this and have no prior experience with GDI.

Static Control Background Color with C++

I am creating a basic GUI with the Windows API and I have run into an issue. It starts with a main window that opens with a custom background color I set (RGB(230,230,230)). It then displays text in the upper left corner with the static control.
settingstext = CreateWindow("STATIC",
"SETTINGS",
SS_LEFT | WS_CHILD,
12,
20,
100,
20,
hwnd,
NULL,
proginstance,
NULL);
ShowWindow(settingstext, 1);
This works, but when the text is displayed I need a way to change the background of it to match the main window or else it just looks like it doesn't blend in.
My question is, how do I do this? I currently use the method below and it works, but I wanted to know, is there a way to permanently set the background color somehow, right after the CreateWindow function for the static control without changing system colors, and just have it apply to that one control and not anything that sends the WM_CTLCOLORSTATIC message. I have experimented around with using the GetDC function and SetBkColor function outside of the message loop but nothing works.
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC) wParam;
SetTextColor(hdcStatic, RGB(0,0,0));
SetBkColor(hdcStatic, RGB(230,230,230));
return (INT_PTR)CreateSolidBrush(RGB(230,230,230));
}
I want to do this because...
I don't want to fill up my message loop with functions that need to be called every time the window repaints.
Have the changes apply to only this static control.
I would be very thankful for any help that could be provided, at least pointing me in the right direction, thanks.
For static text controls there's no permanent way to set the text color or their background. Even if you want to apply the changes to a single static control; you would still have to handle WM_CTLCOLORSTATIC notification message in parent dlgproc just when the control is about to be drawn.
This is due to the DefWindowProc overwriting your changes to the device context each time it handles WM_CTLCOLORSTATIC as stated in the MSDN:
By default, the DefWindowProc function selects the default system colors for the static control.
static HBRUSH hBrush = CreateSolidBrush(RGB(230,230,230));
case WM_CTLCOLORSTATIC:
{
if (settingstext == (HWND)lParam)
//OR if the handle is unavailable to you, get ctrl ID
DWORD CtrlID = GetDlgCtrlID((HWND)lParam); //Window Control ID
if (CtrlID == IDC_STATIC1) //If desired control
{
HDC hdcStatic = (HDC) wParam;
SetTextColor(hdcStatic, RGB(0,0,0));
SetBkColor(hdcStatic, RGB(230,230,230));
return (INT_PTR)hBrush;
}
}
If you're looking to make the control's background transparent over a parent dialog you could use SetBkMode(hdcStatic, TRANSPARENT).
I think there is a permanent way to do it.
Just after you create the label,use GetDC() function to get the Device Context.
Then use:
SetTextColor(hdcStatic, RGB(0,0,0));
SetBkColor(hdcStatic, RGB(230,230,230)); // Code Copied from the above answer by cpx.
And it should do .
Have you considered subclassing the static window and doing owner draw?

how to add bitmap image to buttons in MFC?

I am Trying to add an image to an existing button..I have done that to an extent, the problem is I can add an ownerdrawn Image but am not able to add the extact image that I want.. for the example see the below code
CButton* pBtn= (CButton*)GetDlgItem(ID_WIZBACK);
pBtn->ModifyStyle( 0, BS_ICON );
HICON hIcn= (HICON)LoadImage(
AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDI_ICON3),
IMAGE_ICON,
0,0, // use actual size
LR_DEFAULTCOLOR
);
pBtn->SetIcon( hIcn );
with the above code am converting the bitmap to an icon to add to my button...how can I add the exact Bitmap image directly to an existing button.Please help me frnds..
Steps for assigning bitmap to button in mfc :
Create object of bitmap
Load bitmap by using LoadBitmap()
Get Handle of button using id and GetDlgItem() method
Modify style so that we can assign bitmap to it
use SetBitmap() on button's handle to assign bitmap
Code :
CBitmap bmp;
bmp.LoadBitmap( IDB_BITMAP4 );
CButton* pButton = (CButton* )GetDlgItem(IDC_BUTTON1);
pButton->ModifyStyle(0,BS_BITMAP);
pButton->SetBitmap(bmp);
I actually fixed the problem..what I did is I replaced the HICON with HBITMAP and its working perfect...basically both would work fine but in my case when I loaded the icon into the button the background of the icon was not changing...I tried Bitmap then it work great. Now am working on positioning the Image and to add text...think I could go through
you don't know how much this helped out. Thanks for posting. Also have to change a few other things to bitmap as well ...
CButton* pBtn= (CButton*)GetDlgItem(ID_MYDIALOG);
pBtn->ModifyStyle( 0, BS_BITMAP );
HBITMAP hIcn= (HBITMAP)LoadImage(
AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDB_MYPIC),
IMAGE_BITMAP,
0,0, // use actual size
LR_DEFAULTCOLOR
);
pBtn->SetBitmap( hIcn );
You could subclass existing button using CBitmapButton::SubclassWindow, then use LoadBitmaps.
Use the button classes from the Feature Pack. They have support for showing both text and images on buttons, your regular button can't do that. Look at the 'samples' directory in your VS installation directory.
I want to add some ideas to #Amruta Ghodke 's answer:
You can resize your button using the GetWindowRect and SetWindowPos functions. See an example below:
CRect rc;
pButton->GetWindowRect(rc);
pButton->SetWindowPos(NULL, rc.left, rc.top, myWidth, myHeight, SWP_NOSENDCHANGING | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
If you want to display transparent images, use the software Pixelformer to convert your PNGs to Alpha-enabled BMPs. You will have to:
Go to Image->Properties and set RGB color with alpha channel
Export the file using format A8:R8:G8:B8 and disabled Premultiplied alpha and Top-down row order

Get Thumbnail of background window

I'm trying to get thumbnail pictures of windows that are not visible.
Here's the code I have so far
BOOL CALLBACK WindowProc(HWND hWnd, LPARAM lParam)
{
RECT WindRect;
GetWindowRect(hWnd, &WindRect)
CurrentScreenShot->Next = new ScreenShotList();
CurrentScreenShot = CurrentScreenShot->Next;
HDC SourceDC = GetDC(hWnd);
HDC TargetDC = CreateCompatibleDC(SourceDC);
CurrentScreenShot->ScreenShot = CreateCompatibleBitmap(SourceDC, WindRect.right - WindRect.left, WindRect.bottom - WindRect.top);
BitBlt(TargetDC, 0, 0, WindRect.right - WindRect.left, WindRect.bottom - WindRect.top, SourceDC, 0, 0, SRCCOPY);
ReleaseDC(hWnd, SourceDC);
g_iWindows++;
return TRUE;
}
For now, WindowProc is being called directly using FindWindow to get a handle, though, I eventually want to use EnumWindows to loop through all of the windows to get their thumbnails and store them in a linked list.
WindowProc(FindWindow(NULL, L"File Explorer"), 0);
This code is in a DLL, which is called from a C# Forms application. For now the C# application just takes the bitmap and saves it to a file.
The problem is that unless I use FindWindow to get the visible window (which also happens to be the C# application), the picture ends up being a black box.
Is it possible to get an picture of a background window?
EDIT: This is a Windows Mobile application
There is no redrawing going on for invisible Windows, thats why you cannot get their content from the DC. Try sending a WM_PRINT message to the target window to request that it draws its content to your DC.
Edit:
Sorry, i did not notice this was for Windows Mobile. Other than WM_PRINT, i don't know a way to get the content of an invisible window. Of course you can still show the window (and make sure it is on top / not covered by other windows) and then run the code you have, but thats probably a bit messy.