No announcement yet.

WM_NCHITTEST question...

  • Filter
  • Time
  • Show
Clear All
new posts

  • WM_NCHITTEST question...

    Hello All,

    I was wondering if anybody knows of an API call that tells you
    what the "hit test" is of your current mouse position. DefWindowProc
    processes the WM_NCHITTEST message and returns the "hit test" but
    I'm not having any luck getting this value. I have tried to call
    DefWindowProc directly to get the return value but it always
    returns zero.


  • #2
    Check out the messages like WM_NC...


    HWND hwnd, // handle to window
    WPARAM wParam, // hit-test value
    LPARAM lParam // cursor position);

    [email protected]


    • #3

      You need to post some code so we can see what you are trying to do.

      Likely you are passing the parameters incorrectly.

      Where are you getting your mouse coordinates from ?

      Are you "processing" the WM_NCHITTEST message in a Window procedure,
      or a DDT Dialog procedure or are you trying to call the defwindowproc
      directly with a WM_NCHITTEST message ?

      The mouse coordinates are combined into a single value (X and Y)
      to be passed in the lParam parameter (only). You must also have the
      correct window handle to pass to the DefWindowProc.

      The coordinates are also NOT Client coordinates, but they are Screen
      coordinates. This is very important. This means some coordinates can
      be "outside" of the Windows rectangle.

      Chris Boss
      Computer Workshop
      Developer of "EZGUI"


      • #4
        Mark --
        look my training code
           #Compile Exe
           #Dim All
           #Register None
           #Include "win32api.INC"
           Global oldproc As Long
           CallBack Function DlgProc
              If CbMsg = %WM_DESTROY Then SetWindowLong CbHndl, %GWL_WNDPROC, oldproc
           End Function
           CallBack Function SubClass
              Local SResult As Long, w As String
              sResult = CallWindowProc(oldproc, CbHndl, CbMsg, CbWparam, CbLparam)
              Select Case CbMsg
                 Case %WM_NCHITTEST
                    Select Case SResult
                       Case %HTTRANSPARENT: w$ = "%HTTRANSPARENT"
                       Case %HTNOWHERE    : w$ = "%HTNOWHERE"
                       Case %HTCLIENT     : w$ = "%HTCLIENT"
                       Case %HTCAPTION    : w$ = "%HTCAPTION"
                       Case %HTSYSMENU    : w$ = "%HTSYSMENU"
                       Case %HTSIZE       : w$ = "%HTSIZE"
                       Case %HTMENU       : w$ = "%HTMENU"
                       Case %HTHSCROLL    : w$ = "%HTHSCROLL"
                       Case %HTVSCROLL    : w$ = "%HTVSCROLL"
                       Case %HTMINBUTTON  : w$ = "%HTMINBUTTON"
                       Case %HTMAXBUTTON  : w$ = "%HTMAXBUTTON"
                       Case %HTLEFT       : w$ = "%HTLEFT"
                       Case %HTRIGHT      : w$ = "%HTRIGHT"
                       Case %HTTOP        : w$ = "%HTTOP"
                       Case %HTTOPLEFT    : w$ = "%HTTOPLEFT"
                       Case %HTTOPRIGHT   : w$ = "%HTTOPRIGHT"
                       Case %HTBOTTOM     : w$ = "%HTBOTTOM"
                       Case %HTBOTTOMLEFT : w$ = "%HTBOTTOMLEFT"
                       Case %HTBOTTOMRIGHT: w$ = "%HTBOTTOMRIGHT"
                       Case %HTBORDER     : w$ = "%HTBORDER"
                       %HTOBJECT = 19
                       %HTCLOSE  = 20
                       %HTHELP   = 21
                       Case %HTOBJECT     : w$ = "%HTOBJECT"
                       Case %HTCLOSE      : w$ = "%HTCLOSE"
                       Case %HTHELP       : w$ = "%HTHELP"
                       Case Else          : w$ = Str$(sResult)
                    End Select
                    SetWindowText CbHndl, ByCopy w$ + Str$(LoWrd(CbLparam)) + Str$(HiWrd(CbLparam))
                 Case Else
                 End Select
                 Function = sResult
           End Function
           Function PbMain
              Local hDlg As Long
              Dialog New 0, "Ltr32", , , 200, 100, %WS_CAPTION Or %WS_THICKFRAME Or _
              Control Add TextBox, hDlg, -1, "", 30, 20, 140, 14
              Control Add Button, hDlg, -1, "Button", 30, 60, 140, 14
              OldProc = SetWindowLong(hDlg, %GWL_WNDPROC, CodePtr(subclass))
              Dialog Show Modal hDlg, Call DlgProc
           End Function


        • #5
          If you just want to determine the position of the mouse while moving, and
          you don't want to respond to the Left/Right mouse down then do this...

              CASE %WM_MOUSEMOVE
                    x&= LOWRD(lParam)
                    y&= HIWRD(lParam)

          If you want to respond when the Left or Right Mouse is down and determine
          the position of the mouse then do this...

                  x& = LOWRD(lParam)
                  y& = HIWRD(lParam)
          If you want to process while the mouse is moving and respond to
          the actual hit testing then this is what to do...

              CASE %WM_NCHITTEST '*special case, were you supply Hit test value.
              'LOCAL pt AS POINTAPI
              'LOCAL rc   AS RECT      'Main Window Rect
                   pt.x = lowrd(lparam)    
                   pt.y = hiwrd(lparam)
                   GetWindowRect hWnd,rc
                   ScreenToClient hWnd,pt
                   If     pt.y < 4   AND pt.x < 4 then
                      function = %HTTOPLEFT
                   elseif pt.y < 4 AND  pt.x >= (rc.nRight -rc.nLeft - 4) then
                      function = %HTTOPRIGHT
                   elseif pt.y >= (rc.nBottom -rc.nTop - 4) AND pt.x >= (rc.nRight -rc.nLeft - 4) then
                      function = %HTBOTTOMRIGHT
                  elseIf pt.x < 4 AND pt.y >= (rc.nBottom -rc.nTop - 4) then
                      function = %HTBOTTOMLEFT
                   elseif pt.y < 4   then
                      function = %HTTOP
                   elseIf pt.x < 4 then
                      function = %HTLEFT
                   elseif pt.x >= (rc.nRight -rc.nLeft - 4) then
                      function = %HTRIGHT
                   elseif pt.y >= (rc.nBottom -rc.nTop - 4) then
                      function = %HTBOTTOM
                      function = %HTCAPTION
                   end if
                   Exit Function
          Semens code above is a great example for other situations.

          Regards, Jules


          [This message has been edited by Jules Marchildon (edited July 10, 2000).]


          • #6
            Thank you all!

            I think I have enough to go with now. The whole reason I wanted
            to know about this is because I wanted to make my own speadsheet
            control that had resizeable columns. They would behave much like
            the standard "Header" control does. I wanted to only allow my
            custom header to be resized on the right hand side. I already had
            a chunk of code quite like your Jules but I was undecided on if
            this was the "best/proper" way to do it.

            Thank you all again!



            • #7

              Jules code above will get you started in processing the
              WM_NCHITTEST message. You need to process it yourself,
              rather than pass it on to the defwindowproc.

              [This message has been edited by Chris Boss (edited July 10, 2000).]
              Chris Boss
              Computer Workshop
              Developer of "EZGUI"


              • #8
                Mark, I have done already an example of a header control with resizable
                colums like the way the ListView works. I did another example of a
                very simple grid with cell hit testing. I was going to put the two
                together for a yet another simple example of a Grid control.

                If you want both code examples send me an email, I'll be happy to
                share it with you.

                Regards, Jules
                mailto:[email protected][email protected]</A>



                • #9
                  Jules, your code uses a hard-coded border width of approx 3 pixels... would it not be better to use the true width of a thick-frame for these calculations to ensure your app behaves in a resolution independent manner?

                  You can use GetSystemMetrics(%SM_CXSIZEFRAME) and GetSystemMetrics(%SM_CYSIZEFRAME) to determine the device coordinate (pixel) width of the resizable frame of a window/dialog.

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


                  • #10

                    It has been a few months, I guess my GUI learning curve as tappered off.

                    Yes, it would be recomended to use the true width of the border. But the
                    code was intended to be used with a Custom Border, specifically for the
                    WinLIFT engine. WinLIFT has a special added feature in that you can drag
                    a window not only by its caption, but any place located on the Border.
                    So in this case if I were to use the full width of the border, I would
                    loose that feature.