PlanetSquires Forums

Support Forums => Other Software and Code => Topic started by: Mark Strickland on July 17, 2005, 02:11:58 AM

Title: Looking for a way to capture all control handles at creation
Post by: Mark Strickland on July 17, 2005, 02:11:58 AM
I need to capture the control handles of every INPUT type control (TextBox, etc) on a form and put them in an array.

I would have thought that some CUSTOM message in each control could be used but it seems the ones I guessed like wm_create are not there for controls only forms.

There is a FF_DESTROY but not create.

I know I could use EnumChildWindows for a form but it does not tell me which control is which.

My ideal would be in the CUSTOM message for each control I wanted I could detect and save the handle.

Thanks.
Title: Looking for a way to capture all control handles at creation
Post by: James Klutho on July 17, 2005, 02:19:35 AM
Would it be possible to use a WM_CREATE in the CUSTOM section for each control and gather the info you need there?
Title: Tried wm_create but did not fire in CUSTOM event
Post by: Mark Strickland on July 17, 2005, 02:28:47 AM
James,

I tried in the CUSTOM event with

if wMsg = %wm_create

but it never fires.

That is EXACTLY what I need but ....

Thanks --- I will keep looking.
Title: The only things that fire during startup
Post by: Mark Strickland on July 17, 2005, 03:01:40 AM
A little debugging says during startup these fire for each control and can be caught in the CUSTOM event:

07  WM_SETFOCUS
08  WM_KILLFOCUS
0e  WM_GETTEXTLENGTH
30  WM_SETFONT
c5   EM_LIMITTEXT

Since I don't change fonts I suppose that one would work.
Title: Looking for a way to capture all control handles at creation
Post by: Roger Garstang on July 17, 2005, 03:57:02 AM
EnumChildWindows is probably your best bet, then getting the Class Name (GetClassName) of each returned like "Edit", etc.  I used it in my Bible Processing app...if Michael ever posts the code...that tested what type of control the mouse was over to not change the pointer on Edit controls and such so the I Beam cursor stayed.

Or, you could just use the handle names and add each to the array manually if there isn't many.  FF also has control arrays built in, so you can have it do the work.
Title: Looking for a way to capture all control handles at creation
Post by: TechSupport on July 17, 2005, 12:15:02 PM
You will never see WM_CREATE messages for child controls. This is standard behaviour for child controls. The WM_CREATE is buried somewhere inside Microsoft's code for the class. FireFly creates the control and then subclasses it. That is why you have access to messages that you would not normally have access to (e.g. the WM_CHAR in a TextBox).

You can get a WM_CREATE message for a child control, but it basically involves creating a new class based on the standard class and then writing code to create the control at run time. This is basically called superclassing.

For the majority of applications that you will ever write, subclassing is used more than superclassing. For most of us, you will probably never find a need to resort to superclassing.
Title: Looking for a way to capture all control handles at creation
Post by: TechSupport on July 17, 2005, 12:17:52 PM
... to answer your question, Roger has posted exactly what I would have said. You can call EnumWindows from within the Form's WM_CREATE message handler. You can also use control arrays or simply track the handles in global arrays based on the control's HWND's (refer to the F4 popup list). I expect that you are not creating controls at runtime so you should know what controls you need to deal with.
Title: Looking for a way to capture all control handles at creation
Post by: Patrice Terrier on July 20, 2005, 02:29:40 PM
Here is the code being used in WSA, may be it could help you to deal
with most of the common controls based on their class names.

FUNCTION EnumChildProc(BYVAL hWnd&, BYVAL lParam AS LONG) AS LONG
   LOCAL bt          AS SKALL
   LOCAL rc          AS RECT
   LOCAL cs          AS COLORSCHEME
   LOCAL pt          AS POINTAPI
   LOCAL zChildClass AS ASCIIZ * 32

   IF GetClassName(hWnd&, zChildClass, SIZEOF(zChildClass)) THEN
      hParent& = GetParent(hWnd&)
      ItemParent& = skItem(hParent&)
      zChildClass = UCASE$(zChildClass)
      MDICLIENT$ = "MDICLIENT"
      IF INSTR(zChildClass, MDICLIENT$) THEN zChildClass = MDICLIENT$

    ' May I skin the control?
      IF NOT skSkinActive(hWnd&) THEN FUNCTION = %TRUE: EXIT FUNCTION

      SELECT CASE CONST$ zChildClass

      CASE "EZGUI30_SHAPE_32"       ' Shape control
            FUNCTION = %TRUE: EXIT FUNCTION
      CASE "EZGUI30_DRAGHANDLES_32" ' Drag handles
            FUNCTION = %TRUE: EXIT FUNCTION
      CASE "EZGUI30_MASKEDIT32"     ' Masked Edit
            FUNCTION = %TRUE: EXIT FUNCTION
      CASE "EZGUI30_MCI_32"         ' MCI control
            FUNCTION = %TRUE: EXIT FUNCTION
      CASE "EZGUI30_TURTLE_32"      ' Turtle control
            FUNCTION = %TRUE: EXIT FUNCTION
      CASE "EZGUI_CANVAS_32"        ' Canvas control
            FUNCTION = %TRUE: EXIT FUNCTION
      CASE "EZGUI_MDICLIENT_32"     ' MDI Client control
            FUNCTION = %TRUE: EXIT FUNCTION

      CASE "MDICLIENT"
           IF GetParent(hParent&) = 0 THEN Win(ItemParent&).hMdiClient = hWnd&
           CALL DeleteObject(SetClassLong (hWnd&, %GCL_HBRBACKGROUND, CreateSolidBrush(skGetSysColor(%SKCOLOR_INACTIVECAPTION))))
         ' Should we handle this big mess
           CALL skMonitorCtrl(hWnd&, %CTRL_MDICLIENT)

      CASE "TOOLBARWINDOW32"
           IF GetParent(hParent&) = 0 THEN
              CALL skMonitorCtrl(hWnd&, %CTRL_TOOLBAR)
              cs.dwSize = SIZEOF(COLORSCHEME)
              cs.clrBtnHighlight = skGetSysColor(%SKCOLOR_3DRIGHTBOTTOM)
              cs.clrBtnShadow = skGetSysColor(%SKCOLOR_3DLEFTTOP)
              CALL SendMessage(hWnd&, %TB_SETCOLORSCHEME, 0, BYVAL VARPTR(cs))
           ELSE
              CALL skMonitorCtrl(hWnd&, %CTRL_TOOLBAR)

              cs.dwSize = SIZEOF(COLORSCHEME)
              cs.clrBtnHighlight = skGetSysColor(%SKCOLOR_3DRIGHTBOTTOM)
              cs.clrBtnShadow = skGetSysColor(%SKCOLOR_3DLEFTTOP)
              CALL SendMessage(hWnd&, %TB_SETCOLORSCHEME, 0, BYVAL VARPTR(cs))

              CALL DeleteObject(SetClassLong (hWnd&, %GCL_HBRBACKGROUND, BYVAL %NULL))
              CALL SetWindowLong(hWnd&, %GWL_EXSTYLE, GetWindowLong(hWnd&, %GWL_EXSTYLE) OR %WS_EX_TRANSPARENT)

              Child(skChild(hWnd&)).paintflag = %TRUE
           END IF

      CASE "MSCTLS_STATUSBAR32"
           CALL skMonitorCtrl(hWnd&, %CTRL_STATUS)
           CALL SetWindowLong(hWnd&, %GWL_EXSTYLE, GetWindowLong(hWnd&, %GWL_EXSTYLE) OR %WS_EX_TRANSPARENT)

           IF ItemParent& THEN Win(ItemParent&).hStatus = hWnd&

      CASE "BUTTON"
           WasStyle& = GetWindowLong(hWnd&, %GWL_STYLE)
           IF (WasStyle& AND %BS_GROUPBOX) = %BS_GROUPBOX THEN
              CALL GetClientRect(hWnd&, rc)
              CALL skMonitorCtrl(hWnd&, %CTRL_GROUPBOX)
              CALL SetRect(Child(skChild(hWnd&)).rc, 0, 0, rc.nRight, rc.nBottom)

              CALL SetWindowLong(hWnd&, %GWL_EXSTYLE, GetWindowLong(hWnd&, %GWL_EXSTYLE) OR %WS_EX_TRANSPARENT)

           ELSEIF (WasStyle& AND %BS_CHECKBOX) = %BS_CHECKBOX THEN
              UseStyle& = %CTRL_CHECKBOX
              IF (WasStyle& AND %BS_OWNERDRAW) = %BS_OWNERDRAW THEN
                 UseStyle& = UseStyle& + %CTRL_OWNERDRAWN
              END IF
              CALL skMonitorCtrl(hWnd&, UseStyle&)
           ELSEIF (WasStyle& AND %BS_AUTOCHECKBOX) = %BS_AUTOCHECKBOX THEN
              UseStyle& = %CTRL_CHECKBOX
              IF (WasStyle& AND %BS_OWNERDRAW) = %BS_OWNERDRAW THEN
                 UseStyle& = UseStyle& + %CTRL_OWNERDRAWN
              END IF
              CALL skMonitorCtrl(hWnd&, UseStyle&)
           ELSEIF (WasStyle& AND %BS_RADIOBUTTON) = %BS_RADIOBUTTON THEN
              UseStyle& = %CTRL_RADIOBUTTON
              IF (WasStyle& AND %BS_OWNERDRAW) = %BS_OWNERDRAW THEN
                 UseStyle& = UseStyle& + %CTRL_OWNERDRAWN
              END IF
              CALL skMonitorCtrl(hWnd&, UseStyle&)
           ELSEIF (WasStyle& AND %BS_AUTORADIOBUTTON) = %BS_AUTORADIOBUTTON THEN
              UseStyle& = %CTRL_RADIOBUTTON
              IF (WasStyle& AND %BS_OWNERDRAW) = %BS_OWNERDRAW THEN
                 UseStyle& = UseStyle& + %CTRL_OWNERDRAWN
              END IF
              CALL skMonitorCtrl(hWnd&, UseStyle&)
           ELSE
              IF (WasStyle& AND %BS_OWNERDRAW) = %BS_OWNERDRAW THEN
                 CALL skMonitorCtrl(hWnd&, %CTRL_PUSBUTTON + %CTRL_OWNERDRAWN)
              ELSEIF (WasStyle& AND %BS_ICON) = %BS_ICON THEN
                 CALL skMonitorCtrl(hWnd&, %CTRL_PUSBUTTON + %CTRL_OWNERDRAWN)
              ELSEIF (WasStyle& AND %BS_BITMAP) = %BS_BITMAP THEN
                 CALL skMonitorCtrl(hWnd&, %CTRL_PUSBUTTON + %CTRL_OWNERDRAWN)
              ELSE

                 CALL SetWindowLong(hWnd&, %GWL_EXSTYLE, GetWindowLong(hWnd&, %GWL_EXSTYLE) XOR %WS_EX_DLGMODALFRAME)

                 Label$ = skGetCTLText(hWnd&)
                 ID& = GetDlgCtrlID(hWnd&)
                 EnableMode& = IsWindowEnabled(hWnd&)
                 IF ID& >= %ID_DOCKOUT AND ID& <= %ID_CLOSE THEN ID& = 0
                 IF ID& THEN
                    CALL GetWindowRect(hWnd&, rc)
                    xBut& = rc.nLeft
                    yBut& = rc.nTop
                    ButWidth& = rc.nRight - rc.nLeft
                    ButHeight& = rc.nBottom - rc.nTop
                    CALL SetWindowLong(hWnd&, %GWL_STYLE, WasStyle& OR %BS_OWNERDRAW)
                    bt.Button = 1
                    UseFont& = SendMessage(hWnd&, %WM_GETFONT, 0, 0): IF UseFont& = %NULL THEN UseFont& = skDefaultFont
                    CALL skDrawBut3D(hWnd&, Label$, UseFont&, ButWidth&, ButHeight&, bt)
                    CALL skMonitorCtrl(hWnd&, %CTRL_PUSBUTTON)
                 END IF
              END IF
           END IF

      CASE "SYSTABCONTROL32"
           CALL skMonitorCtrl(hWnd&, %CTRL_TAB)
           CALL DeleteObject(SetClassLong (hWnd&, %GCL_HBRBACKGROUND, GetSysColor(%COLOR_3DFACE)))
           CALL GetWindowRect(hWnd&, rc)
           xOffset& = rc.nLeft: yOffset& = rc.nTop
           XX& = rc.nRight - rc.nLeft: YY& = rc.nBottom - rc.nTop
           CALL SendMessage(hWnd&, %TCM_ADJUSTRECT, %FALSE, BYVAL VARPTR(rc))
           hRgnClip& = CreateRectRgn(0, 0, XX&, YY&)
           xOffset& = rc.nLeft - xOffset&: yOffset& = rc.nTop - yOffset&
           XX& = rc.nRight - rc.nLeft: YY& = rc.nBottom - rc.nTop
           hRgn& = CreateRectRgn(xOffset&, yOffset&, xOffset& + XX&, yOffset& + YY&)
           CALL CombineRgn(hRgnClip&, hRgnClip&, hRgn&, %RGN_DIFF)
           CALL skDeleteObject(hRgn&)
           CALL SetWindowRgn(hWnd&, hRgnClip&, %TRUE)

      CASE "#32770"
           CALL skMonitorCtrl(hWnd&, %CTRL_DIALOG)

      CASE "STATIC"
           CALL skMonitorCtrl(hWnd&, %CTRL_STATIC)
           IF SendMessage(hWnd&, %WM_GETFONT, 0, 0) = %NULL THEN ' Bernard
              CALL PostMessage(hWnd&, %WM_SETFONT, skDefaultFont, 0)
           END IF

      CASE "SYSTREEVIEW32"
           CALL skMonitorCtrl(hWnd&, %CTRL_SYSTREEVIEW)
           UseColor& = skGetSysColor(%SKCOLOR_CAPTIONTEXT)
         ' Check if UseColor& doesn't conflicts with the &hFFFFFF transparent background
           IF UseColor& = &hFFFFFF THEN UseColor& = RGB(250,250,250) ' RGB(255,255,254)
           CALL SendMessage(hWnd&, %TVM_SETBKCOLOR, 0, &hFFFFFF)
           CALL SendMessage(hWnd&, %TVM_SETTEXTCOLOR, 0, UseColor&)
           CALL SendMessage(hWnd&, %TVM_SETLINECOLOR, 0, UseColor&)

      CASE "LISTBOX"
           WasStyle& = GetWindowLong(hWnd&, %GWL_STYLE)
           IF (WasStyle& AND %LBS_HASSTRINGS) THEN
              CALL skMonitorCtrl(hWnd&, %CTRL_LISTBOX)
           END IF

      CASE "MSCTLS_TRACKBAR32"
           CALL skMonitorCtrl(hWnd&, %CTRL_TRACKBAR)

      CASE "SYSLISTVIEW32"
           CALL skMonitorCtrl(hWnd&, %CTRL_LISTVIEW)
           CALL SendMessage(hWnd&, %LVM_SETBKCOLOR, 0, skGetSysColor(%SKCOLOR_INACTIVECAPTION))
           CALL SendMessage(hWnd&, %LVM_SETTEXTCOLOR, 0, skGetSysColor(%SKCOLOR_CAPTIONTEXT))
           CALL SendMessage(hWnd&, %LVM_SETTEXTBKCOLOR, 0, skGetSysColor(%SKCOLOR_INACTIVECAPTION))

      CASE "SYSHEADER32"
           LOCAL pHD AS HD_ITEM
           HeaderCount& = SendMessage(hWnd&, %HDM_GETITEMCOUNT, 0, 0)
           IF HeaderCount& THEN ' Check if we can skin it or not
              DoIt& = -1
              FOR K& = 0 TO HeaderCount& - 1
                  pHD.Mask = %HDI_FORMAT
                  CALL SendMessage(hWnd&, %HDM_GETITEM, K&, VARPTR(pHD))
                  IF (pHD.fmt AND %HDF_OWNERDRAW) = %HDF_OWNERDRAW THEN DoIt& = 0: EXIT FOR
                  IF (pHD.fmt AND %HDF_BITMAP) = %HDF_BITMAP THEN DoIt& = 0: EXIT FOR
                  IF (pHD.fmt AND %HDF_BITMAP_ON_RIGHT) = %HDF_BITMAP_ON_RIGHT THEN DoIt& = 0: EXIT FOR
                  IF (pHD.fmt AND %HDF_IMAGE) = %HDF_IMAGE THEN DoIt& = 0: EXIT FOR
              NEXT
              IF DoIt& THEN CALL skMonitorCtrl(hWnd&, %CTRL_SYSHEADER)
           END IF

      CASE "RICHEDIT"
           CALL skMonitorCtrl(hWnd&, %CTRL_RICHEDIT)

      CASE ELSE
           CALL skMonitorCtrl(hWnd&, %CTRL_UNDEFINED)

      END SELECT
   END IF
   FUNCTION = %TRUE   ' continue enumeration of children...
END FUNCTION