Announcement

Collapse
No announcement yet.

Skin on DDT controls?

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

  • Skin on DDT controls?

    How can I do it? I know with main dialog I simply run:

    Code:
    ..
    ..
    Case %WM_ERASEBKGND
                Select Case UseSkin
                    Case %TRUE                    
                        hBmpDC = CreateCompatibleDC(Cbwparam)
                        SelectObject hBmpDC, hBmp
                        BitBlt Cbwparam, 0, 0, x, y, hBmpDC, 0, 0, %SRCCOPY
                        DeleteDC hBmpDC
                        Function = 1
    ..
    How about for textbox or listbox?

    Thanks

    ------------------
    -Greg
    -Greg
    [email protected]
    MCP,MCSA,MCSE,MCSD

  • #2
    At least, for textboxes and, at least, in some OSes should work
    Code:
       Case %WM_CTLCOLOREDIT
          SetTextColor CbWparam, ...
          SetBkMode CbWparam, %TRANSPARENT
          Function = GetStockObject(%NULL_BRUSH)
    (but it's necessary to update background after each change)

    [This message has been edited by Semen Matusovski (edited March 31, 2001).]

    Comment


    • #3
      Semen,

      That makes perfect sense but what I'm wanting to do is actually
      overlay a BMP instead of a brush. If I'm correct %WM_CTLCOLOREDIT
      simply adjust color properties for a control. What if I want to
      overlay a bmp on a control?

      Thanks

      ------------------
      -Greg
      -Greg
      [email protected]
      MCP,MCSA,MCSE,MCSD

      Comment


      • #4
        Gregery;

        You can't do it from the Dialog procedure !

        You must process the controls WM_ERASEBKGND message to BitBlt
        the Image to its background. This means the only way to accomplish
        this is to subclass the control !



        ------------------
        Chris Boss
        Computer Workshop
        Developer of "EZGUI"
        http://cwsof.com
        http://twitter.com/EZGUIProGuy

        Comment


        • #5
          Greg --
          A way, which I described, works fine for READONLY
          (you fill background, for example, in ERASEBKGND of main dialog).

          If a textbox is not read-only, I know one simple, but not flicker-free way (in EN_UPDATE to ShowWindow 0, then 1).

          Chris -

          To subclass is not a problem, but what to do further ?
          Somehow I tried to "correct" painting in standart textboxes and buttons.
          I lost some hours w/o any success.


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

          Comment


          • #6
            Chris,

            Thanks, I wasn't aware that I even received the WM_ERASEBKGND
            message if I subclass the control.

            Semen I guess that is what I was originally afraid of is the
            flickering of the controls.

            Maybe superclass a text box and use that? You think that it
            would be more realiable as far as apearances?

            ------------------
            -Greg
            -Greg
            [email protected]
            MCP,MCSA,MCSE,MCSD

            Comment


            • #7
              Greg --
              Under Win2000 I exactly see that textbox paints not only in WM_PAINT.
              I am afraid that in WM_KEYDOWN it simply opens DC and draws directly.
              (BTW, for test I use exactly superclass proc).
              I am almost sure that nothing will help.

              To draw and to keep a picture over textbox is simple, but in reverse direction ...
              Easy to write custom control.

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

              Comment


              • #8
                When working with the Edit control (and others that contain text)
                you have to take into consideration how the background is drawn.

                The controls WM_PAINT message will send a WM_CTLCOLORxxxx (ie. WM_CTLCOLOREDIT)
                message to the Dialog procedure of its parent. Three things are done
                here :

                Code:
                SetBkColor hDC, MyRGBColor&     ' Color for text background
                SetBkMode hDC, %OPAQUE          ' set background mode to Opaque
                FUNCTION=MyBrush&               ' Return background Brush handle for non-text background
                EXIT FUNCTION
                When the background mode is Opaque the text itself has its own
                background color (use SetBkColor to set it) and the areas where
                there is no text will be filled with the Brush returned by this
                message.

                To use a Bitmap background for an Edit control would require a few
                steps.

                First, use :

                SetBkMode hDC, %TRANSPARENT

                in the WM_CTLCOLOREDIT message to make the text have a Transparent
                background . This will allow the Bitmap you will paint to show through
                the text itself.

                Second, the Edit control must be subclassed so you can process its
                WM_ERASEBKGDN message. This is where you will paint the background
                with a Bitmap. This messages only gets a DC passed in its parameters
                so you will need to use the API function :

                GetClipBox

                To determine the Rectangle for clipping which is generated by the
                BeginPaint function call in the controls WM_PAINT message.

                Using the rectangle returned by GetClipBox you can BitBlt (or tile
                using multiple BitBlt's) the Bitmap Image into the Edit controls
                background.




                ------------------
                Chris Boss
                Computer Workshop
                Developer of "EZGUI"
                http://cwsof.com
                http://twitter.com/EZGUIProGuy

                Comment


                • #9
                  Chris --
                  It seems to me that I understood your idea.
                  But GetClipBox returns the same value as GetClientRect for parent window.

                  Meanwhile BeginPaint somehow understands invalidated areas. How ?

                  Code:
                     #Compile Exe
                     #Register None
                     #Dim All
                     #Include "WIN32API.INC"
                  
                     CallBack Function SuperEditProc
                        Static OldProc As Long, OffsetWndExtra As Long
                        If CbHndl = 0 Then OldProc = CbWparam: OffsetWndExtra = CbLparam: Exit Function
                        Select Case CbMsg
                           Case %WM_ERASEBKGND
                             Static hBmp As Long, rc As RECT, hBmpDC As Long
                             GetClientRect CbHndl, rc
                             'GetClipBox CbWparam, rc ' <----------------- ????
                             If hBmp = 0 Then _
                                 hBmp = LoadImage(ByVal %NULL, "C:\PbDll60\Samples\Tcp\Smtp.Bmp", _
                                    %IMAGE_BITMAP, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, %LR_LOADFROMFILE)
                             hBmpDC = CreateCompatibleDC(CbWparam)
                             SelectObject hBmpDC, hBmp
                             BitBlt CbWparam, rc.nLeft, rc.nTop, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, hBmpDC, 0, 0, %SRCCOPY
                             DeleteDC hBmpDC
                             Function = 1: Exit Function
                               
                          Case %WM_DESTROY
                             DeleteObject hBmp
                        End Select
                        Function = CallWindowProc(OldProc, CbHndl, CbMsg, CbWparam, CbLparam)
                     End Function
                  
                     Function CreateSuperClass(OldClassName As String, NewClassName As String, lpfnNewWndProc As Long, cbWndExtra As Long) As Long
                        Local wc As WNDCLASSEX
                        wc.cbSize = SizeOf(wc)
                        If GetClassInfoEx(ByVal 0&, ByVal StrPtr(OldClassName), wc) Then
                           CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra
                           wc.hInstance = GetModuleHandle(ByVal 0&)
                           wc.lpszClassName = StrPtr(NewClassName)
                           wc.lpfnWndProc = lpfnNewWndProc
                           wc.cbWndExtra = wc.cbWndExtra + cbWndExtra
                           Function = RegisterClassEx(wc)
                        End If
                     End Function
                     
                     CallBack Function DlgProc
                        Select Case CbMsg
                           Case %WM_CTLCOLOREDIT
                              SetBkMode CbWparam, %TRANSPARENT
                              SetTextColor CbWparam, %White
                              Function = GetStockObject(%NULL_BRUSH)
                        End Select
                     End Function
                  
                     Function PbMain
                        If IsFalse(CreateSuperClass("EDIT", "SuperEdit", CodePtr(SuperEditProc), 4)) Then Exit Function
                  
                        Local hDlg As Long
                        Dialog New 0, "Test", , , 120, 80, %WS_CAPTION Or %WS_SYSMENU Or %WS_MAXIMIZEBOX To hDlg
                        Control Add "SuperEdit", hDlg, 101, "", 10, 10, 100, 60, %WS_CHILD Or %WS_VISIBLE Or %WS_TABSTOP _
                           Or %ES_MULTILINE Or %ES_WANTRETURN, %WS_EX_CLIENTEDGE
                        Dialog Show Modal hDlg Call DlgProc
                  
                     End Function
                  [This message has been edited by Semen Matusovski (edited April 01, 2001).]

                  Comment


                  • #10
                    Semen,

                    I see what your talking about. When I type in the superclass
                    textbox it works fine but if I try to delete the text it is
                    garbled. I also have Win2000. I think that the WM_KEYDOWN
                    causes a DC to be opened and drawn.

                    Any other suggestions?

                    ------------------
                    -Greg
                    -Greg
                    [email protected]
                    MCP,MCSA,MCSE,MCSD

                    Comment


                    • #11
                      Semen's code, with added update handling in dialog's WM_COMMAND.
                      Slight flicker, but works (needs optimization)
                      (edited - removed test with BeginPaint, since it wasn't necessary)
                      Code:
                         #COMPILE EXE
                         #REGISTER NONE
                         #DIM ALL
                         #INCLUDE "WIN32API.INC"
                       
                         CALLBACK FUNCTION SuperEditProc
                            STATIC OldProc AS LONG, OffsetWndExtra AS LONG
                            IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION
                            SELECT CASE CBMSG
                               CASE %WM_ERASEBKGND
                                 STATIC hBmp AS LONG, rc AS RECT, hBmpDC AS LONG
                                 GetClientRect CBHNDL, rc
                                 IF hBmp = 0 THEN _
                                     hBmp = LoadImage(BYVAL %NULL, "C:\PbDll60\Samples\Tcp\Smtp.Bmp", _
                                        %IMAGE_BITMAP, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, %LR_LOADFROMFILE)
                                 hBmpDC = CreateCompatibleDC(CBWPARAM)
                                 SelectObject hBmpDC, hBmp
                                 BitBlt CBWPARAM, 0, 0, rc.nRight, rc.nBottom, hBmpDC, 0, 0, %SRCCOPY
                                 DeleteDC hBmpDC
                                 FUNCTION = 1 : EXIT FUNCTION
                       
                              CASE %WM_DESTROY
                                 DeleteObject hBmp
                            END SELECT
                            FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
                         END FUNCTION
                       
                         FUNCTION CreateSuperClass(OldClassName AS STRING, NewClassName AS STRING, lpfnNewWndProc AS LONG, cbWndExtra AS LONG) AS LONG
                            LOCAL wc AS WNDCLASSEX
                            wc.cbSize = SIZEOF(wc)
                            IF GetClassInfoEx(BYVAL 0&, BYVAL STRPTR(OldClassName), wc) THEN
                               CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra
                               wc.hInstance = GetModuleHandle(BYVAL 0&)
                               wc.lpszClassName = STRPTR(NewClassName)
                               wc.lpfnWndProc = lpfnNewWndProc
                               wc.cbWndExtra = wc.cbWndExtra + cbWndExtra
                               FUNCTION = RegisterClassEx(wc)
                            END IF
                         END FUNCTION
                       
                         CALLBACK FUNCTION DlgProc
                            SELECT CASE CBMSG
                               CASE %WM_COMMAND
                                  IF LOWRD(CBWPARAM) = 101 THEN
                                     LOCAL hDC AS LONG
                                     hDc = GetDc(CBLPARAM) '<- must send this!
                                     SendMessage CBLPARAM, %WM_ERASEBKGND, hDc, 0
                                     InvalidateRect CBLPARAM, BYVAL %NULL, 0 : Updatewindow CBLPARAM
                                     ReleaseDc CBLPARAM, hDc
                                  END IF
                       
                               CASE %WM_CTLCOLOREDIT
                                  SetBkMode CBWPARAM, %TRANSPARENT
                                  SetTextColor CBWPARAM, %White
                                  FUNCTION = GetStockObject(%NULL_BRUSH)
                            END SELECT
                         END FUNCTION
                       
                         FUNCTION PBMAIN
                            IF ISFALSE(CreateSuperClass("EDIT", "SuperEdit", CODEPTR(SuperEditProc), 4)) THEN EXIT FUNCTION
                       
                            LOCAL hDlg AS LONG
                            DIALOG NEW 0, "Test", , , 120, 80, %WS_CAPTION OR %WS_SYSMENU OR %WS_MAXIMIZEBOX TO hDlg
                            CONTROL ADD "SuperEdit", hDlg, 101, "", 10, 10, 100, 60, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP _
                               OR %ES_MULTILINE OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE
                            DIALOG SHOW MODAL hDlg CALL DlgProc
                       
                         END FUNCTION

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




                      [This message has been edited by Borje Hagsten (edited April 01, 2001).]

                      Comment


                      • #12
                        Here is a cleaner implimentation using the %EN_UPDATE event !

                        All that is needed is to invalidate the entire client area of the
                        edit control when %EN_UPDATE is sent.

                        Note: I used my own Bitmap so you may need to change the filename .

                        Code:
                           #COMPILE EXE
                           #REGISTER NONE
                           #DIM ALL
                           #INCLUDE "WIN32API.INC"
                        
                        GLOBAL hDlg AS LONG
                        
                           CALLBACK FUNCTION SuperEditProc
                              STATIC OldProc AS LONG, OffsetWndExtra AS LONG
                              IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION
                              SELECT CASE CBMSG
                                 CASE %WM_ERASEBKGND
                                   STATIC hBmp AS LONG, rc AS RECT, hBmpDC AS LONG
                                   GetClientRect CBHNDL, rc
                                   'GetClipBox CbWparam, rc ' <----------------- ????
                                   IF hBmp = 0 THEN _
                                       hBmp = LoadImage(BYVAL %NULL, "C:\PbDll60\ezgui\samples\logo1.Bmp", _
                                          %IMAGE_BITMAP, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, %LR_LOADFROMFILE)
                                   hBmpDC = CreateCompatibleDC(CBWPARAM)
                                   SelectObject hBmpDC, hBmp
                                   BitBlt CBWPARAM, rc.nLeft, rc.nTop, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, hBmpDC, 0, 0, %SRCCOPY
                                   DeleteDC hBmpDC
                                   FUNCTION = 1: EXIT FUNCTION
                                CASE %WM_DESTROY
                                   DeleteObject hBmp
                              END SELECT
                              FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
                           END FUNCTION
                        
                           FUNCTION CreateSuperClass(OldClassName AS STRING, NewClassName AS STRING, lpfnNewWndProc AS LONG, cbWndExtra AS LONG) AS LONG
                              LOCAL wc AS WNDCLASSEX
                              wc.cbSize = SIZEOF(wc)
                              IF GetClassInfoEx(BYVAL 0&, BYVAL STRPTR(OldClassName), wc) THEN
                                 CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra
                                 wc.hInstance = GetModuleHandle(BYVAL 0&)
                                 wc.lpszClassName = STRPTR(NewClassName)
                                 wc.lpfnWndProc = lpfnNewWndProc
                                 wc.cbWndExtra = wc.cbWndExtra + cbWndExtra
                                 FUNCTION = RegisterClassEx(wc)
                              END IF
                           END FUNCTION
                        
                           CALLBACK FUNCTION DlgProc
                              SELECT CASE CBMSG
                                 CASE %WM_CTLCOLOREDIT
                                    SetBkMode CBWPARAM, %TRANSPARENT
                                    SetBkColor CBWPARAM, %BLACK
                                    SetTextColor CBWPARAM, %WHITE
                                    FUNCTION = GetStockObject(%NULL_BRUSH)
                                    EXIT FUNCTION
                                 CASE %WM_COMMAND
                                      IF LOWRD(CBWPARAM)=101 THEN    ' its the Edit control
                                          IF HIWRD(CBWPARAM)=%EN_UPDATE THEN
                                             InvalidateRect GetDlgItem(hDlg, 101), BYVAL %NULL, 1
                                          END IF
                                      END IF
                                 CASE ELSE
                              END SELECT
                           END FUNCTION
                        
                           FUNCTION PBMAIN
                              IF ISFALSE(CreateSuperClass("EDIT", "SuperEdit", CODEPTR(SuperEditProc), 4)) THEN EXIT FUNCTION
                        
                              DIALOG NEW 0, "Test", , , 120, 80, %WS_CAPTION OR %WS_SYSMENU OR %WS_MAXIMIZEBOX TO hDlg
                              CONTROL ADD "SuperEdit", hDlg, 101, "", 10, 10, 100, 60, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP _
                                 OR %ES_MULTILINE OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE
                              DIALOG SHOW MODAL hDlg CALL DlgProc
                        
                           END FUNCTION

                        ------------------
                        Chris Boss
                        Computer Workshop
                        Developer of "EZGUI"
                        http://cwsof.com
                        http://twitter.com/EZGUIProGuy

                        Comment


                        • #13
                          I didn't test under other OSes (hope, somebody will do this), but it looks that Chris's edition works.
                          Honestly, somehow I tried EN_UPDATE, but used 0 as third parameter in InvalidateRect (typically I do nothing in erasebkgnd).

                          I want to investigate a question with palette for SetTextColor (bitmap it's not a problem - before BltBit).
                          Any thoughts, in which event to realize a palette ?
                          I already tried in CTLCOLOREDIT. It was unsuccessful, but tonight I plan to repeat - just now using Chris's correction.




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

                          Comment


                          • #14
                            Semen,

                            If I'm correct, Chris uses Win95 for development. I'll try and
                            find a Win98 and NT4 machine here at work to test it with.


                            ------------------
                            -Greg
                            -Greg
                            [email protected]
                            MCP,MCSA,MCSE,MCSD

                            Comment


                            • #15
                              Yes, I use WIN95 (OSR1) to test on !



                              ------------------
                              Chris Boss
                              Computer Workshop
                              Developer of "EZGUI"
                              http://cwsof.com
                              http://twitter.com/EZGUIProGuy

                              Comment


                              • #16
                                Chris,

                                Wow Even I know how ugly Win95 OSR1 is. I wonder if IE5.5
                                will even install on that

                                ------------------
                                -Greg
                                -Greg
                                [email protected]
                                MCP,MCSA,MCSE,MCSD

                                Comment


                                • #17
                                  Gregery;

                                  I have IExplorer 5.0 installed which tends to upgrade a number
                                  of OS parts (DLLs).

                                  I have found that working on WIN95 that my software has had few
                                  reports of problems on WIN 98/NT/2K by Beta testers. I try not to
                                  use the fancier API functions and to stick with functions that are
                                  at the core of Windows (least likely to change). Sometimes this limits
                                  what I can do (some functions I can't use), but it tends to make
                                  the software more reliable on more systems.

                                  The only real quirk I came across on WIN 2K that was different on
                                  WIN 95 was that WIN95 only used positive numbers for Handles.
                                  WIN 2K can use negative numbers for handles.

                                  I had to change a lot of code like :

                                  IF hFont>0 THEN

                                  to

                                  IF hFont<>0 THEN



                                  ------------------
                                  Chris Boss
                                  Computer Workshop
                                  Developer of "EZGUI"
                                  http://cwsof.com
                                  http://twitter.com/EZGUIProGuy

                                  Comment


                                  • #18
                                    I gather you mean that under NT/2000, handles are true DWORD values!

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

                                    Comment


                                    • #19
                                      Lance;

                                      Thats a more accurate way to put it.

                                      Since many of us simply use Longs for most everything, handles
                                      are passed using Longs. The problem is that Windows NT/2K use DWords
                                      and they will use all the bits so when the DWord is passed as a long
                                      you can get a negative value.

                                      In essence, if you use Longs for storing Handles , expect negative
                                      values in NT/2K ! If you use DWords then there is no problem since
                                      there is no such thing as a negative DWord.



                                      ------------------
                                      Chris Boss
                                      Computer Workshop
                                      Developer of "EZGUI"
                                      http://cwsof.com
                                      http://twitter.com/EZGUIProGuy

                                      Comment


                                      • #20
                                        Guys --
                                        I hadn't time today to do experiments with palette for foreground/background colors.
                                        But I thought that remains one important question.

                                        Initially Chris suggested to update invalidated regions only.
                                        Realizing of this suggestion reduces flickering, which a little remains
                                        (because in erasebkgnd is updated whole client area).

                                        Somebody has thoughts ?

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

                                        Comment

                                        Working...
                                        X