davornik 4 Posted 15 hours ago Is it possible to detect OnMouseDown and on MouseUp events on the TButtonedEdit RightButton (TEditButton)? I am trying to set it to Show/Hide password when I press/unpress the right button, but there is only an OnClick event for the right button. Tried also subclassing, but there is no handle for the right button in TButtonedEdit? procedure TForm1.FormCreate(Sender: TObject); begin //SetWindowSubclass(ButtonedEdit1.RightButton.Handle, @ButtonedEditSubclassProc, 1, DWORD_PTR(ButtonedEdit1.RightButton)); <- no Handle for RightButton SetWindowSubclass(ButtonedEdit1.Handle, @ButtonedEditSubclassProc, 1, DWORD_PTR(ButtonedEdit1)); end; function ButtonedEditSubclassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM; uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall; begin case uMsg of WM_LBUTTONDOWN: Form1.ButtonedEdit1.PasswordChar:=#0; WM_LBUTTONUP: Form1.ButtonedEdit1.PasswordChar:='*'; WM_NCDESTROY: RemoveWindowSubclass(hWnd, @ButtonedEditSubclassProc, uIdSubclass); end; Result := DefSubclassProc(hWnd, uMsg, wParam, lParam); end; Password is hidden When I press right button is it possible for password to be shown and on unpress to be hidden again? Share this post Link to post
Uwe Raabe 2141 Posted 4 hours ago (edited) The buttons of a TButtonedEdit are no controls, so there simply is no handle. Instead they provide an instance FGlyph of a private type TGlyph derived from TCustomControl, which handles the mouse events. This control has the edit control as parent. Perhaps you can achieve your goal by deriving from TButtonControl and override GetEditButtonClass. This gives you access to the protected FGlyph and allows to replace it with a derived class implementing the requested behavior. Edited 4 hours ago by Uwe Raabe Share this post Link to post
davornik 4 Posted 2 hours ago 1 hour ago, Uwe Raabe said: The buttons of a TButtonedEdit are no controls, so there simply is no handle. Instead they provide an instance FGlyph of a private type TGlyph derived from TCustomControl, which handles the mouse events. This control has the edit control as parent. Perhaps you can achieve your goal by deriving from TButtonControl and override GetEditButtonClass. This gives you access to the protected FGlyph and allows to replace it with a derived class implementing the requested behavior. If I correctly understood goal is to then find private TGlyph class name and then its handle? TGlyph is private inside the Vcl.ButtonedEdit unit. I can search for Glyph handle, and do GetWindowLongPtr/SetWindowLongPtr to detect WM_LBUTTONDOWN and WM_LBUTTONUP messages. var OldGlyphWndProc: Pointer = nil; function CustomGlyphWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin if Msg = WM_LBUTTONUP then Form1.ButtonedEdit1.PasswordChar:='*' // <- this does not fire else if Msg = WM_LBUTTONDOWN then Form1.ButtonedEdit1.PasswordChar:=#0; // <- this now fires Result := CallWindowProc(OldGlyphWndProc, hWnd, Msg, wParam, lParam); end; procedure SubclassRightButtonGlyph(Edit: TButtonedEdit); var GlyphHandle: HWND; ClassName: array[0..255] of Char; begin GlyphHandle := GetWindow(Edit.Handle, GW_CHILD); while GlyphHandle <> 0 do begin if GetClassName(GlyphHandle, ClassName, Length(ClassName)) > 0 then if ClassName = 'TEditButton.TGlyph' then begin OldGlyphWndProc := Pointer(GetWindowLongPtr(GlyphHandle, GWL_WNDPROC)); SetWindowLongPtr(GlyphHandle, GWL_WNDPROC, LONG_PTR(@CustomGlyphWndProc)); Break; end; GlyphHandle := GetWindow(Edit.Handle, GW_HWNDNEXT); end; end; procedure TForm1.FormCreate(Sender: TObject); begin SubclassRightButtonGlyph(ButtonedEdit1); end; How I can see password OnMouseDown, but it does not goes to hidden OnMouseUp? Share this post Link to post