how to set Button BackColor? - windows

How do I change the background color of a button control created using CreateWindow?

The Windows API does not offer many options to customize the appearance of standard controls anymore.
WM_CTLCOLORBTN can be handled by the parent window of a button to control some aspects of a buttons appearance, but uxtheme buttons only use the background brush to paint the area behind the button. The appearance of the face is determined by the current theme.
WM_DRAWITEM can also be handled by the parent window, by setting the BS_OWNERDRAW style on the button. This allows the parent window to completely replace the normal buttons painting logic.

To manage the color of the controls on your dialog box, add a handler to the WM_CTLCOLOR message in your dialog class.
You will then have to add few lines like that :
HBRUSH CYourDialogClass::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_OF_YOUR_BUTTON)
{
pDC->SetBkColor (RGB(0, 0, 255)); // BLUE color for background
pDC->SetTextColor (RGB(255, 0, 0)); // RED color for text
}
return hbr;
}

Related

Is InvalidateRect() enough to ask system to redraw a static control background?

I need to change the font color and background color of a static control. That colors is set by handling the WM_CTLCOLORSTATIC message:
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC) wParam;
SetTextColor(hdcStatic, RGB(fColor.R, fColor.G,fColor.B));
SetBkMode(hdcStatic, TRANSPARENT);
if(hBrush) DeleteObject(hBruash); // free previous brush
hBrush = CreateSolidBrush(RGB(bColor.R, bColor.G, bColor.B));
return (LRESULT) hBrush;
}
I'm calling InvalidateRect() like this, from a button click:
case WM_COMMAND:
switch(LOWORD(wParam))
{
case BUTTONA_ID:
InvalidateRect(hLabel, NULL, TRUE);
break;
}
break;
It this the proper way to ask to the label to be redraw and change its font and background colors?
It this the proper way to ask to the label to be redraw and change its font and background colors?
Yes,a static control doesn't necessarily erase its background prior to drawing the text.
So you can force the control to be invalid, so that you can easily redraw the text without having to perform other additional calls.
More reference: CStatic does not invalidate every time its text is changed

How do I change a button's background color and draw focus rectangle around it?

I changed the button's background color but the button looks like a flat button, the focus rectangle around it is gone, so is the mouse effect when you pass mouse over it.
Below, the mouse over effect I'm talking about.
the regular button:
when mouse pass over it:
Currently the button I changed the background color look like this:
Why does it look like a flat button and how can I change that?
I thought this was going to look like this without focus:
with focus:
I'd like to change that border color too but still have the focus rectangle around it.
Here's my WM_NOTIFY:
case WM_NOTIFY:
{
LPNMHDR pnm = (LPNMHDR) lParam;
if(pnm->hwndFrom == hButton1_tab1 && pnm->code == NM_CUSTOMDRAW)
{
LRESULT res = CustomDrawButton(pnm->hwndFrom, (LPNMCUSTOMDRAW) lParam);
LPNMCUSTOMDRAW nmc = (LPNMCUSTOMDRAW) lParam;
if(nmc->dwDrawStage == CDDS_PREPAINT)
{
HDC hdc = nmc->hdc;
RECT rc = nmc->rc;
FillRect(hdc, &rc, hBrush);
return CDRF_NOTIFYITEMDRAW;
}
}
}
break;
hBrush is defined as:
hBrush = CreateSolidBrush(RGB(0, 128, 0));

SelectObject() not having any effect if called from OnEraseBkgnd()

I have a simple MFC application which draws an ellipse when user left clicks on it. I want to draw a colored ellipse instead of one with a white background. Here are my OnEraseBkgnd() and OnLButtonDown() handlers
HBRUSH NewBrush;
BOOL CMainWindow::OnEraseBkgnd(CDC *pDC){
NewBrush = CreateSolidBrush(RGB(0, 0, 250));
auto res = SelectObject(HDC(*pDC),NewBrush);
if(res==NULL||ERROR(res))
{
MessageBox("SelectObject error");
}
return CFrameWnd::OnEraseBkgnd(pDC); //I have tried return 0, and return 1 as well.
}
void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point){
CClientDC dc(this);
dc.Ellipse(0,0,100,50);
}
I expect a blue ellipse to be drawn, but only a white ellipse gets drawn.
If I do select object in OnLButtonDown() the ellipse is drawn in blue.
void CMainWindow::OnLButtonDown(UINT nFlags, CPoint point){
CClientDC dc(this);
NewBrush = CreateSolidBrush(RGB(0, 0, 250));
SelectObject(HDC(dc),NewBrush);
dc.Ellipse(0,0,100,50);
}
What I don't understand is how that the effect of SelectObject() should be the same, no matter where I do it, as long as I am drawing the ellipse after doing SelectObject(). Since the brush gets attached to the device context, which is a property of my application window. Hence once set should retain its value while the application is running.

IWebBrowser2 control does not resize

I have created a simple Win32 application that embeds the browser control. I handle WM_SIZE on the host window as follows:
case WM_SIZE:
RECT rc = { 0 };
GetClientRect(hwnd, &rc);
::MoveWindow(hWndChild, 0, 0, rc.right, rc.bottom, TRUE);
return 0;
I also handle WM_SIZE on the control window as follows:
case WM_SIZE:
...
IOleInPlaceObject* pl;
ax->OleObject->QueryInterface(IID_IOleInPlaceObject, (void**)&pl);
RECT r;
GetClientRect(ax->Site.Window, &r);
pl->SetObjectRects(&r, &r);
pl->Release();
return 0;
If my initial navigation is set to, say, http://www.microsoft.com, things work as expected. I can resize the host window which in turn resizes the browser control.
However, when I navigate to https://login.live.com, the control just does not resize as shown in the following figure:
Can someone please guide me on what is it that I am missing? Regards.

KineticJS cancel drag instead of stop drag?

I have a kinetic stage and some objects that each are draggable. (See fiddle for example.)
My goal is to allow the user to always be able to middle click to pan the entire stage whether or not he middle clicks on empty space or on any shape drawn to the stage. I need to do this in a way that doesn't break the drag events of existing shapes. Meaning I need the shape dragStart and dragEnd events to be processed normally, but only on left click drag.
I'm able to detect the middle click event on the stage and call dragStop() on the shape if the drag was initiated on one, but calling dragStop() means that the dragstop event is fired and processing occurs on the shape.
// let's pretend that a mouse doesn't have more than 9 buttons
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0];
var mouseDownCount = 0;
document.body.onmousedown = function(evt) {
++mouseDown[evt.button];
++mouseDownCount;
}
document.body.onmouseup = function(evt) {
--mouseDown[evt.button];
--mouseDownCount;
}
stage.on('dragstart', function(e){
if(mouseDownCount){
if(mouseDown[0]){
// Left mouse button drag
if (e.target.nodeType == 'Stage'){
// stop the drag for left click
e.target.stopDrag();
}
} else if (mouseDown[1]){
// Middle mouse button drag
if (e.target.nodeType != 'Stage'){
// stop the drag of the object for left click
e.target.listening(false);
e.target.stopDrag();
e.target.listening(true);
// start the stage drag
e.target.getStage().startDrag()
}
}
}
});
Is there a way to cancel the dragStart event after it has been fired, or in some other way tell dragEnd to not fire? I've tried setting e.target.listening(false) prior to calling dragStop, but that doesn't seem to be working.
Any ideas?
Try to use latest version from GitHub. It has functionality only with left mouse button.

Resources