Announcement

Collapse
No announcement yet.

COMBOBOX tip..

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Jules Marchildon
    replied
    Borje;

    Yes, I understand the trade-offs between the standard control and the
    extended control w/wo OwnerDraw, but just wanted to add one more point...

    ComboBoxEx have same problem, it triggers last
    selection when one tries to ignore.
    If you are trapping the old messages via WM_COMMAND then yes, same
    problem exist. But using the new messages via WM_NOTIFY, the %CBEN_ENDEDIT
    will allow you to look at the NMCBEENDEDIT structure member .iWhy for
    either of the following values;

    CBENF_DROPDOWN
    CBENF_ESCAPE
    CBENF_KILLFOCUS
    CBENF_RETURN

    and you can return false to allow the control to display the selected item or
    return true to abort the edit selection in the case Esc/Killfocus.

    Regards,
    Jules

    Leave a comment:


  • Borje Hagsten
    replied
    ComboBoxEx has nice ability to easily insert images, but still don't
    like it. Don't like MS way to draw selection around text only. Can be
    confusing for some users.

    Better to use ownerdrawn combo and have better control of things. Did
    quick test and see that ComboBoxEx have same problem, it triggers last
    selection when one tries to ignore.


    ------------------

    Leave a comment:


  • Jules Marchildon
    replied
    Borje;

    Have you looked at using the ComboBoxEx() from the common controls instead?
    This will send a %CBEN_ENDEDIT via %WM_NOTIFY and by using the structure passed
    to you, you can determine if you need to return a False to process the notification
    or True to ignore it and preserves the last action.

    Regards,
    Jules

    Leave a comment:


  • Borje Hagsten
    replied
    Okay, found a working way by looking at coordinates. Could have been so simple,
    if only MS had provided the correct info. Found that %CB_GETDROPPEDCONTROLRECT
    returns a rect that starts from entire control's top, including edit part - down
    to height given at creation time, not visible list's real height. Typical MS logic..

    So, one has to grab both window rect, number of items, item height and cursor
    pos, then calculate real list rect from this for compare. How important is this?
    Depends on importance of code, of course. If combobox selection starts a nuclear
    plant in different ways, I guess it can be a bit important..

    Okay, so we know that MS combobox does not always ignore properly if we click
    outside list or press Escape - instead it repeats last selection. Following
    fixes this stupid and potentially dangerous behaviour:
    Code:
                     CASE %CBN_SELENDOK
                        LOCAL itemCount AS LONG, itemHeight AS LONG, visItems AS LONG
                        LOCAL rc AS RECT, rc2 AS RECT, pt AS POINTAPI
     
                        GetCursorPos pt
                        GetWindowRect CBLPARAM, rc2
                        itemCount  = SendMessage(CBLPARAM, %CB_GETCOUNT, 0, 0)
                        itemHeight = SendMessage(CBLPARAM, %CB_GETITEMHEIGHT, 0, 0)
                        SendMessage CBLPARAM, %CB_GETDROPPEDCONTROLRECT, 0, VARPTR(rc)
     
                        'calculate visible dropdown list's real rect
                        rc.nTop    = rc.nTop + rc2.nBottom - rc2.nTop
                        visItems   = MIN&(itemCount, (rc.nBottom - rc.nTop) \ itemHeight)
                        rc.nBottom = rc.nTop + visItems * itemHeight
     
                        IF PtInRect(rc, pt.x, pt.y) = 0 OR _
                           (GetKeyState(%VK_ESCAPE) AND &H8000) THEN EXIT FUNCTION
     
                        BEEP 'or start a space shuttle to Mars, whatever..

    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Borje --
    "Canceled" means Esc ?
    If so, you can subclass - WM_CHAR exactly will be before SELENDOK.

    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Borje Hagsten
    replied
    Okay, tested with other code and got different result. Lance is right
    as usual, message order cannot be trusted and result may be that if one
    really selects something, one has to repeat selection to make it work.

    So, bad tip - ignore! See it works in own editor because I use sub-classed
    combo and do other stunts on select. But even then, I get unpredictable
    result when I switch between documents and a new list is created.

    Ah well, back to the drawing board again..


    ------------------

    Leave a comment:


  • Borje Hagsten
    replied
    Only thing guaranteed is that nothing is guaranteed. Edwin's solution
    can be better in some situations, but what if we want to reselect last
    item again?

    Like in PBedit's case - sometimes we just want to look at list, and
    sometimes we want to repeat selection to go to beginning of a sub
    or function again. Have implemented "flag-way" in my own editor and
    am pleased with result so far..


    ------------------

    Leave a comment:


  • Edwin Knoppert
    replied
    You can also store the last selected index and compare that.

    Not the same..

    ------------------
    http://www.hellobasic.com

    Leave a comment:


  • Lance Edmonds
    replied
    Is the message order guaranteed in that situation?

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Borje Hagsten
    started a topic COMBOBOX tip..

    COMBOBOX tip..

    A tip for handling ignored selections in a combobox. Background: If a
    combobox list is dropped in order to change a selection, but action is
    cancelled by clicking beside the list, whatever, previous selection is
    reinstated and a %CBN_SELENDOK notification message still is triggered.
    Nothing has changed, but since a %CBN_SELENDOK is triggered, code there
    also will be activated (like, repeated).

    We can see this in for example PBedit's sub/function finder combo, where
    this behaviour can cause some frustration, because an ignored selection
    still triggers latest one and cursor jumps back to start of that one. Not
    fun if we were doing work elsewhere and just wanted to have a look in the
    sub/function finder list..

    Not PBedit's fault - it's default Windows behaviour, but sometimes we want
    to decide behaviour ourselves, and then following simple way can be used.

    I looked at message order and found that a %CBN_SELENDCANCEL is sent before
    %CBN_SELENDOK, so by using this, one can make sure the ignore is respected
    all the way. Just set a static flag in %CBN_SELENDCANCEL and let this flag
    decide action in %CBN_SELENDOK, like:
    Code:
    CALLBACK FUNCTION DlgProc
      SELECT CASE CBMSG  'wMsg
         CASE %WM_INITDIALOG
            STATIC gCBflag AS BYTE
     
         CASE %WM_COMMAND
            SELECT CASE CBCTL  'LOWRD(wParam)
               CASE %IDCOMBO
                  SELECT CASE CBCTLMSG  'HIWRD(wParam)
                     CASE %CBN_SELENDCANCEL 'trap this one to enable proper ignore
                        gCBflag = 1
     
                     CASE %CBN_SELENDOK
                        IF gCBflag THEN     'if user cancels, really ignore
                           gCBflag = 0 : EXIT FUNCTION
                        END IF
                        BEEP   'whatever..
                  END SELECT
            END SELECT
      END SELECT
    END FUNCTION

    ------------------
Working...
X