Click to See Complete Forum and Search --> : drawing on pushbutton with bitblt


Pohoda
December 2nd, 2006, 03:01 PM
Hi, I'm trying to put bitmap on button with bitblt function (and I can't use BM_SETIMAGE etc.).


global variables:
HINSTANCE hInst;
HWND hWnd;
HWND bt_up;
HBITMAP hBitmapHome;

WM_CREATE:
bt_up = CreateWindow(TEXT("button"), TEXT("HOME"),
WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
10, 10, 100, 100,
hWnd, (HMENU) 1001, hInst, NULL);

WM_PAINT:
...
hdc2 = GetDC(bt_up);
hBitmapHome = LoadBitmap(hInst, TEXT("HOME"));
if (hBitmapHome == NULL)
MessageBox(hWnd, TEXT("bitmap"), TEXT("err"), MB_OK);
hdcMem = CreateCompatibleDC(hdc2);
SelectObject(hdcMem, hBitmapHome);
BitBlt(hdc2, 90, 90, 40, 40, hdcMem, 0,0,SRCCOPY);
DeleteObject(hdcMem);
...


Problem is, that bitmap is under the button, not on it. Anyone has idea where I'm wrong?

kkez
December 3rd, 2006, 05:42 AM
Subclass the button and handle its WM_PAINT message, not its parent one.

Pohoda
December 3rd, 2006, 05:59 AM
Thanks for help, but I'm not sure how can I do it. I write it in C (not C++) so I don't use classes. Is it possible to do it? Give me, please, an example.

ovidiucucu
December 3rd, 2006, 07:43 AM
Set BS_OWNERDRAW (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/Buttons/ButtonReference/ButtonStyles.asp) style for the button then handle WM_DRAWITEM (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/comboboxes/comboboxreference/comboboxmessages/wm_drawitem.asp) notification message sent to its parent.

LPDRAWITEMSTRUCT pdis;
const UINT nButtonID = 1001;
HBITMAP hBitmap, hBitmapOld;
BITMAP bmp;
HDC hdcMem;

switch (message)
{
case WM_CREATE:
CreateWindow(_T("button"), _T(""),
WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_OWNERDRAW,
10, 10, 100, 100,
hWnd, (HMENU)nButtonID, hInst, NULL);
break;
case WM_DRAWITEM:
pdis = (LPDRAWITEMSTRUCT)lParam;
if(nButtonID == pdis->CtlID)
{
hBitmap = LoadBitmap(hInst, _T("HOME"));
GetObject(hBitmap, sizeof(BITMAP), &bmp);

hdcMem = CreateCompatibleDC(pdis->hDC);
hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
BitBlt(pdis->hDC, 0, 0, bmp.bmWidth, bmp.bmHeight,
hdcMem, 0, 0, SRCCOPY);

SelectObject(hdcMem, hBitmapOld);
DeleteObject(hBitmap);
DeleteDC(hdcMem);

switch(pdis->itemState)
{
case ODS_SELECTED:
// ...
break;
case ODS_FOCUS:
// ...
break;
case ODS_DISABLED:
// ...
break;
}
}
break;
// ...
// ...
Note that above code is just a brief example. You can improve it according to your needs, e.g. size the button to fit the bitmap, draw text, draw frame to reflect the button status selected, focused, or disabled (you can even draw a different bitmap for each status).

Pohoda
December 3rd, 2006, 09:15 AM
Thanks very much, now I understand.