How to make an icon button in C++ - c++

I know how to draw a button in C++ but how would i make an icon on it can someone post source or give reference please? by SendMessage() or if not that way just please paste
Please need easier anwsers without so many files im new a bit

Since you're new, you may also wish to consult the MSDN Library. You can find information on Button Styles (see, specifically, the BS ICON and BS BITMAP styles) and the BM_SETIMAGE message .

If you use MFC then I would recommend you to use the following CButton method SetIcon:
CButton myButton;
// Create an icon button.
myButton.Create(_T("My button"), WS_CHILD|WS_VISIBLE|BS_ICON,
CRect(10,10,60,50), pParentWnd, 1);
// Set the icon of the button to be the system question mark icon.
myButton.SetIcon( ::LoadIcon(NULL, IDI_QUESTION) );
This works very well.

send BM_SETIMAGE message, and pass loaded image handle to lParam.
button1 = CreateWindowW(L"BUTTON", L"&Button", WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_BITMAP, 20, 50, 80, 25, hwnd, (HMENU) 600, NULL, NULL);
hImg = LoadImageW(NULL, L"test123.bmp", IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_LOADFROMFILE);
SendMessageW(button1, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hImg);
P.S: you need to use BS_BITMAP flag when CreateWindow()

Related

How to put an icon on a text button?

I want to have both an image icon and text on the same button, like here in Word for example.
I set an icon on a button, but the text disappears.
HANDLE hBmp = (HBITMAP)LoadImage(g_hDllInstance,
MAKEINTRESOURCE(IDB_BITMAP4),
IMAGE_BITMAP,
NULL,
NULL,
LR_DEFAULTCOLOR);
HWND hwndButton = CreateWindowEx(
NULL,
_T("BUTTON"),
_T("SOME TEXT"),
BS_BITMAP | WS_VISIBLE | WS_CHILD,
point.x - 47,
point.y - 3,
36,
40,
hWnd,
(HMENU)200,
NULL,
NULL);
SendMessage(
(HWND)hwndButton,
(UINT)BM_SETIMAGE,
(WPARAM)IMAGE_BITMAP,
(LPARAM)hBmp);
I have also tried to set the icon on a smaller subwindow on my button, but for some reason my subwindow is not visible.
Instructions on how to get a button to display both an image and text are outlined in the Button Styles reference1:
The appearance of text or an icon or both on a button control depends on the BS_ICON and BS_BITMAP styles, and whether the BM_SETIMAGE message is sent. The possible results are as follows.
BS_ICON or BS_BITMAP set? | BM_SETIMAGE called? | Result
--------------------------+---------------------+--------------------
Yes | Yes | Show icon only.
No | Yes | Show icon and text.
Yes | No | Show text only.
No | No | Show text only
In other words: Don't set the BS_ICON or BS_BITMAP style (but do set the BS_TEXT style), and send a BM_SETIMAGE message once the button has been created.
To see this in action, create a standard Windows Desktop application in Visual Studio, and apply the following changes:
Enable visual styles. This is easiest done by placing a #pragma linker directive into the only compilation unit:
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
Create the button in the main window's WM_CREATE handler:
case WM_CREATE:
{
HWND btn{ ::CreateWindowExW(0x0, L"BUTTON", L"Button text",
WS_VISIBLE | WS_CHILD | BS_TEXT,
10, 10, 200, 50, hWnd, (HMENU)110,
nullptr, nullptr) };
HICON icon{ (HICON)::LoadImageW(::GetModuleHandle(nullptr),
MAKEINTRESOURCEW(107),
IMAGE_ICON, 32, 32, 0x0) };
::SendMessageW(btn, BM_SETIMAGE, IMAGE_ICON, (LPARAM)icon);
}
break;
Make sure to adjust the numeric constants as needed. 110 is the button's control identifier, 107 is the resource ID of the wizard-generated application icon resource, and 32 are the width and height of the requested icon.
This code produces the following output:
1 Note, that you have to enable visual styles for this to work.

WinApi : Add style to combo box

I'm trying to add CBS_OWNERDRAWFIXED style to an existing combobox , my code doesn't work and I have no idea why .
I suspect maybe the expression oldStyle | addedStyle is not valid , but I can't figure out why.
HWND hwnd = CreateWindow(
L"ComboBox",
L"",
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST ,
200,
200,
200,
200,
parentHandle,
(HMENU)1,
GetModuleHandle(NULL),
NULL);
auto comboBoxStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
comboBoxStyle = comboBoxStyle | CBS_OWNERDRAWFIXED;
SetWindowLongPtr(hwnd, GWL_STYLE, comboBoxStyle);
the output is just regular combobox , without any change.
This particular style can only be specified at creation time. The documentation alludes to this when it says:
CBS_OWNERDRAWFIXED
Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are all the same height. The owner window receives a WM_MEASUREITEM message when the combo box is created and a WM_DRAWITEM message when a visual aspect of the combo box has changed.

C++ Button with transparent background

I'm creating a basic application in C++ (Win32 API). I tried to make a button with the CreateWindow() function as seen below:
button1 = CreateWindow("button", TEXT("Click Me!"), WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 100, 200, 70, 25, hwnd, (HMENU)NULL, NULL, NULL);
The problem is that there is a white border around the button as you can see here:
Link
I tried to make it transparent with this code but is doesn't work.
case WM_CTLCOLORBTN:{
HBRUSH hBrushbtn;
hBrushbtn = (HBRUSH)GetStockObject(NULL_BRUSH);
SetBkMode((HDC) wParam, TRANSPARENT);
return ((LRESULT)hBrushbtn);
break;
}
How can I do this?
Thanks
SetBkMode() affects whether or not text rendering is transparent or not, which is not the issue here.
You're going to have to WM_PRINTCLIENT up to the parent control into the button's DC, as I demonstrate here. (Note that my code still calls SetBkMode() for transparent text in checkboxes, groupboxes, labels, etc.; for pushbuttons it won't matter if you're using visual styles).

Change button style on the fly in Win32

Below is part of a working normal win32 application created from scratch, not dialog based. it will show the text on the buttom, not top:
hButtonApply = CreateWindow(
"BUTTON",
"Reset",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_BOTTOM,
95, 130, 120, 40,
hWnd, (HMENU)IDC_BUTTON_RESET, hInstance, NULL);
SendMessage(hButtonApply, BM_SETSTYLE, BS_TOP, TRUE);
this however makes it a radio button:
SendMessage(hButtonApply, BM_SETSTYLE, BS_RADIOBUTTON, TRUE);
same for a resource-defined dialog button control.
Subclassing is acceptable. Owner-Drawn Buttons are not acceptable. Thanks, Haotian Yang
Some window styles can only be set during CreateWindow, I guess this might be one of them.
Did you try SetWindowLong ?
Edit:
This seems to work:
LONG style = GetWindowLong(hBtn,GWL_STYLE);
style = (style & ~BS_BOTTOM) | BS_TOP;
SetWindowLong(hBtn,GWL_STYLE,style);

C++ Win32 API Controls messages

im starting with Win32 api, im adding a button control to my main window with the flowing code:
HWND boton = CreateWindow(
"BUTTON", //
"Caption", //
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles.
250, // x position.
10, // y position.
100, // Button width.
40, // Button height.
hwnd, // Parent window.
NULL, // No menu.
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL); // Pointer not needed.
how can i assign it an id, so i can get the message on the loop, in the message loop im trying to catch the message as WM_COMMAND but i don't get any result i've tried with WM_NOTIFY too.
To assign it an ID, you have to use the hMenu parameter. If you have specified that the window will be a child (i.e. with WS_CHILD), the hMenu parameter will be interpreted as an integer ID for the window. Also, provide the BS_NOTIFY style.
HWND boton = CreateWindow (
"BUTTON",
WS_TAPSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_NOTIFY,
250, 10, 100, 40,
hwnd,
(HMENU)101, // This becomes the Control ID
(HINSTNACE)GetWindowLong(hwnd,GWL_HINSTANCE),
NULL);
EDIT: Special shout goes out to Heath Hunnicutt for the info on BS_NOTIFY.
In fact, you do not need to specify an ID for the button. The problem is your code is missing a style bit to CreateWindow().
You must specify the style BS_NOTIFY for the parent window to receive notifications from Button controls.
You will then receive window message WM_COMMAND with (HIWORD(w_param) == BN_CLICKED) every time your button is clicked. See the BN_CLICKED documentation for more.
Using a control ID is unnecessary because the BN_CLICKED message will provide you with the control's window handle. Because you are already required to keep track of the window handle in order to properly call DestroyWindow when you receive WM_DESTROY comparing the button's window handle is just as easy as using a control ID.
To set the window id, pass it in as if it were an HMENU:
(HMENU) nChildID