问题
My Custom menu is coming along nicely and can detect when the mouse is within the boundaries of the link rectangles and respond to mouseup events. What I would now like for it to do is change the colours of the link rectangles when the user hovers the mouse within their boundaries. I've set colour properties this way before but manually and not dynamically.
Basically, nothing happens. Debugging shows that the mouse position routine is working perfectly but the rectangles stay the same colour.
I've created a simple array of ButtonStates and assigned them colours:
type
T_ButtonState = (bttn_off);
private
{ Private declarations }
bttnStatus : TOC_ButtonState;
const stateColor : array[T_ButtonState, false..true] of TColor = ((clDkGray, clGray));
And am now trying to manipulate the value of T_ButtonState so I can set the colour in my paint routine:
// User actions
procedure T_MenuPanel.MouseMove(Shift:TShiftState; X,Y:Integer);
var
loop : integer;
begin
for loop := 0 to High(MenuRects) do
begin
if PtInRect(MenuRects[loop], Point(X, Y)) then
bttnStatus := bttn_off;
end;
inherited;
end;
This is my drawing routine:
for count := 0 to fLinesText.Count - 1 do
begin
// Define y2
y2 := TextHeight(fLinesText.strings[count])*2;
// Draw the rectangle
itemR := Rect(x1, y1, x2, y2*(count+1));
Pen.color := clGray;
Brush.color := stateColor[bttn_off][bttnStatus = bttn_off]; // Nothing Happens!!!
Rectangle(itemR);
// Push rectangle info to array
MenuRects[count] := itemR;
// Draw the text
TextRect(itemR, x1+5, y1+5, fLinesText.strings[count]);
// inc y1 for positioning the next box
y1 := y1+y2;
end;
回答1:
You're detecting where the mouse is when it moves, and you account for that detection when you draw. However, moving the mouse doesn't necessarily make your control redraw itself, so the movement isn't apparent in your control. When you detect mouse movement, signal to the control that it needs to be redrawn by calling its Invalidate
method.
procedure T_MenuPanel.MouseMove(Shift:TShiftState; X,Y:Integer);
var
loop: integer;
begin
for loop := 0 to High(MenuRects) do begin
if PtInRect(MenuRects[loop], Point(X, Y)) then begin
bttnStatus := bttn_off;
// Ssgnal that we need repainting
Invalidate;
end;
end;
inherited;
end;
When the OS next has a chance, it will ask your control to repaint itself. That's usually sufficient, but if you want the visual update to be immediate, you can call Refresh
instead of Invalidate
.
来源:https://stackoverflow.com/questions/23917365/freepascal-how-do-i-change-the-colour-of-a-tpaint-object-on-mouseover