locked
Non-MFC Button Controls RRS feed

  • Question

  • Hi

    I'm new to Windows Mobile programming.
    Q:
    I need to create two different buttons on a simple Windows Mobile application screen.
    I'm not sure how the controls are passed between WM_Paint and the button controls.
    Are there code examples out there where they show how to implment these non-MFC button handlers
    eg, where on the touchscreen phone, on tapping the button, it brings me to another screen.

    Thank you
    Thursday, April 30, 2009 4:03 AM

Answers

  • There are lots of ways to do this. The most popular are:
    1. Use a window handle for each button. You create a custom class for your buttons and essentially handle the WM_PAINT, WM_LBUTTONDOWN, WM_LBUTTONUP and maybe WM_ERASEBKGND. You should paint the window differently according to its state: pressed or released. When you "release" the button (WM_LBUTTONUP) you should send a WM_COMMAND message to the parent to notify that the button was pressed. If you want this control to work in a dialog you will have to implement more message handlers, like WM_SETFOCUS and WM_KILLFOCUS.
    2. Paint the button in the container window directly. You will have to handle the same messages as before but on the container window. Each button will have its own RECT and this is how you what button the WM_LBUTTONDOWN and WM_LBUTTONUP messages refer to. The advantage of this approach is speed: having more child windows just makes the user interface run slower. The disadvantage is added work fore you.

    João Paulo Figueira (Device Application Development MVP)
    • Marked as answer by warrentang Wednesday, May 6, 2009 3:15 AM
    Thursday, April 30, 2009 9:09 AM

All replies

  • There are lots of ways to do this. The most popular are:
    1. Use a window handle for each button. You create a custom class for your buttons and essentially handle the WM_PAINT, WM_LBUTTONDOWN, WM_LBUTTONUP and maybe WM_ERASEBKGND. You should paint the window differently according to its state: pressed or released. When you "release" the button (WM_LBUTTONUP) you should send a WM_COMMAND message to the parent to notify that the button was pressed. If you want this control to work in a dialog you will have to implement more message handlers, like WM_SETFOCUS and WM_KILLFOCUS.
    2. Paint the button in the container window directly. You will have to handle the same messages as before but on the container window. Each button will have its own RECT and this is how you what button the WM_LBUTTONDOWN and WM_LBUTTONUP messages refer to. The advantage of this approach is speed: having more child windows just makes the user interface run slower. The disadvantage is added work fore you.

    João Paulo Figueira (Device Application Development MVP)
    • Marked as answer by warrentang Wednesday, May 6, 2009 3:15 AM
    Thursday, April 30, 2009 9:09 AM
  • Hi Joao

    Thanks for responding.
    I like to use the 1. approach.


    I tried this but I still can't get it to work. Nothing painted on main screen.


    Buttons[2].h_bmp = SHLoadImageResource(NULL, IDB_BITMAP1);

     

    hdc = BeginPaint(Buttons[2].hButton,&ps);

    hDC = CreateCompatibleDC (hdc);

    SelectObject( hDC, Buttons[2].h_bmp);

    GetObject (Buttons[2].h_bmp,

     

     

    sizeof (bmp), &bmp);

    RECT rect;

    GetWindowRect(Buttons[2].hButton, &rect);

     

     

    BitBlt (hdc, rect.left, rect.top, bmp.bmWidth, bmp.bmHeight, hDC, 0, 0, SRCCOPY);



    Where should this code snippet be put in ? WM_COMMAND ?
    I don't have a dialog box to draw.
    Just the main window to draw these buttons on it.

    Are my code snippet steps right ?

    I need more help.
    Advance thanks
    Thursday, April 30, 2009 5:44 PM
  • Hi Joao

    If I like to use your 1. approrach, would I create all the custom buttons inside WM_PAINT using the code snippet below ?
    In other words I would have 1 WM_PAINT in the application and not 4 WM_PAINT each in a different "button" function, right ?
    Can you share with us more details on that ?


    Belloc Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals(courtesy of Belloc Contribution)

    With the Windows API you would do as follows :

    Suppose hButtonBitmap is the handle of a bitmap resource containing the button without borders.

    Assume the following code belongs to the procedure that processes the button messages, i.e., hWnd is the button window

    case WM_PAINT:

    BeginPaint(hWnd, &ps);

    //  Create memory DC to contain hButtonBitmap

    hButtonDC = CreateCompatibleDC(ps.hdc);
    hButtonBitmap = SelectObject(hButtonDC, hButtonBitmap);

    //  Create second memory DC where the button borders will be drawn and select into this DC an empty bitmap with the
    //  size of the button bitmap

    hMemDC = CreateCompatibleDC(ps.hdc);
    hBitmap = CreateCompatibleBitmap(ps.hdc, ps.rcPaint.right, ps.rcPaint.bottom);
    hBitmap = SelectObject(hMemDC, hBitmap);

    //  Copy hButtonDC into hMemDC

    BitBlt(hMemDC, 0, 0,  ps.rcPaint.right, ps.rcPaint.bottom, hButtonDC, 0, 0, SRCCOPY);

    //  Paint the button borders with black pixels (1 pixel width)

    PatBlt(hMemDC, 0, 0, ps.rcPaint.right - 1, 1, BLACKNESS);
    PatBlt(hMemDC, ps.rcPaint.right - 1, 0, 1, ps.rcPaint.bottom, BLACKNESS);
    PatBlt(hMemDC,  0, ps.rcPaint.bottom - 1, ps.rcPaint.right , 1, BLACKNESS);
    PatBlt(hMemDC, 0, 0, 1, ps.rcPaint.bottom - 1, BLACKNESS);

    //  Paint the button with drawn borders to its window DC, ps.hdc .

    BitBlt(ps.hdc, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom, hMemDC, 0, 0, SRCCOPY); 

    //  Delete hBitmap e hMemDC

    DeleteObject(SelectObjec(hMemDC, hBitmap));
    DeleteDC(hMemDC);

    //  Delete hButtonDC

    SelectObject(hButtonDC, hButtonBitmap);
    DeleteDC(hButtonDC);

    EndPaint(hWnd, &ps);
    Thursday, April 30, 2009 11:06 PM