NO

Author Topic: Problem in placing bitmaps on a button  (Read 12765 times)

pitter2206

  • Guest
Problem in placing bitmaps on a button
« on: December 18, 2010, 09:09:18 PM »
I tried a lot, but the bitmap will not be shown on the button:

Code: [Select]
HBITMAP hbit = SHLoadDIBitmap(L"\\My Flash Disk\\Button.bmp");
HWND imgCtrl = CreateWindow( _T("Button"), buttons[11].text, WS_VISIBLE | SS_CENTERIMAGE | SS_BITMAP, 362, 222, 105, 45, hwndDlg, (HMENU)Button12, ghInstance, NULL);
SendMessage(imgCtrl,STM_SETIMAGE, (WPARAM)IMAGE_BITMAP,(LPARAM)hbit);

If I change _T("Button") to _T("STATIC"), the Bitmap is shown, but... I need a button...  :'(

What the hell is going wrong there?

Edit:

If I push the Button I created, it changes to a checkbox  ??? ??? ???
« Last Edit: December 18, 2010, 09:59:21 PM by pitter2206 »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2116
Re: Problem in placing bitmaps on a button
« Reply #1 on: December 19, 2010, 09:51:37 AM »
http://msdn.microsoft.com/en-us/library/ms926160.aspx
Quote
Note   Windows CE does not support the BS_BITMAP, BS_FLAT, BS_ICON, BS_PUSHBOX, BS_TEXT, or BS_USERBUTTON styles. Use the BS_OWNERDRAW style to create the effects that you would achieve otherwise by using the BS_BITMAP, BS_ICON, or BS_USERBUTTON button styles.
You can use STATIC window with SS_CENTERIMAGE | SS_BITMAP | SS_NOTIFY to send message to WM_COMMAND
for selecting your options.
« Last Edit: December 19, 2010, 10:54:41 AM by timovjl »
May the source be with you

Offline Stefan Pendl

  • Global Moderator
  • Member
  • *****
  • Posts: 582
    • Homepage
Re: Problem in placing bitmaps on a button
« Reply #2 on: December 19, 2010, 12:06:03 PM »
Don't use the static text control styles with the button, you need to use the button styles.

If you use control styles out of context, you will never get the expected result.

The best resource is MSDN, see Windows Controls.

The correct button styles with an explanation are at MSDN Button Styles.
---
Stefan

Proud member of the UltraDefrag Development Team

pitter2206

  • Guest
Re: Problem in placing bitmaps on a button
« Reply #3 on: December 19, 2010, 02:59:36 PM »
Thank you for responding to my problem with the buttons.

STATIC Window creates only a Bitmap, without Button-Style. So you can´t see if the button is pressed or not.

I think there will only one possibility to use bitmaps on a button, if I create an ownerdraw-button... but never tried this an nowhere seen yet, how this would work.

Another thing is, that every bitmap I use, the memory is filled more. The tool I created uses about 3.000Kb now... every bit more will run in errors...
I think it will be better to use standard-buttons in this tool....

For other tools it would be fine, if I would know how it works. Is there someone who could post an example for using ownerdraw-buttons?

Offline Stefan Pendl

  • Global Moderator
  • Member
  • *****
  • Posts: 582
    • Homepage
Re: Problem in placing bitmaps on a button
« Reply #4 on: December 19, 2010, 04:24:25 PM »
No need for owner-drawn buttons, but for using the correct styles and messages.

I just noticed, that you use the static text control message.

Go and read the MSDN page about button styles.

I would really like to know, where you collected this wrong information about using static styles and messages for buttons?
---
Stefan

Proud member of the UltraDefrag Development Team

pitter2206

  • Guest
Re: Problem in placing bitmaps on a button
« Reply #5 on: December 19, 2010, 04:46:53 PM »
I only tried with STATIC... as you can see in my thread.

All the other fine working buttons are created like this:
Code: [Select]
CreateWindow(_T("Button"), buttons[8].text, WS_VISIBLE|WS_CHILD|BS_MULTILINE, 11, 222, 105, 45, hwndDlg, (HMENU) Button9, NULL, NULL);

Only one button I tried to put a bitmap on, because I wanted to mark the exit-button better. So I tried it like that:
Code: [Select]
HBITMAP hbit = SHLoadDIBitmap(L"\\My Flash Disk\\Button.bmp");
HWND imgCtrl = CreateWindow( _T("Button"), buttons[11].text, WS_VISIBLE | SS_CENTERIMAGE | SS_BITMAP, 362, 222, 105, 45, hwndDlg, (HMENU)Button12, ghInstance, NULL);
SendMessage(imgCtrl,STM_SETIMAGE, (WPARAM)IMAGE_BITMAP,(LPARAM)hbit);
OK... I forgot to take the text-var off... but that doesn´t matter in this case...

All tries to put a bitmap on to a button failed....  the only success was, that my button had no bitmap, but CE showed a checkbox instead of a pushbutton...

I studied the MSDN-pages... but I didn´t find the point where I make the mistake...

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2116
Re: Problem in placing bitmaps on a button
« Reply #6 on: December 19, 2010, 06:59:28 PM »
SS_CENTERIMAGE | SS_BITMAP are for STATIC window.

Simplified example for owner draw button in WinCE:
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define IDM_EXIT 6001
#define IDM_TEST 6002
#define IDM_BTN1 6010

LRESULT WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
void OnDestroy(HWND hwnd);
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem);

TCHAR szAppName[] = L"OwnerDrawCE";
TCHAR szFrameClass[] = L"cOwnerDrawCE";
HWND hFrame;
HANDLE hInst;
HWND hWndBtn1, hWndBtn2;
HBITMAP hBM;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
MSG msg;

//memset(&wc, 0, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
// wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = szFrameClass;

if (!RegisterClass(&wc)) {
MessageBox(NULL,L"Error with RegisterClass",0,0);
return 0;
}

hInst = hInstance;

hFrame = CreateWindowEx(WS_EX_CAPTIONOKBTN, szFrameClass, szAppName,
//WS_OVERLAPPEDWINDOW,
WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
if(!hFrame) return 0;
ShowWindow(hFrame, nCmdShow);
UpdateWindow(hFrame);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT WINAPI WndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg) {
case WM_COMMAND: return OnCommand(hwnd,(int)LOWORD(wParam),(HWND)lParam,(UINT)HIWORD(wParam)),0;
case WM_CREATE: return OnCreate(hwnd,(LPCREATESTRUCT)lParam),0;
case WM_DESTROY: return OnDestroy(hwnd),0;
case WM_DRAWITEM: return (OnDrawItem(hwnd,(const DRAWITEMSTRUCT*)lParam),0);

default:
return DefWindowProc(hwnd, wMsg, wParam, lParam);
}
}

BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
OutputDebugString(L"WM_CREATE");
hWndBtn1 = CreateWindow( L"BUTTON", L"Exit", WS_VISIBLE, 5, 5, 105, 45, hwnd, (HMENU)IDM_EXIT, hInst, NULL);
hWndBtn1 = CreateWindow( L"BUTTON", L"Button 1", WS_VISIBLE | BS_OWNERDRAW, 5, 50, 105, 45, hwnd, (HMENU)IDM_BTN1, hInst, NULL);
hBM = SHLoadDIBitmap(L"\\Storage Card\\Button1.bmp");
return 0;
}

void OnDestroy(HWND hwnd)
{
OutputDebugString(L"WM_DESTROY");
if (hBM) DeleteObject(hBM);
PostQuitMessage(0);
}

void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) {
case IDM_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0L);
return;
}
}

void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
{
RECT rc;
HDC hdc;
HDC hdcMem;
HBITMAP hbmOld;
BITMAP bm;

rc = lpDrawItem->rcItem;
hdc = lpDrawItem->hDC;

hdcMem = CreateCompatibleDC(hdc);
hbmOld = SelectObject(hdcMem, hBM);
GetObject(hBM, sizeof(bm), &bm);
//BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
//SelectObject(hdcMem, hbmOld);
if (lpDrawItem->itemState & ODS_SELECTED) {
BitBlt(hdc, 1, 1, bm.bmWidth-1, bm.bmHeight-1, hdcMem, 0, 0, SRCCOPY);
DrawEdge(lpDrawItem->hDC, &rc, EDGE_SUNKEN, BF_RECT);
//DrawEdge(lpDrawItem->hDC, (LPBORDERWIDTHS)&lpDrawItem->rcItem, EDGE_SUNKEN, BF_RECT);
} else {
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
DrawEdge(lpDrawItem->hDC, &rc, EDGE_RAISED, BF_RECT);
}
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
}
« Last Edit: December 20, 2010, 03:18:14 PM by timovjl »
May the source be with you

pitter2206

  • Guest
Re: Problem in placing bitmaps on a button
« Reply #7 on: December 20, 2010, 12:38:17 PM »
Hi timovjl,

thank you for this example, I´ll give it a try...  :)
I think I now understand how to work with ownerdraw-buttons...

Thank you very much!

Happy X-mas for you and your familly!

pitter2206

  • Guest
Re: Problem in placing bitmaps on a button
« Reply #8 on: December 20, 2010, 06:12:04 PM »
Sorry, it´s me again...  :-[

I think I didn´t understand anything...
I tried to understand the code you posted, but what I don´t understand is, how to get a few ownerdraw-buttons with different bmp´s.

Code: [Select]
RECT rc;
HDC hdc;
HDC hdcMem;
HBITMAP hbmOld;
BITMAP bm;

rc = lpDrawItem->rcItem;
hdc = lpDrawItem->hDC;

hdcMem = CreateCompatibleDC(hdc);
hbmOld = SelectObject(hdcMem, hBM);
GetObject(hBM, sizeof(bm), &bm);
if (lpDrawItem->itemState & ODS_SELECTED) {
BitBlt(hdc, 1, 1, bm.bmWidth-1, bm.bmHeight-1, hdcMem, 0, 0, SRCCOPY);
DrawEdge(lpDrawItem->hDC, &rc, EDGE_SUNKEN, BF_RECT);
} else {
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
DrawEdge(lpDrawItem->hDC, &rc, EDGE_RAISED, BF_RECT);
}
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);

This will set the bitmap hBM to all ownerdraw-buttons. How can I put another bitmap on each button?  ???

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2116
Re: Problem in placing bitmaps on a button
« Reply #9 on: December 20, 2010, 07:15:29 PM »
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define IDM_EXIT 6001
#define IDM_TEST 6002
#define IDM_BTN1 6010

LRESULT WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
void OnDestroy(HWND hwnd);
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem);

TCHAR szAppName[] = L"WSDIFrameCE";
TCHAR szFrameClass[] = L"cWSDIFrameCE";
HWND hFrame;
HANDLE hInst;
HWND hWndBtn1, hWndBtn2;
#define BUTTONMAX 2
HBITMAP hBM[BUTTONMAX];

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
MSG msg;

//memset(&wc, 0, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
// wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = szFrameClass;

if (!RegisterClass(&wc)) {
MessageBox(NULL,L"Error with RegisterClass",0,0);
return 0;
}

hInst = hInstance;

hFrame = CreateWindowEx(WS_EX_CAPTIONOKBTN, szFrameClass, szAppName,
//WS_OVERLAPPEDWINDOW,
WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
if(!hFrame) return 0;
ShowWindow(hFrame, nCmdShow);
UpdateWindow(hFrame);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT WINAPI WndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch(wMsg) {
case WM_COMMAND: return OnCommand(hwnd,(int)LOWORD(wParam),(HWND)lParam,(UINT)HIWORD(wParam)),0;
case WM_CREATE: return OnCreate(hwnd,(LPCREATESTRUCT)lParam),0;
case WM_DESTROY: return OnDestroy(hwnd),0;
case WM_DRAWITEM: return (OnDrawItem(hwnd,(const DRAWITEMSTRUCT*)lParam),0);

default:
return DefWindowProc(hwnd, wMsg, wParam, lParam);
}
}

BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
OutputDebugString(L"WM_CREATE");
hWndBtn1 = CreateWindow( L"BUTTON", L"Exit", WS_VISIBLE, 5, 5, 105, 45, hwnd, (HMENU)IDM_EXIT, hInst, NULL);
hWndBtn2 = CreateWindow( L"BUTTON", L"Button 1", WS_VISIBLE | BS_OWNERDRAW, 5, 55, 105, 45, hwnd, (HMENU)IDM_BTN1, hInst, NULL);
hWndBtn2 = CreateWindow( L"BUTTON", L"Button 2", WS_VISIBLE | BS_OWNERDRAW, 5, 105, 105, 45, hwnd, (HMENU)(IDM_BTN1+1), hInst, NULL);
hBM[0] = SHLoadDIBitmap(L"\\Storage Card\\Button1.bmp");
hBM[1] = SHLoadDIBitmap(L"\\Storage Card\\Button2.bmp");
return 0;
}

void OnDestroy(HWND hwnd)
{
OutputDebugString(L"WM_DESTROY");
for (int i = 0; i < BUTTONMAX; i++)
if (hBM[i]) DeleteObject(hBM[i]);
PostQuitMessage(0);
}

void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) {
case IDOK:
case IDM_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0L);
return;
}
}

/*
typedef struct tagDRAWITEMSTRUCT {
  UINT      CtlType;
  UINT      CtlID;
  UINT      itemID;
  UINT      itemAction;
  UINT      itemState;
  HWND      hwndItem;
  HDC       hDC;
  RECT      rcItem;
  ULONG_PTR itemData;
} DRAWITEMSTRUCT;
*/

void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
{
RECT rc;
HDC hdc;
HDC hdcMem;
HBITMAP hBM0;
BITMAP bm;
int nIdx;

if (lpDrawItem->CtlID < IDM_BTN1 || lpDrawItem->CtlID > (IDM_BTN1+BUTTONMAX))
return;

nIdx = lpDrawItem->CtlID-IDM_BTN1;
rc = lpDrawItem->rcItem;
hdc = lpDrawItem->hDC;
//hBM0 = hBM[lpDrawItem->CtlID-IDM_BTN1];
hBM0 = hBM[nIdx];

hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem, hBM0);
GetObject(hBM0, sizeof(bm), &bm);
if (lpDrawItem->itemState & ODS_SELECTED) {
BitBlt(hdc, 1, 1, bm.bmWidth-1, bm.bmHeight-1, hdcMem, 0, 0, SRCCOPY);
DrawEdge(lpDrawItem->hDC, &rc, EDGE_SUNKEN, BF_RECT);
} else {
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
DrawEdge(lpDrawItem->hDC, &rc, EDGE_RAISED, BF_RECT);
}
DeleteDC(hdcMem);

}
May the source be with you

pitter2206

  • Guest
Re: Problem in placing bitmaps on a button
« Reply #10 on: December 20, 2010, 07:19:46 PM »
UFF!!!

Thanks a lot!  :)

pitter2206

  • Guest
Re: Problem in placing bitmaps on a button
« Reply #11 on: December 20, 2010, 07:26:08 PM »
I don´t know what this mistake means:

AAA_Programme_GP5_Medion\test.exe\main.c(91): warning #2176: Unrecognized character escape sequence '\s'.
These lines are marked:

Code: [Select]
hBM[0] = SHLoadDIBitmap(L"\\Storage Card\\Button1.bmp");
hBM[1] = SHLoadDIBitmap(L"\\Storage Card\\Button2.bmp");