Jump to content

Recommended Posts

Posted

WM_NCLBUTTONDOWN reports on Button up and WM_NCLBUTTONUP reports on double click. What can I do to fix this?

TIA

#Include <Constants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global $hGui = GUICreate("Costum Titlebar", 500, 300)

Global $hDll = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;long;ptr')
Global $pDll = DllCallbackGetPtr($hDll)
Global $hProc = _WinAPI_SetWindowLong($hGui, $GWL_WNDPROC, $pDll)

GUISetState()

Do
Until GUIGetMsg() = -3

_WinAPI_SetWindowLong($hGui, $GWL_WNDPROC, $hProc)
DllCallbackFree($hDll)

Func _WinProc($hWnd, $iMsg, $wParam, $lParam)
 Local $Res = _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam)
 Local $hDC = _WinAPI_GetWindowDC($hWnd)
 Local $tRECT = DllStructCreate($tagRect)
 DllStructSetData($tRECT, "Left", 23)
 DllStructSetData($tRECT, "Top", 7)
 DllStructSetData($tRECT, "Right", 500)
 DllStructSetData($tRECT, "Bottom", 25)

    Switch $iMsg
        Case $WM_NCACTIVATE, $WM_NCPAINT
   $hDC = _WinAPI_GetWindowDC($hWnd)
   _WinAPI_SetBkColor($hDC, 0x00FF00)
   _WinAPI_DrawText($hDC, "  " & WinGetTitle($hWnd) & "   ", $tRECT, $DT_LEFT)
   _Winapi_ReleaseDC($hWnd, $hDC)
  Case $WM_NCLBUTTONDOWN
   $x = BitAND($lParam, 0x0000FFFF)
      $y = BitShift($lParam, 16)
   ConsoleWrite("Down at " & $x & "/" & $y & @cr)
  Case $WM_NCLBUTTONUP
   $x = BitAND($lParam, 0x0000FFFF)
      $y = BitShift($lParam, 16)
   ConsoleWrite("Up at " & $x & "/" & $y & @cr)
 EndSwitch
 Return $Res
EndFunc

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Posted (edited)

WM_NCLBUTTONDOWN reports on Button up and WM_NCLBUTTONUP reports on double click. What can I do to fix this?

TIA

additional message handling is required to make a custom button work on the titlebar.

1: The WM_NCLBUTTONDOWN message is not passed until mouse capture is released.

2: The WM_NCLBUTTONUP message is posted when the user releases the left mouse button

while the cursor is within the nonclient area of a window.

This message is posted to the window that contains the cursor.

If a window has captured the mouse, this message is not posted.

it helps to use the WinSpector or Window Detective utilities, as they can subclass a window

so you can see what the messages are.

this is just a quick kludge to show a working example,

you need to call systemparaminfo API (I think?) to get the non-client area dimensions.

check the forum for non client area script examples

maybe look at ANYGUI examples, or search 'titlebar'

a point in rect test is used in WM_NCHITTEST to check if the click is on the button,

and a return of HTBORDER to tell the window the border was clicked so we get a WM_NCLBUTTONUP message.

boolean flags used to block keydn/up messages outside of button.

there was some key bounce with the WM_NCLBUTTONUP message being repeated twice,

so I added an additional boolean flag.

if the button is clicked, then the mouse moved off the button and released,

then like a normal button, no WM_NCLBUTTONUP message is sent.

;Author: funkey, modified by rover 2k11
#Include <Constants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global $tRECT = DllStructCreate($tagRect)
DllStructSetData($tRECT, "Left", 23)
DllStructSetData($tRECT, "Top", 7)
DllStructSetData($tRECT, "Right", 143)
DllStructSetData($tRECT, "Bottom", 25)

Global $tRECTx = DllStructCreate($tagRect);need non-client area dimensions here
DllStructSetData($tRECTx, "Left", 21)
DllStructSetData($tRECTx, "Top", -23)
DllStructSetData($tRECTx, "Right", 140)
DllStructSetData($tRECTx, "Bottom", -5);quick hack to set rect in non-client area

Global $fNCKeyDn = False, $fNCKeyUp = False

Global $hGui = GUICreate("Costum Titlebar", 500, 300)

Global $hDll = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;long;ptr')
Global $pDll = DllCallbackGetPtr($hDll)
Global $hProc = _WinAPI_SetWindowLong($hGui, $GWL_WNDPROC, $pDll)

GUISetState()

Do
Until GUIGetMsg() = -3

_WinAPI_SetWindowLong($hGui, $GWL_WNDPROC, $hProc)
DllCallbackFree($hDll)



Func _WinProc($hWnd, $iMsg, $wParam, $lParam)

    Switch $iMsg
        Case $WM_NCHITTEST;, $wm_
            ;http://msdn.microsoft.com/en-us/library/ms645618(VS.85).aspx
;http://stackoverflow.com/questions/521147/the-curious-problem-of-the-missing-wm-nclbuttonup-message-when-a-window-isnt-max
            Local $tPoint = DllStructCreate($tagPOINT)
            DllStructSetData($tPoint, 1, BitAND($lParam, 0x0000FFFF))
            DllStructSetData($tPoint, 2, BitShift($lParam, 16))
            _WinAPI_ScreenToClient($hWnd, $tPoint)
            If _WinAPI_PtInRect($tRECTx, $tPoint) Then
                $fNCKeyDn = True
                Return $HTBORDER ; tell the window the mouse is clicking on the border so we get a WM_NCLBUTTONUP message
            EndIf
            $fNCKeyDn = False ;required to prevent key down message if titlebar clicked after keyup on button
        Case $WM_NCLBUTTONUP
            If $fNCKeyDn = True And $fNCKeyUp = True Then
                $fNCKeyUp = False
                $x = BitAND($lParam, 0x0000FFFF)
                $y = BitShift($lParam, 16)
                ConsoleWrite("+Up at " & $x & "/" & $y & @cr)
            EndIf
        ;WM_NCLBUTTONDBLCLK: optionally allow fast clicking of button, otherwise some repeated clicks are missed.
        Case $WM_NCLBUTTONDOWN, $WM_NCLBUTTONDBLCLK
            If $fNCKeyDn = True Then
                $fNCKeyUp = True
                $x = BitAND($lParam, 0x0000FFFF)
                $y = BitShift($lParam, 16)
                ConsoleWrite("-Down at " & $x & "/" & $y & @cr)
            EndIf
    EndSwitch

    Local $Res = _WinAPI_CallWindowProc($hProc, $hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
        Case $WM_NCACTIVATE, $WM_NCPAINT
           Local $hDC = _WinAPI_GetWindowDC($hWnd)
           _WinAPI_SetBkColor($hDC, 0x00FF00)
           _WinAPI_DrawText($hDC, "  " & WinGetTitle($hWnd) & "   ", $tRECT, $DT_LEFT)
           _Winapi_ReleaseDC($hWnd, $hDC)
    EndSwitch
    Return $Res
EndFunc
Edited by rover

I see fascists...

Posted

Thank you very much for this. It helped a lot to do what I want.

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...