I'm looking at using modeless childwindows as containers for single or multiple controls that have canned functionality that I would use many places in my programs. Here is a small example of using this method and would like feedback as to whether you use this method or warnings etc.

Thanks,

(The gradient button code from a posting by Chris Boss)

Code:
#COMPILE EXE
#DIM ALL

'------------------------------------------------------------------------------
'   ** Includes **
'------------------------------------------------------------------------------
#IF NOT %DEF(%WINAPI)
  #INCLUDE "WIN32API.INC"
#ENDIF
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Constants **
'------------------------------------------------------------------------------
%IDD_DIALOG1  =  101
%IDD_DIALOG2  =  102
%BTN_BUTTON1  = 1000
%BTN_BUTTON2  = 1001
%TXT_TEXTBOX1 = 1002
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Declarations **
'------------------------------------------------------------------------------
DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
DECLARE CALLBACK FUNCTION ShowDIALOG2Proc()
DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION ShowDIALOG3(BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION ShowDIALOG4(BYVAL hParent AS DWORD) AS LONG
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Main Application Entry Point **
'------------------------------------------------------------------------------
GLOBAL hdlg1 AS LONG,hdlg2 AS LONG,hdlg3 AS LONG
FUNCTION PBMAIN()
  ShowDIALOG1 %HWND_DESKTOP
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** CallBacks **
'------------------------------------------------------------------------------
CALLBACK FUNCTION ShowDIALOG1Proc()

  SELECT CASE AS LONG CBMSG
    CASE %WM_INITDIALOG
      ShowDIALOG2 %HWND_DESKTOP
      ShowDIALOG3 %HWND_DESKTOP
      ShowDIALOG4 %HWND_DESKTOP

    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
      ' Process control notifications
      SELECT CASE AS LONG CBCTL

      END SELECT
  END SELECT
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Dialogs **
'------------------------------------------------------------------------------
FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
  LOCAL lRslt AS LONG
  LOCAL hDlg  AS DWORD
  DIALOG NEW hParent, "Dialog1", 91, 70, 489, 303, %WS_POPUP OR %WS_BORDER OR _
    %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR _
    %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
    %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
    %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
  CONTROL ADD TEXTBOX, hDlg, %TXT_TEXTBOX1, "TextBox1", 80, 4, 166, 16
  hdlg1 = hdlg
  DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
  FUNCTION = lRslt
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
CALLBACK FUNCTION ShowDIALOG2Proc()

  SELECT CASE AS LONG CBMSG
    CASE %WM_INITDIALOG
      ' Initialization handler

    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
      ' Process control notifications
      SELECT CASE AS LONG CBCTL
        CASE %BTN_BUTTON1
          IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
            CONTROL SET TEXT hdlg1,%TXT_TEXTBOX1,"Updated by a child window button 1 " + TIME$
          END IF
        CASE %BTN_BUTTON2
          IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
            CONTROL SET TEXT hdlg1,%TXT_TEXTBOX1,"Updated by a child window button 2 " + TIME$
          END IF

      END SELECT
  END SELECT
END FUNCTION
FUNCTION ShowDIALOG2(BYVAL hParent AS DWORD) AS LONG
  LOCAL lRslt AS LONG

  LOCAL hDlg  AS DWORD
  DIALOG NEW hDlg1, "Dialog2", 151, 81, 120, 18,%DS_CONTROL OR %WS_CHILD OR %WS_VISIBLE,%WS_EX_LEFT, TO hDlg
  CONTROL ADD BUTTON, hDlg, %BTN_BUTTON1, "ChildButton1", 0, 0, 58, 18
  CONTROL ADD BUTTON, hDlg, %BTN_BUTTON2, "ChildButton2", 59, 0, 58, 18
  hdlg2 = hdlg
  DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG2Proc TO lRslt
  FUNCTION = lRslt
END FUNCTION
FUNCTION ShowDIALOG3(BYVAL hParent AS DWORD) AS LONG
  LOCAL lRslt AS LONG

  LOCAL hDlg  AS DWORD
  DIALOG NEW hDlg1, "Dialog2", 90, 85, 50, 10,%DS_CONTROL OR %WS_CHILD OR %WS_VISIBLE,%WS_EX_LEFT, TO hDlg
  CONTROL ADD LABEL, hDlg, 101,"Label control",0,0,50,10
  CONTROL SET COLOR hDlg,101,%BLACK,%MAGENTA
  hdlg3 = hdlg

  DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG2Proc TO lRslt
  FUNCTION = lRslt
END FUNCTION
%IDC_BUTTON1  = 1005
'-----------------------------------------------------------
SUB DrawGradient (BYVAL hDC AS DWORD)
   LOCAL rectFill AS RECT
   LOCAL rectClient AS RECT
   LOCAL fStep AS SINGLE
   LOCAL hBrush AS DWORD
   LOCAL lOnBand AS LONG

   GetClientRect WindowFromDC(hDC), rectClient
   fStep = rectClient.nbottom / 200

   FOR lOnBand = 0 TO 199
      SetRect rectFill, 0, lOnBand * fStep, rectClient.nright + 1, (lOnBand + 1) * fStep
      hBrush = CreateSolidBrush(RGB((255 - lOnBand), (255 - lOnBand), (255 - lOnBand)))
      Fillrect hDC, rectFill, hBrush
      DeleteObject hBrush
   NEXT
END SUB
CALLBACK FUNCTION ShowDIALOG4Proc()
  LOCAL hOldFnt AS DWORD, szText AS ASCIIZ * 128
  LOCAL dis AS DRAWITEMSTRUCT PTR, hPen AS DWORD, hBrush AS DWORD
  LOCAL rc AS RECT

    SELECT CASE AS LONG CBMSG
      CASE %WM_INITDIALOG
      CASE %WM_DRAWITEM
          BEEP
           dis = CBLPARAM
         IF @dis.CtlId = %IDC_BUTTON1 THEN
           rc = @dis.rcItem
           IF (@dis.itemState AND %ODS_SELECTED) THEN
              DrawGradient(@dis.hDc)
              DrawEdge @dis.hDc, rc, %EDGE_SUNKEN     , %BF_RECT
           ELSE
              DrawGradient(@dis.hDc)
              DrawEdge @dis.hDc, rc, %EDGE_RAISED    , %BF_RECT
           END IF

           SetBkMode @dis.hDc, %Transparent
           SetTextColor @dis.hDc, &H404040

           SendMessage @dis.hWndItem, %WM_GETTEXT, SIZEOF(szText), VARPTR(szText)
           DrawText @dis.hDc, szText, LEN(szText), rc, %DT_CENTER OR %DT_VCENTER OR %DT_SINGLELINE
           FUNCTION = %True
         END IF

      CASE %WM_SIZE
         IF CBWPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CBHNDL, rc
            MoveWindow GetDlgItem(CBHNDL, %IDC_BUTTON1),  0, 0, rc.nright, rc.nbottom, %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE LOWRD(CBWPARAM)
            CASE %IDC_BUTTON1
              IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                CONTROL SET TEXT hdlg1, %TXT_TEXTBOX1,"Updated by a child gradient button " + TIME$
               END IF
         END SELECT
   END SELECT
END FUNCTION
FUNCTION ShowDIALOG4(BYVAL hParent AS DWORD) AS LONG
    LOCAL lRslt AS LONG
    LOCAL hDlg  AS DWORD

    DIALOG NEW hdlg1, "DDT GradBn", 151, 101, 120, 23, %DS_CONTROL OR %WS_CHILD OR %WS_VISIBLE,%WS_EX_LEFT TO hDlg
    CONTROL ADD BUTTON,  hdlg, %IDC_BUTTON1, "&Button1", _
                    0, 0, 120, 23, _
                    %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_OWNERDRAW
    DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG4Proc TO lRslt
    FUNCTION = lRslt
END FUNCTION
'------------------------------------------------------------------------------
Bob Mechler