Announcement

Collapse
No announcement yet.

sdk transparent labels on gradient bkgrnd

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

  • #21
    Post a compileable sample with the bare essentials.
    What happens when you drag the mouse in the text box?
    Dominic Mitchell
    Phoenix Visual Designer
    http://www.phnxthunder.com

    Comment


    • #22
      Hi Dominic,

      Just wanted to post lastest testing info. See if I can do what you said,
      but will be later tonight.

      If I CALL PaintBg(CBHNDL, CBWPARAM,0,0,0) from %WM_CTLCOLOREDIT, it paints gradient rect behind textbox alright and dialog is not transparent, but any editing flickers as bad as ever?
      Code:
        
         CASE %WM_CTLCOLOREDIT
            SELECT CASE GetDlgCtrlID(CBLPARAM) 
              CASE 104
               SelectObject CBWPARAM, hFont11
               SetTextColor CBWPARAM, RGB(64,0,0)
               SetBkMode CBWPARAM,%TRANSPARENT
               CALL PaintBg(CBHNDL,CBWPARAM,0,0,0)
              FUNCTION = hFont11
            END SELECT
            EXIT FUNCTION
      In Sub PaintBg, I use:
      GetWindowRect GetDlgItem(hDlg, %IDT_TEXT), rc

      Comment


      • #23
        Dominic,

        Here compilable sample:

        Code:
        #COMPILE EXE
        #REGISTER NONE
        #DIM ALL
        #IF NOT %DEF(%WINAPI)
            #INCLUDE "WIN32API.INC"
        #ENDIF
        
        %IDT_TEXT       = 1000
        
        GLOBAL hDlg AS DWORD
        GLOBAL ghKbrdHook, KEYP, KEY13 AS LONG
        GLOBAL lpfnKbrdHook AS LONG
        '========================KEYBOARDHOOK FUNCTION===================================================
           FUNCTION KeyboardHook(BYVAL iCode AS INTEGER, BYVAL wParam AS LONG, _
            BYVAL lParam AS LONG) AS DWORD
            FUNCTION = CallNextHookEx(ghKbrdHook, iCode, wParam, lParam)
             IF iCode = %HC_ACTION THEN
               IF ISFALSE(lParam AND &H80000000) THEN ' KeyUp
                STATIC nHook AS LONG
                INCR nHook
                KEYP = wParam
                IF KEY13 = 1 THEN
                   KEYP = 32  ' <SPACE BAR>, SUB PRINTRECORD, 7-18-2007, so dialog does not leave shadow
                END IF
               END IF
             END IF
           END FUNCTION
            
           FUNCTION MakeFont(BYVAL SYSFont AS STRING, BYVAL PointSize AS LONG) AS LONG
             LOCAL hDC      AS LONG
             LOCAL CyPixels AS LONG
             hDC = GetDC(%HWND_DESKTOP)
             CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
             ReleaseDC %HWND_DESKTOP, hDC
             PointSize =-MulDiv(PointSize, CyPixels, 72)
             FUNCTION = CreateFont(PointSize, 0, 0, 0, %FW_NORMAL, 0, 0, 0, _
             %ANSI_CHARSET, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                %DEFAULT_QUALITY, %FF_DONTCARE, BYCOPY SYSFont)
           END FUNCTION
        
           FUNCTION WINMAIN (BYVAL hCurInstance  AS LONG, _
                              BYVAL hPrevInstance AS LONG, _
                              BYVAL lpszCmdLine   AS ASCIIZ PTR, _
                              BYVAL nCmdShow      AS LONG) EXPORT AS LONG
             ' File to open when program starts up
             CALL MAINDIALOG
           END FUNCTION 'FUNCTION WINMAIN
        
           CALLBACK FUNCTION CancelCallBack
              DIALOG END CBHNDL, 0
           END FUNCTION
        
           SUB MAINDIALOG
             STATIC hBrush50 AS DWORD
             LOCAL    Result AS LONG
             GLOBAL   x1, y1, x2, y2, hToolTip AS LONG
              x1 = 77: y1 = 22: x2 = 407: y2 = 347 ' = units 407 wide for windows 98, 10-22-2007
             ' Create our top level primary GUI
             DIALOG NEW %HWND_DESKTOP, "", 0, 0, x2, y2, _
               %DS_CENTER OR %DS_SETFONT OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX _
               OR %WS_OVERLAPPEDWINDOW, %WS_EX_CONTROLPARENT, TO hDlg
        
             IF ERR OR hDlg = 0 THEN EXIT SUB  ' Error occurred
             
             CONTROL ADD TEXTBOX,  hDlg, %IDT_TEXT,      "",              58,   74 ,270, 205, _
              %ES_NOHIDESEL OR %ES_AUTOVSCROLL OR %ES_MULTILINE OR %ES_LEFT _
               OR %WS_TABSTOP, %WS_EX_TRANSPARENT
               
             CONTROL ADD BUTTON,  hDlg, %IDCANCEL,    "&Quit",  370,  305,  31,  14 CALL CancelCallBack
             ', %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_OWNERDRAW OR %BS_PUSHLIKE, 0
        
             DIALOG SHOW MODAL hDlg, CALL MAINDIALOGCallBack TO Result
        
             IF Result = 0 THEN
              EXIT SUB
             END IF
             DIALOG END hDlg
             hDlg = 0
           END SUB
        
           CALLBACK FUNCTION MAINDIALOGCallBack
            SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
             '--------------------------------------------------------------------
             ghKbrdHook = SetWindowsHookEx(%WH_KEYBOARD, CODEPTR(KeyboardHook), _
             0, GetCurrentThreadId)
             '====================================================================
             LOCAL Lb         AS LOGBRUSH
             LOCAL lf         AS LOGFONT
             STATIC hFont11    AS LONG
             STATIC hBrush10  AS LONG
             
               hFont11 = MakeFont("MS Sans Serif", 8)
               GetObject hFont11, SIZEOF(lf), BYVAL VARPTR(lf)
               lf.lfWeight = %FW_BOLD
               Lb.lbStyle  = %NULL_BRUSH
               hBrush10  = CreateSolidBrush(GetSysColor(%COLOR_3DFACE))
               
               SendMessage GetDlgItem(hDlg, %IDCANCEL), %WM_SETFONT, hFont11, 0
               SendMessage GetDlgItem(hDlg, %IDT_TEXT), %WM_SETFONT, hFont11, 0
               
            CASE %WM_CTLCOLOREDIT
              SELECT CASE GetDlgCtrlID(CBLPARAM) ' paints textbox background, but flickers
                CASE 1000
                 SelectObject CBWPARAM, hFont11
                 SetTextColor CBWPARAM, RGB(64,0,0)
                 SetBkMode CBWPARAM,%TRANSPARENT
                 CALL PaintBg(CBHNDL,CBWPARAM,0,0,0)
                FUNCTION = hFont11
              END SELECT
        
             CASE %WM_DESTROY
                ' The dialog is being destroyed, so release the bitmap handle
                 UnhookWindowsHookEx ghKbrdHook
                 DeleteObject hBrush10
              'For windows 98 problem to fix 1 keypress exit 3-27-2006 AND SKINS 4-24-2006
              DIALOG END CBHNDL, 5000
              
              ' Initialization handler - KEEPS HELPFILE ON TOP AND DISABLES hDlg, 2-19-2008
            CASE %WM_NCACTIVATE
              STATIC hWndSaveFocus AS DWORD
              IF ISFALSE CBWPARAM THEN
              ' Save control focus
              hWndSaveFocus = GetFocus()
              ELSEIF hWndSaveFocus THEN
              ' Restore control focus
              SetFocus(hWndSaveFocus)
              hWndSaveFocus = 0
              END IF
              
            CASE %WM_COMMAND
               SELECT CASE AS LONG CBCTL
                IF CBCTL = %IDT_TEXT THEN
                 KEY13 = 1
                 
                 SELECT CASE HIWRD(CBWPARAM)
                    CASE %EN_UPDATE,%EN_CHANGE,%EN_VSCROLL
                       CALL reduceflick ' USE THIS IN PLACE OF "control redraw cbhndl, %idt_text
                 END SELECT
                 'EXIT FUNCTION   ' Causes redraw
                END IF
                FUNCTION = 1
                ' To close program with 1 keypress for windows 98, must be a case, not if cbctl
                CASE %IDCANCEL ' <ESC> KEY
                 IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                  DIALOG POST CBHNDL, %WM_USER + 500, 0, 0
                 END IF
                 FUNCTION = 1
                 
               END SELECT
            END SELECT
        
           END FUNCTION ' FUNCTION DIARYCALLBACK FUNCTION
        
        FUNCTION SetColor (BYVAL tCOLOR AS BYTE) AS WORD
            ' the windows api GradientFill routine wants r/g/b colors to be
            ' 16 bit words with the 8 bit color values left shifted 8 bits.
            ' this takes care of that.
            LOCAL clr AS WORD
            clr = tCOLOR
            SHIFT LEFT clr, 8
            FUNCTION = clr
        END FUNCTION
        
        SUB PaintBg(BYVAL hDialog AS LONG, BYVAL hDC AS DWORD, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
             ' this is to paint the background of the dialog
             ' it's all straight out of the MSDN help file.  We can change the values
             ' if we like.
             LOCAL rc AS Rect
             LOCAL Xin&
             LOCAL Yin&,Temp&,cRed&,cGreen&,cBlue&
             DIM vert(1) AS TRIVERTEX
             DIM gRect AS GRADIENT_RECT
        
               ' Tile the background
             GetWindowRect GetDlgItem(hDlg, %IDT_TEXT), rc
        
             Xin = rc.nRight - rc.nLeft
             Yin = rc.nBottom - rc.nTop
             Xin = rc.nRight - rc.nLeft
             Yin = rc.nBottom - rc.nTop
        
             'Temp& = RGB(205,214,255)
             Temp& = RGB(226,187,143) ' TAN 'RGB(255,128,255) ' changes to magenta
             IF Temp& <> 0 THEN
               cRed&   = Temp& MOD 256
               cGreen& = (Temp& \ 256) MOD 256
               cBlue&  = ((Temp& \ 256) \ 256) MOD 256
             ELSE
               cRed&   = 192
               cGreen& = 224
               cBlue&  = 192
             END IF
             vert(0).x      = 0 '29 '58 '116 'textbox up lft col in pixels  '0
             vert(0).y      = 0 '37 '74 '148 'textbox up lft row in pixels  '0
             vert(0).Red    = SetColor(cRed& - 90)
             vert(0).Green  = SetColor(cGreen& - 90)
             vert(0).Blue   = SetColor(cBlue& - 90)
             vert(0).Alpha  = &H0000
             vert(1).x      = xin
             vert(1).y      = yin
             vert(1).Red    = SetColor(cRed&)
             vert(1).Green  = SetColor(cGreen&)
             vert(1).Blue   = SetColor(cBlue&)
             vert(1).Alpha  = &H0000
             gRect.UpperLeft  = 0
             gRect.LowerRight = 1
             GradientFill hDc, vert(0), 2, gRect, 1, %GRADIENT_FILL_RECT_V
        
        END SUB
                       
            SUB ReduceFlick  ' per Chris Boss
               LOCAL rtc AS RECT
               ' Works either way?
               GetWindowRect GetDlgItem(hDlg, %IDT_TEXT), rtc
               ScreenToClient hDlg, BYVAL VARPTR(rtc.nLeft)  ' converts first pair
               InvalidateRect hDlg, rtc, 1
               ScreenToClient hDlg, BYVAL VARPTR(rtc.nRight) ' converts second pair
               InvalidateRect hDlg, rtc, 1
            END SUB
        when I drag mouse in textbox, it gradually disapears?

        Comment


        • #24
          Are all the text boxes multiline, or is it acceptable to make any that are single line mutiline?
          Dominic Mitchell
          Phoenix Visual Designer
          http://www.phnxthunder.com

          Comment


          • #25
            Ignore the last question, the solution I came up with works for both single and mutiline text boxes.
            Dominic Mitchell
            Phoenix Visual Designer
            http://www.phnxthunder.com

            Comment


            • #26
              The following code modifies your sample to avoid flickering.
              This code renders the background and text of the edit control to a memory device context
              and then BitBlt's the image to the screen.
              See WM_CTLCOLORDLG, WM_CTLCOLOREDIT, WM_SIZE(if dialog and controls are resizeable),
              PaintBg, CreateBg, PaintEdit, and Edit_SubclassProc.

              Note: do not add the WS_EX_TRANSPARENT style to the edit controls.
              If the control is resizeable, the WS_EX_TRANSPARENT style will cause flickering.
              In fact, this style serves no purpose when this technique is used.
              Note: the edit control must be subclassed or superclassed.

              Code:
              #COMPILE EXE
              #REGISTER NONE
              #DIM ALL
              #IF NOT %DEF(%WINAPI)
                  #INCLUDE "WIN32API.INC"
              #ENDIF
              
              TYPE DIALOGBACKGROUND
                hBmpOld   AS DWORD
                hDC       AS DWORD
              END TYPE
              
              %IDT_TEXT       = 1000
              
              GLOBAL hDlg AS DWORD
              GLOBAL ghKbrdHook, KEYP, KEY13 AS LONG
              GLOBAL lpfnKbrdHook AS LONG
              
              '========================KEYBOARDHOOK FUNCTION===================================================
              FUNCTION KeyboardHook(BYVAL iCode AS INTEGER, BYVAL wParam AS LONG, _
                       BYVAL lParam AS LONG) AS DWORD
              
                FUNCTION = CallNextHookEx(ghKbrdHook, iCode, wParam, lParam)
              
                IF iCode = %HC_ACTION THEN
                  IF ISFALSE(lParam AND &H80000000) THEN ' KeyUp
                    STATIC nHook AS LONG
                    INCR nHook
                    KEYP = wParam
                    IF KEY13 = 1 THEN
                       KEYP = 32  ' <SPACE BAR>, SUB PRINTRECORD, 7-18-2007, so dialog does not leave shadow
                    END IF
                  END IF
                END IF
              
              END FUNCTION
              
              FUNCTION MakeFont(BYVAL SYSFont AS STRING, BYVAL PointSize AS LONG) AS LONG
              
                LOCAL hDC      AS LONG
                LOCAL CyPixels AS LONG
                hDC = GetDC(%HWND_DESKTOP)
                CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
                ReleaseDC %HWND_DESKTOP, hDC
                PointSize =-MulDiv(PointSize, CyPixels, 72)
                FUNCTION = CreateFont(PointSize, 0, 0, 0, %FW_NORMAL, 0, 0, 0, _
                          %ANSI_CHARSET, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                            %DEFAULT_QUALITY, %FF_DONTCARE, BYCOPY SYSFont)
              
              END FUNCTION
              
              FUNCTION WINMAIN (BYVAL hCurInstance  AS LONG, _
                                BYVAL hPrevInstance AS LONG, _
                                BYVAL lpszCmdLine   AS ASCIIZ PTR, _
                                BYVAL nCmdShow      AS LONG) EXPORT AS LONG
                ' File to open when program starts up
                CALL MAINDIALOG
              END FUNCTION 'FUNCTION WINMAIN
              
              CALLBACK FUNCTION CancelCallBack
                DIALOG END CBHNDL, 0
              END FUNCTION
              
              SUB MAINDIALOG
                STATIC hBrush50 AS DWORD
                LOCAL    Result AS LONG
                LOCAL    hWndControl AS DWORD
                GLOBAL   x1, y1, x2, y2, hToolTip AS LONG
                x1 = 77: y1 = 22: x2 = 407: y2 = 347 ' = units 407 wide for windows 98, 10-22-2007
                ' Create our top level primary GUI
                DIALOG NEW %HWND_DESKTOP, "", 0, 0, x2, y2, _
                 %DS_CENTER OR %DS_SETFONT OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX _
                 OR %WS_OVERLAPPEDWINDOW OR %WS_CLIPCHILDREN, %WS_EX_CONTROLPARENT, TO hDlg
              
                IF ERR OR hDlg = 0 THEN EXIT SUB  ' Error occurred
              
                CONTROL ADD TEXTBOX,  hDlg, %IDT_TEXT,      "",              58,   74 ,270, 205, _
                %ES_NOHIDESEL OR %ES_AUTOVSCROLL OR %ES_LEFT OR %ES_MULTILINE OR %WS_BORDER _
                 OR %WS_TABSTOP 
                ' Subclass text box
                hWndControl = GetDlgItem(hDlg,%IDT_TEXT)
                SetProp hWndControl, "OLDWNDPROC", SetWindowLong(hWndControl, %GWL_WNDPROC, CODEPTR(Edit_SubclassProc))
              
                CONTROL ADD BUTTON,  hDlg, %IDCANCEL,    "&Quit",  370,  305,  31,  14 CALL CancelCallBack
                ', %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_OWNERDRAW OR %BS_PUSHLIKE, 0
              
                DIALOG SHOW MODAL hDlg, CALL MAINDIALOGCallBack TO Result
              
                IF Result = 0 THEN
                  EXIT SUB
                END IF
                DIALOG END hDlg
              
                hDlg = 0
              END SUB
              
              CALLBACK FUNCTION MAINDIALOGCallBack
              
                SELECT CASE AS LONG CBMSG
                  CASE %WM_INITDIALOG
                    '--------------------------------------------------------------------
                    ghKbrdHook = SetWindowsHookEx(%WH_KEYBOARD, CODEPTR(KeyboardHook), _
                    0, GetCurrentThreadId)
                    '====================================================================
                    LOCAL Lb         AS LOGBRUSH
                    LOCAL lf         AS LOGFONT
                    LOCAL trc        AS RECT  
                    LOCAL ptDlgBg    AS DIALOGBACKGROUND PTR
                    LOCAL hDC        AS DWORD
                    LOCAL hDCBg      AS DWORD
                    LOCAL hEdit      AS DWORD
                    LOCAL cxEdit     AS LONG
                    LOCAL cyEdit     AS LONG
                    STATIC hFont11   AS LONG
                    STATIC hBrush10  AS LONG
              
                    CALL CreateBg(CBHNDL,0,0,0)
              
                    hFont11 = MakeFont("MS Sans Serif", 8)
                    GetObject hFont11, SIZEOF(lf), BYVAL VARPTR(lf)
                    lf.lfWeight = %FW_BOLD
                    Lb.lbStyle  = %NULL_BRUSH
                    hBrush10  = CreateSolidBrush(GetSysColor(%COLOR_3DFACE))
              
                    SendMessage GetDlgItem(hDlg, %IDCANCEL), %WM_SETFONT, hFont11, 0
                    SendMessage GetDlgItem(hDlg, %IDT_TEXT), %WM_SETFONT, hFont11, 0
              
                  CASE %WM_CTLCOLORDLG
                    CALL PaintBg(CBHNDL,CBWPARAM,0,0,0)
                    FUNCTION = GetStockObject(%NULL_BRUSH)
              
                  CASE %WM_CTLCOLOREDIT
              
                    SELECT CASE GetDlgCtrlID(CBLPARAM) ' paints textbox background, but flickers
                      CASE %IDT_TEXT
                        SetTextColor CBWPARAM, RGB(64,0,0)
                        SetBkMode CBWPARAM,%TRANSPARENT
                        FUNCTION = GetStockObject(%NULL_BRUSH)
                    END SELECT
              
                  CASE %WM_SIZE
                    CALL CreateBg(CBHNDL,0,0,0)
                    
                    InvalidateRect CBHNDL, BYVAL %NULL, %TRUE
                    UpdateWindow CBHNDL
                    
                    IF CBWPARAM <> %SIZE_MINIMIZED THEN
                      hEdit = GetDlgItem(CBHNDL, %IDT_TEXT)
                      GetWindowRect hEdit, trc
                      MapWindowPoints %NULL, CBHNDL, BYVAL VARPTR(trc), 2
                      SetWindowPos hEdit, %NULL, 0, 0, LO(WORD, CBLPARAM) - trc.nLeft - 20, _
                                   HI(WORD, CBLPARAM) - trc.nTop - 80, %SWP_NOZORDER OR %SWP_NOMOVE
                    END IF
              
                  CASE %WM_DESTROY
                    ptDlgBg = RemoveProp(CBHNDL, "DIALOG_BACKGROUND")
                    IF ptDlgBg THEN
                      DeleteObject SelectObject(@ptDlgBg.hDC, @ptDlgBg.hBmpOld)
                      DeleteDC @ptDlgBg.hDC
                      HeapFree GetProcessHeap(), 0, ptDlgBg
                    END IF
                    ' The dialog is being destroyed, so release the bitmap handle
                    UnhookWindowsHookEx ghKbrdHook
                    DeleteObject hBrush10
                    'For windows 98 problem to fix 1 keypress exit 3-27-2006 AND SKINS 4-24-2006
                    DIALOG END CBHNDL, 5000
              
                  ' Initialization handler - KEEPS HELPFILE ON TOP AND DISABLES hDlg, 2-19-2008
                  CASE %WM_NCACTIVATE
                    STATIC hWndSaveFocus AS DWORD
                    IF ISFALSE CBWPARAM THEN
                      ' Save control focus
                      hWndSaveFocus = GetFocus()
                      ELSEIF hWndSaveFocus THEN
                        ' Restore control focus
                        SetFocus(hWndSaveFocus)
                        hWndSaveFocus = 0
                    END IF
              
                  CASE %WM_COMMAND
              
                    SELECT CASE AS LONG CBCTL
                      IF CBCTL = %IDT_TEXT THEN
                       KEY13 = 1
                      END IF
                      FUNCTION = 1
              
                      ' To close program with 1 keypress for windows 98, must be a case, not if cbctl
                      CASE %IDCANCEL ' <ESC> KEY
                         IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            DIALOG POST CBHNDL, %WM_USER + 500, 0, 0
                         END IF
                         FUNCTION = 1
                    END SELECT
              
                END SELECT
              
              END FUNCTION ' FUNCTION DIARYCALLBACK FUNCTION
              
              FUNCTION SetColor (BYVAL tCOLOR AS BYTE) AS WORD
                  ' the windows api GradientFill routine wants r/g/b colors to be
                  ' 16 bit words with the 8 bit color values left shifted 8 bits.
                  ' this takes care of that.
                  LOCAL clr AS WORD
                  clr = tCOLOR
                  SHIFT LEFT clr, 8
                  FUNCTION = clr
              END FUNCTION
              
              SUB PaintBg(BYVAL hDlg AS LONG, BYVAL hDC AS DWORD, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
              
                LOCAL rc        AS RECT   
                LOCAL ptDlgBg   AS DIALOGBACKGROUND PTR
                LOCAL hDCBg     AS DWORD
              
                ptDlgBg = GetProp(hDlg, "DIALOG_BACKGROUND")
                hDCBg = @ptDlgBg.hDC
                GetClientRect hDlg, rc
                BitBlt hDC, 0, 0, rc.nRight, rc.nBottom, hDCBg, 0, 0, %SRCCOPY
              
              END SUB
              
              '-------------------------------------------------------------------------------
              '
              ' CreateBg
              ' This procedure creates a bitmap, gradient fills it, and stores
              ' the entire thing in a memory device context.
              ' The same technique can be used for bitmaps loaded from a file or a resource.
              '
              '-------------------------------------------------------------------------------
              
              SUB CreateBg(BYVAL hDlg AS LONG, BYVAL r AS LONG, BYVAL g AS LONG, BYVAL b AS LONG)
                   ' this is to paint the background of the dialog
                   ' it's all straight out of the MSDN help file.  We can change the values
                   ' if we like.
                   LOCAL rc       AS Rect 
                   LOCAL ptDlgBg  AS DIALOGBACKGROUND PTR
                   LOCAL hDC      AS DWORD
                   LOCAL hDCBg    AS DWORD
                   LOCAL hBmpOld  AS DWORD
              
                   LOCAL Xin&
                   LOCAL Yin&,Temp&,cRed&,cGreen&,cBlue&
                   DIM vert(1) AS TRIVERTEX
                   DIM gRect AS GRADIENT_RECT
              
                     ' Tile the background
                   GetClientRect hDlg, rc
              
                   ptDlgBg = GetProp(hDlg, "DIALOG_BACKGROUND")
                   IF ptDlgBg THEN
                     hDCBg = @ptDlgBg.hDC
                     DeleteObject SelectObject(hDCBg, @ptDlgBg.hBmpOld)    
                     DeleteDC hDCBg
                   ELSE
                     ptDlgBg = HeapAlloc(GetProcessHeap(), %HEAP_ZERO_MEMORY, SIZEOF(@ptDlgBg))
                     SetProp hDlg, "DIALOG_BACKGROUND", ptDlgBg
                   END IF
                   hDC = GetDC(hDlg)
                   hDCBg = CreateCompatibleDC(hDC)
                   @ptDlgBg.hDC = hDCBg
                   @ptDlgBg.hBmpOld = SelectObject(hDCBg, CreateCompatibleBitmap(hDC, rc.nRight, rc.nBottom))
              
                   Xin = rc.nRight - rc.nLeft
                   Yin = rc.nBottom - rc.nTop
                   Xin = rc.nRight - rc.nLeft
                   Yin = rc.nBottom - rc.nTop
              
                   'Temp& = RGB(205,214,255)
                   Temp& = RGB(226,187,143) ' TAN 'RGB(255,128,255) ' changes to magenta
                   IF Temp& <> 0 THEN
                     cRed&   = Temp& MOD 256
                     cGreen& = (Temp& \ 256) MOD 256
                     cBlue&  = ((Temp& \ 256) \ 256) MOD 256
                   ELSE
                     cRed&   = 192
                     cGreen& = 224
                     cBlue&  = 192
                   END IF
                   vert(0).x      = 0 '29 '58 '116 'textbox up lft col in pixels  '0
                   vert(0).y      = 0 '37 '74 '148 'textbox up lft row in pixels  '0
                   vert(0).Red    = SetColor(cRed& - 90)
                   vert(0).Green  = SetColor(cGreen& - 90)
                   vert(0).Blue   = SetColor(cBlue& - 90)
                   vert(0).Alpha  = &H0000
                   vert(1).x      = xin
                   vert(1).y      = yin
                   vert(1).Red    = SetColor(cRed&)
                   vert(1).Green  = SetColor(cGreen&)
                   vert(1).Blue   = SetColor(cBlue&)
                   vert(1).Alpha  = &H0000
                   gRect.UpperLeft  = 0
                   gRect.LowerRight = 1
                   GradientFill hDCBg, vert(0), 2, gRect, 1, %GRADIENT_FILL_RECT_V
              
                   ReleaseDC hDlg, hDC
              
              END SUB
              
              '-------------------------------------------------------------------------------
              '
              ' PaintEdit
              ' This procedure renders the background and text of an edit control to a
              ' memory dc to avoid flicker.
              '
              '-------------------------------------------------------------------------------
              
              FUNCTION PaintEdit _
                ( _
                BYVAL lpOldWndProc  AS DWORD, _
                BYVAL hWnd          AS DWORD, _
                BYVAL uMsg          AS DWORD, _
                BYVAL wParam        AS DWORD, _
                BYVAL lParam        AS LONG _
                ) AS LONG
              
                LOCAL trc       AS RECT 
                LOCAL ptDlgBg   AS DIALOGBACKGROUND PTR
                LOCAL hDCBg     AS DWORD
                LOCAL hDC       AS DWORD
                LOCAL hDCMem    AS DWORD
                LOCAL hBmpOld   AS DWORD
                LOCAL cxEdit    AS DWORD
                LOCAL cyEdit    AS DWORD
                LOCAL x         AS LONG
                LOCAL y         AS LONG
                LOCAL lRetVal   AS LONG
              
                ' Let the edit control do its thing.
                ' A flag is set to avoid double paints in case a WM_PAINT message is generated
                SetProp hWnd, "SKIP_PAINT_FLAG", 1
                lRetVal = CallWindowProc(lpOldWndProc, hWnd, uMsg, wParam, lParam)
                RemoveProp hWnd, "SKIP_PAINT_FLAG"
              
                GetClientRect hWnd, trc
                cxEdit = trc.nRight
                cyEdit = trc.nBottom
                MapWindowPoints hWnd, hDlg, BYVAL VARPTR(trc), 2
                x = trc.nLeft
                y = trc.nTop
              
                ' Get the background image of the dialog
                ' (it is stored in a memory dc)
                ptDlgBg = GetProp(hDlg, "DIALOG_BACKGROUND")
                hDCBg = @ptDlgBg.hDC
              
                ' Render the background of the client area of the dialog that is occupied by the
                ' edit control to the memory dc used for drawing the contents of the edit control
                hDC = GetDC(hWnd)
                hDCMem = CreateCompatibleDC(hDC)
                hBmpOld = SelectObject(hDCMem, CreateCompatibleBitmap(hDC, cxEdit, cyEdit))
                BitBlt hDCMem, 0, 0, cxEdit, cyEdit, hDCBg, x, y, %SRCCOPY
                ' Tell the edit control to draw its text to the memory dc
                SendMessage hWnd, %WM_PRINTCLIENT, hDCMem, %PRF_CLIENT
                ' Copy the finished product to the screen
                HideCaret hWnd
                BitBlt hDC, 0, 0, cxEdit, cyEdit, hDCMem, 0, 0, %SRCCOPY
                ShowCaret hWnd
                DeleteObject SelectObject(hDCMem, hBmpOld)
                DeleteDC hDCMem
                ReleaseDC hWnd, hDC
              
                FUNCTION = lRetVal
              
              END FUNCTION
              
              '-------------------------------------------------------------------------------
              
              FUNCTION Edit_SubclassProc _
                ( _
                BYVAL hWnd    AS DWORD, _ ' control handle
                BYVAL uMsg    AS DWORD, _ ' type of message
                BYVAL wParam  AS DWORD, _ ' first message parameter
                BYVAL lParam  AS LONG _   ' second message parameter
                ) EXPORT AS LONG
              
                LOCAL tps             AS PAINTSTRUCT
                LOCAL lpOldWndProc    AS DWORD    ' address of original window procedure
              
                lpOldWndProc = GetProp(hWnd, "OLDWNDPROC")
              
                SELECT CASE uMsg
                  CASE %WM_KEYDOWN
                    FUNCTION = PaintEdit(lpOldWndProc, hWnd, uMsg, wParam, lParam)
                    EXIT FUNCTION
              
                  CASE %WM_CHAR
                    FUNCTION = PaintEdit(lpOldWndProc, hWnd, uMsg, wParam, lParam)
                    EXIT FUNCTION
              
                  CASE %WM_LBUTTONDOWN
                    FUNCTION = PaintEdit(lpOldWndProc, hWnd, uMsg, wParam, lParam)
                    EXIT FUNCTION
              
                  CASE %WM_MOUSEMOVE
                    IF GetCapture() = hWnd THEN
                      FUNCTION = PaintEdit(lpOldWndProc, hWnd, uMsg, wParam, lParam)
                      EXIT FUNCTION
                    END IF
              
                  CASE %WM_PAINT
                    BeginPaint hWnd, tps
                    EndPaint hWnd, tps
                    IF GetProp(hWnd, "SKIP_PAINT_FLAG") = 0 THEN
                      CALL PaintEdit(lpOldWndProc, hWnd, uMsg, wParam, lParam)
                    END IF
                    EXIT FUNCTION
              
                  CASE %WM_DESTROY
                    RemoveProp hWnd, "SKIP_PAINT_FLAG"
                    ' Remove control subclassing
                    SetWindowLong hWnd, %GWL_WNDPROC, RemoveProp(hWnd, "OLDWNDPROC")
                END SELECT
              
                FUNCTION = CallWindowProc(lpOldWndProc, hWnd, uMsg, wParam, lParam)
              
              END FUNCTION
              Last edited by Dominic Mitchell; 20 Feb 2008, 01:37 AM. Reason: Invalidate entire client area of dialog on WM_SIZE
              Dominic Mitchell
              Phoenix Visual Designer
              http://www.phnxthunder.com

              Comment


              • #27
                Dominic,

                Your example code seems to work fine, but when I integrated into
                my program, I get windows error: "The procedure entry point
                SymSetSymWithAddr64 could not be located on the dynamic link
                Library DBGHELP.dll"

                Only thing I can see different is that I don't use
                CASE %WM_CTLCOLORDLG or CASE %WM_SIZE

                Later, after double checking, found my error. Left out the code:
                " CALL CreateBg(CBHNDL,0,0,0)"
                in CASE %WM_INITALIZE
                Now works beautifully!!! Flicker Free!!!
                This is a very fine piece of coding.
                One other question. How can I RENDER a bitmap instead of just
                painting a gradient color on bitmap? Your code mentions that it
                is possible, but can't figure out how to load a bitmap from file?
                Do I need a patternbrush?

                Thanks for your taking the time to do such great work.
                Last edited by BRENT GARDNER; 20 Feb 2008, 10:40 AM.

                Comment


                • #28
                  I will modify your sample code as soon as I find the time.
                  You are already using a bitmap, it is just not obvious.
                  Dominic Mitchell
                  Phoenix Visual Designer
                  http://www.phnxthunder.com

                  Comment


                  • #29
                    Thanks Dominic,

                    Your right it is not obvious. If you are going to create code, can the bitmap be bigger than the textbox? My program uses the bitmap as a frame and background for editing text. I used a graphic control with dimensions 53,61,205,229 dialog units, and the textbox is inside: 58,74,270,205. The bitmap is rendered (0,0)-(285,229).

                    Comment


                    • #30
                      Back to the gradient tab control questions.
                      I just about have everything the way I want it with the help and advice from Chris Boss and Dominic. A colleague pointed out that the tabs themselves don't redraw correctly once selected and I can see the point. They are ownerdrawn style and are painted in WM_DRAWITEM initially.

                      Dialog Redraw hdlg will redraw them correctly after a tab click but I really don't want the flicker.

                      The dialog background has a gradient, the tabs have a gradient and the tab control background also has a gradient via the subclassing that uses the Chris Boss suggestion of processing the wm_erasebk.. event and paint the tab body background with a gradient.

                      After a tab click the clicked tab raises a little bit. The next click doesn't return the first tab to it's original state. My question is, do I trigger a redraw of the dialog background, the tab background or the tab items.

                      Bob Mechler

                      If that isn't enough info, I'm just about finished with a compilable example. I hope to use this as a general template for future consistency in my look and feel for new programs.

                      Comment

                      Working...
                      X