mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-14 01:56:36 +08:00
179 lines
4.9 KiB
ObjectPascal
179 lines
4.9 KiB
ObjectPascal
{
|
|
SizeGripHWND.pas
|
|
|
|
Delphi component to add a size grip (like if you use a status bar) to the
|
|
lower right corner of any window control. This is intended for small
|
|
footprint non-VCL delphi applications and paints the size grip just using
|
|
the standard API functions (no layout control, no themes).
|
|
|
|
Version 1.2a - always find the most current version at
|
|
http://flocke.vssd.de/prog/code/pascal/sizegrip/
|
|
|
|
Copyright (C) 2005, 2006 Volker Siebert <flocke@vssd.de>
|
|
All rights reserved.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
DEALINGS IN THE SOFTWARE.
|
|
}
|
|
|
|
unit SizeGripHWND;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages;
|
|
|
|
procedure SetWindowSizeGrip(hWnd: HWND; Enable: boolean);
|
|
|
|
implementation
|
|
|
|
const
|
|
SizeGripProp = 'SizeGrip';
|
|
|
|
type
|
|
TWndProc = function (hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
|
|
|
|
PGripInfo = ^TGripInfo;
|
|
TGripInfo = record
|
|
OldWndProc: TWndProc;
|
|
Enabled: boolean;
|
|
GripRect: TRect;
|
|
end;
|
|
|
|
function SizeGripWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
|
|
var
|
|
Info: PGripInfo;
|
|
dc: HDC;
|
|
pt: TPoint;
|
|
|
|
// Invalidate the current grip rectangle
|
|
procedure InvalidateGrip;
|
|
begin
|
|
with Info^ do
|
|
if (GripRect.Right > GripRect.Left) and
|
|
(GripRect.Bottom > GripRect.Top) then
|
|
InvalidateRect(hWnd, @GripRect, true);
|
|
end;
|
|
|
|
// Update (and invalidate) the current grip rectangle
|
|
procedure UpdateGrip;
|
|
begin
|
|
with Info^ do
|
|
begin
|
|
GetClientRect(hWnd, GripRect);
|
|
GripRect.Left := GripRect.Right - GetSystemMetrics(SM_CXHSCROLL);
|
|
GripRect.Top := GripRect.Bottom - GetSystemMetrics(SM_CYVSCROLL);
|
|
end;
|
|
|
|
InvalidateGrip;
|
|
end;
|
|
|
|
function CallOld: LRESULT;
|
|
begin
|
|
Result := CallWindowProc(@Info^.OldWndProc, hWnd, Msg, wParam, lParam);
|
|
end;
|
|
|
|
begin
|
|
Info := PGripInfo(GetProp(hWnd, SizeGripProp));
|
|
if Info = nil then
|
|
Result := DefWindowProc(hWnd, Msg, wParam, lParam)
|
|
else if not Info^.Enabled then
|
|
Result := CallOld
|
|
else
|
|
begin
|
|
case Msg of
|
|
WM_NCDESTROY: begin
|
|
Result := CallOld;
|
|
|
|
SetWindowLong(hWnd, GWL_WNDPROC, LongInt(@Info^.OldWndProc));
|
|
RemoveProp(hWnd, SizeGripProp);
|
|
Dispose(Info);
|
|
end;
|
|
|
|
WM_PAINT: begin
|
|
Result := CallOld;
|
|
if wParam = 0 then
|
|
begin
|
|
dc := GetDC(hWnd);
|
|
DrawFrameControl(dc, Info^.GripRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
|
|
ReleaseDC(hWnd, dc);
|
|
end;
|
|
end;
|
|
|
|
WM_NCHITTEST: begin
|
|
pt.x := TSmallPoint(lParam).x;
|
|
pt.y := TSmallPoint(lParam).y;
|
|
ScreenToClient(hWnd, pt);
|
|
if PtInRect(Info^.GripRect, pt) then
|
|
Result := HTBOTTOMRIGHT
|
|
else
|
|
Result := CallOld;
|
|
end;
|
|
|
|
WM_SIZE: begin
|
|
InvalidateGrip;
|
|
Result := CallOld;
|
|
UpdateGrip;
|
|
end;
|
|
|
|
else
|
|
Result := CallOld;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ Note that SetWindowSizeGrip(..., false) does not really remove the hook -
|
|
it just sets "Enabled" to false. The hook plus all data is removed when
|
|
the window is destroyed.
|
|
}
|
|
procedure SetWindowSizeGrip(hWnd: HWND; Enable: boolean);
|
|
var
|
|
Info: PGripInfo;
|
|
begin
|
|
Info := PGripInfo(GetProp(hWnd, SizeGripProp));
|
|
if (Info = nil) and Enable then
|
|
begin
|
|
New(Info);
|
|
FillChar(Info^, SizeOf(TGripInfo), 0);
|
|
|
|
with Info^ do
|
|
begin
|
|
Info^.OldWndProc := TWndProc(Pointer(GetWindowLong(hWnd, GWL_WNDPROC)));
|
|
|
|
GetClientRect(hWnd, GripRect);
|
|
GripRect.Left := GripRect.Right - GetSystemMetrics(SM_CXHSCROLL);
|
|
GripRect.Top := GripRect.Bottom - GetSystemMetrics(SM_CYVSCROLL);
|
|
end;
|
|
|
|
SetProp(hWnd, SizeGripProp, Cardinal(Info));
|
|
SetWindowLong(hWnd, GWL_WNDPROC, LongInt(@SizeGripWndProc));
|
|
end;
|
|
|
|
if (Info <> nil) then
|
|
if Enable <> Info^.Enabled then
|
|
with Info^ do
|
|
begin
|
|
Enabled := Enable;
|
|
if (GripRect.Right > GripRect.Left) and
|
|
(GripRect.Bottom > GripRect.Top) then
|
|
InvalidateRect(hWnd, @GripRect, true);
|
|
end;
|
|
end;
|
|
|
|
end.
|