No announcement yet.

RRBUTTON custom control for PB/DLL

  • Filter
  • Time
  • Show
Clear All
new posts

  • RRBUTTON custom control for PB/DLL

    Don't know where else to announce these controls, so here it goes again..
    (will update my website this weekend and recreate my PB page)

    Uploaded to

    RRBUTTON.INC, combined button/label custom control for PB/DLL.
    Same control can be used as Flat button, Raised Button or even as
    inactive/active Label - the later good for things like URL controls, etc.
    The control can position bitmaps, icons and text in exact location, plus
    show different images and text color depending on flat, up or down state.
    Can even show 3-D text. Sample program provided, to show some of the
    features and how to use the control.

    Public Domain, free to use and modify as you whish..


  • #2
    Borje --
    I tested under Win2000.
    A control is nice, but I found the same problem as in POFFS - automatic button up, unlike button is pressed.

    I avoid SetCapture and use enough simple way (it seems to me suggested by Jules):
    in mouse down I set SetTimer (let's say 10 ms) and test in WM_TIMER a location of cursor (windowFromPoint ?).
    If occurs mouse_up - means "clicked"; if cursor is under another window - automatic button up.

    E-MAIL: [email protected]


    • #3
      Oh-oh, just when you think all is well. Thanks, Semen. Interesting
      too - is problem only when non-clicked mouse moves over control? I
      mean, if to click control, hold down button and move mouse in and out
      from control, does it respond properly? Maybe SetCapture only works
      with control in focus? Strange, if that is so.

      Reason for asking is bigger than this button - I have used SetCapture
      in so many places. WM_TIMER is good tips and I'll have a look at it,
      but it doesn't solve all issues - well, in a way it do, but means a
      lot more code. Wonder why it don't work in Win2K? Think MS are evil there..



      • #4
        I like the progressbar the most Borje!
        Really good looking

        About the timer.
        Sometimes is method is reffered as 'VB building' (The controls way )

        This is not true, MS uses the timer for these matters all the time.
        You can see that in a LB or toolbar etc..



        • #5
          Borje --
          > is problem only when non-clicked mouse moves over control?
          I can't even test: I click a button and after some hundreds ms a button is automatic "up".
          Too fast, I even have no real possibility to move a mouse.

          > Maybe SetCapture only works with control in focus? Strange, if that is so.

          I don't think so also, but there are strange moments. That's why I refused from using it.
          BTW, SetTimer doesn't require a lot of code, at least more that SetCapture (remember no. of ReleaseCapture in your code).

          [This message has been edited by Semen Matusovski (edited September 09, 2001).]


          • #6
            Okay, thanks - you have convinced me, fellows. MS are evil. Will
            change to use timer later on tonight. Must fix my old car first..



            • #7
              Okay, replaced some of the Captures with a timer. Works fine in Win98,
              but so did SetCapture too, so don't know. Kept one for case when button
              is pressed and mouse button released elsewhere. Hope this will work.
              Wonder if MS evil plot is to finally break all app's developed for Win95/98..

              New files uploaded to



              • #8
                Borje --
                I tested flat buttons under Win2000 - nothing changed.
                Just now I am under Win98 SE.
                Behaviour is another (and as expected).
                Found another visible difference: when I move a mouse over control, a button is raised under 98 (nothing happends under 2000).

                E-MAIL: [email protected]


                • #9

                  Fantastic control! Thanks alot AGAIN!

                  One other note, if options set to Raised Label, Show Focus and 3D Text,
                  "after" I have clicked some buttons while Rased button option, I can TAB
                  the focus thru all the controls. I don't think Labels receive focus do they?

                  Thanks again for all your hard work! A very useful control!




                  • #10
                    'SEPTEMBER 10: Added %RBM_SETIMGPOSLOCK to enable image to show
                    'up/down state by itself. Changed some of the code that handles
                    'up/down states, so labels are treated properly in all situations.
                    'Added resource file and some smiley icons to show how new message
                    'can work with image on a button (here on round button).

                    New file uploaded - now a bloated 32 KB one..

                    Win2000 problem: Simply can't understand. If not even timer works, it
                    must be PtInRegion that fails. If PtInRegion fails, where is Bill's
                    phone number? Can't test myself. All works fine for me here in Win95/98.



                    • #11
                      Borje --
                      > it must be PtInRegion that fails.
                      > If PtInRegion fails, where is Bill's phone number?
                      Not agree.

                      I see GetCursorPos (screen coordinates) ... PtInRegion
                      A region in a moment of creation actually is defined in client coordinates.
                      Probably, under 9x PtInRegion does "black work": tests to which window hRgn is selected and so on.
                      But it's not documented and not true for 2000 (and, guess, for NT/XP also).

                      In MSDN there is a sample of PtInRegion: client coordinates, hRgn is not selected.

                      I download latest release and changed 3 PtInRegion by WindowFromPoint (pt.x, pt.y) = (<> ) hWnd.
                      Began to work (except one detail - if cursor is over control and I do Alt-Tab, occurs WM_COMMAND).

                      E-MAIL: [email protected]


                      • #12
                        Nice work! Only the following happens: Under NT4/sp6, the hand-cursor doesn't show
                        (Tested on 3 PC's; the cursor just dissapears, there's nothing.. )
                        Under W2K everything works OK!

                        mailto[email protected][email protected]</A>

                        "Simplicity is a prerequisite for reliability"


                        • #13
                          Borje, excellent work thanks for sharing it with us, I for one have been after something like this for buttons for a long time
                          But I too get the same behavior Peter has described in that with "Show Hand Cursor" checked, the cursor disappears when you move it over the buttons (im also on NT4 like Peter), thats the only irregular behaviour ive noticed though
                          Best regards,



                          • #14
                            I am lost. So in other words, GetCursorPos pt and ScreenToClient hWnd, pt
                            before PtInRegion (or use HI/LOWRD(lParam) directly in mouse event) should
                            corrects this in Win2000? Then it don't work in Win95/98. Sigh! I see sample
                            code in winapi.hlp and at MSDN (and in source code forum) that also must fail.

                            GetRgnBox tells me region uses screen coordinates in Win95/98. (!) GetCursorPos
                            gives screen coordinates. Ok in Win95/98, in other words. Could it be a bug in
                            region handling in Win95/98? Seems like it is - PtInRect gives different result.

                            Strange thing is, if a button looks rounded, a region has been set properly to
                            the control. Region coordinates must then be that of the control, otherwise it
                            wouldn't have a rounded look. In other words, PtInRect and PtInRegion should
                            use same coordinate system. Not true in Win95/98.

                            Maybe only fix is to look for Windows version and alter detection accordingly?
                            Wonder if same problem exist in NT. Strange that no info about the difference
                            can be found at MSDN.

                            Will look more later - must do other things to..



                            • #15
                              Now I really get lost - Peter, is everything really ok in your Win2000?
                              Then why PtInRegion problems in Semen's Win2000?

                              Hand cursor problem is no mystery though. Guess Hand cursor came in later
                              versions of Windows. Will add a Hand.cur to resource file later, to fix this.



                              • #16

                                Does your problem occur with the Universal Regions Button Demo I posted too?
                                Those buttons are ownerdraw type, not full custom, but does do a Point-In-Rect
                                for the Hover action. I just want to compare notes.


                                ' HitTest() -determines if point is inside the button region
                                FUNCTION HitTest(hWnd AS LONG,pt AS POINTAPI) AS LONG
                                    LOCAL hRgn    AS LONG
                                    LOCAL rgnRect AS RECT
                                    LOCAL lresult AS LONG
                                    'create handle to a window region.
                                    hRgn = CreateRectRgn(0, 0, 0, 0)
                                    'copy this window region into it
                                    Call GetWindowRgn(hWnd,hRgn)
                                    'get the bounding rect of this region
                                    Call GetRgnBox(hRgn, rgnRect)
                                    'First check if point is in region bounding rect.
                                    'Then check if point is in the region in addition
                                    'to being in the bounding rect.
                                    lresult = PtInRect(rgnRect, pt.x, pt.y) AND PtInRegion(hRgn, pt.x, pt.y)
                                    'Clean up and exit.
                                    Call DeleteObject(hRgn)
                                    FUNCTION = lresult
                                END FUNCTION
                                ' CheckHover() -is mouse hover inside region, display Hover bmp
                                SUB CheckHover(pt AS POINTAPI, ptCD AS tagCTLDATA PTR)
                                    IF  HitTest(@ptCD.hButton,pt) = %true THEN
                                        IF @ptCD.bCapture = %false THEN
                                            Call SetCapture(@ptCD.hButton)
                                            @ptCD.bCapture = %true
                                        END IF
                                        IF @ptCD.bHover = %false THEN
                                            @ptCD.bHover = %true
                                            Call RedrawWindow(@ptCD.hButton, ByVal %NULL, %NULL, %RFLAG)
                                        END IF
                                        IF @ptCD.bCapture = %true THEN
                                            Call ReleaseCapture()
                                            @ptCD.bCapture = %false
                                        END IF
                                        @ptCD.bHover = %FALSE
                                        Call RedrawWindow(@ptCD.hButton, ByVal %NULL, %NULL, %RFLAG)
                                    END IF
                                END SUB

                                [This message has been edited by Jules Marchildon (edited September 10, 2001).]


                                • #17
                                  Jules --
                                  The Universal Regions Button Demo works more or less normally.
                                  At least, when I press a button, it doesn't automatic up.
                                  Moving cursor over control (changing a color) works fine and de-facto imm.

                                  But I see a problem with, for example, Btn9.
                                  I press it in left part, then move a cursor down.
                                  A button remains "pressed" in area, which is "nearest", but should belong to a dialog.

                                  Guess, that PtInRegion doesn't work here also (PtInRect, of course, works).

                                  [This message has been edited by Semen Matusovski (edited September 10, 2001).]


                                  • #18
                                    Hi Semen;

                                    Thanks for the verification!
                                    Regarding the last point, it suppose to behave that way. This was not my
                                    code, for some reason the origional author did it that way, at least does not
                                    Check the Hover state when the mouse is captured, the button seems to handle it
                                    by default and uses the wrong region. But interesting point, in any case.


                                    [This message has been edited by Jules Marchildon (edited September 10, 2001).]


                                    • #19

                                      Okay, checked a few things, one thing is not certain. Semen, can
                                      you find out what the return value is when CreateRoundRectRgn() is called
                                      in several places in the I suspect on your system that you
                                      are getting a %NULL. ??? I don't think the PtInRect or PtInRegion are the
                                      problem, just a big hunch...


                                      [This message has been edited by Jules Marchildon (edited September 10, 2001).]


                                      • #20
                                        Jules --
                                        No. Create...Rgn and SetWindowRgn works fine.

                                        Let's open MSDN, remarks for SetWindowRgn
                                        After a successful call to SetWindowRgn, the system owns the region specified by the region Handle hRgn.
                                        The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle.
                                        In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.
                                        In other words - if you call SetWindowRgn, say good-buy to hRgn.
                                        Windows have right to do with it's internals, what it wants.

                                        BTW, I saw in Borje's code DeleteObject hRgn. Because actually it doesn't work, nothing happends.
                                        But as I remember 9x, attempt to delete alive hRgn, which was selected by SetWindowRgn, leads to GPF (under 2000 OS simply ignores).

                                        I am lazt to reboot to 9x. I tested under 2000 following:
                                           #Compile Exe
                                           #Register None
                                           #Dim All
                                           #Include "WIN32API.INC"
                                           Function PBProc (ByVal hWnd As Long, ByVal wMsg As Long, _
                                                             ByVal wParam As Long, ByVal lParam As Long) As Long
                                              Select Case wMsg
                                                 Case %WM_SIZE
                                                    Static OldRgn As Long
                                                    Local i As Long, rc As RECT
                                                    GetClientRect hWnd, rc
                                                    i = CreateRoundRectRgn(0, 0, rc.nRight, rc.nBottom, 0.5 * rc.nRight, 0.5 * rc.nBottom)  ' Oval
                                                    If PtInRegion(i, rc.nRight / 2, rc.nBottom / 2) Then MsgBox "First Ok", %MB_TASKMODAL
                                                    SetWindowRgn hWnd, i, 1
                                                    If PtInRegion(i, rc.nRight / 2, rc.nBottom / 2) Then MsgBox "Second Ok", %MB_TASKMODAL
                                              End Select
                                              Function = DefWindowProc(hWnd, wMsg, wParam, lParam)
                                          End Function
                                          Function RegisterPBCtrl As Long
                                             Local wc          As WNDCLASS
                                             Local szClassName As Asciiz * 10
                                             Local hLib        As Long
                                             szClassName      = "PB"
                                             wc.lpfnWndProc   = CodePtr(PBProc)
                                             wc.hInstance     = GetModuleHandle(ByVal %NULL)
                                             wc.hBRBACKGROUND = GetStockObject(%WHITE_BRUSH)
                                             wc.lpszClassName = VarPtr(szClassName)
                                             Function = RegisterClass(wc)
                                          End Function
                                          Function PbMain
                                             Local hDlg As Long
                                             Dialog New %HWND_DESKTOP, "PB URL", ,, 200, 150, %WS_CAPTION Or %WS_SYSMENU To hDlg
                                             Control Add "PB", hDlg, 101, "Test", 10, 45, 80, 40, %WS_CHILD Or %WS_VISIBLE
                                             Dialog Show Modal hDlg
                                          End Function
                                        "First Ok" only. Guess that under 9x there are two "Ok".


                                        E-MAIL: [email protected]