Announcement

Collapse
No announcement yet.

WS_CHILD and clipping..

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

  • WS_CHILD and clipping..

    Is it completely impossible to create child controls that can stretch
    outside of parent? Reason for asking: want to create own tooltips for
    a custom control list. The label will always be part of parent, but
    may have to stretch outside for long items near border.

    I know about popups and have tried that. While it works, it's a lot of
    extra code and I have trouble preventing focus to change without
    flicker. Using simple in-house label is soo much easier and cleaner.
    If only I could turn of clipping somehow and make it stretch outside parent..

    Interesting test was to create a label with both WS_POPUP and WS_CHILD
    style. MS says it can't be done and while it can, they probably are
    right because label is created without id, so impossible to do anything
    more with it. Still, it shows and can be placed freely on screen at
    creation time. (not useful and probably not safe, but fun to see..



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

  • #2
    Borje -
    Use POPUP and ShowWindow hWndLabel, %SW_SHOWNA

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

    Comment


    • #3
      Borje;

      Tooltip popup windows are not Child windows !

      They are likely Top Most windows and they use the %WS_POPUP style.

      This is why they can overlap outside of the Dialog.

      A Child window can never be displayed outside of the parent !

      If you want to build your own customized Tooltip, why not try
      superclassing the Tooltip control itself ! Simply process the
      WM_PAINT messages yourself.


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


      [This message has been edited by Chris Boss (edited April 30, 2001).]
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        Borje; Here is my quick thought on this subject, instead of using
        a window at all, grab the ScreenDC and just paint some dumb objects
        directly to the screen. Not as simple as a label, but should be a walk
        in the park for you.

        Regards,
        Jules
        Best regards
        Jules
        www.rpmarchildon.com

        Comment


        • #5
          Here is interesting test. Control is created as popup, not child.
          SpyXX shows control has handle and parent is ok, but it has no id!
          This is where it failed for me, because without id, no way to handle
          control.

          But, by using FindWindow, I found a way to get handle and thereby
          possibility to handle the label. Very interesting. Guess only safe
          way here is by creating the control with specific string initially
          set, use FindWindow to get control's handle, then wipe out or change
          initial string in control. Neat way to do tooltips, but I wonder how
          safe it is, since something obviously is wrong. I mean, why no id?
          Code:
          '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
          ' Declares
          '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
          #COMPILE EXE
          #INCLUDE "WIN32API.INC"
           
          GLOBAL lHWnd AS LONG
          DECLARE CALLBACK FUNCTION DlgProc() AS LONG
           
          '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
          ' Create dialog and controls, etc
          '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
          FUNCTION PBMAIN () AS LONG
            LOCAL hDlg AS LONG, r AS RECT, r2 AS RECT, caption AS STRING
           
            DIALOG NEW 0, "Click to show/hide....",,, 120, 50, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg
            GetWindowRect hDlg, r
            GetClientRect hDlg, r2
            r.nTop = r.nTop + (r.nBottom - r.nTop) - r2.nBottom  'calculate position
            r.nLeft = r.nLeft + (r.nRight - r.nLeft) - r2.nRight
           
            DIALOG PIXELS hDlg, r.nLeft, r.nTop TO UNITS r.nLeft, r.nTop
            CONTROL ADD LABEL, hDlg, 10, "[email protected]£${{[]}i8fdy3457359", _
                               r.nLeft, r.nTop, 200, 20, _
                               %WS_POPUP OR %WS_BORDER OR %SS_CENTER
           
            'CONTROL HANDLE hDlg, 10 TO lHWnd                     '<- returns zero, because control has no id!
            lHWnd = FindWindow ("", "[email protected]£${{[]}i8fdy3457359")   '<- used special string to find correct control
           
            IF lHWnd THEN
               SetWindowText lHWnd, "Here I am, floating - but where's my id?" + CHR$(0) '<- set new text to label
            ELSE
               MSGBOX "Could not find label"
            END IF
           
            DIALOG SHOW MODAL hDlg CALL DlgProc
          END FUNCTION
           
          '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
          ' Main callback
          '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
          CALLBACK FUNCTION DlgProc() AS LONG
            STATIC tg AS LONG
            SELECT CASE CBMSG
               CASE %WM_CTLCOLORSTATIC
                  IF GetDlgCtrlID(CBLPARAM) = 10 THEN BEEP '<- label has no id, but rest is ok!
                  SetBkColor CBWPARAM, GetSysColor(%COLOR_INFOBK)
                  FUNCTION = GetSysColorBrush(%COLOR_INFOBK)
           
               CASE %WM_LBUTTONDOWN
                  IF lHWnd THEN
                     IF tg THEN
                        ShowWindow lHWnd, %SW_SHOWNA
                     ELSE
                        ShowWindow lHWnd, %SW_HIDE
                     END IF
                     tg = NOT tg
                  END IF
            END SELECT
          END FUNCTION

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

          Comment


          • #6
            Borje --
            1) Can't understandand, why do you use Control Add instead of CreateWindowEx.
            2) Why "label" instead of ordinary custom control ?
            Anyway it's necessary to calculate rect, to resize and so on.
            I looked my "tooltip" for console app (BTW, multiline).
            WindowProc is about 40 statements only.



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

            Comment


            • #7
              In this case, because of simple DDT sample. In custom control I work
              on I use CreateWindow - same result, but in different way. CreateWindow
              returns zero, but with FindWindow, I still can find the handle and use
              the control. Weird. Same result if I do custom control label too. Only
              different if to use popup dialog, but this way is more fun, since MS
              says it can't be done..

              With CreateWindow, use WS_CHILD + WS_POPUP for same result, because DDT
              engine adds WS_CHILD automatically. Seriously, it may be dangerous since
              id never appears. Still, it seems to work fine and is a neat way to
              create own tooltips, so I don't know. Maybe will use it anyway and see
              what happens. For test, replace DIALOG PIXELS and CONTROL ADD lines with:
              Code:
                'following returns zero, but FindWindow will find it anyway..
                lHWnd = CreateWindow ("STATIC",_                              'window class name
                                   "[email protected]£${{[]}i8fdy3457359" + CHR$(0),_      'window caption
                                   %WS_CHILD OR %WS_POPUP OR %WS_BORDER OR %SS_CENTER, _  'window style    %WS_CHILD OR
                                   r.nLeft, r.nTop, 300, 30, _                'initial x-y-w-h
                                   hDlg,_                                     'parent window handle
                                   10,_                                       'control id
                                   GetModuleHandle(BYVAL %NULL),_             'program instance handle
                                   %NULL)                                     'creation parameter
              ------------------

              Comment


              • #8
                Borje;

                The Tooltip can't have an ID, since it is not a child window.
                The parameter used by CreateWindow to set the ID value is also
                the same parameter used to set the menu handle for a Top level
                window (which a Tooltip is). Since a tooltip has no menu, the
                ID/Menu value is set to zero.

                Only child windows can be refered to by an ID number.

                You would not use CONTROL ADD to create a Tooltip control
                since it is not a control. While DDT may let you do this,
                the Control Add command wasn't intended for creating top level
                windows (as far as I can tell).

                Using CreateWindowEx makes more sense to me.

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


                [This message has been edited by Chris Boss (edited April 30, 2001).]
                Chris Boss
                Computer Workshop
                Developer of "EZGUI"
                http://cwsof.com
                http://twitter.com/EZGUIProGuy

                Comment


                • #9
                  Ah, thanks Chris. That explains it. I don't use CONTROL ADD self, only
                  did it to show sample. Found some other weird things with using label
                  this way, so I'll use own custom control class for it instead. MS
                  seems to be right in one way, POPUP and CHILD does not go well together,
                  even if it can be done.


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

                  Comment


                  • #10
                    Borje --
                    what do you think about this simple way of re-position of standart tooltip ?
                    (really could br replaced WM_PAINT and other events)

                    Tested under Win2000 only.

                    Code:
                       #Compile Exe
                       #Dim all
                       #Include "win32api.inc"
                       #Include "CommCtrl.Inc"
                       #Resource "c:\PbDll60\Samples\Skeleton\SKELETON.PBR"
                    
                       Global OldProc As Long, hDlg As Long
                        CallBack Function ToolProc
                           Select Case CbMsg
                              Case %WM_WINDOWPOSCHANGED
                                 Dim rc1 As RECT, rc2 As RECT, rc As RECT
                                 GetWindowRect hDlg, rc1
                                 GetWindowRect CbHndl, rc2
                                 rc.nLeft = rc1.nLeft
                                 rc.nTop = rc1.nTop - (rc2.nBottom - rc2.nTop)
                                 If rc.nLeft <> rc2.nLeft Or rc.nTop <> rc2.nTop Then _
                                    SetWindowPos CbHndl, 0, rc.nLeft, rc.nTop, 0, 0, %SWP_NOSIZE Or %SWP_NOACTIVATE Or %SWP_NOZORDER
                           End Select
                           Function = CallWindowProc(OldProc, CbHndl, CbMsg, CbWparam, CbLparam)
                        End Function
                    
                       Function PbMain
                         Dim hWnd_ToolTip As Long, i As Long, ti As TOOLINFO
                    
                         InitCommonControls
                         hWnd_ToolTip = CreateWindowEx( 0, "tooltips_class32", "", %TTS_ALWAYSTIP, 0, 0, 0, 0, 0, _
                             ByVal 0&, GetModuleHandle(ByVal 0&), ByVal 0&)
                         OldProc = SetWindowLong(hWnd_ToolTip, %GWL_WNDPROC, CodePtr(ToolProc))
                    
                         Dialog New 0, "Tooltip example",,, 400, 40, %WS_CAPTION Or %WS_SYSMENU To hDlg
                         Control Add ImgButton, hDlg, 101, "PROGRAM", 5,  5, 25, 25
                         Control Add ImgButton, hDlg, 102, "TOOLBAR", 45,  5, 350, 25
                         Dim Txt(1 : 2) As Asciiz * 100
                    
                         ti.cbSize   = Len(ti)
                         ti.uFlags   = %TTF_SUBCLASS Or %TTF_IDISHWND
                         For i = 1 To 2
                            ti.hWnd     = hDlg
                            ti.uId      = GetDlgItem(hDlg, 100 + i)
                            Txt(i) = "Id =" + Str$(100 + i)
                            ti.lpszText = VarPtr(Txt(i))
                            SendMessage hWnd_ToolTip, %TTM_ADDTOOL, 0, ByVal VarPtr(ti)
                         Next
                         Dialog Show Modal hDlg
                    
                         End Function
                    ------------------
                    E-MAIL: [email protected]

                    Comment


                    • #11
                      Yes, but involves MS control. I like to have my own for many reasons,
                      one being the possibility to do more with it in the future. I have it
                      working here now, only a few things left to solve, plus write sample
                      app and some documentation..

                      BTW, mostly for lurkers, because I know you already know this, Semen:
                      If to use %WM_WINDOWPOSCHANGING message instead, one can do same job
                      without SetWindowPos. Like in your ToolProc, instead use:
                      Code:
                                CASE %WM_WINDOWPOSCHANGING
                                   DIM rc1 AS RECT, rc2 AS RECT, wp AS WINDOWPOS PTR
                                   wp = CBLPARAM
                                   GetWindowRect hDlg, rc1 : GetWindowRect CBHNDL, rc2
                                   @wp.x = rc1.nLeft
                                   @wp.y = rc1.nTop - (rc2.nBottom - rc2.nTop)
                                   FUNCTION = 0 : EXIT FUNCTION
                      BTW2, how to create a popup dialog from within a container control?
                      From dialog, ok. from within a custom control, I get nothing, until
                      I set style to child + popup and use FindWindow to get handle. Plain
                      popup style simply produces nothing there. Maybe popup dialogs must
                      start from other dialogs and not from within a control. Or, maybe I
                      have done something wrong - will check later.

                      Almost tempted to follow Jules' tips and paint "fake control" directly
                      to screen instead..


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

                      Comment

                      Working...
                      X