Announcement

Collapse
No announcement yet.

Weird transparent checkbox

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

  • Weird transparent checkbox

    An app. of mine has a bitmap background instead of the default (or any other) solid color. The dialog has a checkbox and its text should be displayed on a transparent background (as if it were printed on the photograph itself). I found this:
    Code:
    CASE %WM_CTLCOLORSTATIC
      SELECT CASE GetDlgCtrlId(CBLPARAM)
        CASE %IDC_NameOfControl
          SetBkMode CBWPARAM, %TRANSPARENT
          SetTextColor CBWPARAM, %BLACK
          FUNCTION = GetStockObject(%NULL_BRUSH)
        CASE ELSE
          ' don't change all the other controls 
          EXIT FUNCTION
      END SELECT
    This works, until ... the text is dynamically changed and the new text is placed without deleting the old string, which makes it de facto unreadable. Any idea how to overcome this?

    Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
    http://zijlema.basicguru.eu
    *** Opinions expressed here are not necessarily untrue ***

  • #2
    until ... the text is dynamically changed and the new text is placed without deleting the old string
    Um, delete the old string by overwriting it with spaces before writing the new string? Force a redraw of the entire control and not just the text area by doing an InvalidateRect() with background erase=true + UpdateWindow() ?
    Michael Mattias
    Member
    Last edited by Michael Mattias; 15 Jan 2008, 09:28 AM.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      The problem has to do with how Transparent controls work.

      They do not draw their background. They simply draw objects on the existing background. Windows generates WM_PAINT for all non-transparent controls first and then it generates WM_PAINT for the transparent controls (WS_EX_TRANSPARENT extended style). These controls don't draw like normal controls. They don't repaint their background.

      I had this problem when writing my GUI engine. The SetText command I wrote had problems when changing the text on static or button class controls which use the WS_EX_TRANSPARENT extended style.

      The solution was this:

      - get the controls coordinates (RECT) and its area.
      - convert those values to the client coordinates of the parent dialog
      - invalidate (use InvalidateRect API function) that area on the parent dialog.

      This will force the dialog to repaint the controls background and the control will repaint the text.
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        Bingo!

        Thanks Chris,

        Your idea works. This is the code, I wrote. Is this correct?
        Code:
         
        LOCAL rt AS RECT
        GetWindowRect GetDlgItem(CBHNDL, %ID_CONTROL), rt  ' get the control's area inside the dialog
        InvalidateRect CBHNDL, rt, 1                       ' invalidate that specific area

        Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
        http://zijlema.basicguru.eu
        *** Opinions expressed here are not necessarily untrue ***

        Comment


        • #5
          Your control must be in just the right place so the code is accidently working.

          GetWindowrect uses screen coordinates.

          InvalidateRect use client coordinates

          If a window is full screened, they may be close, but still not the same.

          You need to convert the screen coordinates to client coordinates of the dialog.

          The ScreenToClient API function converts coordinates (works with POINT type, not RECT) from screen to client.
          (You will need two calls to ScreenToClient, since it works with POINT structure, one for first coordinate pair in RECT and one for the second coordinate pair)

          Code:
          GetWindowRect GetDlgItem(CBHNDL, %ID_CONTROL), rt
          ScreenToClient CBHNDL, BYVAL VARPTR(rt.nLeft)  ' converts first pair
          ScreenToClient CBHNDL, BYVAL VARPTR(rt.nRight) ' converts second pair
          InvalidateRect CBHNDL, rt, 1
          Chris Boss
          Member
          Last edited by Chris Boss; 15 Jan 2008, 11:14 AM.
          Chris Boss
          Computer Workshop
          Developer of "EZGUI"
          http://cwsof.com
          http://twitter.com/EZGUIProGuy

          Comment


          • #6
            Isn't GetWindowRect() + ScreenToClient() client kind of the long way as long as there is a GetClientRect() function?
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              GetClientRect will not return the entire area of a control, but only the client area (doesn't include borders). Also the client area returned will not be in relation to the parent dialog, but in relation to the control itself (ie. top left corner is always 0,0 and not in relation to the parent dialog).

              What is needed is coordinates which are in relation to the parent dialog and GetWindowRect and then converting to client coordinates of the parent dialog is the only way.

              What we are invalidating is not the control itself, but the area underneath the control on the parent dialog.
              Chris Boss
              Computer Workshop
              Developer of "EZGUI"
              http://cwsof.com
              http://twitter.com/EZGUIProGuy

              Comment


              • #8
                To find out the possible differences I wrote the 4 RECT values to a file, before and after calling the ScreenToClient-function. This were the results.
                Before:
                • nLeft: 354
                • nTop: 285
                • nRight: 552
                • nBottom: 306


                After:
                • nLeft: 138
                • nTop: 41
                • nRight: 336
                • nBottom: 62


                Nevertheless, when I omit the ScreenToClient-calls, the app. still works correctly. So, to be very honest, I do not understand it too well.

                Egbert Zijlema, journalist and programmer (zijlema at basicguru dot eu)
                http://zijlema.basicguru.eu
                *** Opinions expressed here are not necessarily untrue ***

                Comment


                • #9
                  You're right about GetCLientRect. Brain lock here. I actually use getWindowRect+ScreenToClient myself all the time to relocate/resize controls on WM_SIZE.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    I always use MapWindowPoints when converting to/from window and client coordinates.
                    Code:
                       ' Convert from window coordinates to client coordinates of the hDialog
                       GetWindowRect hWndControl, rc
                       MapWindowPoints %HWND_DESKTOP, hDialog, rc, 2
                    You can also use MapWindowPoints to convert individual PointAPI points in addition to Rects.
                    Code:
                       ' Convert from window coordinates to client coordinates of the hDialog
                       GetCursorPos pt
                       MapWindowPoints %HWND_DESKTOP, hDialog, pt, 1
                    Paul Squires
                    FireFly Visual Designer (for PowerBASIC Windows 10+)
                    Version 3 now available.
                    http://www.planetsquires.com

                    Comment


                    • #11
                      Hi all,

                      I'm having a similar problem with radiobuttons. I also use a bmp for my dialog background. What I have found is that while the XP theme manifest is turned on the radiobuttons have a light grey background but when I turn off the manifest by not including it in my resource then the background of the radiobuttons paint correctly and have the background of the dialog.

                      For the most part I like the XP theme; at least, when you consider the highlighted nature of the standard buttons when the mouse flies over them. Most of the other theme features I could do without.

                      Currently I'm running Windows Vista Home Premium SP1 with PBWin 8.4
                      Programming method is SDK.

                      My question: could some of the XP theme features be deselected programmatically without turning them all off.

                      Thanks

                      Comment


                      • #12
                        My question: could some of the XP theme features be deselected programmatically without turning them all off.
                        Unfortunately, no. By including the manifest, you are essentially telling windows "theme all controls and control backgrounds". The answer is the same for progress bars and other common controls - the colors cannot be changed from the theme setting. All you can do is work around it by placing the controls on a child dialog so they "blend" the correct background. If you want it to have a different look for non-themed systems, IsAppThemed can be used for theme detection.
                        kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                        Comment


                        • #13
                          Ah Ha!

                          As I said, I'm running Windows Vista Home Premium SP1 with PBWin 8.4 and the radiobuttons have a light grey background on top of the bitmap when the XP theme manifest is turned on but the radiobutton text blends correctly with the background when the XP Theme is turned off.

                          Recently, I tried my app on an XP SP2 machine and viola the radiobuttons painted correctly no matter if the XP Theme was on or off. Apparently Vista's common dialog DLL is defective. Has anyone noticed this?

                          Comment


                          • #14
                            Vista's default theme is different than XP's. For example Image buttons in XP don't change, but do under Vista.
                            Scott Slater
                            Summit Computer Networks, Inc.
                            www.summitcn.com

                            Comment

                            Working...
                            X