git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.jvcl@12 7f62d464-2af8-f54e-996c-e91b33f51cbe
8878 lines
249 KiB
ObjectPascal
8878 lines
249 KiB
ObjectPascal
{-------------------------------------------------------------------------------
|
||
QWindows.pas
|
||
|
||
Copyright (c) 2003,2004, Andre Snepvangers (asn att xs4all dott nl),
|
||
|
||
All rights reserved.
|
||
|
||
Version 1.0
|
||
Description: Qt based wrappers for common MS Windows API's
|
||
Purpose: Reduce coding effort for porting VCL based components to VisualCLX
|
||
compatible components. Simplify VCL code sharing.
|
||
|
||
Contributor(s): Andreas Hausladen [Andreas dott Hausladen att gmx dott de]
|
||
|
||
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 origin of this software must not be misrepresented, you must
|
||
not claim that you wrote the original software. If you use this
|
||
software in a product, an acknowledgment in the product documentation
|
||
would be appreciated but is not required.
|
||
|
||
Altered source versions must be plainly marked as such, and must not
|
||
be misrepresented as being the original 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.
|
||
--------------------------------------------------------------------------------
|
||
|
||
Known Issues:
|
||
- Covers only a small part of the Windows APIs
|
||
- Not all functionality is supported
|
||
{-----------------------------------------------------------------------------}
|
||
// $Id: QWindows.pas 11641 2007-12-24 16:34:00Z outchy $
|
||
|
||
unit QWindows;
|
||
|
||
interface
|
||
|
||
uses
|
||
{$IFDEF MSWINDOWS}
|
||
Windows,
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Libc, DateUtils,
|
||
{$ENDIF LINUX}
|
||
Types, StrUtils, SysUtils, Classes, Math, Contnrs, SyncObjs, QDialogs,
|
||
QTypes, Qt, QConsts, QGraphics, QControls, QForms, QExtCtrls, QStdCtrls,
|
||
QButtons, QImgList, QStyle;
|
||
|
||
type
|
||
IPerformControl = interface
|
||
['{B11AA73D-D7C2-43E5-BED8-8F82DE6152AB}']
|
||
function Perform(Msg: Cardinal; WPar, LPar: Longint): Longint;
|
||
end;
|
||
|
||
{$IFDEF LINUX}
|
||
resourcestring
|
||
SFCreateError = 'Unable to create file %s';
|
||
SFOpenError = 'Unable to open file %s';
|
||
SReadError = 'Error reading file';
|
||
SWriteError = 'Error writing file';
|
||
SQThreadError = 'Thread Error in QWindows: %s (%d)';
|
||
{$ENDIF LINUX}
|
||
|
||
var
|
||
NewStyleControls: Boolean = True;
|
||
|
||
const
|
||
{ SetBkMode: background modes }
|
||
TRANSPARENT = 1; // BGMode_TransparentMode
|
||
OPAQUE = 2; // BGMode_OpaqueMode
|
||
|
||
{ constants for CreateDIBitmap }
|
||
CBM_INIT = 4; { initialize bitmap }
|
||
DIB_RGB_COLORS = 0;
|
||
// DIB_PAL_COLORS = 1; // not supported by CreateDIBitmap
|
||
|
||
{ windows symbolic colors } { mapping VisualCLX Symbolic colors}
|
||
COLOR_SCROLLBAR = 0; // clNormalButton
|
||
COLOR_BACKGROUND = 1; // clNormalBackground
|
||
COLOR_ACTIVECAPTION = 2; // clActiveHighlightedText
|
||
COLOR_INACTIVECAPTION = 3; // clDisabledHighlightedText
|
||
COLOR_MENU = 4; // clNormalMid
|
||
COLOR_WINDOW = 5; // clNormalBase
|
||
COLOR_WINDOWFRAME = 6; // clNormalHighlight
|
||
COLOR_MENUTEXT = 7; // clNormalButtonText
|
||
COLOR_WINDOWTEXT = 8; // clNormalText
|
||
COLOR_CAPTIONTEXT = 9; // clNormalHighlightedText
|
||
COLOR_ACTIVEBORDER = 10; // clActiveHighlight
|
||
COLOR_INACTIVEBORDER = 11; // clDisabledHighlight
|
||
COLOR_APPWORKSPACE = 12; // clNormalMid
|
||
COLOR_HIGHLIGHT = 13; // clNormalHighlight
|
||
COLOR_HIGHLIGHTTEXT = 14; // clNormalHighlightedText
|
||
COLOR_BTNFACE = 15; // clNormalButton
|
||
COLOR_BTNSHADOW = $10; // clNormalDark
|
||
COLOR_GRAYTEXT = 17; // clNormalDisabledText
|
||
COLOR_BTNTEXT = 18; // clNormalButtonText
|
||
COLOR_INACTIVECAPTIONTEXT = 19; // clDisabledHighlightedText
|
||
COLOR_BTNHIGHLIGHT = 20; // clActiveLight
|
||
COLOR_3DDKSHADOW = 21; // clNormalMid
|
||
COLOR_3DLIGHT = 22; // clNormalMidLight
|
||
COLOR_INFOTEXT = 23; // clNormalText
|
||
COLOR_INFOBK = 24; // TColor($E1FFFF)
|
||
// = 25; // ?? (asn: defined as clBlack for now)
|
||
COLOR_HOTLIGHT = 26; // clActiveHighlight (asn: ??)
|
||
COLOR_GRADIENTACTIVECAPTION = 27; // clActiveHighLight (asn: ??)
|
||
COLOR_GRADIENTINACTIVECAPTION = 28; // clDisabledHighlight (asn: ??)
|
||
|
||
COLOR_ENDCOLORS = COLOR_GRADIENTINACTIVECAPTION;
|
||
(*
|
||
COLOR_MENUHILIGHT = 29;
|
||
COLOR_MENUBAR = 30;
|
||
COLOR_ENDCOLORS = COLOR_MENUBAR;
|
||
*)
|
||
|
||
COLOR_DESKTOP = COLOR_BACKGROUND;
|
||
COLOR_3DFACE = COLOR_BTNFACE;
|
||
COLOR_3DSHADOW = COLOR_BTNSHADOW;
|
||
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT;
|
||
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT;
|
||
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT;
|
||
|
||
{ CombineRgn return values }
|
||
NULLREGION = 1; // Region is empty
|
||
SIMPLEREGION = 2; // Region is a rectangle
|
||
COMPLEXREGION = 3; // Region is not a rectangle
|
||
ERROR = 0; // Region error
|
||
RGN_ERROR = ERROR;
|
||
|
||
{ constants for CreatePolygon }
|
||
ALTERNATE = 1;
|
||
WINDING = 2;
|
||
|
||
{ flags for DrawFrameControl }
|
||
DFC_CAPTION = 1;
|
||
DFC_MENU = 2;
|
||
DFC_SCROLL = 3;
|
||
DFC_BUTTON = 4;
|
||
DFC_POPUPMENU = 5;
|
||
|
||
DFCS_CAPTIONCLOSE = 0;
|
||
DFCS_CAPTIONMIN = 1;
|
||
DFCS_CAPTIONMAX = 2;
|
||
DFCS_CAPTIONRESTORE = 3;
|
||
DFCS_CAPTIONHELP = 4;
|
||
|
||
DFCS_MENUARROW = 0;
|
||
DFCS_MENUCHECK = 1;
|
||
DFCS_MENUBULLET = 2;
|
||
DFCS_MENUARROWRIGHT = 4;
|
||
|
||
DFCS_SCROLLUP = 0;
|
||
DFCS_SCROLLDOWN = 1;
|
||
DFCS_SCROLLLEFT = 2;
|
||
DFCS_SCROLLRIGHT = 3;
|
||
DFCS_SCROLLCOMBOBOX = 5;
|
||
DFCS_SCROLLSIZEGRIP = 8;
|
||
DFCS_SCROLLSIZEGRIPRIGHT = $10;
|
||
|
||
DFCS_BUTTONCHECK = 0;
|
||
DFCS_BUTTONRADIOIMAGE = 1;
|
||
DFCS_BUTTONRADIOMASK = 2;
|
||
DFCS_BUTTONRADIO = 4;
|
||
DFCS_BUTTON3STATE = 8;
|
||
DFCS_BUTTONPUSH = $10;
|
||
|
||
DFCS_INACTIVE = $100;
|
||
DFCS_PUSHED = $200;
|
||
DFCS_CHECKED = $400;
|
||
DFCS_TRANSPARENT = $800;
|
||
DFCS_HOT = $1000;
|
||
DFCS_ADJUSTRECT = $2000;
|
||
DFCS_FLAT = $4000;
|
||
DFCS_MONO = $8000;
|
||
|
||
{ 3D border styles }
|
||
BDR_RAISEDOUTER = 1;
|
||
BDR_SUNKENOUTER = 2;
|
||
BDR_RAISEDINNER = 4;
|
||
BDR_SUNKENINNER = 8;
|
||
|
||
BDR_OUTER = BDR_SUNKENOUTER or BDR_RAISEDOUTER;
|
||
BDR_INNER = BDR_SUNKENINNER or BDR_SUNKENOUTER;
|
||
BDR_RAISED = BDR_RAISEDINNER or BDR_RAISEDOUTER;
|
||
BDR_SUNKEN = BDR_SUNKENINNER or BDR_SUNKENOUTER;
|
||
|
||
EDGE_RAISED = BDR_RAISEDOUTER or BDR_RAISEDINNER;
|
||
EDGE_SUNKEN = BDR_SUNKENOUTER or BDR_SUNKENINNER;
|
||
EDGE_ETCHED = BDR_SUNKENOUTER or BDR_RAISEDINNER;
|
||
EDGE_BUMP = BDR_RAISEDOUTER or BDR_SUNKENINNER;
|
||
|
||
{ Border flags }
|
||
BF_LEFT = 1;
|
||
BF_TOP = 2;
|
||
BF_RIGHT = 4;
|
||
BF_BOTTOM = 8;
|
||
BF_DIAGONAL = $10;
|
||
|
||
BF_TOPLEFT = BF_TOP or BF_LEFT;
|
||
BF_TOPRIGHT = BF_TOP or BF_RIGHT;
|
||
BF_BOTTOMLEFT = BF_BOTTOM or BF_LEFT;
|
||
BF_BOTTOMRIGHT = BF_BOTTOM or BF_RIGHT;
|
||
BF_RECT = BF_TOPLEFT or BF_BOTTOMRIGHT;
|
||
|
||
{ For diagonal lines, the BF_RECT flags specify the end point of the}
|
||
{ vector bounded by the rectangle parameter.}
|
||
BF_DIAGONAL_ENDTOPRIGHT = BF_DIAGONAL or BF_TOP or BF_RIGHT;
|
||
BF_DIAGONAL_ENDTOPLEFT = BF_DIAGONAL or BF_TOP or BF_LEFT;
|
||
BF_DIAGONAL_ENDBOTTOMLEFT = BF_DIAGONAL or BF_BOTTOM or BF_LEFT;
|
||
BF_DIAGONAL_ENDBOTTOMRIGHT = BF_DIAGONAL or BF_BOTTOM or BF_RIGHT;
|
||
|
||
BF_MIDDLE = $800; { Fill in the middle }
|
||
BF_SOFT = $1000; { For softer buttons }
|
||
BF_ADJUST = $2000; { Calculate the space left over }
|
||
BF_FLAT = $4000; { For flat rather than 3D borders }
|
||
BF_MONO = $8000; { For monochrome borders }
|
||
|
||
{ DrawIconEx diFlags }
|
||
DI_MASK = 1;
|
||
DI_IMAGE = 2;
|
||
DI_NORMAL = 3;
|
||
// DI_COMPAT = 4; not supported
|
||
DI_DEFAULTSIZE = 8;
|
||
|
||
{ DrawText format (windows) flags }
|
||
DT_TOP = 0;
|
||
DT_LEFT = 0;
|
||
DT_CENTER = 1;
|
||
DT_RIGHT = 2;
|
||
DT_VCENTER = 4;
|
||
DT_BOTTOM = 8;
|
||
DT_WORDBREAK = $10;
|
||
DT_SINGLELINE = $20;
|
||
DT_EXPANDTABS = $40;
|
||
DT_TABSTOP = $80;
|
||
DT_NOCLIP = $100;
|
||
(* DT_EXTERNALLEADING = $200; // not supported *)
|
||
DT_CALCRECT = $400;
|
||
DT_NOPREFIX = $800;
|
||
DT_INTERNAL = $1000; // Uses the system font to calculate text metrics.
|
||
DT_EDITCONTROL = $2000; // ignored
|
||
DT_PATH_ELLIPSIS = $4000;
|
||
DT_ELLIPSIS = $8000;
|
||
DT_END_ELLIPSIS = DT_ELLIPSIS;
|
||
DT_MODIFYSTRING = $10000;
|
||
DT_RTLREADING = $20000; // ignored
|
||
DT_WORD_ELLIPSIS = $40000;
|
||
DT_HIDEPREFIX = $100000;
|
||
DT_PREFIXONLY = $200000;
|
||
|
||
{ ExtTextOut format flags }
|
||
ETO_OPAQUE = 2;
|
||
ETO_CLIPPED = 4;
|
||
ETO_RTLREADING = $80; // ignored
|
||
|
||
{ font metrics }
|
||
DEFAULT_PITCH = 0;
|
||
FIXED_PITCH = 1;
|
||
VARIABLE_PITCH = 2;
|
||
DEFAULT_CHARSET = 1;
|
||
|
||
{$IFDEF LINUX}
|
||
HINSTANCE_ERROR = 0;
|
||
HINSTANCE_OK = HINSTANCE_ERROR + 1;
|
||
{$ENDIF LINUX}
|
||
|
||
{ BrushStyle mappings}
|
||
HS_BDIAGONAL = BrushStyle_BDiagPattern; // 45-degree downward left-to-right hatch
|
||
HS_CROSS = BrushStyle_CrossPattern; // Hor. and vertical crosshatch
|
||
HS_DIAGCROSS = BrushStyle_DiagCrossPattern;// 45-degree crosshatch
|
||
HS_FDIAGONAL = BrushStyle_FDiagPattern; // 45-degree upward left-to-right hatch
|
||
HS_HORIZONTAL = BrushStyle_HorPattern; // Horizontal hatch
|
||
HS_VERTICAL = BrushStyle_VerPattern; // Vertical hatch
|
||
|
||
HWND_TOP = Cardinal(0);
|
||
HWND_BOTTOM = Cardinal(1);
|
||
HWND_TOPMOST = Cardinal(-1);
|
||
HWND_NOTOPMOST = Cardinal(-2);
|
||
|
||
{$IFDEF LINUX}
|
||
{ GlobalMemory }
|
||
GMEM_FIXED = 0;
|
||
GMEM_MOVEABLE = 2;
|
||
GMEM_NOCOMPACT = $10;
|
||
GMEM_NODISCARD = $20;
|
||
GMEM_ZEROINIT = $40; // only supported flag
|
||
GMEM_MODIFY = $80;
|
||
GMEM_DISCARDABLE = $100;
|
||
GMEM_NOT_BANKED = $1000;
|
||
GMEM_SHARE = $2000;
|
||
GMEM_DDESHARE = $2000;
|
||
GMEM_NOTIFY = $4000;
|
||
GMEM_LOWER = GMEM_NOT_BANKED;
|
||
GMEM_VALID_FLAGS = 32626;
|
||
GMEM_INVALID_HANDLE = $8000;
|
||
|
||
GHND = GMEM_MOVEABLE or GMEM_ZEROINIT;
|
||
GPTR = GMEM_FIXED or GMEM_ZEROINIT;
|
||
|
||
{$ENDIF LINUX}
|
||
|
||
|
||
INFINITE = Longword($FFFFFFFF); // Infinite timeout
|
||
INVALID_HANDLE_VALUE = DWORD(-1);
|
||
MaxWord = High(Cardinal);
|
||
|
||
{ MessageBox() return values }
|
||
IDCLOSE = 0;
|
||
IDOK = 1;
|
||
IDCANCEL = 2;
|
||
IDYES = 3;
|
||
IDNO = 4;
|
||
IDABORT = 5;
|
||
IDRETRY = 6;
|
||
IDIGNORE = 7;
|
||
{ aliases }
|
||
ID_OK = IDOK;
|
||
ID_CANCEL = IDCANCEL;
|
||
ID_ABORT = IDABORT;
|
||
ID_RETRY = IDRETRY;
|
||
ID_IGNORE = IDIGNORE;
|
||
ID_YES = IDYES;
|
||
ID_NO = IDNO;
|
||
ID_CLOSE = IDCLOSE;
|
||
IDHELP = 9; // not supported
|
||
ID_HELP = IDHELP; // not supported
|
||
IDTRYAGAIN = IDRETRY;
|
||
IDCONTINUE = IDIGNORE;
|
||
|
||
{$EXTERNALSYM LB_OKAY}
|
||
LB_OKAY = 0;
|
||
{$EXTERNALSYM LB_ERR}
|
||
LB_ERR = -1;
|
||
{$EXTERNALSYM LB_ERRSPACE}
|
||
LB_ERRSPACE = -2;
|
||
{$EXTERNALSYM CB_OKAY}
|
||
CB_OKAY = 0;
|
||
{$EXTERNALSYM CB_ERR}
|
||
CB_ERR = -1;
|
||
{$EXTERNALSYM CB_ERRSPACE}
|
||
CB_ERRSPACE = -2;
|
||
|
||
|
||
MAX_COMPUTERNAME_LENGTH = 15;
|
||
|
||
{ MessageBox() WinFlags }
|
||
MB_OK = $0000;
|
||
MB_OKCANCEL = $0001;
|
||
MB_ABORTRETRYIGNORE = $0002;
|
||
MB_YESNOCANCEL = $0003;
|
||
MB_YESNO = $0004;
|
||
MB_RETRYCANCEL = $0005;
|
||
MB_HELP = $4000; { Help Button not supported}
|
||
MB_ICONHAND = $0010;
|
||
MB_ICONQUESTION = $0020;
|
||
MB_ICONEXCLAMATION = $0030;
|
||
MB_ICONASTERISK = $0040;
|
||
MB_USERICON = $0080;
|
||
MB_DEFBUTTON1 = $0000;
|
||
MB_DEFBUTTON2 = $0100;
|
||
MB_DEFBUTTON3 = $0200;
|
||
MB_DEFBUTTON4 = $0300;
|
||
MB_ICONWARNING = MB_ICONEXCLAMATION;
|
||
MB_ICONERROR = MB_ICONHAND;
|
||
MB_ICONINFORMATION = MB_ICONASTERISK;
|
||
MB_ICONSTOP = MB_ICONHAND;
|
||
|
||
{ MouseKeys }
|
||
MK_LBUTTON = 1;
|
||
MK_RBUTTON = 2;
|
||
MK_SHIFT = 4;
|
||
MK_CONTROL = 8;
|
||
MK_MBUTTON = $10;
|
||
|
||
{ TDrawItemStruct itemstate }
|
||
ODS_DISABLED = 1;
|
||
ODS_SELECTED = 2;
|
||
ODS_FOCUS = 4;
|
||
|
||
{ Pen Styles }
|
||
PS_NULL = 0; // PenStyle_NoPen
|
||
PS_SOLID = 1; // PenStyle_SolidLine
|
||
PS_DASH = 2; // PenStyle_DashLine
|
||
PS_DOT = 3; // PenStyle_DotLine
|
||
PS_DASHDOT = 4; // PenStyle_DashDotLine
|
||
PS_DASHDOTDOT = 5; // PenStyle_DashDotDotLine
|
||
PS_STYLE_MASK = 15; // PenStyle_MPenStyle
|
||
{caps}
|
||
PS_ENDCAP_FLAT = 0; // PenCapStyle_FlatCap
|
||
PS_ENDCAP_SQUARE = 16; // PenCapStyle_SquareCap
|
||
PS_ENDCAP_ROUND = 32; // PenCapStyle_RoundCap
|
||
PS_ENDCAP_MASK = 48; // PenCapStyle_MPenCapStyle
|
||
{join}
|
||
PS_JOIN_MITER = 0; // PenJoinStyle_MiterJoin
|
||
PS_JOIN_BEVEL = 64; // PenJoinStyle_BevelJoin
|
||
PS_JOIN_ROUND = 128; // PenJoinStyle_RoundJoin
|
||
PS_JOIN_MASK = $C0; // PenCapStyle_MPenCapStyle
|
||
|
||
{ BitBlt/StretchBlt: supported windows dwRop Raster OPerations }
|
||
BLACKNESS = $00000042; // RasterOp_ClearROP
|
||
DSTINVERT = $00550009; // RasterOp_NotROP
|
||
MERGECOPY = $00C000CA; // RasterOp_OrROP
|
||
MERGEPAINT = $00BB0226; // RasterOp_NotOrRop
|
||
NOTSRCCOPY = $00330008; // RasterOp_NotCopyROP
|
||
NOTSRCERASE = $001100A6; // RasterOp_NorROP
|
||
SRCAND = $008800C6; // RasterOp_AndROP
|
||
SRCCOPY = $00CC0020; // RasterOp_CopyROP
|
||
SRCERASE = $00440328; // RasterOp_AndNotROP
|
||
SRCINVERT = $00660046; // RasterOp_XorROP
|
||
SRCPAINT = $00EE0086; // RasterOp_OrROP;
|
||
WHITENESS = $00FF0062; // RasterOp_SetROP
|
||
PATCOPY = $00F00021; // dest = pattern
|
||
PATPAINT = $00FB0A09; // dest = DPSnoo = PDSnoo
|
||
PATINVERT = $005A0049; // dest = pattern XOR dest
|
||
ROP_DSPDxax = $00E20746; // dest = ((pattern XOR dest) AND source) XOR Dest
|
||
ROP_DSna = $00220326; // RasterOp_NotAndROP
|
||
ROP_DSno = MERGEPAINT;
|
||
ROP_DPSnoo = PATPAINT;
|
||
ROP_D = $00AA0029; // RasterOp_NopROP
|
||
ROP_Dn = DSTINVERT; // DSTINVERT
|
||
ROP_SDna = SRCERASE; // SRCERASE
|
||
ROP_SDno = $00DD0228; // RasterOp_OrNotROP
|
||
ROP_DSan = $007700E6; // RasterOp_NandROP
|
||
ROP_DSon = $001100A6; // NOTSRCERASE
|
||
//ROP_Pn = $000F0001; //
|
||
|
||
{ SetROP2: windows ROP2 values }
|
||
R2_BLACK = 9; // RasterOp_ClearROP: Pixel is always 0.
|
||
R2_WHITE = 10; // RasterOp_SetROP:Pixel is always 1.
|
||
R2_NOP = 11; // RasterOp_NopROP: Pixel remains unchanged.
|
||
R2_NOT = 8; // RasterOp_NotROP: inverse of the screen color.
|
||
R2_COPYPEN = 0; // RasterOp_CopyROP: Pixel is the pen color.
|
||
R2_NOTCOPYPEN = 4; // RasterOp_NotCopyROP; inverse of the pen color.
|
||
R2_MERGEPENNOT = 13; // RasterOp_OrNotROP: combination of the pen color and the inverse of the screen color.
|
||
R2_MASKPENNOT = 12; // RasterOp_AndNotROP: combination of the colors common to both the pen and the inverse of the screen.
|
||
R2_MERGEPEN = 1; // RasterOp_OrROP: combination of the pen color and the screen color.
|
||
R2_NOTMERGEPEN = 15; // RasterOp_NorROP: inverse of the R2_MERGEPEN color.
|
||
R2_MASKPEN = 7; // RasterOp_AndROP: combination of the colors common to both the pen and the screen.
|
||
R2_NOTMASKPEN = 14; // RasterOp_NandROP: inverse of the R2_MASKPEN color.
|
||
R2_XORPEN = 2; // RasterOp_XorROP: combination of the colors in the pen and in the screen, but not in both.
|
||
R2_NOTXORPEN = 6; // RasterOp_NotXorROP: inverse of the R2_XORPEN color.
|
||
R2_MASKNOTPEN = 3; // RasterOp_NotAndROP: combination of the colors common to both the screen and the inverse of the pen.
|
||
R2_MERGENOTPEN = 5; // RasterOp_NotOrROP: combination of the screen color and the inverse of the pen color.
|
||
|
||
RT_RCDATA = Types.RT_RCDATA;
|
||
RT_BITMAP = PChar(2);
|
||
|
||
{ WM_xSCROLL ScrollCodes }
|
||
SB_BOTTOM = 1;
|
||
SB_ENDSCROLL = 2;
|
||
SB_LINEDOWN = 3;
|
||
SB_LINEUP = 4;
|
||
SB_PAGEDOWN = 5;
|
||
SB_PAGEUP = 6;
|
||
SB_THUMBPOSITION = 7;
|
||
SB_THUMBTRACK = 8;
|
||
SB_TOP = 9;
|
||
|
||
SB_HORZ = 1;
|
||
SB_VERT = 2;
|
||
SB_BOTH = SB_HORZ or SB_VERT;
|
||
|
||
|
||
{ semaphores }
|
||
STATUS_WAIT_0 = $00000000;
|
||
STATUS_ABANDONED_WAIT_0 = $00000080;
|
||
STATUS_TIMEOUT = $00000102;
|
||
WAIT_FAILED = Longword($FFFFFFFF);
|
||
WAIT_OBJECT_0 = STATUS_WAIT_0;
|
||
WAIT_ABANDONED = STATUS_ABANDONED_WAIT_0;
|
||
WAIT_ABANDONED_0 = STATUS_ABANDONED_WAIT_0;
|
||
WAIT_TIMEOUT = STATUS_TIMEOUT;
|
||
MAXIMUM_WAIT_OBJECTS = 64;
|
||
|
||
{ ShowWindow() Commands }
|
||
SW_HIDE = 0;
|
||
SW_SHOWNORMAL = 1;
|
||
SW_NORMAL = 1;
|
||
SW_SHOWMINIMIZED = 2;
|
||
SW_SHOWMAXIMIZED = 3;
|
||
SW_MAXIMIZE = 3;
|
||
SW_SHOWNOACTIVATE = 4;
|
||
SW_SHOW = 5;
|
||
SW_MINIMIZE = 6;
|
||
SW_SHOWMINNOACTIVE = 7;
|
||
SW_SHOWNA = 8;
|
||
SW_RESTORE = 9;
|
||
SW_SHOWDEFAULT = 10;
|
||
SW_MAX = 10;
|
||
|
||
{ SetWindowPos Flags }
|
||
SWP_NOSIZE = 1;
|
||
SWP_NOMOVE = 2;
|
||
SWP_NOZORDER = 4;
|
||
SWP_NOREDRAW = 8;
|
||
SWP_NOACTIVATE = $10;
|
||
SWP_FRAMECHANGED = $20; { The frame changed: send WM_NCCALCSIZE }
|
||
SWP_SHOWWINDOW = $40;
|
||
SWP_HIDEWINDOW = $80;
|
||
SWP_NOCOPYBITS = $100; // ignored
|
||
SWP_NOOWNERZORDER = $200; { Don't do owner Z ordering }
|
||
SWP_NOSENDCHANGING = $400; // ignores
|
||
SWP_DRAWFRAME = SWP_FRAMECHANGED;
|
||
SWP_NOREPOSITION = SWP_NOOWNERZORDER;
|
||
SWP_DEFERERASE = $2000;
|
||
SWP_ASYNCWINDOWPOS = $4000; // ignored
|
||
|
||
TA_LEFT = Integer(AlignmentFlags_AlignLeft);
|
||
TA_RIGHT = Integer(AlignmentFlags_AlignRight);
|
||
TA_CENTER = Integer(AlignmentFlags_AlignHCenter);
|
||
TA_TOP = Integer(AlignmentFlags_AlignTop);
|
||
TA_BOTTOM = Integer(AlignmentFlags_AlignBottom);
|
||
VTA_CENTER = Integer(AlignmentFlags_AlignVCenter);
|
||
TA_NOUPDATECP = 0;
|
||
TA_UPDATECP = $8000;
|
||
TA_BASELINE = $4000;
|
||
VTA_BASELINE = TA_BASELINE;
|
||
|
||
{$IFDEF LINUX}
|
||
{virtual memory handling}
|
||
PAGE_NOACCESS = 0;
|
||
PAGE_READONLY = PROT_READ;
|
||
PAGE_READWRITE = PROT_READ or PROT_WRITE;
|
||
//PAGE_WRITECOPY = PROT_ ; // not implemented
|
||
PAGE_EXECUTE = PROT_EXEC;
|
||
PAGE_EXECUTE_READ = PAGE_EXECUTE or PAGE_READONLY;
|
||
PAGE_EXECUTE_READWRITE = PAGE_EXECUTE or PAGE_READWRITE;
|
||
//PAGE_EXECUTE_WRITECOPY = PAGE_EXECUTE or PAGE_WRITECOPY;
|
||
{$ENDIF LINUX}
|
||
|
||
|
||
{ Windows VK_ keycodes to Qt key }
|
||
VK_BACK = Key_Backspace;
|
||
VK_TAB = Key_Tab;
|
||
VK_RETURN = Key_Enter; //Key_Return = Enter key from keypad
|
||
VK_SHIFT = Key_Shift;
|
||
VK_CONTROL = Key_Control;
|
||
VK_MENU = Key_Alt;
|
||
VK_PAUSE = Key_Pause;
|
||
VK_CAPITAL = Key_CapsLock;
|
||
VK_ESCAPE = 4096;
|
||
VK_SPACE = Key_Space;
|
||
VK_PRIOR = Key_Prior;
|
||
VK_NEXT = Key_Next;
|
||
VK_END = Key_End;
|
||
VK_HOME = Key_Home;
|
||
VK_LEFT = Key_Left;
|
||
VK_UP = Key_Up;
|
||
VK_RIGHT = Key_Right;
|
||
VK_DOWN = Key_Down;
|
||
{ VK_SELECT = 41; }
|
||
VK_PRINT = Key_Print;
|
||
{ VK_EXECUTE = 43; }
|
||
VK_SNAPSHOT = Key_Print;
|
||
VK_INSERT = Key_Insert;
|
||
VK_DELETE = Key_Delete;
|
||
VK_HELP = Key_Help;
|
||
{ VK_LWIN = 91; }
|
||
{ VK_RWIN = 92; }
|
||
VK_APPS = Key_Menu;
|
||
VK_NUMPAD0 = Key_0;
|
||
VK_NUMPAD1 = Key_1;
|
||
VK_NUMPAD2 = Key_2;
|
||
VK_NUMPAD3 = Key_3;
|
||
VK_NUMPAD4 = Key_4;
|
||
VK_NUMPAD5 = Key_5;
|
||
VK_NUMPAD6 = Key_6;
|
||
VK_NUMPAD7 = Key_7;
|
||
VK_NUMPAD8 = Key_8;
|
||
VK_NUMPAD9 = Key_9;
|
||
VK_MULTIPLY = Key_Asterisk;
|
||
VK_ADD = Key_Plus;
|
||
VK_SUBTRACT = Key_Minus;
|
||
VK_DECIMAL = Key_Period;
|
||
VK_DIVIDE = Key_Slash;
|
||
VK_F1 = Key_F1;
|
||
VK_F2 = Key_F2;
|
||
VK_F3 = Key_F3;
|
||
VK_F4 = Key_F4;
|
||
VK_F5 = Key_F5;
|
||
VK_F6 = Key_F6;
|
||
VK_F7 = Key_F7;
|
||
VK_F8 = Key_F8;
|
||
VK_F9 = Key_F1;
|
||
VK_F10 = Key_F10;
|
||
VK_F11 = Key_F11;
|
||
VK_F12 = Key_F12;
|
||
VK_F13 = Key_F13;
|
||
VK_F14 = Key_F14;
|
||
VK_F15 = Key_F15;
|
||
VK_F16 = Key_F16;
|
||
VK_F17 = Key_F17;
|
||
VK_F18 = Key_F18;
|
||
VK_F19 = Key_F19;
|
||
VK_F20 = Key_F20;
|
||
VK_F21 = Key_F21;
|
||
VK_F22 = Key_F22;
|
||
VK_F23 = Key_F23;
|
||
VK_F24 = Key_F24;
|
||
VK_NUMLOCK = Key_NumLock;
|
||
VK_SCROLL = Key_ScrollLock;
|
||
{ VK_L.. & VK_R.. mapping: }
|
||
{ Alt, Ctrl and Shift keys produce same keycode }
|
||
VK_LSHIFT = Key_Shift;
|
||
VK_RSHIFT = Key_Shift;
|
||
VK_LCONTROL = Key_Control;
|
||
VK_RCONTROL = Key_Control;
|
||
VK_LMENU = Key_Alt;
|
||
VK_RMENU = Key_Alt;
|
||
|
||
{ Qt alignment flags, (as used by Canvas.TextRect) }
|
||
AlignLeft = $1;
|
||
AlignRight = $2;
|
||
AlignHCenter = $4;
|
||
AlignTop = $8;
|
||
AlignBottom = $10;
|
||
AlignVCenter = $20;
|
||
AlignCenter = $24;
|
||
SingleLine = $40;
|
||
DontClip = $80;
|
||
ExpandTabs = $100;
|
||
ShowPrefix = $200;
|
||
WordBreak = $400;
|
||
BreakAnywhere = $800;
|
||
// DontPrint = $1000; not used
|
||
{ Additional constanst for Qt text alignments used by DrawText }
|
||
QtAlignMask = $FFF;
|
||
CalcRect = $10000;
|
||
ClipPath = $20000;
|
||
ClipName = $40000;
|
||
ClipToWord = $100000;
|
||
ModifyString = $200000;
|
||
|
||
pf24bit = pf32bit;
|
||
clSystemColor = $FF000000;
|
||
clMoneyGreen = TColor($C0DCC0);
|
||
clSkyBlue = TColor($F0CAA6);
|
||
clCream = TColor($F0FBFF);
|
||
clMedGray = TColor($A4A0A0);
|
||
clWindowFrame = cl3DDkShadow;
|
||
|
||
crColorTo = crNoRole;
|
||
clColorTo = TColor(-15);
|
||
clNormalColorTo = TColor(clColorTo - cloNormal);
|
||
clActiveColorTo = TColor(clColorTo - cloActive);
|
||
clDisabledColorTo = TColor(clColorTo - cloDisabled);
|
||
|
||
clNoRole = TColor(-15);
|
||
clNormalNoRole = TColor(clNoRole - cloNormal);
|
||
clDisabledNoRole = TColor(clNoRole - cloDisabled);
|
||
clActiveNoRole = TColor(clNoRole - cloActive);
|
||
clDesktop = clDisabledNoRole;
|
||
clColor0 = clMask;
|
||
clColor1 = clDontMask;
|
||
|
||
// Windows symbolic colors to mapping VisualCLX symbolic colors
|
||
Win2TColor: array [0..COLOR_ENDCOLORS] of TColor = (
|
||
clNormalButton, clNormalBackground, clActiveHighlightedText, // 0
|
||
clDisabledHighlightedText, clNormalMid, clNormalBase, // 3
|
||
clNormalHighlight, clNormalButtonText, clNormalText, // 6
|
||
clNormalHighlightedText, clActiveHighlight, clDisabledHighlight, // 9
|
||
clNormalMid, clNormalHighlight, clNormalHighlightedText, // 12
|
||
clNormalButton, clNormalDark, clDisabledText, // 15
|
||
clNormalButtonText, clDisabledHighlightedText, clActiveLight, // 18
|
||
clNormalMid, clNormalMidLight, clNormalText, // 21
|
||
clInfoBk, clBlack, clActiveHighlight, // 24
|
||
clActiveHighLight, clDisabledHighlight // 27
|
||
);
|
||
|
||
{ SendMessage / PostMessage }
|
||
QEventType_Message = QEventType(2105);
|
||
{ Timer message id}
|
||
WM_TIMER = $0113; { 275 }
|
||
|
||
type
|
||
TAppEventHook = class(TComponent)
|
||
private
|
||
FHook: QApplication_hookH;
|
||
protected
|
||
function EventFilter(Receiver: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
end;
|
||
|
||
TMsg = packed record
|
||
hwnd: QWidgetH;
|
||
message: Integer;
|
||
wParam: Integer;
|
||
lParam: Integer;
|
||
case integer of
|
||
0:
|
||
(
|
||
time: Cardinal;
|
||
pt: TPoint;
|
||
);
|
||
1: ( Result: Integer);
|
||
2: ( Handled: LongBool);
|
||
end;
|
||
PMsg = ^TMsg;
|
||
|
||
TMessage = packed record
|
||
Msg: Cardinal;
|
||
case Integer of
|
||
0:
|
||
(
|
||
WParam: Longint;
|
||
LParam: Longint;
|
||
Result: Longint;
|
||
);
|
||
1:
|
||
(
|
||
WParamLo: Word;
|
||
WParamHi: Word;
|
||
LParamLo: Word;
|
||
LParamHi: Word;
|
||
ResultLo: Word;
|
||
ResultHi: Word
|
||
);
|
||
end;
|
||
PMessage = ^TMessage;
|
||
|
||
{ Provided to simplify VCL source sharing }
|
||
HWND = QWidgetH;
|
||
HCURSOR = QCursorH;
|
||
HRGN = QRegionH;
|
||
HBRUSH = QBrushH;
|
||
HBITMAP = QPixmapH;
|
||
HDC = QPainterH;
|
||
HFONT = QFontH;
|
||
UINT = Cardinal;
|
||
ULONG = Cardinal;
|
||
DWORD = Cardinal;
|
||
BOOL = LongBool;
|
||
WPARAM = Integer;
|
||
LPARAM = Integer;
|
||
LRESULT = Integer;
|
||
TPointL = TPoint;
|
||
COLORREF = Integer;
|
||
TColorRef = COLORREF;
|
||
|
||
TWinControlActionLink = TWidgetControlActionLink;
|
||
TControlClass = class of TControl;
|
||
|
||
{$EXTERNALSYM TCaption}
|
||
TCaption = QTypes.TCaption;
|
||
|
||
{$EXTERNALSYM TOwnerDrawState}
|
||
TOwnerDrawState = QStdCtrls.TOwnerDrawState;
|
||
|
||
{$EXTERNALSYM PPoint}
|
||
{$EXTERNALSYM TPoint}
|
||
PPoint = Types.PPoint;
|
||
TPoint = Types.TPoint;
|
||
|
||
{$EXTERNALSYM PRect}
|
||
{$EXTERNALSYM TRect}
|
||
PRect = Types.PRect;
|
||
TRect = Types.TRect;
|
||
|
||
{$EXTERNALSYM PSize}
|
||
{$EXTERNALSYM TSize}
|
||
TSize = Types.TSize;
|
||
PSize = Types.PSize;
|
||
|
||
PSmallPoint = Types.PSmallPoint;
|
||
TSmallPoint = Types.TSmallPoint;
|
||
{$EXTERNALSYM PSmallPoint}
|
||
{$EXTERNALSYM TSmallPoint}
|
||
|
||
TTime = type TDateTime;
|
||
TDate = type TDateTime;
|
||
{$EXTERNALSYM TDate}
|
||
{$EXTERNALSYM TTime}
|
||
|
||
{ colors }
|
||
TRGBQuad = packed record
|
||
rgbBlue: Byte;
|
||
rgbGreen: Byte;
|
||
rgbRed: Byte;
|
||
rgbReserved: Byte;
|
||
end;
|
||
TRGBTriple = TRGBQuad; // Qt does not support 24 bit pixmaps
|
||
|
||
{ fonts }
|
||
tagTEXTMETRICA = record
|
||
tmHeight: Longint;
|
||
tmAscent: Longint;
|
||
tmDescent: Longint;
|
||
//tmInternalLeading: Longint; // not supported
|
||
tmExternalLeading: Longint;
|
||
tmAveCharWidth: Longint;
|
||
tmMaxCharWidth: Longint;
|
||
tmWeight: Longint;
|
||
//tmOverhang: Longint; // not supported
|
||
tmDigitizedAspectX: Longint;
|
||
tmDigitizedAspectY: Longint;
|
||
tmFirstChar: AnsiChar;
|
||
tmLastChar: AnsiChar;
|
||
tmDefaultChar: AnsiChar;
|
||
tmBreakChar: AnsiChar;
|
||
tmItalic: Byte;
|
||
tmUnderlined: Byte;
|
||
tmStruckOut: Byte;
|
||
tmPitchAndFamily: Byte;
|
||
tmCharSet: Byte;
|
||
end;
|
||
TTextMetric = tagTEXTMETRICA;
|
||
TEXTMETRIC = TTextMetric;
|
||
|
||
{ Logical Pen }
|
||
PLogPen = ^TLogPen;
|
||
tagLOGPEN = packed record
|
||
lopnStyle: UINT;
|
||
lopnWidth: TPoint;
|
||
lopnColor: COLORREF;
|
||
end;
|
||
TLogPen = tagLOGPEN;
|
||
LOGPEN = tagLOGPEN;
|
||
|
||
{ Logical Palette }
|
||
PPaletteEntry = ^TPaletteEntry;
|
||
tagPALETTEENTRY = packed record
|
||
peRed: Byte;
|
||
peGreen: Byte;
|
||
peBlue: Byte;
|
||
peFlags: Byte;
|
||
end;
|
||
TPaletteEntry = tagPALETTEENTRY;
|
||
PALETTEENTRY = tagPALETTEENTRY;
|
||
|
||
PLogPalette = ^TLogPalette;
|
||
tagLOGPALETTE = packed record
|
||
palVersion: Word;
|
||
palNumEntries: Word;
|
||
palPalEntry: array[0..0] of TPaletteEntry;
|
||
end;
|
||
TLogPalette = tagLOGPALETTE;
|
||
LOGPALETTE = tagLOGPALETTE;
|
||
|
||
PMaxLogPalette = ^TMaxLogPalette;
|
||
TMaxLogPalette = packed record
|
||
palVersion: Word;
|
||
palNumEntries: Word;
|
||
palPalEntry: array[Byte] of TPaletteEntry;
|
||
end;
|
||
|
||
PtagBITMAP = ^tagBITMAP;
|
||
tagBITMAP = packed record
|
||
//bmType: Longint;
|
||
bmWidth: Longint;
|
||
bmHeight: Longint;
|
||
//bmWidthBytes: Longint;
|
||
//bmPlanes: Word;
|
||
bmBitsPixel: Word;
|
||
//bmBits: Pointer;
|
||
end;
|
||
|
||
PBitmapInfoHeader = ^TBitmapInfoHeader;
|
||
tagBITMAPINFOHEADER = packed record
|
||
biSize: DWORD;
|
||
biWidth: Longint;
|
||
biHeight: Longint;
|
||
biPlanes: Word;
|
||
biBitCount: Word;
|
||
biCompression: DWORD;
|
||
biSizeImage: DWORD;
|
||
biXPelsPerMeter: Longint;
|
||
biYPelsPerMeter: Longint;
|
||
biClrUsed: DWORD;
|
||
biClrImportant: DWORD;
|
||
end;
|
||
TBitmapInfoHeader = tagBITMAPINFOHEADER;
|
||
BITMAPINFOHEADER = tagBITMAPINFOHEADER;
|
||
|
||
PBitmapInfo = ^TBitmapInfo;
|
||
tagBITMAPINFO = packed record
|
||
bmiHeader: TBitmapInfoHeader;
|
||
bmiColors: array[0..0] of TRGBQuad;
|
||
end;
|
||
TBitmapInfo = tagBITMAPINFO;
|
||
BITMAPINFO = tagBITMAPINFO;
|
||
|
||
PBitmapFileHeader = ^TBitmapFileHeader;
|
||
tagBITMAPFILEHEADER = packed record
|
||
bfType: Word;
|
||
bfSize: DWORD;
|
||
bfReserved1: Word;
|
||
bfReserved2: Word;
|
||
bfOffBits: DWORD;
|
||
end;
|
||
TBitmapFileHeader = tagBITMAPFILEHEADER;
|
||
BITMAPFILEHEADER = tagBITMAPFILEHEADER;
|
||
|
||
tagDRAWITEMSTRUCT = packed record
|
||
CtlType: Cardinal;
|
||
CtlID: Cardinal;
|
||
itemID: Cardinal;
|
||
itemAction: Cardinal;
|
||
itemState: Cardinal;
|
||
hwndItem: QWidgetH;
|
||
hDC: QPainterH;
|
||
rcItem: TRect;
|
||
itemData: Cardinal;
|
||
end;
|
||
TDrawItemStruct = tagDRAWITEMSTRUCT;
|
||
DRAWITEMSTRUCT = tagDRAWITEMSTRUCT;
|
||
|
||
type
|
||
TDeviceCap = (
|
||
HORZSIZE, {Horizontal size in millimeters}
|
||
VERTSIZE, {Vertical size in millimeters}
|
||
HORZRES, {Horizontal width in pixels}
|
||
VERTRES, {Vertical height in pixels}
|
||
BITSPIXEL, {Number of bits per pixel}
|
||
PLANES, {Number of planes}
|
||
NUMCOLORS,
|
||
LOGPIXELSX, {Logical pixelsinch in X}
|
||
LOGPIXELSY, {Logical pixelsinch in Y}
|
||
PHYSICALWIDTH, {Physical Width in device units}
|
||
PHYSICALHEIGHT, {Physical Height in device units}
|
||
PHYSICALOFFSETX, {Physical Printable Area X margin}
|
||
PHYSICALOFFSETY {Physical Printable Area Y margin}
|
||
);
|
||
|
||
{ Mapping Modes }
|
||
TMapMode = (
|
||
MM_TEXT = 1,
|
||
MM_LOMETRIC = 2,
|
||
MM_HIMETRIC = 3,
|
||
MM_LOENGLISH = 4,
|
||
MM_HIENGLISH = 5,
|
||
MM_TWIPS = 6,
|
||
MM_ISOTROPIC = 7,
|
||
MM_ANISOTROPIC = 8
|
||
);
|
||
|
||
const
|
||
{ Min and Max Mapping Mode values }
|
||
MM_MIN = MM_TEXT;
|
||
MM_MAX = MM_ANISOTROPIC;
|
||
MM_MAX_FIXEDSCALE = MM_TWIPS;
|
||
|
||
type
|
||
TMinMaxInfo = packed record
|
||
ptReserved: TPoint;
|
||
ptMaxSize: TPoint;
|
||
ptMaxPosition: TPoint;
|
||
ptMinTrackSize: TPoint;
|
||
ptMaxTrackSize: TPoint;
|
||
end;
|
||
|
||
(*)
|
||
PPaintStruct = ^TPaintStruct;
|
||
tagPAINTSTRUCT = packed record
|
||
hdc: HDC;
|
||
fErase: BOOL;
|
||
rcPaint: TRect;
|
||
fRestore: BOOL;
|
||
fIncUpdate: BOOL;
|
||
rgbReserved: array[0..31] of Byte;
|
||
end;
|
||
TPaintStruct = tagPAINTSTRUCT;
|
||
PAINTSTRUCT = tagPAINTSTRUCT;
|
||
(*)
|
||
|
||
{ regions }
|
||
type
|
||
TCombineMode = (
|
||
RGN_AND, // Creates the intersection of the two combined regions.
|
||
RGN_COPY, // Creates a copy of the region identified by hrgnSrc1.
|
||
RGN_DIFF, // Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.
|
||
RGN_OR, // Creates the union of two combined regions.
|
||
RGN_XOR // Creates the union of two combined regions except for any overlapping areas.
|
||
);
|
||
|
||
PSecurityAttributes = Pointer;
|
||
|
||
{ StretchBlt() Modes }
|
||
TStretchMode = (
|
||
BLACKONWHITE = 1,
|
||
WHITEONBLACK = 2,
|
||
COLORONCOLOR = 3,
|
||
HALFTONE = 4
|
||
);
|
||
|
||
const
|
||
MAXSTRETCHBLTMODE = 4;
|
||
STRETCH_ANDSCANS = BLACKONWHITE;
|
||
STRETCH_ORSCANS = WHITEONBLACK;
|
||
STRETCH_DELETESCANS = COLORONCOLOR;
|
||
STRETCH_HALFTONE = HALFTONE;
|
||
|
||
{ Stock Logical Objects }
|
||
type
|
||
TStockObjectBrush = (
|
||
WHITE_BRUSH = 0,
|
||
LTGRAY_BRUSH = 1,
|
||
GRAY_BRUSH = 2,
|
||
DKGRAY_BRUSH = 3,
|
||
BLACK_BRUSH = 4,
|
||
NULL_BRUSH = 5,
|
||
DC_BRUSH = 18
|
||
);
|
||
|
||
TStockObjectPen = (
|
||
WHITE_PEN = 6,
|
||
BLACK_PEN = 7,
|
||
NULL_PEN = 8,
|
||
DC_PEN = 19
|
||
);
|
||
|
||
TStockObjectFont = (
|
||
OEM_FIXED_FONT = 10,
|
||
ANSI_FIXED_FONT = 11,
|
||
ANSI_VAR_FONT = 12,
|
||
SYSTEM_FONT = 13,
|
||
DEVICE_DEFAULT_FONT = 14,
|
||
DEFAULT_PALETTE = 15,
|
||
SYSTEM_FIXED_FONT = $10,
|
||
DEFAULT_GUI_FONT = 17
|
||
);
|
||
|
||
const
|
||
HOLLOW_BRUSH = NULL_BRUSH;
|
||
STOCK_LAST = DC_PEN;
|
||
|
||
type
|
||
TSysMetrics = (
|
||
SM_CXSCREEN, SM_CYSCREEN,
|
||
SM_CXVSCROLL, SM_CYVSCROLL,
|
||
SM_CXHSCROLL, SM_CYHSCROLL,
|
||
SM_CXSMICON, SM_CYSMICON,
|
||
SM_CXICON, SM_CYICON,
|
||
SM_CXBORDER, SM_CYBORDER,
|
||
SM_CXFRAME, SM_CYFRAME,
|
||
SM_CYCAPTION, SM_CXDLGFRAME,
|
||
SM_CYDLGFRAME
|
||
);
|
||
|
||
{$IFDEF LINUX}
|
||
TSystemTime = record
|
||
wYear: Word;
|
||
wMonth: Word;
|
||
wDayOfWeek: Word;
|
||
wDay: Word;
|
||
wHour: Word;
|
||
wMinute: Word;
|
||
wSecond: Word;
|
||
wMilliseconds: Word;
|
||
end;
|
||
{$ENDIF LINUX}
|
||
|
||
{ threads }
|
||
type
|
||
TThreadPriority = Integer;
|
||
|
||
const
|
||
tpIdle: TThreadPriority = 0;
|
||
THREAD_PRIORITY_ERROR_RETURN = 255;
|
||
|
||
type { wait for object}
|
||
TWOHandleArray = array[0..MAXIMUM_WAIT_OBJECTS - 1] of THandle;
|
||
PWOHandleArray = ^TWOHandleArray;
|
||
|
||
TWindowPlacement = packed record
|
||
length: Cardinal;
|
||
flags: Integer;
|
||
showCmd: UInt;
|
||
ptMinPosition: TPoint;
|
||
ptMaxPosition: TPoint;
|
||
rcNormalPosition: TRect;
|
||
end;
|
||
PWindowPlacement = ^TWindowPlacement;
|
||
|
||
type
|
||
TTimerProc = procedure(Widget: QWidgetH; Msg: Cardinal; WMTimerId: Cardinal; TickCount: Cardinal);
|
||
TAppEventFilterMethod = function (Sender: QObjectH; Event: QEventH): Boolean; cdecl;
|
||
PAppEventFilterMethod = ^TAppEventFilterMethod;
|
||
|
||
function InstallApplicationEventHook(EventFilter: TEventFilterMethod): QApplication_hookH;
|
||
|
||
procedure WakeUpGuiThread;
|
||
{
|
||
Dummies for ... VCL
|
||
asn: AFAIK use of RightToLeft or LeftToRight is automatic
|
||
}
|
||
const
|
||
BiDiMode: TBiDiMode = bdLeftToRight; // asn: var?
|
||
|
||
function DrawTextBiDiModeFlagsReadingOnly: Longint;
|
||
function DrawTextBiDiModeFlags(Flags: Longint): Longint;
|
||
procedure ChangeBiDiModeAlignment(var Alignment: TAlignment);
|
||
function UseRightToLeftAlignment: Boolean;
|
||
|
||
{ Palette colors }
|
||
function GetSysColor(SysColor: Integer): TColorRef; // windows SysColor !!
|
||
function SetSysColor(RefColor: TColor; TrueColor: TColorRef): Boolean;
|
||
function SetSysColors(Elements: Integer; const lpaElements;
|
||
const lpaRgbValues): LongBool;
|
||
|
||
{
|
||
QGraphics.ColorToRGB supports only
|
||
TMappedColor = clActiveHighlightedText..clNormalForeground
|
||
Returns clBlack for any other color !
|
||
|
||
This implementation uses Instance.Palette and supports all colors
|
||
if Instance = nil then it will use Application.MainForm, in that
|
||
case clHighlightedText..clForeground is mapped to clNormalHighlightedText..clNormalForeground
|
||
If the Color is an RGB value, clDefault, clNone, it returns the Color itself.
|
||
}
|
||
function ColorToRGB(Color: TColor; Instance: TWidgetControl = nil): TColor;
|
||
|
||
function RGB(Red, Green, Blue: Integer): TColorRef;
|
||
function GetBValue(Col: TColorRef): Byte;
|
||
function GetGValue(Col: TColorRef): Byte;
|
||
function GetRValue(Col: TColorRef): Byte;
|
||
function pfDevice: TPixelFormat;
|
||
|
||
function SetRect(var R: TRect; Left, Top, Right, Bottom: Integer): LongBool;
|
||
function IsRectEmpty(R: TRect): LongBool;
|
||
function EqualRect(R1, R2: TRect): LongBool;
|
||
function UnionRect(var Dst: TRect; R1, R2: TRect): LongBool;
|
||
function CopyRect(var Dst: TRect; const Src: TRect): LongBool; overload;
|
||
function SubtractRect(var dR: TRect; const R1, R2: TRect): LongBool;
|
||
function CenterRect(InnerRect, OuterRect: TRect): TRect;
|
||
function PtInRect(const R: TRect; pt: TPoint): LongBool; overload;
|
||
function PtInRect(const R: TRect; X, Y: integer): LongBool; overload;
|
||
function IntersectRect(var R: TRect; const R1, R2: TRect): LongBool;
|
||
function PointInEllipse(pt: TPoint; BoundingRect: TRect): boolean;
|
||
function PtInEllipse(const R: TRect; pt: TPoint): LongBool;
|
||
|
||
{ brushes }
|
||
function CreateSolidBrush(Color: TColor): QBrushH;
|
||
function CreateHatchBrush(bStyle: BrushStyle; Color: TColor): QBrushH;
|
||
function DeleteObject(Handle: QBrushH): LongBool; overload;
|
||
|
||
function CreatePen(Style, Width: Integer; Color: TColor): QPenH;
|
||
function DeleteObject(Handle: QPenH): LongBool; overload;
|
||
|
||
function DPtoLP(Handle: QPainterH; var Points; Count: Integer): LongBool;
|
||
function LPtoDP(Handle: QPainterH; var Points; Count: Integer): LongBool;
|
||
function SetWindowOrgEx(Handle: QPainterH; X, Y: Integer; OldOrg: PPoint): LongBool;
|
||
function GetWindowOrgEx(Handle: QPainterH; Org: PPoint): LongBool; overload;
|
||
function GetWindowOrgEx(Handle: QPainterH; var Org: TPoint): LongBool; overload;
|
||
{ limited implementations of }
|
||
function BitBlt(DestDC: QPainterH; X, Y, Width, Height: Integer; SrcDC: QPainterH;
|
||
XSrc, YSrc: Integer; Rop: RasterOp; IgnoreMask: Boolean = true): LongBool; overload;
|
||
function BitBlt(DestDC: QPainterH; X, Y, Width, Height: Integer; SrcDC: QPainterH;
|
||
XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean = true): LongBool; overload;
|
||
{
|
||
does the required start/stop painting if needed
|
||
adjust x,y & XSrc,YSrc ico TControlCanvas (as used by TGraphicControl)
|
||
}
|
||
function BitBlt(DestCanvas: TCanvas; X, Y, Width, Height: Integer; SrcCanvas: TCanvas;
|
||
XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean = true): LongBool; overload;
|
||
|
||
{
|
||
// Calculates coord of TopLeft in Paintdevice coordinates
|
||
// ((0,0) for bitmaps and TWidgetControl derived classes)
|
||
}
|
||
function PainterOffset(Canvas: TCanvas): TPoint;
|
||
|
||
function PatBlt(Handle: QPainterH; X, Y, Width, Height: Integer;
|
||
WinRop: Cardinal): LongBool; overload;
|
||
function PatBlt(Canvas: TCanvas; X, Y, Width, Height: Integer;
|
||
WinRop: Cardinal): LongBool; overload;
|
||
|
||
procedure CopyRect(DstCanvas: TCanvas; const Dest: TRect; Canvas: TCanvas;
|
||
const Source: TRect); overload;
|
||
procedure BrushCopy(DstCanvas: TCanvas; const Dest: TRect; Bitmap: TBitmap;
|
||
const Source: TRect; Color: TColor);
|
||
|
||
function StretchBlt(DestDC: QPainterH; dx, dy, dw, dh: Integer;
|
||
SrcDC: QPainterH; sx, sy, sw, sh: Integer; WinRop: Cardinal;
|
||
IgnoreMask: Boolean = True): LongBool; overload;
|
||
function StretchBlt(DestDC: QPainterH; dx, dy, dw, dh: Integer;
|
||
SrcDC: QPainterH; sx, sy, sw, sh: Integer; Rop: RasterOp;
|
||
IgnoreMask: Boolean = True): LongBool; overload;
|
||
function StretchBlt(DestCanvas: TCanvas; dx, dy, dw, dh: Integer;
|
||
SrcCanvas: TCanvas; sx, sy, sw, sh: Integer; WinRop: Cardinal;
|
||
IgnoreMask: Boolean = True): LongBool; overload;
|
||
function ScrollDC(Handle: QPainterH; dx, dy: Integer; var Scroll, Clip: TRect;
|
||
Rgn: QRegionH; Update: PRect): LongBool;
|
||
|
||
{ TODO -oahuser : StretchBlt function should use the flag }
|
||
function GetStretchBltMode(DC: QPainterH): TStretchMode;
|
||
function SetStretchBltMode(DC: QPainterH; StretchMode: TStretchMode): TStretchMode;
|
||
|
||
function SetROP2(Handle: QPainterH; Rop: Integer): Integer; overload;
|
||
function GetROP2(Handle: QPainterH): Integer; overload;
|
||
function GetPixel(Handle: QPainterH; X, Y: Integer): TColorRef;
|
||
function SetPixel(Handle: QPainterH; X, Y: Integer; Color: TColor): TColorRef;
|
||
function SetTextColor(Handle: QPainterH; color: TColor): TColorRef;
|
||
function SetBkColor(Handle: QPainterH; color: TColor): TColorRef;
|
||
function GetBkMode(Handle: QPainterH): Integer;
|
||
function SetBkMode(Handle: QPainterH; BkMode: Integer): Integer;
|
||
function SetDCBrushColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
function SetDCPenColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
function SetPenColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
procedure SetPainterFont(Handle: QPainterH; Font: TFont);
|
||
|
||
function CreateCompatibleDC(Handle: QPainterH; Width: Integer = 1; Height: Integer = 1): QPainterH;
|
||
function CreateCompatibleBitmap(Handle: QPainterH; Width, Height: Integer): QPixmapH;
|
||
function CreateBitmap(Width, Height: Integer; Planes, BitCount: Longint; Bits: Pointer): QPixmapH;
|
||
function CreateDIBitmap(Handle: QPainterH; var InfoHeader: TBitmapInfoHeader;
|
||
dwUsage: Longword; InitBits: PChar; var InitInfo: TBitmapInfo; wUsage: Cardinal): QPixmapH;
|
||
|
||
function GetBitmapBits(Bitmap: QPixmapH; Count: Longint; Bits: Pointer): Longint;
|
||
function SetBitmapBits(Bitmap: QPixmapH; Count: Longint; Bits: Pointer): Longint;
|
||
|
||
function GetObject(Handle: QPixmapH; Size: Cardinal; Data: PtagBITMAP): Boolean; overload;
|
||
function GetObject(Handle: QPenH; Size: Cardinal; Data: PLogPen): Boolean; overload;
|
||
|
||
function GetStockObject(fnObject: TStockObjectBrush): QBrushH; overload;
|
||
function GetStockObject(fnObject: TStockObjectPen): QPenH; overload;
|
||
function GetStockObject(fnObject: TStockObjectFont): QFontH; overload;
|
||
|
||
function GetMapMode(Handle: QPainterH): TMapMode;
|
||
function SetMapMode(Handle: QPainterH; MapMode: TMapMode): TMapMode;
|
||
|
||
// DeleteObject is intended to destroy the Handle returned by CreateCompatibleBitmap
|
||
// (it destroys the Painter AND PaintDevice)
|
||
function DeleteObject(Handle: QPainterH): LongBool; overload;
|
||
function DeleteObject(Handle: QPixmapH): LongBool; overload;
|
||
function GetDC(Handle: QWidgetH): QPainterH; overload;
|
||
function GetDC(Handle: Integer): QPainterH; overload;
|
||
function GetWindowDC(Handle: QWidgetH): QPainterH;
|
||
|
||
function ReleaseDC(wdgtH: QWidgetH; Handle: QPainterH): Integer; overload;
|
||
function ReleaseDC(wdgtH: Integer; Handle: QPainterH): Integer; overload;
|
||
function DeleteDC(Handle: QPainterH): LongBool;
|
||
|
||
function SaveDC(Handle: QPainterH): Integer;
|
||
{ only negative and zero values of nSaveDC are supported }
|
||
function RestoreDC(Handle: QPainterH; nSavedDC: Integer): LongBool;
|
||
|
||
function ExtTextOut(Handle: QPainterH; X, Y: Integer; WinFlags: Cardinal;
|
||
R: PRect; const Text: WideString; Len: Integer; lpDx: Pointer): LongBool; overload;
|
||
function ExtTextOut(Handle: QPainterH; X, Y: Integer; WinFlags: Cardinal;
|
||
R: PRect; pText: PChar; Len: Integer; lpDx: Pointer): LongBool; overload;
|
||
function ExtTextOutW(Handle: QPainterH; X, Y: Integer; WinFlags: Cardinal;
|
||
R: PRect; pText: PWideChar; Len: Integer; lpDx: Pointer): LongBool;
|
||
|
||
{ TODO -oahuser : text functions (ExtTextOut, TextOut) should use these flags }
|
||
function SetTextAlign(Handle: QPainterH; Mode: Cardinal): Cardinal;
|
||
function GetTextAlign(Handle: QPainterH): Cardinal;
|
||
|
||
function FillRect(Handle: QPainterH; const R: TRect; Brush: QBrushH): LongBool;
|
||
|
||
function GetCurrentPositionEx(Handle: QPainterH; pos: PPoint): LongBool;
|
||
function GetTextExtentPoint32(Handle: QPainterH; const Text: WideString; Len: Integer;
|
||
var Size: TSize): LongBool; overload;
|
||
function GetTextExtentPoint32(Handle: QPainterH; pText: PChar; Len: Integer;
|
||
var Size: TSize): LongBool; overload;
|
||
function GetTextExtentPoint32W(Handle: QPainterH; pText: PWideChar; Len: Integer;
|
||
var Size: TSize): LongBool;
|
||
function GetTextExtentPoint32(Canvas: TCanvas; const Text: WideString; Len: Integer;
|
||
var Size: TSize): LongBool; overload;
|
||
|
||
function FrameRect(Handle: QPainterH; const R: TRect; Brush: QBrushH): LongBool; overload;
|
||
procedure FrameRect(Canvas: TCanvas; const R: TRect); overload;
|
||
function FrameRgn(Handle: QPainterH; Region: QRegionH; Brush: QBrushH; Width, Height: integer): LongBool;
|
||
|
||
function DrawFocusRect(Handle: QPainterH; const R: TRect): LongBool;
|
||
function InvertRect(Handle: QPainterH; const R: TRect): LongBool;
|
||
function Rectangle(Handle: QPainterH; Left, Top, Right, Bottom: Integer): LongBool;
|
||
function RoundRect(Handle: QPainterH; Left, Top, Right, Bottom, X3, Y3: Integer): LongBool;
|
||
function Ellipse(Handle: QPainterH; Left, Top, Right, Bottom: Integer): LongBool;
|
||
function LineTo(Handle: QPainterH; X, Y: Integer): LongBool;
|
||
function MoveToEx(Handle: QPainterH; X, Y: Integer; Point: PPoint): LongBool;
|
||
function DrawIcon(Handle: QPainterH; X, Y: Integer; hIcon: QPixmapH): LongBool;
|
||
function DrawIconEx(Handle: QPainterH; X, Y: Integer; hIcon: QPixmapH;
|
||
W, H: Integer; istepIfAniCur: Integer; hbrFlickerFreeDraw: QBrushH;
|
||
diFlags: Cardinal): LongBool;
|
||
|
||
function DrawFrameControl(Handle: QPainterH; const Rect: TRect; uType,
|
||
uState: Longword): LongBool; overload;
|
||
{ missing DrawFrameControl flags:
|
||
DFC_SCROLL: DFCS_SCROLLSIZEGRIP, DFCS_SCROLLSIZEGRIPRIGHT
|
||
DFC_BUTTON: DFCS_BUTTONRADIOIMAGE, DFCS_BUTTONRADIOMASK, DFCS_BUTTON3STATE
|
||
DFC_POPUPMENU: all }
|
||
function DrawFrameControl(Canvas: TCanvas; const Rect: TRect; uType,
|
||
uState: Longword): LongBool; overload;
|
||
function DrawEdge(Handle: QPainterH; var Rect: TRect; Edge: Cardinal;
|
||
Flags: Cardinal): LongBool;
|
||
|
||
procedure RequiredState(ACanvas: TCanvas; State: TCanvasState);
|
||
|
||
{ limited implementation of }
|
||
function DrawText2(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
var R: TRect; WinFlags: Integer): Integer; overload;
|
||
function DrawText(Handle: QPainterH; Text: PAnsiChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
function DrawText(Handle: QPainterH; Text: TCaption; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
function DrawTextW(Handle: QPainterH; Text: PWideChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
function DrawText(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
x,y, w, h: Integer; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
function DrawText(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
{
|
||
additional functionality DrawText(Canvas, .....
|
||
- canvas start/stop
|
||
- sets painterfont
|
||
}
|
||
function DrawText(Canvas :TCanvas; Text: TCaption; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: integer = 0): Integer; overload;
|
||
function DrawText(Canvas: TCanvas; Text: PAnsiChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
function DrawTextW(Canvas :TCanvas; Text: PWideChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
function DrawTextEx(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; DTParams: Pointer): Integer; overload;
|
||
function DrawTextEx(Handle: QPainterH; Text: PChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; DTParams: Pointer): Integer; overload;
|
||
|
||
{ limited implementation of }
|
||
function GetSystemMetrics(PropItem: TSysMetrics): Integer;
|
||
|
||
{ (very) limited implementations of }
|
||
function GetDeviceCaps(Handle: QPainterH; devcap: TDeviceCap): Integer; overload;
|
||
function GetDeviceCaps(Handle: QPaintDeviceH; devcap: TDeviceCap): Integer; overload;
|
||
|
||
function GetTextMetrics(Handle: QPainterH; var tt: TTextMetric): Integer;
|
||
// widget related function
|
||
function BringWindowToTop(Handle: QWidgetH): LongBool;
|
||
function CloseWindow(Handle: QWidgetH): LongBool;
|
||
function DestroyWindow(Handle: QWidgetH): LongBool;
|
||
function EnableWindow(Handle: QWidgetH; Value: Boolean): LongBool;
|
||
function GetClientRect(Handle: QWidgetH; var R: TRect): LongBool;
|
||
function GetFocus: QWidgetH;
|
||
function GetParent(Handle: QWidgetH): QWidgetH;
|
||
function SetParent(hWndChild, hWndNewParent: QWidgetH): QWidgetH;
|
||
function GetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement): LongBool;
|
||
function GetWindowRect(Handle: QWidgetH; var R: TRect): LongBool;
|
||
function WindowFromDC(Handle: QPainterH): QWidgetH; overload;
|
||
function WindowFromDC(Handle: QPaintDeviceH): QWidgetH; overload;
|
||
|
||
{ hWndParent is ignored under Linux }
|
||
function ChildWindowFromPoint(hWndParent: QWidgetH; Point: TPoint): QWidgetH;
|
||
|
||
function WindowFromPoint(Point: TPoint): QWidgetH;
|
||
function FindCLXWindow(const Point: TPoint): TWidgetControl;
|
||
function FindVCLWindow(const Point: TPoint): TWidgetControl;
|
||
function GetClassName(Handle: QWidgetH; Buffer: PChar; MaxCount: Integer): Integer;
|
||
function IsIconic(Handle: QWidgetH): LongBool;
|
||
|
||
function HWND_DESKTOP: QWidgetH;
|
||
function GetDesktopWindow: QWidgetH;
|
||
function GetActiveWindow: QWidgetH;
|
||
function GetForegroundWindow: QWidgetH;
|
||
procedure SetActiveWindow(Handle: QWidgetH);
|
||
function InvalidateRect(Handle: QWidgetH; R: PRect; EraseBackground: Boolean): LongBool;
|
||
function ValidateRect(hWnd: QWidgetH; R: PRect): LongBool;
|
||
function UpdateWindow(Handle: QWidgetH): LongBool;
|
||
function IsChild(ParentHandle, ChildHandle: QWidgetH): LongBool;
|
||
function IsWindowEnabled(Handle: QWidgetH): LongBool;
|
||
function IsWindowVisible(Handle: QWidgetH): LongBool;
|
||
function MapWindowPoints(WidgetTo, WidgetFrom: QWidgetH; var Points; nr: Cardinal): Integer;
|
||
function SetFocus(Handle: QWidgetH): QWidgetH;
|
||
function SetForegroundWindow(Handle: QWidgetH): LongBool;
|
||
function SetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement): LongBool;
|
||
function SwitchToThisWindow(Handle: QWidgetH; Restore: Boolean): LongBool;
|
||
|
||
function ClientToScreen(Handle: QWidgetH; var Point: TPoint): LongBool;
|
||
function ScreenToClient(Handle: QWidgetH; var Point: TPoint): LongBool;
|
||
function SmallPointToPoint(const P: TSmallPoint): TPoint;
|
||
function PointToSmallPoint(const P: TPoint): TSmallPoint;
|
||
|
||
function SetWindowPos(Wnd, WndInsertAfter: QWidgetH; X, Y, cx, cy: Integer;
|
||
uFlags: Longword): LongBool; overload;
|
||
function SetWindowPos(Wnd, WndInsertAfter: Cardinal; X, Y, cx, cy: Integer;
|
||
uFlags: Longword): LongBool; overload;
|
||
function SetWindowPos(Wnd: QWidgetH; WndInsertAfter: Cardinal; X, Y, cx, cy: Integer;
|
||
uFlags: Longword): LongBool; overload;
|
||
|
||
{ Controls.pas implements, so we need it, too }
|
||
procedure MoveWindowOrg(DC: QPainterH; DX, DY: Integer);
|
||
|
||
function ShowWindow(Handle: QWidgetH; showCmd: UInt): LongBool;
|
||
|
||
function MessageBox(parent: QWidgetH; Text, Caption: string; WinFlags: Cardinal): Integer; overload;
|
||
function MessageBox(parent: QWidgetH; Text, Caption: WideString; WinFlags: Cardinal): Integer; overload;
|
||
function MessageBox(parent: QWidgetH; pText, pCaption: PChar; WinFlags: Cardinal): Integer; overload;
|
||
//function MessageBoxW(parent: QWidgetH; pText, pCaption: PWideChar; WinFlags: Cardinal): Integer;
|
||
|
||
function SelectObject(Handle: QPainterH; Font: QFontH): QFontH; overload;
|
||
function SelectObject(Handle: QPainterH; Brush: QBrushH): QBrushH; overload;
|
||
function SelectObject(Handle: QPainterH; Pen: QPenH): QPenH; overload;
|
||
// limited to CreateCompatibleDC Handles.
|
||
function SelectObject(Handle: QPainterH; Bitmap: QPixmapH): QPixmapH; overload;
|
||
|
||
function CombineRgn(DestRgn, Source1, Source2: QRegionH; Operation: TCombineMode): Integer;
|
||
function CreateEllipticRgn(Left, Top, Right, Bottom: Integer): QRegionH;
|
||
function CreateEllipticRgnIndirect(Rect: TRect): QRegionH;
|
||
//function CreatePolygonRgn(p1: TPointArray; FillMode: Integer): QRegionH;
|
||
function CreatePolygonRgn(const Points; Count, FillMode: Integer): QRegionH;
|
||
function CreateRectRgn(Left, Top, Right, Bottom: Integer): QRegionH;
|
||
function CreateRectRgnIndirect(Rect: TRect): QRegionH;
|
||
function CreateRoundRectRgn(x1, y1, x2, y2, WidthEllipse, HeightEllipse: Integer): QRegionH;
|
||
function DeleteObject(Region: QRegionH): LongBool; overload;
|
||
function EqualRgn(Rgn1, Rgn2: QRegionH): LongBool;
|
||
function FillRgn(Handle: QPainterH; Region: QRegionH; Brush: QBrushH): LongBool;
|
||
function GetClipRgn(Handle: QPainterH; rgn: QRegionH): Integer;
|
||
function ExcludeClipRect(Handle: QPainterH; X1, Y1, X2, Y2: Integer): Integer; overload;
|
||
function ExcludeClipRect(Handle: QPainterH; const R: TRect): Integer; overload;
|
||
function IntersectClipRect(Handle: QPainterH; X1, Y1, X2, Y2: Integer): Integer; overload;
|
||
function IntersectClipRect(Handle: QPainterH; const R: TRect): Integer; overload;
|
||
function InvertRgn(Handle: QPainterH; Region: QRegionH): LongBool;
|
||
function OffsetClipRgn(Handle: QPainterH; X, Y: Integer): Integer;
|
||
function OffsetRgn(Region: QRegionH; X, Y: Integer): Integer;
|
||
function PtInRegion(Rgn: QRegionH; X, Y: Integer): Boolean;
|
||
function RectInRegion(RGN: QRegionH; const Rect: TRect): LongBool;
|
||
function SelectClipRgn(Handle: QPainterH; Region: QRegionH): Integer; overload;
|
||
function SelectClipRgn(Handle: QPainterH; Region: Integer): Integer; overload;
|
||
function SetRectRgn(Rgn: QRegionH; X1, Y1, X2, Y2: Integer): LongBool;
|
||
function SetWindowRgn(Handle: QWidgetH; Region: QRegionH; Redraw: LongBool): Integer;
|
||
{ SetWindowRgn limitation: The region must have negative top coordinate in
|
||
order to contain the window's caption bar. }
|
||
{ asn: Qt operates on the client rectangle of the form: windows/x11 titlebar
|
||
and windows/x11 borders are not included, hence the negative values }
|
||
function GetWindowRgn(Handle: QWidgetH; Region: QRegionH): Integer;
|
||
|
||
{ viewports }
|
||
function SetViewportExtEx(Handle: QPainterH; XExt, YExt: Integer; Size: PSize): LongBool;
|
||
function SetViewPortOrgEx(Handle: QPainterH; X, Y: Integer; OldOrg: PPoint): LongBool;
|
||
function GetViewportExtEx(Handle: QPainterH; Size: PSize): LongBool;
|
||
|
||
{ Text clipping }
|
||
function TruncatePath(const FilePath: string; Canvas: TCanvas; MaxLen: Integer): string;
|
||
function TruncateName(const Name: WideString; Canvas: TCanvas; MaxLen: Integer; QtFlags: integer = 0): WideString;
|
||
|
||
procedure TextOutAngle(Handle: QPainterH; Angle, Left, Top: Integer; Text: WideString); overload;
|
||
procedure TextOutAngle(ACanvas: TCanvas; Angle, Left, Top: Integer; Text: WideString); overload;
|
||
|
||
procedure CopyMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
|
||
procedure FillMemory(Dest: Pointer; Len: Cardinal; Fill: Byte);
|
||
procedure MoveMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
|
||
procedure ZeroMemory(Dest: Pointer; Len: Cardinal);
|
||
|
||
{ ------------ Caret -------------- }
|
||
function CreateCaret(Widget: QWidgetH; Pixmap: QPixmapH; Width, Height: Integer): Boolean; overload;
|
||
function CreateCaret(Widget: QWidgetH; ColorCaret: Cardinal; Width, Height: Integer): Boolean; overload;
|
||
function GetCaretBlinkTime: Cardinal;
|
||
function SetCaretBlinkTime(uMSeconds: Cardinal): LongBool;
|
||
function HideCaret(Widget: QWidgetH): Boolean;
|
||
function ShowCaret(Widget: QWidgetH): Boolean;
|
||
function SetCaretPos(X, Y: Integer): Boolean;
|
||
function GetCaretPos(var Pt: TPoint): Boolean;
|
||
function DestroyCaret: Boolean;
|
||
|
||
procedure SetCursorPos(X, Y: integer);
|
||
function GetCursorPos(var P: TPoint): LongBool;
|
||
|
||
function GetDoubleClickTime: Cardinal;
|
||
function SetDoubleClickTime(Interval: Cardinal): LongBool;
|
||
function ReleaseCapture: LongBool;
|
||
function SetCapture(Widget: QWidgetH): QWidgetH;
|
||
function GetCapture: QWidgetH;
|
||
function SetCursor(Handle: QCursorH; Save: Boolean = False): QCursorH;
|
||
function Win2QtAlign(Flags: Integer): Integer;
|
||
function QtStdAlign(Flags: Integer): Word;
|
||
|
||
function IsCharAlpha(Ch: Char): LongBool;
|
||
function IsCharAlphaNumeric(Ch: Char): LongBool;
|
||
|
||
{ Messaging }
|
||
function Perform(Control: TControl; Msg: Cardinal; WPar, LPar: Longint): Longint;
|
||
function PostMessage(Receiver: QWidgetH; MsgId: Integer; WPar, LPar: Longint): LongBool; overload;
|
||
function PostMessage(AControl: TWidgetControl; MsgId: Integer; WPar, LPar: Longint): LongBool; overload;
|
||
{ SendMessage synchronizes with the main (event handling) thread. }
|
||
function SendMessage(Receiver: QWidgetH; MsgId: Integer; WPar, LPar: Longint): Integer; overload;
|
||
function SendMessage(AControl: TWidgetControl; MsgId: Integer; WPar, LPar: Longint): Integer; overload;
|
||
|
||
// procedure IgnoreNextEvents(Handle: QObjectH; const Events: array of QEventType);
|
||
{ equivalent to "while PeekMessage(h, evstart, evend, PM_REMOVE" }
|
||
//procedure IgnoreMouseEvents(Handle: QObjectH);
|
||
function IgnoreMouseEvents(Handle: QObjectH; Event: QEventH): boolean;
|
||
|
||
function SetTimer(Wnd: QWidgetH; WMTimerID, Elapse: Cardinal;
|
||
TimerFunc: TTimerProc): Cardinal; overload;
|
||
function SetTimer(Instance: TWidgetControl; WMTimerID, Elapse: Cardinal;
|
||
TimerFunc: TTimerProc): Cardinal; overload;
|
||
function KillTimer(Wnd: QWidgetH; WMTimerId: Cardinal): LongBool; overload;
|
||
function KillTimer(Instance: TWidgetControl; WMTimerId: Cardinal): LongBool; overload;
|
||
|
||
function MAKEIPRANGE(low, high: Byte): integer;
|
||
function MAKEIPADDRESS(b1, b2, b3, b4: cardinal): integer;
|
||
function FIRST_IPADDRESS(x: cardinal): cardinal;
|
||
function SECOND_IPADDRESS(x: cardinal): cardinal;
|
||
function THIRD_IPADDRESS(x: cardinal): cardinal;
|
||
function FOURTH_IPADDRESS(x: cardinal): cardinal;
|
||
|
||
{ wrappers for Windows, implementations for Linux}
|
||
function ShellExecute(Handle: QWidgetH; Operation, FileName, Parameters,
|
||
Directory: PChar; ShowCmd: Integer): THandle; overload;
|
||
function ShellExecute(Handle: QWidgetH; const Operation, FileName, Parameters,
|
||
Directory: string; ShowCmd: Integer): THandle; overload;
|
||
function ShellExecute(Handle: Integer; Operation, FileName, Parameters,
|
||
Directory: PChar; ShowCmd: Integer): THandle; overload;
|
||
|
||
{ Platform dependendant wrappers}
|
||
function GetTickCount: Cardinal;
|
||
function GetUserName(Buffer: PChar; var Size: Cardinal): LongBool;
|
||
function GetComputerName(Buffer: PChar; var Size: Cardinal): LongBool;
|
||
procedure OutputDebugString(lpOutputString: PAnsiChar); overload;
|
||
procedure OutputDebugString(OutputString: AnsiString); overload;
|
||
function InterlockedIncrement(var I: Integer): Integer;
|
||
function InterlockedDecrement(var I: Integer): Integer;
|
||
function InterlockedExchange(var A: Integer; B: Integer): Integer;
|
||
function InterlockedExchangeAdd(var A: Integer; B: Integer): Integer;
|
||
function QueryPerformanceCounter(var PerformanceCount: int64): LongBool;
|
||
function QueryPerformanceFrequency(var Frequency: int64): LongBool;
|
||
|
||
{$IFDEF MSWINDOWS}
|
||
function GetKeyState(nVirtKey: Integer): SmallInt;
|
||
//
|
||
// Taken from QDialogs
|
||
//
|
||
procedure EnableTaskWindows(WindowList: Pointer);
|
||
function DisableTaskWindows(ActiveWindow: Windows.HWnd): Pointer;
|
||
{$ENDIF MSWINDOWS}
|
||
|
||
function CopyFile(lpExistingFileName, lpNewFileName: PChar;
|
||
bFailIfExists: LongBool): LongBool; overload;
|
||
|
||
function CopyFileA(lpExistingFileName, lpNewFileName: PAnsiChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
function CopyFileW(lpExistingFileName, lpNewFileName: PWideChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
{$IFDEF LINUX}
|
||
function CopyFile(const Source, Destination: string;
|
||
FailIfExists: Boolean): LongBool; overload;
|
||
|
||
function FileGetSize(const FileName: string): Cardinal;
|
||
function FileGetAttr(const FileName: string): Integer;
|
||
function FileGetTime(const FileName: string): Integer;
|
||
function MakeIntResource(Value: Integer): PChar;
|
||
function MakeWord(A, B: Byte): Word;
|
||
function MakeLong(A, B: Word): Longint;
|
||
function HiWord(L: DWORD): Word;
|
||
function HiByte(W: Word): Byte;
|
||
|
||
procedure GetLocalTime(var st: TSystemTime);
|
||
|
||
procedure MessageBeep(Value: Integer); // value ignored
|
||
|
||
function CoCreateGUID(out Guid: TGUID): HResult;
|
||
|
||
function Succeeded(Res: HResult): Boolean;
|
||
function Failed(Res: HResult): Boolean;
|
||
function ResultCode(Res: HResult): Integer;
|
||
|
||
function GetCurrentProcess: THandle;
|
||
|
||
function TerminateThread(ThreadID: TThreadID; RetVal: Integer): LongBool;
|
||
{
|
||
NOTE:
|
||
The Windows API's SuspendThread & ResumeThread are functions.
|
||
With QWindows / Linux these are procedures
|
||
}
|
||
function SuspendThread(ThreadID: TThreadID): LongBool;
|
||
function ResumeThread(ThreadID: TThreadID): LongBool;
|
||
function GetThreadPolicy(ThreadID: TThreadID): Integer;
|
||
procedure SetThreadPolicy(ThreadID: TThreadID; value: Integer);
|
||
function GetThreadPriority(ThreadID: TThreadID): Integer;
|
||
function SetThreadPriority(ThreadID: TThreadID; priority: Integer): LongBool;
|
||
|
||
function VirtualProtect(lpAddress: Pointer; dwSize, flNewProtect: Cardinal;
|
||
lpflOldProtect: Pointer): LongBool; overload;
|
||
function VirtualProtect(lpAddress: Pointer; dwSize, flNewProtect: Cardinal;
|
||
var OldProtect: Cardinal): LongBool; overload;
|
||
|
||
function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
|
||
lpBuffer: Pointer; nSize: LongWord; var lpNumberOfBytesRead: Longword): LongBool;
|
||
function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
|
||
lpBuffer: Pointer; nSize: LongWord; var lpNumberOfBytesWritten: Longword): LongBool;
|
||
procedure FlushInstructionCache(PID: cardinal; OrgCalProc: Pointer; size: Integer);
|
||
|
||
{ Limitations:
|
||
- GetKeyState calls GetAsyncKeyState
|
||
- GetAsyncKeyState only supports VK_SHIFT, VK_CONTROL and VK_MENU }
|
||
function GetKeyState(nVirtKey: Integer): SmallInt;
|
||
function GetAsyncKeyState(vKey: Integer): SmallInt;
|
||
|
||
// events are limited to the process
|
||
function CreateEvent(EventAttributes: PSecurityAttributes;
|
||
ManualReset, InitialState: LongBool; Name: PChar): THandle;
|
||
function OpenEvent(DesiredAccess: Longword; InheritHandle: LongBool;
|
||
Name: PChar): THandle;
|
||
{$ENDIF LINUX}
|
||
function SetEvent(Event: THandle): LongBool;
|
||
function ResetEvent(Event: THandle): LongBool;
|
||
function PulseEvent(Event: THandle): LongBool; // calls SetEvent()
|
||
|
||
{$IFDEF LINUX}
|
||
function CreateMutex(MutexAttributes: PSecurityAttributes; InitialOwner: LongBool;
|
||
Name: PChar): THandle;
|
||
function OpenMutex(DesiredAccess: Longword; InheritHandle: Boolean;
|
||
Name: PChar): THandle;
|
||
function ReleaseMutex(Mutex: THandle): LongBool;
|
||
|
||
function CreateSemaphore(SemaphoreAttributes: PSecurityAttributes;
|
||
InitialCount, MaximumCount: Longint; Name: PChar): THandle;
|
||
function OpenSemaphore(DesiredAccess: Longword; InheritHandle: LongBool;
|
||
Name: PChar): THandle;
|
||
function ReleaseSemaphore(Semaphore: THandle; ReleaseCount: Longint;
|
||
PreviousCount: PInteger): LongBool;
|
||
|
||
function semtimedop(semid: Integer; sops: PSemaphoreBuffer;
|
||
nsops: size_t; timeout: PTimeSpec): Integer; {$IFDEF DEBUG}cdecl;{$ENDIF}
|
||
|
||
function WaitForSingleObject(Handle: THandle; Milliseconds: Cardinal): Cardinal;
|
||
|
||
{ Operate on semaphore. }
|
||
|
||
function WaitForMultipleObjects(Count: Cardinal; Handles: PWOHandleArray;
|
||
WaitAll: LongBool; Milliseconds: Cardinal): Cardinal;
|
||
|
||
{ all Handles are TObject derived classes }
|
||
|
||
function CloseHandle(hObject: THandle): LongBool;
|
||
|
||
{ memory management }
|
||
function GlobalAllocPtr(Flags: Integer; Bytes: Longint): Pointer;
|
||
function GlobalReAllocPtr(P: Pointer; Bytes: Longint; Flags: Integer): Pointer;
|
||
function GlobalFreePtr(P: Pointer): THandle;
|
||
|
||
function GlobalAlloc(uFlags: Cardinal; dwBytes: Longword): Cardinal;
|
||
function GlobalReAlloc(hMem: Cardinal; dwBytes: Longword; uFlags: Cardinal): Cardinal;
|
||
function GlobalSize(hMem: Cardinal): Longword;
|
||
function GlobalLock(hMem: Cardinal): Pointer;
|
||
function GlobalHandle(Mem: Pointer): Cardinal;
|
||
function GlobalUnlock(hMem: Cardinal): LongBool;
|
||
function GlobalFree(hMem: Cardinal): Cardinal;
|
||
{$ENDIF LINUX}
|
||
|
||
|
||
{$IFDEF LINUX}
|
||
var
|
||
Shell: string = 'kfmclient exec'; // KDE. Gnome equivalent ?
|
||
IpcDirectory: string = '/tmp/kylix/ipc'; // for named semaphores/mutex
|
||
{$ENDIF LINUX}
|
||
|
||
implementation
|
||
|
||
{$IFDEF MSWINDOWS}
|
||
uses
|
||
ShellAPI, DateUtils;
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
uses
|
||
Xlib;
|
||
{$ENDIF LINUX}
|
||
|
||
const
|
||
VersionInfo = '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/branches/JVCL3_36_PREPARATION/archive/QWindows.pas $' + #13 + '$Revision: 11641 $' + #13 + '$Date: 2007-12-24 17:34:00 +0100 (lun., 24 déc. 2007) $' + #13;
|
||
|
||
type
|
||
THackCanvas = class(TCanvas);
|
||
TOpenWidgetControl = class(TWidgetControl);
|
||
|
||
var
|
||
AppEventHook: TAppEventHook = nil;
|
||
|
||
procedure AppEventHookNeeded;
|
||
begin
|
||
if not Assigned(AppEventHook) then
|
||
AppEventHook := TAppEventHook.Create(nil);
|
||
end;
|
||
{ used internally }
|
||
|
||
procedure MapPainterLP(Handle: QPainterH; var x, y: Integer); overload;
|
||
begin
|
||
QWMatrix_map(QPainter_worldMatrix(Handle), x, y, @x, @y);
|
||
end;
|
||
|
||
procedure MapPainterLP(Handle: QPainterH; var x0, y0, x1, y1: Integer); overload;
|
||
var
|
||
Matrix: QWMatrixH;
|
||
begin
|
||
Matrix := QPainter_worldMatrix(Handle);
|
||
QWMatrix_map(Matrix, x0, y0, @x0, @y0);
|
||
QWMatrix_map(Matrix, x1, y1, @x1, @y1);
|
||
end;
|
||
|
||
procedure MapPainterLP(Handle: QPainterH; var Pt: TPoint); overload;
|
||
begin
|
||
QWMatrix_map(QPainter_worldMatrix(Handle), PPoint(@Pt), PPoint(@Pt));
|
||
end;
|
||
|
||
procedure MapPainterLP(Handle: QPainterH; var R: TRect); overload;
|
||
begin
|
||
QWMatrix_map(QPainter_worldMatrix(Handle), PRect(@R), PRect(@R));
|
||
end;
|
||
|
||
procedure MapPainterLPwh(Handle: QPainterH; var Width, Height: Integer); overload;
|
||
var
|
||
Matrix: QWMatrixH;
|
||
begin
|
||
Matrix := QPainter_worldMatrix(Handle);
|
||
|
||
Matrix := QWMatrix_create(QWMatrix_m11(Matrix), QWMatrix_m12(Matrix),
|
||
QWMatrix_m21(Matrix), QWMatrix_m22(Matrix), 0, 0); // no translation
|
||
try
|
||
QWMatrix_map(Matrix, Width, Height, @Width, @Height);
|
||
finally
|
||
QWMatrix_destroy(Matrix);
|
||
end;
|
||
end;
|
||
|
||
function CreateMappedRegion(Handle: QPainterH; Region: QRegionH): QRegionH;
|
||
var
|
||
Matrix, RelativeMatrix: QWMatrixH;
|
||
Bmp1, Bmp2: QBitmapH;
|
||
Painter: QPainterH;
|
||
R, FillR: TRect;
|
||
Brush: QBrushH;
|
||
begin
|
||
Result := QRegion_create(Region);
|
||
Matrix := QPainter_worldMatrix(Handle);
|
||
|
||
if (QWMatrix_m11(Matrix) = 1) and (QWMatrix_m12(Matrix) = 0) and
|
||
(QWMatrix_m21(Matrix) = 0) and (QWMatrix_m22(Matrix) = 1) then
|
||
begin
|
||
if (QWMatrix_dx(Matrix) <> 0) or (QWMatrix_dy(Matrix) <> 0) then
|
||
QRegion_translate(Result, Round(QWMatrix_dx(Matrix)), Round(QWMatrix_dy(Matrix)));
|
||
end
|
||
else
|
||
begin
|
||
RelativeMatrix := QWMatrix_create(
|
||
QWMatrix_m11(Matrix), QWMatrix_m12(Matrix),
|
||
QWMatrix_m21(Matrix), QWMatrix_m22(Matrix),
|
||
0, 0
|
||
);
|
||
QRegion_boundingRect(Result, @R);
|
||
QRegion_translate(Result, -R.Left, -R.Top);
|
||
|
||
Bmp1 := QBitmap_create(Abs(R.Right - R.Left), Abs(R.Bottom - R.Top), True,
|
||
QPixmapOptimization_DefaultOptim);
|
||
try
|
||
FillR := R;
|
||
OffsetRect(FillR, -R.Left, -R.Top);
|
||
|
||
Painter := QPainter_create(Bmp1);
|
||
try
|
||
QPainter_setClipRegion(Painter, Result);
|
||
QPainter_setClipping(Painter, True);
|
||
|
||
Brush := GetStockObject(BLACK_BRUSH);
|
||
QPainter_fillRect(Painter, @FillR, Brush);
|
||
DeleteObject(Brush);
|
||
finally
|
||
QPainter_destroy(Painter);
|
||
end;
|
||
QRegion_destroy(Result);
|
||
|
||
QWMatrix_map(RelativeMatrix, PRect(@R), PRect(@R));
|
||
|
||
Bmp2 := QBitmap_create(Abs(R.Right - R.Left), Abs(R.Bottom - R.Top), False,
|
||
QPixmapOptimization_DefaultOptim);
|
||
try
|
||
QPixmap_xForm(Bmp1, Bmp2, RelativeMatrix);
|
||
Result := QRegion_create(Bmp2);
|
||
finally
|
||
QBitmap_destroy(Bmp2);
|
||
end;
|
||
finally
|
||
QBitmap_destroy(Bmp1);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{---------------------------------------}
|
||
type
|
||
PPainterInfo = ^TPainterInfo;
|
||
TPainterInfo = record
|
||
Painter: QPainterH;
|
||
IsCompatibleDC: Boolean;
|
||
TextAlignment: Cardinal;
|
||
StetchBltMode: TStretchMode;
|
||
MapMode: TMapMode;
|
||
end;
|
||
|
||
var
|
||
PainterInfos: TList = nil;
|
||
|
||
function GetPainterInfo(Handle: QPainterH; var Info: PPainterInfo): Boolean;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
Result := False;
|
||
Info := nil;
|
||
if PainterInfos <> nil then
|
||
begin
|
||
for i := 0 to PainterInfos.Count - 1 do
|
||
if PPainterInfo(PainterInfos[i])^.Painter = Handle then
|
||
begin
|
||
Result := True;
|
||
Info := PPainterInfo(PainterInfos[i]);
|
||
Exit;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function NewPainterInfo(Handle: QPainterH): PPainterInfo;
|
||
begin
|
||
New(Result);
|
||
Result^.Painter := Handle;
|
||
Result^.IsCompatibleDC := False;
|
||
Result^.TextAlignment := TA_LEFT or TA_TOP;
|
||
Result^.StetchBltMode := STRETCH_DELETESCANS;
|
||
Result^.MapMode := MM_TEXT;
|
||
|
||
if PainterInfos = nil then
|
||
PainterInfos := TList.Create;
|
||
PainterInfos.Add(Result);
|
||
end;
|
||
|
||
function SetPainterInfo(Handle: QPainterH): PPainterInfo;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
Result := nil;
|
||
if PainterInfos <> nil then
|
||
begin
|
||
for i := 0 to PainterInfos.Count - 1 do
|
||
if PPainterInfo(PainterInfos[i])^.Painter = Handle then
|
||
begin
|
||
Result := PPainterInfo(PainterInfos[i]);
|
||
Exit;
|
||
end;
|
||
end;
|
||
if Result = nil then
|
||
Result := NewPainterInfo(Handle);
|
||
end;
|
||
|
||
procedure DeletePainterInfo(Handle: QPainterH);
|
||
var
|
||
P: PPainterInfo;
|
||
begin
|
||
if PainterInfos <> nil then
|
||
begin
|
||
if GetPainterInfo(Handle, P) then
|
||
begin
|
||
PainterInfos.Delete(PainterInfos.IndexOf(P));
|
||
Dispose(P);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure FreePainterInfos;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
if PainterInfos <> nil then
|
||
begin
|
||
for i := 0 to PainterInfos.Count - 1 do
|
||
Dispose(PPainterInfo(PainterInfos[i]));
|
||
PainterInfos.Free;
|
||
end;
|
||
end;
|
||
{----------------------------------------}
|
||
|
||
procedure WakeUpGuiThread;
|
||
begin
|
||
QApplication_wakeUpGuiThread(Application.Handle);
|
||
end;
|
||
|
||
function DrawTextBiDiModeFlagsReadingOnly: Longint;
|
||
begin
|
||
Result := 0;
|
||
end;
|
||
|
||
function DrawTextBiDiModeFlags(Flags: Longint): Longint;
|
||
begin
|
||
Result := Flags;
|
||
end;
|
||
|
||
procedure ChangeBiDiModeAlignment(var Alignment: TAlignment);
|
||
begin
|
||
end;
|
||
|
||
function UseRightToLeftAlignment: Boolean;
|
||
begin
|
||
Result := False;
|
||
end;
|
||
|
||
function GetSysColor(SysColor: Integer): TColorRef;
|
||
// VCL / windows colors
|
||
begin
|
||
if (SysColor >= 0) and (SysColor <= COLOR_ENDCOLORS) then
|
||
SysColor := GetSysColor( Win2TColor[SysColor] );
|
||
case SysColor of
|
||
clInfoBk:
|
||
Result := TColorRef(Application.HintColor);
|
||
clDeskTop:
|
||
Result := TColorRef(QColorColor(QWidget_BackgroundColor(QApplication_desktop)));
|
||
else
|
||
Result := TColorRef(Application.Palette.GetColor(SysColor));
|
||
end;
|
||
end;
|
||
|
||
const
|
||
ColorRoles: array[1..15] of TColorRole =(
|
||
crForeground, crButton, crLight, crMidlight, crDark, crMid,
|
||
crText, crBrightText, crButtonText, crBase, crBackground, crShadow,
|
||
crHighlight, crHighlightText, crNoRole);
|
||
|
||
function SetSysColor(RefColor: TColor; TrueColor: TColorRef): Boolean;
|
||
begin
|
||
with Application.Palette do // asn: positive values or only rgb values?
|
||
if TrueColor >= TColor(0) then
|
||
begin
|
||
Result := True;
|
||
case RefColor of
|
||
clNormalNoRole..clNormalForeground:
|
||
SetColor(cgInactive, ColorRoles[-(RefColor+cloNormal)], TrueColor);
|
||
clDisabledHighlightedText..clDisabledForeground:
|
||
SetColor(cgDisabled, ColorRoles[-(RefColor+cloDisabled)], TrueColor);
|
||
clActiveNoRole..clActiveForeground:
|
||
SetColor(cgActive, ColorRoles[-(RefColor+cloActive)], TrueColor);
|
||
else
|
||
Result := False
|
||
end;
|
||
end
|
||
else // if
|
||
Result := False; // only rgb values are accepted (asn: see remark above)
|
||
|
||
end;
|
||
|
||
function SetSysColors(Elements: Integer; const lpaElements;
|
||
const lpaRgbValues): LongBool;
|
||
var
|
||
i: Integer;
|
||
refcolor : PColor;
|
||
realcolor : PColor;
|
||
begin
|
||
Result := True;
|
||
refcolor := PColor(lpaElements);
|
||
realcolor := PColor(lpaRGBvalues);
|
||
Application.Palette.BeginUpdate;
|
||
try
|
||
for i := 0 to Elements-1 do
|
||
begin
|
||
if not SetSysColor( refcolor^, realcolor^)
|
||
then
|
||
Result := False;
|
||
inc(refcolor);
|
||
inc(realcolor);
|
||
end;
|
||
finally
|
||
Application.Palette.EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
type
|
||
TStockObjectResource = class(TObject)
|
||
private
|
||
FStockObject: Integer;
|
||
FHandle: Pointer;
|
||
FRefCount: Integer;
|
||
public
|
||
constructor Create(AHandle: Pointer; AStockObject: Integer);
|
||
destructor Destroy; override;
|
||
function AddRef: Pointer;
|
||
procedure Release;
|
||
|
||
property Handle: Pointer read FHandle;
|
||
property StockObject: Integer read FStockObject;
|
||
end;
|
||
|
||
TStockObjectList = class(TObjectList)
|
||
public
|
||
function FindStockObject(AStockObject: Integer): TStockObjectResource;
|
||
class function ReleaseStockObject(AHandle: Pointer): Boolean;
|
||
end;
|
||
|
||
var
|
||
StockObjectList: TStockObjectList = nil;
|
||
StockObjectListCritSect: TRTLCriticalSection;
|
||
|
||
constructor TStockObjectResource.Create(AHandle: Pointer; AStockObject: Integer);
|
||
begin
|
||
inherited Create;
|
||
AddRef;
|
||
FHandle := AHandle;
|
||
FStockObject := AStockObject;
|
||
end;
|
||
|
||
destructor TStockObjectResource.Destroy;
|
||
type
|
||
Int = Integer;
|
||
begin
|
||
case StockObject of
|
||
Int(WHITE_BRUSH)..Int(NULL_BRUSH), Int(DC_BRUSH):
|
||
QBrush_destroy(QBrushH(Handle));
|
||
Int(WHITE_PEN)..Int(NULL_PEN), Int(DC_PEN):
|
||
QPen_destroy(QPenH(Handle));
|
||
Int(OEM_FIXED_FONT)..Int(DEVICE_DEFAULT_FONT), Int(SYSTEM_FIXED_FONT), Int(DEFAULT_GUI_FONT):
|
||
QFont_destroy(QFontH(Handle));
|
||
end;
|
||
StockObjectList.Extract(Self);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TStockObjectResource.AddRef: Pointer;
|
||
begin
|
||
Inc(FRefCount);
|
||
Result := Handle;
|
||
end;
|
||
|
||
procedure TStockObjectResource.Release;
|
||
begin
|
||
Dec(FRefCount);
|
||
if FRefCount = 0 then
|
||
Free;
|
||
end;
|
||
|
||
function TStockObjectList.FindStockObject(AStockObject: Integer): TStockObjectResource;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
for i := 0 to Count - 1 do
|
||
begin
|
||
Result := TStockObjectResource(Items[i]);
|
||
if Result.StockObject = AStockObject then
|
||
Exit;
|
||
end;
|
||
Result := nil;
|
||
end;
|
||
|
||
class function TStockObjectList.ReleaseStockObject(AHandle: Pointer): Boolean;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
EnterCriticalSection(StockObjectListCritSect);
|
||
try
|
||
if Assigned(StockObjectList) then
|
||
begin
|
||
for i := 0 to StockObjectList.Count - 1 do
|
||
if TStockObjectResource(StockObjectList.Items[i]).Handle = AHandle then
|
||
begin
|
||
TStockObjectResource(StockObjectList.Items[i]).Release;
|
||
Result := True;
|
||
Exit;
|
||
end;
|
||
end;
|
||
Result := False;
|
||
finally
|
||
LeaveCriticalSection(StockObjectListCritSect);
|
||
end;
|
||
end;
|
||
|
||
function GetStockObject(fnObject: Integer): Pointer; overload;
|
||
const
|
||
BrushColors: array[WHITE_BRUSH..BLACK_BRUSH] of TColor =
|
||
(clWhite, clLtGray, clGray, clDkGray, clBlack);
|
||
{$IFDEF MSWINDOWS}
|
||
SystemFont: WideString = 'System';
|
||
GuiFont: array[Boolean] of WideString = ('MS Sans Serife', 'Tahoma');
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
SystemFont: WideString = 'Fixed'; // asn: is not always True
|
||
// GuiFont: array[Boolean] of WideString = ('Verdana', 'Verdana');
|
||
//asn: in JVCL units Helvetica is used. Why introduce another?
|
||
GuiFont: array[Boolean] of WideString = ('Helvetica', 'Helvetica');
|
||
{$ENDIF LINUX}
|
||
type
|
||
Int = Integer;
|
||
var
|
||
Resource: TStockObjectResource;
|
||
GuiFontSelector: Boolean;
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
GuiFontSelector := Win32MajorVersion >= 5;
|
||
{$ELSE}
|
||
GuiFontSelector := True;
|
||
{$ENDIF MSWINDOWS}
|
||
EnterCriticalSection(StockObjectListCritSect);
|
||
try
|
||
if not Assigned(StockObjectList) then
|
||
StockObjectList := TStockObjectList.Create;
|
||
Resource := StockObjectList.FindStockObject(fnObject);
|
||
if Resource <> nil then
|
||
Result := Resource.AddRef
|
||
else
|
||
begin
|
||
case fnObject of
|
||
Int(WHITE_BRUSH)..Int(BLACK_BRUSH):
|
||
Result := CreateSolidBrush(BrushColors[TStockObjectBrush(fnObject)]);
|
||
Int(NULL_BRUSH):
|
||
Result := QBrush_create(BrushStyle_NoBrush);
|
||
Int(DC_BRUSH):
|
||
Result := CreateSolidBrush(clWhite);
|
||
Int(WHITE_PEN):
|
||
Result := CreatePen(PS_SOLID, 1, clWhite);
|
||
Int(BLACK_PEN):
|
||
Result := CreatePen(PS_SOLID, 1, clBlack);
|
||
Int(NULL_PEN):
|
||
Result := CreatePen(PS_NULL, 1, clWhite);
|
||
Int(DC_PEN):
|
||
Result := CreatePen(PS_SOLID, 1, clWhite);
|
||
Int(OEM_FIXED_FONT), Int(ANSI_FIXED_FONT), Int(SYSTEM_FONT), Int(SYSTEM_FIXED_FONT):
|
||
Result := QFont_create(@SystemFont, 8, 1, False);
|
||
Int(ANSI_VAR_FONT), Int(DEVICE_DEFAULT_FONT), Int(DEFAULT_GUI_FONT):
|
||
Result := QFont_create(@GuiFont[GuiFontSelector], 8, 1, False);
|
||
else
|
||
Result := nil;
|
||
end;
|
||
if Result <> nil then
|
||
StockObjectList.Add(TStockObjectResource.Create(Result, fnObject));
|
||
end;
|
||
finally
|
||
LeaveCriticalSection(StockObjectListCritSect);
|
||
end;
|
||
end;
|
||
|
||
function GetStockObject(fnObject: TStockObjectBrush): QBrushH;
|
||
begin
|
||
Result := QBrushH(GetStockObject(Integer(fnObject)));
|
||
end;
|
||
|
||
function GetStockObject(fnObject: TStockObjectPen): QPenH;
|
||
begin
|
||
Result := QPenH(GetStockObject(Integer(fnObject)));
|
||
end;
|
||
|
||
function GetStockObject(fnObject: TStockObjectFont): QFontH;
|
||
begin
|
||
Result := QFontH(GetStockObject(Integer(fnObject)));
|
||
end;
|
||
|
||
function GetMapMode(Handle: QPainterH): TMapMode;
|
||
var
|
||
P: PPainterInfo;
|
||
begin
|
||
if GetPainterInfo(Handle, P) then
|
||
Result := P.MapMode
|
||
else
|
||
Result := MM_TEXT;
|
||
end;
|
||
|
||
function SetMapMode(Handle: QPainterH; MapMode: TMapMode): TMapMode;
|
||
var
|
||
Matrix: QWMatrixH;
|
||
dpi: TSize;
|
||
m11, m22: Double;
|
||
dx, dy: Double;
|
||
|
||
procedure SetM(const Am11, Am22: Double);
|
||
begin
|
||
m11 := Am11;
|
||
m22 := Am22;
|
||
end;
|
||
|
||
begin
|
||
dpi.cx := GetDeviceCaps(Handle, LOGPIXELSX);
|
||
dpi.cy := GetDeviceCaps(Handle, LOGPIXELSY);
|
||
|
||
Result := GetMapMode(Handle);
|
||
case MapMode of
|
||
MM_TEXT:
|
||
SetM(1, 1);
|
||
|
||
MM_LOMETRIC:
|
||
SetM((dpi.cx / 2.54) / 100, -(dpi.cy / 2.54) / 100);
|
||
MM_HIMETRIC:
|
||
SetM((dpi.cx / 2.54) / 1000, -(dpi.cy / 2.54) / 1000);
|
||
|
||
MM_LOENGLISH:
|
||
SetM(dpi.cx / 10, -dpi.cy / 10);
|
||
MM_HIENGLISH:
|
||
SetM(dpi.cx / 100, -dpi.cy / 100);
|
||
|
||
MM_TWIPS:
|
||
SetM(dpi.cx / 1440, -dpi.cy / 1440);
|
||
|
||
MM_ISOTROPIC:
|
||
|
||
end;
|
||
// translate matrix
|
||
if QPainter_hasWorldXForm(Handle) then
|
||
begin
|
||
dx := QWMatrix_dx(QPainter_worldMatrix(Handle));
|
||
dy := QWMatrix_dy(QPainter_worldMatrix(Handle));
|
||
end
|
||
else
|
||
begin
|
||
dx := 0;
|
||
dy := 0;
|
||
end;
|
||
Matrix := QWMatrix_create(m11, 0, 0, m22, dx, dy);
|
||
QPainter_setWorldMatrix(Handle, Matrix, False);
|
||
QWMatrix_destroy(Matrix);
|
||
SetPainterInfo(Handle).MapMode := MapMode;
|
||
end;
|
||
|
||
function CreatePen(Style, Width: Integer; Color: TColor): QPenH;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
QC := QColor(Color);
|
||
Result := QPen_create(QC, Width, PenStyle(Style));
|
||
QColor_destroy(QC);
|
||
end;
|
||
|
||
function DeleteObject(Handle: QPenH): LongBool;
|
||
begin
|
||
try
|
||
// if not TStockObjectList.ReleaseStockObject(Handle) then
|
||
QPen_destroy(Handle);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function CreateSolidBrush(Color: TColor): QBrushH;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
QC := QColor(Color);
|
||
Result := QBrush_create(QC, BrushStyle_SolidPattern);
|
||
QColor_destroy(QC);
|
||
end;
|
||
|
||
function CreateHatchBrush(bStyle: BrushStyle; Color: TColor): QBrushH;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
QC := QColor(Color);
|
||
Result := QBrush_create(QC, bStyle);
|
||
QColor_destroy(QC);
|
||
end;
|
||
|
||
function DeleteObject(Handle: QBrushH): LongBool;
|
||
begin
|
||
Result := False;
|
||
if Handle <> nil then
|
||
begin
|
||
try
|
||
// if not TStockObjectList.ReleaseStockObject(Handle) then
|
||
QBrush_destroy(Handle);
|
||
Result := True;
|
||
except
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function EnableWindow(Handle: QWidgetH; Value: Boolean): LongBool;
|
||
begin
|
||
try
|
||
QWidget_setEnabled(Handle, Value);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement): LongBool;
|
||
begin
|
||
try
|
||
Result := ShowWindow(Handle, W.ShowCmd);
|
||
with W.rcNormalPosition do
|
||
QWidget_setGeometry(Handle, Left, Top, Right - Left, Bottom - Top);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetWindowPlacement(Handle: QWidgetH; W: PWindowPlacement): LongBool;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
try
|
||
QWidget_geometry(Handle, @R);
|
||
W.rcNormalPosition.Left := R.Left;
|
||
W.rcNormalPosition.Top := R.Top;
|
||
W.rcNormalPosition.Right := R.Right;
|
||
W.rcNormalPosition.Bottom := R.Bottom;
|
||
if QWidget_isMinimized(Handle) then
|
||
W.showCmd := SW_SHOWMINIMIZED
|
||
else if QWidget_isMaximized(Handle) then
|
||
W.showCmd := SW_SHOWMAXIMIZED
|
||
else if not QWidget_isVisible(Handle) then
|
||
W.showCmd := SW_HIDE
|
||
else
|
||
W.showCmd := SW_SHOWNORMAL;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetWindowRect(Handle: QWidgetH; var R: TRect): LongBool;
|
||
begin
|
||
try
|
||
QWidget_frameGeometry(Handle, @R);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetClientRect(Handle: QWidgetH; var R: TRect): LongBool;
|
||
begin
|
||
try
|
||
QWidget_rect(Handle, @R);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function ShowWindow(Handle: QWidgetH; showCmd: UInt): LongBool;
|
||
var
|
||
ActWidget: QWidgetH;
|
||
begin
|
||
try
|
||
case ShowCmd of
|
||
SW_MINIMIZE, SW_SHOWMINIMIZED:
|
||
QWidget_showMinimized(Handle);
|
||
SW_MAXIMIZE:
|
||
QWidget_showMaximized(Handle);
|
||
SW_HIDE:
|
||
QWidget_hide(Handle);
|
||
SW_SHOWNOACTIVATE, SW_SHOWMINNOACTIVE:
|
||
begin
|
||
ActWidget := QApplication_activeWindow(Application.Handle);
|
||
if ShowCmd = SW_SHOWNOACTIVATE then
|
||
QWidget_showNormal(Handle)
|
||
else
|
||
QWidget_showMinimized(Handle);
|
||
if Assigned(ActWidget) then
|
||
QWidget_setActiveWindow(ActWidget);
|
||
end;
|
||
else
|
||
QWidget_showNormal(Handle);
|
||
end;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
type
|
||
THackedWidgetControl = class(TWidgetControl);
|
||
|
||
function SetWindowPos(Wnd, WndInsertAfter: QWidgetH; X, Y, cx, cy: Integer;
|
||
uFlags: Longword): LongBool;
|
||
var
|
||
R, Geometry: TRect;
|
||
WidgetFlags: Cardinal;
|
||
Control: THackedWidgetControl;
|
||
LastActiveWidget: QWidgetH;
|
||
LastActiveWinId: Cardinal;
|
||
begin
|
||
Result := False;
|
||
if Wnd = nil then
|
||
Exit;
|
||
try
|
||
LastActiveWidget := QApplication_activeWindow(Application.Handle);
|
||
if LastActiveWidget <> nil then
|
||
LastActiveWinId := QWidget_winId(LastActiveWidget)
|
||
else
|
||
LastActiveWinId := 0;
|
||
|
||
// we must use CLX methods or CLX will be a pain.
|
||
Control := THackedWidgetControl(FindControl(Wnd));
|
||
|
||
if Control <> nil then
|
||
Geometry := Control.BoundsRect
|
||
else
|
||
QWidget_geometry(Wnd, @Geometry);
|
||
|
||
if uFlags and SWP_HIDEWINDOW <> 0 then
|
||
begin
|
||
if Control <> nil then
|
||
Control.Hide
|
||
else
|
||
QWidget_hide(Wnd);
|
||
end;
|
||
|
||
if uFlags and SWP_NOSIZE <> 0 then
|
||
begin
|
||
cx := Geometry.Right - Geometry.Left;
|
||
cy := Geometry.Bottom - Geometry.Top;
|
||
end;
|
||
if uFlags and SWP_NOMOVE <> 0 then
|
||
begin
|
||
X := Geometry.Left;
|
||
Y := Geometry.Top;
|
||
end;
|
||
R := Rect(X, Y, X + cx, Y + cy);
|
||
if not EqualRect(R, Geometry) then
|
||
begin
|
||
if Control <> nil then
|
||
Control.BoundsRect := R
|
||
else
|
||
QWidget_setGeometry(Wnd, X, Y, cx, cy);
|
||
end;
|
||
|
||
if uFlags and SWP_FRAMECHANGED <> 0 then
|
||
begin
|
||
QWidget_adjustSize(Wnd);
|
||
if Control <> nil then
|
||
Control.AdjustSize;
|
||
end;
|
||
|
||
if (uFlags and SWP_NOOWNERZORDER = 0) and (uFlags and SWP_NOZORDER = 0) and
|
||
(Cardinal(WndInsertAfter) <> HWND_TOP) and (Cardinal(WndInsertAfter) <> HWND_BOTTOM) and
|
||
(Cardinal(WndInsertAfter) <> HWND_TOPMOST) then
|
||
if (not QWidget_isTopLevel(Wnd)) and (QWidget_parentWidget(Wnd) <> nil) then
|
||
SetWindowPos(QWidget_parentWidget(Wnd), WndInsertAfter, 0, 0, 0, 0,
|
||
SWP_NOSIZE or SWP_NOMOVE or SWP_NOREDRAW or SWP_NOACTIVATE or
|
||
SWP_NOCOPYBITS or SWP_NOSENDCHANGING);
|
||
|
||
if (uFlags and SWP_NOZORDER = 0) then
|
||
begin
|
||
WidgetFlags := QOpenWidget_getWFlags(QOpenWidgetH(Wnd));
|
||
|
||
case Cardinal(WndInsertAfter) of
|
||
HWND_TOP:
|
||
QWidget_raise(Wnd);
|
||
HWND_BOTTOM:
|
||
QWidget_lower(Wnd);
|
||
HWND_TOPMOST:
|
||
if (Control <> nil) and (TWidgetControl(Control) is TForm) then
|
||
TForm(Control).FormStyle := fsStayOnTop
|
||
else
|
||
QOpenWidget_setWFlags(QOpenWidgetH(Wnd),
|
||
WidgetFlags or Cardinal(WidgetFlags_WStyle_StaysOnTop));
|
||
HWND_NOTOPMOST:
|
||
if (Control <> nil) and (TWidgetControl(Control) is TForm) then
|
||
TForm(Control).FormStyle := fsNormal
|
||
else
|
||
QOpenWidget_setWFlags(QOpenWidgetH(Wnd),
|
||
WidgetFlags and not Cardinal(WidgetFlags_WStyle_StaysOnTop));
|
||
else
|
||
// remove top most state
|
||
if WidgetFlags and Cardinal(WidgetFlags_WStyle_StaysOnTop) <> 0 then
|
||
begin
|
||
if (Control <> nil) and (TWidgetControl(Control) is TForm) then
|
||
TForm(Control).FormStyle := fsNormal
|
||
else
|
||
QOpenWidget_setWFlags(QOpenWidgetH(Wnd),
|
||
WidgetFlags and not Cardinal(WidgetFlags_WStyle_StaysOnTop));
|
||
end;
|
||
// after widget
|
||
QWidget_stackUnder(Wnd, WndInsertAfter);
|
||
end;
|
||
end;
|
||
|
||
if uFlags and SWP_SHOWWINDOW <> 0 then
|
||
begin
|
||
if Control <> nil then
|
||
Control.Show
|
||
else
|
||
QWidget_show(Wnd);
|
||
end;
|
||
|
||
if (uFlags and SWP_NOACTIVATE = 0) and (QWidget_isVisible(Wnd)) then
|
||
QWidget_setActiveWindow(Wnd);
|
||
|
||
if (uFlags and SWP_NOREDRAW = 0) and (QWidget_isVisible(Wnd)) then
|
||
QWidget_update(Wnd);
|
||
|
||
if (uFlags and SWP_NOACTIVATE <> 0) and Assigned(LastActiveWidget) then
|
||
if QWidget_find(LastActiveWinId) = LastActiveWidget then // valid LastActiveWidget
|
||
QWidget_setActiveWindow(LastActiveWidget);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SetWindowPos(Wnd, WndInsertAfter: Cardinal; X, Y, cx, cy: Integer;
|
||
uFlags: Longword): LongBool;
|
||
begin
|
||
Result := SetWindowPos(QWidgetH(Wnd), QWidgetH(WndInsertAfter), X, Y, cx, cy, uFlags);
|
||
end;
|
||
|
||
function SetWindowPos(Wnd: QWidgetH; WndInsertAfter: Cardinal; X, Y, cx, cy: Integer;
|
||
uFlags: Longword): LongBool;
|
||
begin
|
||
Result := SetWindowPos(Wnd, QWidgetH(WndInsertAfter), X, Y, cx, cy, uFlags);
|
||
end;
|
||
|
||
procedure MoveWindowOrg(DC: QPainterH; DX, DY: Integer);
|
||
var
|
||
P: TPoint;
|
||
begin
|
||
GetWindowOrgEx(DC, P);
|
||
SetWindowOrgEx(DC, P.X - DX, P.Y - DY, nil);
|
||
end;
|
||
|
||
function IsWindowVisible(Handle: QWidgetH): LongBool;
|
||
begin
|
||
Result := QWidget_isVisible(Handle);
|
||
end;
|
||
|
||
function IsWindowEnabled(Handle: QWidgetH): LongBool;
|
||
begin
|
||
Result := QWidget_isEnabled(Handle);
|
||
end;
|
||
|
||
function SetFocus(Handle: QWidgetH): QWidgetH;
|
||
begin
|
||
try
|
||
Result := GetFocus;
|
||
QWidget_setFocus(Handle);
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
function GetFocus: QWidgetH;
|
||
begin
|
||
Result := QApplication_focusWidget(Application.Handle);
|
||
end;
|
||
|
||
function GetBkMode(Handle: QPainterH): Integer;
|
||
begin
|
||
case QPainter_BackgroundMode(Handle) of
|
||
BGMode_TransparentMode:
|
||
Result := TRANSPARENT; // BGMode_TransparentMode
|
||
BGMode_OpaqueMode:
|
||
Result := OPAQUE; // BGMode_OpaqueMode
|
||
else
|
||
Result := OPAQUE;
|
||
end;
|
||
end;
|
||
|
||
function SetBkMode(Handle: QPainterH; BkMode: Integer): Integer;
|
||
begin
|
||
Result := GetBkMode(Handle);
|
||
case BkMode of
|
||
TRANSPARENT:
|
||
QPainter_setBackgroundMode(Handle, BGMode_TransparentMode);
|
||
OPAQUE:
|
||
QPainter_setBackgroundMode(Handle, BGMode_OpaqueMode);
|
||
end;
|
||
end;
|
||
|
||
function SetPenColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
Result := QColorColor(QPen_color(QPainter_pen(Handle)));
|
||
QC := QColor(Color);
|
||
QPainter_setPen(Handle, QC);
|
||
QColor_destroy(QC);
|
||
end;
|
||
|
||
function SetTextColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
begin
|
||
Result := SetPenColor(Handle, Color);
|
||
end;
|
||
|
||
function SetBkColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
Result := QColorColor(QPainter_backgroundColor(Handle));
|
||
QC := QColor(Color);
|
||
QPainter_setBackgroundColor(Handle, QC);
|
||
QColor_destroy(QC);
|
||
end;
|
||
|
||
function SetDCBrushColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
Result := QColorColor(QBrush_color(QPainter_brush(Handle)));
|
||
QC := QColor(Color);
|
||
QPainter_setBrush(Handle, QC);
|
||
QColor_destroy(QC);
|
||
end;
|
||
|
||
function SetDCPenColor(Handle: QPainterH; Color: TColor): TColorRef;
|
||
begin
|
||
Result := SetPenColor(Handle, Color);
|
||
end;
|
||
|
||
procedure SetPainterFont(Handle: QPainterH; Font: QGraphics.TFont);
|
||
begin
|
||
QPainter_setFont(Handle, Font.Handle);
|
||
QPainter_setPen(Handle, Font.FontPen);
|
||
end;
|
||
|
||
function GetParent(Handle: QWidgetH): QWidgetH;
|
||
begin
|
||
Result := QWidget_parentWidget(Handle);
|
||
end;
|
||
|
||
function SetParent(hWndChild, hWndNewParent: QWidgetH): QWidgetH;
|
||
var
|
||
Pt: TPoint;
|
||
begin
|
||
try
|
||
Result := GetParent(hWndChild);
|
||
QWidget_pos(hWndChild, @Pt);
|
||
QWidget_reparent(hWndChild, hWndNewParent, @Pt, QWidget_isVisible(hWndChild));
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
function RasterOpToWinRop(Rop: RasterOp): cardinal;
|
||
begin
|
||
case Rop of
|
||
RasterOp_ClearROP : Result := BLACKNESS;
|
||
RasterOp_NotROP : Result := DSTINVERT;
|
||
RasterOp_NotOrRop : Result := MERGEPAINT;
|
||
RasterOp_NotCopyROP : Result := NOTSRCCOPY;
|
||
RasterOp_NorROP : Result := NOTSRCERASE;
|
||
RasterOp_AndROP : Result := SRCAND;
|
||
RasterOp_CopyROP : Result := SRCCOPY;
|
||
RasterOp_AndNotROP : Result := SRCERASE;
|
||
RasterOp_XorROP : Result := SRCINVERT;
|
||
RasterOp_OrROP : Result := SRCPAINT;
|
||
RasterOp_SetROP : Result := WHITENESS;
|
||
RasterOp_NotAndROP : Result := ROP_DSna;
|
||
RasterOp_NopROP : Result := ROP_D;
|
||
RasterOp_OrNotROP : Result := ROP_SDno;
|
||
RasterOp_NandROP : Result := ROP_DSan;
|
||
else
|
||
Result := 0; // to satisfy compiler
|
||
end;
|
||
end;
|
||
|
||
function WinRopToRasterOp(WinRop: Cardinal; var Rop: RasterOp): Boolean;
|
||
begin
|
||
Result := True;
|
||
case WinRop of
|
||
BLACKNESS : Rop := RasterOp_ClearROP;
|
||
DSTINVERT : Rop := RasterOp_NotROP;
|
||
// MERGECOPY : Rop := RasterOp_OrROP; {DSa}
|
||
MERGEPAINT : Rop := RasterOp_NotOrRop;
|
||
NOTSRCCOPY : Rop := RasterOp_NotCopyROP;
|
||
NOTSRCERASE: Rop := RasterOp_NorROP;
|
||
SRCAND : Rop := RasterOp_AndROP;
|
||
SRCCOPY : Rop := RasterOp_CopyROP;
|
||
SRCERASE : Rop := RasterOp_AndNotROP;
|
||
SRCINVERT : Rop := RasterOp_XorROP;
|
||
SRCPAINT : Rop := RasterOp_OrROP;
|
||
WHITENESS : Rop := RasterOp_SetROP;
|
||
ROP_DSna : Rop := RasterOp_NotAndROP;
|
||
ROP_D : Rop := RasterOp_NopROP;
|
||
ROP_SDno : Rop := RasterOp_OrNotROP;
|
||
ROP_DSan : Rop := RasterOp_NandROP;
|
||
else
|
||
Rop := RasterOp(-1);
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function PatternPaint(DestDC: QPainterH; X, Y, W, H: Integer; rop: RasterOp): LongBool;
|
||
var
|
||
trop: RasterOp;
|
||
bkmode: Integer;
|
||
begin
|
||
try
|
||
trop := QPainter_rasterOp(DestDC);
|
||
bkmode := SetBkMode(DestDC, OPAQUE);
|
||
try
|
||
QPainter_setRasterOp(DestDC, rop); // asn: or use current ?
|
||
QPainter_fillRect(DestDC, X, Y, W, H, QPainter_brush(DestDC)); // current brush
|
||
finally
|
||
QPainter_setRasterOp(DestDC, trop);
|
||
SetBkMode(DestDC, bkmode);
|
||
end;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function BitBlt(DestDC: QPainterH; X, Y, Width, Height: Integer; SrcDC: QPainterH;
|
||
XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: Boolean): LongBool;
|
||
var
|
||
TempDC: QPainterH;
|
||
Rop: RasterOp;
|
||
begin
|
||
if WinRopToRasterOp(WinRop, Rop) then // directly maps ?
|
||
Result := BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Rop, IgnoreMask)
|
||
else // no
|
||
begin
|
||
case WinRop of
|
||
MERGECOPY: { PSa: Dest := Pattern AND Source }
|
||
begin
|
||
try
|
||
TempDC := CreateCompatibleDC(DestDC, Width, Height);
|
||
try
|
||
PatternPaint(TempDc, 0, 0, Width, Height, RasterOp_CopyROP); // Create Pattern
|
||
BitBlt(TempDc, 0, 0, Width, Height, SrcDC, XSrc, YSrc, RasterOp_AndRop); {PSa}
|
||
Result := BitBlt(DestDc, X, Y, Width, Height, tempDC, XSrc, YSrc, RasterOp_CopyROP);
|
||
except
|
||
Result := False;
|
||
end;
|
||
QPainter_destroy(tempDC);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
PATCOPY:
|
||
Result := PatternPaint(DestDC, X, Y, Width, Height, RasterOp_CopyROP);
|
||
|
||
PATINVERT:
|
||
Result := PatternPaint(DestDC, X, Y, Width, Height, RasterOp_XorROP);
|
||
|
||
PATPAINT:
|
||
begin // DPSnoo = PDSnoo
|
||
Result := BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc,
|
||
RasterOp_NotOrRop); // DSno
|
||
if Result then
|
||
Result := PatternPaint(DestDC, X, Y, Width, Height, RasterOp_XOrROP);
|
||
end;
|
||
|
||
ROP_DSPDxax:
|
||
begin
|
||
TempDC := CreateCompatibleDC(DestDC, Width, Height);
|
||
try
|
||
// copy DestDC to pixmap
|
||
BitBlt(TempDC, 0, 0, Width, Height, DestDC, X, Y, RasterOp_XorROP);
|
||
BitBlt(TempDC, 0, 0, Width, Height, TempDC, 0, 0, PATINVERT); // PDx
|
||
BitBlt(TempDC, 0, 0, Width, Height, SrcDC, XSrc, YSrc, RasterOp_AndROP); // SPDxa
|
||
Result := BitBlt(DestDC, X, Y, Width, Height, TempDC, 0, 0, RasterOp_XorROP); // DSPDxax
|
||
except
|
||
Result := False;
|
||
end;
|
||
DeleteObject(TempDC);
|
||
end;
|
||
else
|
||
Result := False;
|
||
end;
|
||
end
|
||
end;
|
||
|
||
function BitBlt(DestDC: QPainterH; X, Y, Width, Height: Integer; SrcDC: QPainterH;
|
||
XSrc, YSrc: Integer; Rop: RasterOp; IgnoreMask: Boolean): LongBool;
|
||
var
|
||
d_dx, d_dy, d_sx, d_sy, d_sw, d_sh, d_dw, d_dh: Integer;
|
||
begin
|
||
if (DestDC = nil) or (SrcDC = nil) then
|
||
Result := False
|
||
else
|
||
begin
|
||
Result := True;
|
||
try
|
||
// Windows's BitBlt uses logical units
|
||
d_dx := X;d_dy := Y;d_dw := Width;d_dh := Height;
|
||
d_sx := XSrc; d_sy := YSrc;d_sw := Width; d_sh := Height;
|
||
|
||
MapPainterLP(DestDC, d_dx, d_dy);
|
||
MapPainterLPwh(DestDC, d_dw, d_dh);
|
||
MapPainterLP(SrcDC, d_sx, d_sy);
|
||
MapPainterLPwh(SrcDC, d_sw, d_sh);
|
||
|
||
if (d_dw = d_sw) and (d_dh = d_sh) then // device bitBlt possible
|
||
Qt.bitBlt(QPainter_device(DestDC), d_dx, d_dy, QPainter_device(SrcDC),
|
||
d_sx, d_sy, d_sw, d_sh, Rop,
|
||
IgnoreMask) // ignore the Mask because Windows's BitBlt does not use Masks
|
||
else
|
||
StretchBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width, Height,
|
||
Rop, IgnoreMask);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function PainterOffset(Canvas: TCanvas): TPoint;
|
||
var
|
||
aControl: TControl;
|
||
begin
|
||
Result.X := 0;
|
||
Result.Y := 0;
|
||
if Canvas is TControlCanvas then
|
||
begin
|
||
AControl := TControlCanvas(Canvas).Control;
|
||
if AControl = nil then
|
||
Exit;
|
||
if not (AControl is TWidgetControl) then
|
||
begin
|
||
Result.X := aControl.Left;
|
||
Result.Y := aControl.Top;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function BitBlt(DestCanvas: TCanvas; X, Y, Width, Height: Integer; SrcCanvas: TCanvas;
|
||
XSrc, YSrc: Integer; WinRop: Cardinal; IgnoreMask: boolean): LongBool;
|
||
begin
|
||
DestCanvas.Start;
|
||
SrcCanvas.Start;
|
||
Result := BitBlt(DestCanvas.Handle, X, Y , Width, Height, SrcCanvas.Handle,
|
||
XSrc, YSrc, WinRop, IgnoreMask);
|
||
SrcCanvas.Stop;
|
||
DestCanvas.Stop;
|
||
end;
|
||
|
||
const
|
||
CopyModeToRasterOp: array[TCopyMode] of RasterOp = (
|
||
{cmBlackness} RasterOp_ClearROP, {cmDstInvert} RasterOp_NotROP,
|
||
{cmMergeCopy} RasterOp_AndROP, {cmMergePaint} RasterOP_NotOrROP,
|
||
{cmNotSrcCopy} RasterOp_NotCopyROP, {cmNotSrcErase}RasterOp_NorROP,
|
||
{cmPatCopy} RasterOp_NopROP, {cmPatInvert} RasterOp_NopROP,
|
||
{cmPatPaint} RasterOp_NotOrROP, {cmSrcAnd} RasterOp_AndROP,
|
||
{cmSrcCopy} RasterOp_CopyROP, {cmSrcErase} RasterOp_AndNotROP,
|
||
{cmSrcInvert} RasterOp_XorROP, {cmSrcPaint} RasterOP_OrROP,
|
||
{cmWhiteness} RasterOp_SetROP, {cmCreateMask} RasterOp_NopROP);
|
||
|
||
|
||
procedure CopyRect(DstCanvas: TCanvas; const Dest: TRect; Canvas: TCanvas;
|
||
const Source: TRect);
|
||
begin
|
||
StretchBlt(DstCanvas, Dest.Left, Dest.Top,
|
||
Dest.Right - Dest.Left, Dest.Bottom - Dest.Top,
|
||
Canvas, Source.Left, Source.Top,
|
||
Source.Right - Source.Left, Source.Bottom - Source.Top,
|
||
RasterOpToWinRop(CopyModeToRasterOp[DstCanvas.CopyMode]));
|
||
end;
|
||
|
||
procedure BrushCopy(DstCanvas: TCanvas; const Dest: TRect; Bitmap: TBitmap;
|
||
const Source: TRect; Color: TColor);
|
||
var
|
||
Bmp: TBitmap;
|
||
X, Y: integer;
|
||
begin
|
||
Bmp := TBitmap.Create;
|
||
with Bmp do
|
||
begin
|
||
Width := Source.Right - Source.Left;
|
||
Height := Source.Bottom - Source.Top;
|
||
Canvas.Start;
|
||
Canvas.Draw( -Source.Left, -Source.Top, Bitmap);
|
||
TransparentColor := Color;
|
||
Transparent := True;
|
||
Canvas.Stop;
|
||
end;
|
||
with DstCanvas do
|
||
begin
|
||
Start;
|
||
FillRect(Dest);
|
||
X := Dest.Left;
|
||
while X < Dest.Right do
|
||
begin
|
||
Y := Dest.Top;
|
||
while Y < Dest.Bottom do
|
||
begin
|
||
Draw(X, Y, Bmp);
|
||
Y := Y + Bmp.Height;
|
||
end;
|
||
X := X + Bmp.Width;
|
||
end;
|
||
Stop;
|
||
end;
|
||
Bmp.Free;
|
||
end;
|
||
|
||
function PatBlt(Handle: QPainterH; X, Y, Width, Height: Integer; WinRop: Cardinal): LongBool;
|
||
begin
|
||
Result := BitBlt(Handle, X, Y, Width, Height, Handle, X, Y, WinRop);
|
||
end;
|
||
|
||
function PatBlt(Canvas: TCanvas; X, Y, Width, Height: Integer; WinRop: Cardinal): LongBool;
|
||
begin
|
||
Canvas.Start;
|
||
Result := BitBlt(Canvas.Handle, X, Y, Width, Height, Canvas.Handle, X, Y, WinRop);
|
||
Canvas.Stop;
|
||
end;
|
||
|
||
function StretchBlt(DestDC: QPainterH; dx, dy, dw, dh: Integer;
|
||
SrcDC: QPainterH; sx, sy, sw, sh: Integer; WinRop: Cardinal;
|
||
IgnoreMask: Boolean): LongBool;
|
||
var
|
||
Bmp1, Bmp2: QPixmapH;
|
||
Painter : QPainterH;
|
||
d_sx, d_sy, d_sw, d_sh: Integer;
|
||
d_dx, d_dy, d_dw, d_dh: Integer;
|
||
begin
|
||
Result := False;
|
||
if (DestDC = nil) and (QPainter_isActive(DestDC)) then
|
||
Exit;
|
||
|
||
// Windows's StretchBlt uses logical units
|
||
d_sx := sx;d_sy := sy;d_sw := sw;d_sh := sh;
|
||
d_dx := dx;d_dy := dy;d_dw := dw;d_dh := dh;
|
||
|
||
MapPainterLP(DestDC, d_dx, d_dy);
|
||
MapPainterLPwh(DestDC, d_dw, d_dh);
|
||
MapPainterLP(SrcDC, d_sx, d_sy);
|
||
MapPainterLPwh(SrcDC, d_sw, d_sh);
|
||
|
||
if (d_dw = d_sw) and (d_dh = d_sh) then // device bitBlt possible
|
||
Result := BitBlt(DestDC, dx, dy, dw, dh, SrcDC, sx, sy, WinRop, IgnoreMask)
|
||
else
|
||
begin
|
||
if not QPainter_isActive(SrcDC) then
|
||
Exit;
|
||
try
|
||
Bmp1 := nil;
|
||
Bmp2 := nil;
|
||
try
|
||
// temporary bitmaps are in device units
|
||
Bmp1 := CreateCompatibleBitmap(SrcDC, d_sw, d_sh);
|
||
Bmp2 := CreateCompatibleBitmap(DestDC, d_dw, d_dh);
|
||
Qt.bitBlt(Bmp1, 0, 0, QPainter_device(SrcDC), d_sx, d_sy, d_sw, d_sh,
|
||
RasterOp_CopyROP, IgnoreMask); // use device units
|
||
Painter := QPainter_create(Bmp2);
|
||
QPainter_save(Painter);
|
||
QPainter_scale(Painter, d_dw/d_sw, d_dh/d_sh);
|
||
QPainter_drawPixmap(Painter, 0, 0, Bmp1, 0, 0, d_sw, d_sh);
|
||
QPainter_restore(Painter);
|
||
Result := BitBlt(DestDC, dx, dy, dw, dh, Painter, 0, 0, WinRop, IgnoreMask); // maps logical units
|
||
QPainter_destroy(Painter);
|
||
finally
|
||
if Assigned(Bmp1) then
|
||
QPixmap_destroy(Bmp1);
|
||
if Assigned(Bmp2) then
|
||
QPixmap_destroy(Bmp2);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function StretchBlt(DestDC: QPainterH; dx, dy, dw, dh: Integer;
|
||
SrcDC: QPainterH; sx, sy, sw, sh: Integer; Rop: RasterOp; IgnoreMask: Boolean): LongBool;
|
||
begin
|
||
Result := StretchBlt(DestDC, dx, dy, dw, dh, SrcDC, sx, sy, sw, sh,
|
||
RasterOpToWinRop(Rop), IgnoreMask);
|
||
end;
|
||
|
||
function StretchBlt(DestCanvas: TCanvas; dx, dy, dw, dh: Integer;
|
||
SrcCanvas: TCanvas; sx, sy, sw, sh: Integer; WinRop: Cardinal; IgnoreMask: Boolean): LongBool;
|
||
//var
|
||
// d,s :TPoint;
|
||
begin
|
||
DestCanvas.Start;
|
||
SrcCanvas.Start;
|
||
// d := PainterOffset(DestCanvas);
|
||
// s := PainterOffset(SrcCanvas);
|
||
// Result := StretchBlt(DestCanvas.Handle, dx + d.x, dy + d.y, dw, dh, SrcCanvas.Handle,
|
||
// sx + s.x, sy + s.y, sw, sh, WinRop, IgnoreMask);
|
||
Result := StretchBlt(DestCanvas.Handle, dx, dy, dw, dh, SrcCanvas.Handle,
|
||
sx, sy, sw, sh, WinRop, IgnoreMask);
|
||
SrcCanvas.Stop;
|
||
DestCanvas.Stop;
|
||
end;
|
||
|
||
function GetStretchBltMode(DC: QPainterH): TStretchMode;
|
||
var
|
||
P: PPainterInfo;
|
||
begin
|
||
if DC <> nil then
|
||
begin
|
||
if GetPainterInfo(DC, P) then
|
||
Result := P.StetchBltMode
|
||
else
|
||
Result := STRETCH_DELETESCANS;
|
||
end
|
||
else
|
||
Result := STRETCH_DELETESCANS;
|
||
end;
|
||
|
||
function SetStretchBltMode(DC: QPainterH; StretchMode: TStretchMode): TStretchMode;
|
||
begin
|
||
try
|
||
Result := GetStretchBltMode(DC);
|
||
SetPainterInfo(DC).StetchBltMode := StretchMode;
|
||
except
|
||
Result := STRETCH_DELETESCANS;
|
||
end;
|
||
end;
|
||
|
||
function ScrollDC(Handle: QPainterH; dx, dy: Integer; var Scroll, Clip: TRect;
|
||
Rgn: QRegionH; Update: PRect): LongBool;
|
||
var
|
||
R1, R2: TRect;
|
||
rg1, rg2: QRegionH;
|
||
begin
|
||
// assume device units = pixels
|
||
IntersectRect(R2, Scroll, Clip); // clipped source rectangle
|
||
OffsetRect(R2, dx, dy);
|
||
IntersectRect(R2, R2, Clip); // R2: clipped destination rectangle
|
||
if not isRectEmpty(R2) then
|
||
begin
|
||
R1 := R2;
|
||
OffsetRect(R1, -dx, -dy); // R1: adjusted source rectangle
|
||
Result := BitBlt(Handle, R2.Left, R2.Top, R2.Right-R2.Left, R2.Bottom-R2.Top,
|
||
Handle, R1.Left, R1.Top, SRCCOPY);
|
||
end
|
||
else
|
||
Result := False; // asn: or True ?
|
||
if (Rgn <> nil) or (Update <> nil) then
|
||
begin
|
||
rg1 := CreateRectRgnIndirect(Scroll);
|
||
rg2 := CreateRectRgnIndirect(R2);
|
||
CombineRgn(rg2, rg1, rg2, RGN_DIFF);
|
||
if Rgn <> nil then
|
||
CombineRgn(Rgn, Rg2, Rg2, RGN_OR);
|
||
if Update <> nil then
|
||
QRegion_boundingRect(rg2, Update);
|
||
QRegion_destroy(rg2);
|
||
QRegion_destroy(rg1);
|
||
end;
|
||
end;
|
||
|
||
function SetROP2(Handle: QPainterH; Rop: Integer): Integer;
|
||
var
|
||
rop2: RasterOp;
|
||
begin
|
||
case Rop of
|
||
R2_BLACK : rop2 := RasterOp_ClearROP;
|
||
R2_WHITE : rop2 := RasterOp_SetROP;
|
||
R2_NOP : rop2 := RasterOp_NopROP;
|
||
R2_NOT : rop2 := RasterOp_NotROP;
|
||
R2_COPYPEN : rop2 := RasterOp_CopyROP;
|
||
R2_NOTCOPYPEN : rop2 := RasterOp_NotCopyROP;
|
||
R2_MERGEPENNOT: rop2 := RasterOp_OrNotROP;
|
||
R2_MASKPENNOT : rop2 := RasterOp_AndNotROP;
|
||
R2_MERGEPEN : rop2 := RasterOp_OrROP;
|
||
R2_NOTMERGEPEN: rop2 := RasterOp_NorROP;
|
||
R2_MASKPEN : rop2 := RasterOp_AndROP;
|
||
R2_NOTMASKPEN : rop2 := RasterOp_NandROP;
|
||
R2_XORPEN : rop2 := RasterOp_XorROP;
|
||
R2_NOTXORPEN : rop2 := RasterOp_NotXorROP;
|
||
R2_MASKNOTPEN : rop2 := RasterOp_NotAndROP;
|
||
R2_MERGENOTPEN: rop2 := RasterOp_NotOrROP;
|
||
else
|
||
Result := -1;
|
||
Exit;
|
||
end;
|
||
Result := GetROP2(Handle);
|
||
QPainter_setRasterOp(Handle, rop2);
|
||
end;
|
||
|
||
function GetROP2(Handle: QPainterH): Integer;
|
||
var
|
||
rop2: RasterOp;
|
||
begin
|
||
rop2 := QPainter_rasterOp(Handle);
|
||
case rop2 of
|
||
RasterOp_ClearROP : Result := R2_BLACK;
|
||
RasterOp_SetROP : Result := R2_WHITE;
|
||
RasterOp_NopROP : Result := R2_NOP;
|
||
RasterOp_NotROP : Result := R2_NOT;
|
||
RasterOp_CopyROP : Result := R2_COPYPEN;
|
||
RasterOp_NotCopyROP: Result := R2_NOTCOPYPEN;
|
||
RasterOp_OrNotROP : Result := R2_MERGEPENNOT;
|
||
RasterOp_AndNotROP : Result := R2_MASKPENNOT;
|
||
RasterOp_OrROP : Result := R2_MERGEPEN;
|
||
RasterOp_NorROP : Result := R2_NOTMERGEPEN;
|
||
RasterOp_AndROP : Result := R2_MASKPEN;
|
||
RasterOp_NandROP : Result := R2_NOTMASKPEN;
|
||
RasterOp_XorROP : Result := R2_XORPEN;
|
||
RasterOp_NotXorROP : Result := R2_NOTXORPEN;
|
||
RasterOp_NotAndROP : Result := R2_MASKNOTPEN;
|
||
RasterOp_NotOrROP : Result := R2_MERGENOTPEN;
|
||
else
|
||
Result := -1;
|
||
end;
|
||
end;
|
||
|
||
function SetForegroundWindow(Handle: QWidgetH): LongBool;
|
||
begin
|
||
try
|
||
Result := QWidget_isTopLevel(Handle);
|
||
if Result then
|
||
QWidget_raise(Handle);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function BringWindowToTop(Handle: QWidgetH): LongBool;
|
||
begin
|
||
try
|
||
while not QWidget_isTopLevel(Handle) do
|
||
Handle := QWidget_parentWidget(Handle);
|
||
Result := Handle <> nil;
|
||
if Result then
|
||
begin
|
||
QWidget_show(Handle);
|
||
QWidget_raise(Handle);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SwitchToThisWindow(Handle: QWidgetH; Restore: Boolean): LongBool;
|
||
begin
|
||
try
|
||
Result := QWidget_isTopLevel(Handle);
|
||
if Result then
|
||
begin
|
||
if Restore then
|
||
QWidget_show(Handle);
|
||
QWidget_setActiveWindow(Handle);
|
||
end;
|
||
except
|
||
Result:= True;
|
||
end;
|
||
end;
|
||
|
||
function CloseWindow(Handle: QWidgetH): LongBool;
|
||
begin
|
||
try
|
||
Result := QWidget_isTopLevel(Handle);
|
||
if Result then
|
||
QWidget_close(Handle)
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function DestroyWindow(Handle: QWidgetH): LongBool;
|
||
begin
|
||
try
|
||
Result := QWidget_isTopLevel(Handle);
|
||
if Result then
|
||
QWidget_destroy(Handle);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function WindowFromDC(Handle: QPaintDeviceH): QWidgetH;
|
||
var
|
||
WidgetList: QObjectListH;
|
||
Widget: QWidgetH;
|
||
I: integer;
|
||
begin
|
||
Result := nil;
|
||
WidgetList := QObject_queryList(Application.AppWidget, 'QWidget','*', true, true);
|
||
for I := 0 to QObjectList_count(WidgetList) - 1 do
|
||
begin
|
||
Widget := QWidgetH(QObjectList_at(WidgetList, I));
|
||
if QWidget_isVisible(Widget) and (QWidget_to_QPaintDevice(Widget) = Handle) then
|
||
begin
|
||
Result := Widget;
|
||
break;
|
||
end;
|
||
end;
|
||
QObjectList_destroy(WidgetList);
|
||
end;
|
||
|
||
function WindowFromDC(Handle: QPainterH): QWidgetH;
|
||
begin
|
||
Result := nil;
|
||
if QPainter_isActive(Handle) then
|
||
Result := WindowFromDC(QPainter_device(Handle));
|
||
end;
|
||
|
||
|
||
function ChildWindowFromPoint(hWndParent: QWidgetH; Point: TPoint): QWidgetH;
|
||
begin
|
||
try
|
||
Result := QApplication_widgetAt(@Point, True);
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
function WindowFromPoint(Point: TPoint): QWidgetH;
|
||
begin
|
||
try
|
||
Result := QApplication_widgetAt(@Point, False);
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
function FindCLXWindow(const Point: TPoint): TWidgetControl;
|
||
var
|
||
Handle: QWidgetH;
|
||
begin
|
||
Handle := WindowFromPoint(Point);
|
||
Result := nil;
|
||
while Handle <> nil do
|
||
begin
|
||
Result := FindControl(Handle);
|
||
if Result <> nil
|
||
then
|
||
Exit;
|
||
Handle := GetParent(Handle);
|
||
end;
|
||
end;
|
||
|
||
function FindVCLWindow(const Point: TPoint): TWidgetControl;
|
||
begin
|
||
Result := FindCLXWindow(Point);
|
||
end;
|
||
|
||
function GetClassName(Handle: QWidgetH; Buffer: PChar; MaxCount: Integer): Integer;
|
||
begin
|
||
Result := 0;
|
||
if Handle <> nil then
|
||
begin
|
||
Result := Length(QObject_className(Handle));
|
||
if Buffer <> nil then
|
||
StrLCopy(Buffer, QObject_className(Handle), MaxCount);
|
||
end;
|
||
end;
|
||
|
||
function IsIconic(Handle: QWidgetH): LongBool;
|
||
begin
|
||
Result := False;
|
||
if Handle = nil then
|
||
Exit;
|
||
try
|
||
Result := QWidget_isMinimized(Handle);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function ClientToScreen(Handle: QWidgetH; var Point: TPoint): LongBool;
|
||
begin
|
||
try
|
||
QWidget_mapToGlobal(Handle, @Point, @Point);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function ScreenToClient(Handle: QWidgetH; var Point: TPoint): LongBool;
|
||
begin
|
||
try
|
||
QWidget_mapFromGlobal(Handle, @Point, @Point);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SmallPointToPoint(const P: TSmallPoint): TPoint;
|
||
begin
|
||
Result := Point(P.x, P.y);
|
||
end;
|
||
|
||
function PointToSmallPoint(const P: TPoint): TSmallPoint;
|
||
begin
|
||
Result.x := SmallInt(P.X);
|
||
Result.y := SmallInt(P.Y);
|
||
end;
|
||
|
||
function MapWindowPoints(WidgetTo, WidgetFrom: QWidgetH; var Points; nr: Cardinal): Integer;
|
||
var
|
||
i: Integer;
|
||
p1: PPoint;
|
||
p2: TPoint;
|
||
begin
|
||
p1 := @Points;
|
||
try
|
||
if (IsChild(WidgetTo, WidgetFrom)) and (nr > 0) then
|
||
begin
|
||
QWidget_mapTo(WidgetFrom, p1, WidgetTo, @p2);
|
||
TSmallPoint(Result).x := p2.X - p1.X;
|
||
TSmallPoint(Result).y := p2.Y - p1.Y;
|
||
for i:= 0 to nr - 1 do
|
||
begin
|
||
QWidget_mapTo(WidgetFrom, p1, WidgetTo, p1);
|
||
Inc(p1);
|
||
end;
|
||
end
|
||
else
|
||
Result := 0;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function InvalidateRect(Handle: QWidgetH; R: PRect; EraseBackground: Boolean): LongBool;
|
||
var
|
||
Control: TWidgetControl;
|
||
begin
|
||
Result := False;
|
||
if Handle = nil then
|
||
Exit;
|
||
try
|
||
Control := FindControl(Handle);
|
||
if Control <> nil then
|
||
Control.InvalidateRect(R^, EraseBackGround);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function ValidateRect(hWnd: QWidgetH; R: PRect): LongBool;
|
||
var
|
||
Event: QPaintEventH;
|
||
begin
|
||
Event := QPaintEvent_create(R, false);
|
||
try
|
||
Result := QApplication_sendEvent(hWnd, QEventH(Event));
|
||
finally
|
||
QPaintEvent_destroy(Event);
|
||
end;
|
||
end;
|
||
|
||
function UpdateWindow(Handle: QWidgetH): LongBool;
|
||
begin
|
||
Result := False;
|
||
if Handle <> nil then
|
||
Exit;
|
||
try
|
||
QWidget_update(Handle);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function IsChild(ParentHandle, ChildHandle: QWidgetH): LongBool;
|
||
var
|
||
ParentH: QWidgetH;
|
||
begin
|
||
Result := False;
|
||
ParentH := QWidget_parentWidget(ChildHandle);
|
||
while (ParentH <> nil) and (not Result) do
|
||
begin
|
||
Result := ParentH = ParentHandle;
|
||
ParentH := QWidget_parentWidget(ParentH);
|
||
end;
|
||
end;
|
||
|
||
function MessageBox(parent: QWidgetH; Text, Caption: WideString; WinFlags: Cardinal): Integer; overload;
|
||
var
|
||
Button0, Button1, Button2: Integer;
|
||
const
|
||
ButtonOk = 1;
|
||
ButtonCancel = 2;
|
||
ButtonYes = 3;
|
||
ButtonNo = 4;
|
||
ButtonAbort = 5;
|
||
ButtonRetry = 6;
|
||
ButtonIgnore = 7;
|
||
ButtonDefault = $100;
|
||
ButtonEscape = $200;
|
||
begin
|
||
case (WinFlags and $7) of
|
||
MB_OKCANCEL:
|
||
begin
|
||
Button0 := ButtonOk;
|
||
Button1 := ButtonCancel or ButtonEscape;
|
||
Button2 := 0;
|
||
end;
|
||
MB_ABORTRETRYIGNORE:
|
||
begin
|
||
Button0 := ButtonAbort;
|
||
Button1 := ButtonRetry or ButtonDefault;
|
||
Button2 := ButtonIgnore;
|
||
end;
|
||
MB_YESNOCANCEL:
|
||
begin
|
||
Button0 := ButtonYes;
|
||
Button1 := ButtonNo;
|
||
Button2 := ButtonCancel or ButtonEscape;
|
||
end;
|
||
MB_YESNO:
|
||
begin
|
||
Button0 := ButtonYes;
|
||
Button1 := ButtonNo or ButtonEscape;
|
||
Button2 := 0;
|
||
end;
|
||
MB_RETRYCANCEL:
|
||
begin
|
||
Button0 := ButtonRetry;
|
||
Button1 := ButtonCancel or ButtonEscape;
|
||
Button2 := 0;
|
||
end;
|
||
else // MB_OK and non supported
|
||
begin
|
||
Button0 := ButtonOk or ButtonEscape;
|
||
Button1 := 0;
|
||
Button2 := 0;
|
||
end;
|
||
end;
|
||
case (WinFlags and $300) of
|
||
MB_DEFBUTTON2: Button1 := Button1 or ButtonDefault;
|
||
MB_DEFBUTTON3: Button2 := Button2 or ButtonDefault;
|
||
else
|
||
// MB_DEFBUTTON1:
|
||
Button0 := Button0 or ButtonDefault;
|
||
end;
|
||
case (WinFlags and $F0) of
|
||
MB_ICONINFORMATION:
|
||
Result := QMessageBox_information(parent, @caption, @text,
|
||
button0, button1, button2);
|
||
MB_ICONWARNING:
|
||
Result := QMessageBox_warning(parent, @caption, @text,
|
||
button0, button1, button2);
|
||
MB_ICONQUESTION:
|
||
Result := QMessageBox_information(parent, @caption, @text,
|
||
button0, button1, button2);
|
||
else
|
||
// MB_ICONSTOP:
|
||
Result := QMessageBox_critical(parent, @caption, @text,
|
||
button0, button1, button2);
|
||
end;
|
||
end;
|
||
|
||
function MessageBox(parent: QWidgetH; pText, pCaption: PChar; WinFlags: Cardinal): Integer;
|
||
var
|
||
wsText, wsCaption: WideString;
|
||
begin
|
||
wsText := pText;
|
||
wsCaption := pCaption;
|
||
Result := MessageBox(parent, wsText, wsCaption, WinFlags);
|
||
end;
|
||
|
||
function MessageBox(parent: QWidgetH; Text, Caption: String; WinFlags: Cardinal): Integer; overload;
|
||
begin
|
||
Result := MessageBox(parent, Text, Caption, WinFlags);
|
||
end;
|
||
|
||
function MessageBoxW(parent: QWidgetH; pText, pCaption: PWideChar; WinFlags: Cardinal): Integer;
|
||
var
|
||
wsText, wsCaption: WideString;
|
||
begin
|
||
wsText := pText;
|
||
wsCaption := pCaption;
|
||
Result := MessageBox(parent, wsText, wsCaption, WinFlags);
|
||
end;
|
||
|
||
function SelectObject(Handle: QPainterH; Font: QFontH): QFontH;
|
||
begin
|
||
Result := QPainter_font(Handle);
|
||
QPainter_setFont(Handle, Font);
|
||
end;
|
||
|
||
function SelectObject(Handle: QPainterH; Brush: QBrushH): QBrushH;
|
||
begin
|
||
Result := QPainter_brush(Handle);
|
||
QPainter_setBrush(Handle, Brush);
|
||
end;
|
||
|
||
function SelectObject(Handle: QPainterH; Pen: QPenH): QPenH;
|
||
begin
|
||
Result := QPainter_pen(Handle);
|
||
QPainter_setPen(Handle, Pen);
|
||
end;
|
||
|
||
function SelectObject(Handle: QPainterH; Bitmap: QPixmapH): QPixmapH;
|
||
var
|
||
P: PPainterInfo;
|
||
begin
|
||
if GetPainterInfo(Handle, P) and (P.IsCompatibleDC) then
|
||
begin
|
||
Result := QPixmapH(QPainter_device(Handle)); // IsCompatibleDC -> device is QPixmapH
|
||
if QPainter_isActive(Handle) then
|
||
QPainter_end(Handle);
|
||
|
||
QPainter_begin(Handle, Bitmap);
|
||
end
|
||
else
|
||
//Result := nil;
|
||
raise Exception.Create('SelectObject(HBITMAP) is limited to CreateCompatibleDC handles');
|
||
end;
|
||
|
||
function GetRegionType(rgn: QRegionH): Integer;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
try
|
||
if QRegion_isEmpty(rgn) then
|
||
Result := NULLREGION
|
||
else
|
||
begin
|
||
QRegion_boundingRect(rgn, @R);
|
||
if QRegion_contains(rgn, PRect(@R)) then
|
||
Result := SIMPLEREGION
|
||
else
|
||
Result := COMPLEXREGION;
|
||
end;
|
||
except
|
||
Result := RGN_ERROR;
|
||
end;
|
||
end;
|
||
|
||
function CreateEllipticRgn(Left, Top, Right, Bottom: Integer): QRegionH;
|
||
begin
|
||
Result := QRegion_create(Left, Top, Right - Left, Bottom - Top, QRegionRegionType_Ellipse);
|
||
end;
|
||
|
||
function CreateEllipticRgnIndirect(Rect: TRect): QRegionH;
|
||
begin
|
||
Result := QRegion_create(@Rect, QRegionRegionType_Ellipse);
|
||
end;
|
||
|
||
function CreateRectRgn(Left, Top, Right, Bottom: Integer): QRegionH;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
SetRect(R, Left, Top, Right, Bottom);
|
||
Result := QRegion_create(@R, QRegionRegionType_Rectangle);
|
||
end;
|
||
|
||
function CreateRectRgnIndirect(Rect: TRect): QRegionH;
|
||
begin
|
||
Result := QRegion_create(@Rect, QRegionRegionType_Rectangle);
|
||
end;
|
||
|
||
function CreateRoundRectRgn(x1, y1, x2, y2, WidthEllipse, HeightEllipse: Integer): QRegionH;
|
||
var
|
||
Bmp: QBitmapH;
|
||
Painter: QPainterH;
|
||
begin
|
||
Bmp := QBitmap_create(x2-x1+1, y2-y1+1, True, QPixmapOptimization_DefaultOptim);
|
||
Painter := QPainter_create(Bmp);
|
||
QPainter_setBrush(Painter, QPen_color(QPainter_pen(painter)));
|
||
QPainter_drawRoundRect(Painter, 0, 0, x2-x1, y2-y1, WidthEllipse, HeightEllipse);
|
||
QPainter_destroy(Painter);
|
||
Result := QRegion_create(Bmp);
|
||
QBitmap_destroy(Bmp);
|
||
QRegion_translate(Result, x1, y1);
|
||
end;
|
||
|
||
function CreatePolygonRgn(const Points; Count, FillMode: Integer): QRegionH;
|
||
var
|
||
pts: TPointArray;
|
||
i: Integer;
|
||
p: PPoint;
|
||
begin
|
||
SetLength(pts, Count);
|
||
p := PPoint(@Points);
|
||
for i := 0 to Count - 1 do
|
||
begin
|
||
pts[i].X := p.X;
|
||
pts[i].Y := p.Y;
|
||
Inc(p);
|
||
end;
|
||
Result := QRegion_create(@pts[0], Fillmode = WINDING);
|
||
end;
|
||
|
||
function SelectClipRgn(Handle: QPainterH; Region: QRegionH): Integer;
|
||
var
|
||
Clipping: Boolean;
|
||
begin
|
||
Result := RGN_ERROR;
|
||
if Handle = nil then
|
||
Exit;
|
||
try
|
||
Clipping := Region <> nil;
|
||
if Clipping then
|
||
begin
|
||
Region := CreateMappedRegion(Handle, Region);
|
||
try
|
||
QPainter_setClipRegion(Handle, Region);
|
||
Result := GetRegionType(Region);
|
||
finally
|
||
QRegion_destroy(Region);
|
||
end;
|
||
end
|
||
else
|
||
Result := NULLREGION;
|
||
QPainter_setClipping(Handle, Clipping);
|
||
except
|
||
Result := RGN_ERROR;
|
||
end;
|
||
end;
|
||
|
||
function SelectClipRgn(Handle: QPainterH; Region: Integer): Integer;
|
||
begin
|
||
Result := SelectClipRgn(Handle, QRegionH(Region));
|
||
end;
|
||
|
||
function ExcludeClipRect(Handle: QPainterH; X1, Y1, X2, Y2: Integer): Integer;
|
||
var
|
||
ExcludeRgn, Rgn: QRegionH;
|
||
begin
|
||
MapPainterLP(Handle, X1, Y1, X2, Y2);
|
||
ExcludeRgn := QRegion_create(X1, Y1, X2 - X1, Y2 - Y1, QRegionRegionType_Rectangle);
|
||
try
|
||
Rgn := QPainter_clipRegion(Handle);
|
||
QRegion_subtract(Rgn, Rgn, ExcludeRgn);
|
||
QPainter_setClipRegion(Handle, Rgn); // otherwide the new clip region is not accepter
|
||
QPainter_setClipping(Handle, True);
|
||
Result := GetRegionType(Rgn);
|
||
except
|
||
Result := RGN_ERROR;
|
||
end;
|
||
QRegion_destroy(ExcludeRgn);
|
||
end;
|
||
|
||
function ExcludeClipRect(Handle: QPainterH; const R: TRect): Integer;
|
||
begin
|
||
with R do
|
||
Result := ExcludeClipRect(Handle, Left, Top, Right, Bottom);
|
||
end;
|
||
|
||
function IntersectClipRect(Handle: QPainterH; X1, Y1, X2, Y2: Integer): Integer;
|
||
var
|
||
IntersectRgn, Rgn: QRegionH;
|
||
begin
|
||
MapPainterLP(Handle, X1, Y1, X2, Y2);
|
||
IntersectRgn := QRegion_create(X1, Y1, X2 - X1, Y2 - Y1, QRegionRegionType_Rectangle);
|
||
try
|
||
if QPainter_hasClipping(Handle) then
|
||
begin
|
||
Rgn := QPainter_clipRegion(Handle);
|
||
if QRegion_isNull(Rgn) then
|
||
QRegion_unite(Rgn, Rgn, IntersectRgn)
|
||
else
|
||
QRegion_intersect(Rgn, Rgn, IntersectRgn);
|
||
end
|
||
else
|
||
begin
|
||
QPainter_setClipRegion(Handle, InterSectRgn);
|
||
Rgn := QPainter_clipRegion(Handle);
|
||
end;
|
||
QPainter_setClipping(Handle, True);
|
||
Result := GetRegionType(Rgn);
|
||
except
|
||
Result := RGN_ERROR;
|
||
end;
|
||
QRegion_destroy(IntersectRgn);
|
||
end;
|
||
|
||
function IntersectClipRect(Handle: QPainterH; const R: TRect): Integer;
|
||
begin
|
||
with R do
|
||
Result := IntersectClipRect(Handle, Left, Top, Right, Bottom);
|
||
end;
|
||
|
||
function SetRectRgn(Rgn: QRegionH; X1, Y1, X2, Y2: Integer): LongBool;
|
||
var
|
||
rgn2: QRegionH;
|
||
R: TRect;
|
||
begin
|
||
SetRect(R, X1, Y1, X2, Y2);
|
||
rgn2 := QRegion_create(@R, QRegionRegionType_Rectangle);
|
||
try
|
||
QRegion_unite(rgn2, rgn, rgn2);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
QRegion_destroy(rgn2);
|
||
end;
|
||
|
||
function EqualRgn(Rgn1, Rgn2: QRegionH): LongBool;
|
||
var
|
||
tmpRgn: QRegionH;
|
||
begin
|
||
tmpRgn := QRegion_create;
|
||
try
|
||
Result := CombineRgn(tmpRgn, Rgn1, Rgn2, RGN_XOR) = NULLREGION
|
||
except
|
||
Result := False;
|
||
end;
|
||
QRegion_destroy(tmpRgn);
|
||
end;
|
||
|
||
function GetClipRgn(Handle: QPainterH; rgn: QRegionH): Integer;
|
||
begin
|
||
if QPainter_hasClipping(Handle)
|
||
then
|
||
begin
|
||
QRegion_unite(QPainter_clipRegion(Handle), rgn, QPainter_clipRegion(Handle));
|
||
Result := GetRegionType(rgn);
|
||
end
|
||
else
|
||
Result := NULLREGION;
|
||
end;
|
||
|
||
function CombineRgn(DestRgn, Source1, Source2: QRegionH;
|
||
Operation: TCombineMode): Integer;
|
||
begin
|
||
try
|
||
case Operation of
|
||
RGN_OR:
|
||
QRegion_unite(Source1, DestRgn, Source2);
|
||
RGN_AND:
|
||
QRegion_intersect(Source1, DestRgn, Source2);
|
||
// RGN_DIFF Subtracts Source2 from Source1
|
||
RGN_DIFF:
|
||
QRegion_subtract(Source1, DestRgn, Source2);
|
||
// RGN_XOR creates the union of two combined regions except for any
|
||
// overlapping areas.
|
||
RGN_XOR:
|
||
QRegion_eor(Source1, DestRgn, Source2);
|
||
// RGN_COPY: Creates a copy of the region identified by Source1.
|
||
RGN_COPY:
|
||
QRegion_unite(Source1, DestRgn, Source1)
|
||
else
|
||
Result := RGN_ERROR;
|
||
Exit;
|
||
end;
|
||
Result := GetRegionType(DestRgn);
|
||
except
|
||
Result := RGN_ERROR;
|
||
end;
|
||
end;
|
||
|
||
function OffsetRgn(Region: QRegionH; X, Y:Integer): Integer;
|
||
begin
|
||
QRegion_translate(Region, X, Y);
|
||
Result := GetRegionType(Region);
|
||
end;
|
||
|
||
function OffsetClipRgn(Handle: QPainterH; X, Y: Integer): Integer;
|
||
begin
|
||
try
|
||
if QPainter_hasClipping(Handle) then
|
||
begin
|
||
OffsetRgn(QPainter_clipRegion(Handle), X, Y);
|
||
Result := GetRegionType(QPainter_clipRegion(Handle));
|
||
end
|
||
else
|
||
Result := RGN_ERROR;
|
||
except
|
||
Result := RGN_ERROR;
|
||
end;
|
||
end;
|
||
|
||
function InvertRgn(Handle: QPainterH; Region: QRegionH): LongBool;
|
||
var
|
||
Rgn: QRegionH;
|
||
R: TRect;
|
||
begin
|
||
try
|
||
QPainter_window(Handle, @R);
|
||
OffsetRect(R, -R.Left, -R.Top);
|
||
rgn := QRegion_create(@R, QRegionRegionType_Rectangle);
|
||
try
|
||
QRegion_subtract(rgn, Region, Region);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
QRegion_destroy(rgn);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function FillRgn(Handle: QPainterH; Region: QRegionH; Brush: QBrushH): LongBool;
|
||
var
|
||
OldRgn: QRegionH;
|
||
R: TRect;
|
||
hasClipping: Boolean;
|
||
begin
|
||
OldRgn := nil;
|
||
Result := False;
|
||
QPainter_save(Handle);
|
||
try
|
||
hasClipping := QPainter_hasClipping(Handle);
|
||
if hasClipping then
|
||
OldRgn := QPainter_clipRegion(Handle);
|
||
if SelectClipRgn(Handle, Region) <> RGN_ERROR then
|
||
begin
|
||
QRegion_boundingRect(Region, @R);
|
||
QPainter_fillRect(Handle, @R, Brush);
|
||
if hasClipping then
|
||
SelectClipRgn(Handle, OldRgn);
|
||
Result := True;
|
||
end;
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
end;
|
||
|
||
function FrameRgn(Handle: QPainterH; Region: QRegionH; Brush: QBrushH; Width, Height: integer): LongBool;
|
||
var
|
||
R: TRect;
|
||
X, Y: integer;
|
||
Pen: QPenH;
|
||
|
||
function IsBorderPoint(X, Y: integer): Boolean;
|
||
var
|
||
I, J, K: integer;
|
||
begin
|
||
Result := False;
|
||
if PtInRegion(Region, X, Y) then
|
||
begin
|
||
K := 0;
|
||
For I := -Width to Width do
|
||
For J := -Height to Height do
|
||
begin
|
||
If not PtInRegion(Region, X + I , Y + J) then
|
||
begin
|
||
Inc(K);
|
||
if K > 1 then // 2 points required windows uses 1 point
|
||
begin
|
||
Result := True;
|
||
exit;
|
||
end;
|
||
end;
|
||
end
|
||
end;
|
||
end;
|
||
begin
|
||
// Result := false;
|
||
QPainter_save(Handle);
|
||
try
|
||
QRegion_boundingRect(Region, @R);
|
||
Pen := QPen_create(QBrush_color(Brush), 1, PenStyle_SolidLine);
|
||
try
|
||
QPainter_setPen(Handle, Pen);
|
||
finally
|
||
QPen_destroy(Pen);
|
||
end;
|
||
for X := R.Left to R.Right do
|
||
for Y := R.Top to R.Bottom do
|
||
if IsBorderPoint(X, Y) then
|
||
QPainter_drawPoint(Handle, X, Y);
|
||
Result := True;
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
end;
|
||
|
||
function DeleteObject(Region: QRegionH): LongBool;
|
||
begin
|
||
try
|
||
// if not TStockObjectList.ReleaseStockObject(Region) then
|
||
QRegion_destroy(Region);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function PtInRegion(Rgn: QRegionH; X, Y: Integer): Boolean;
|
||
var
|
||
P :TPoint;
|
||
begin
|
||
P.X := X;
|
||
P.Y := Y;
|
||
Result := QRegion_contains(Rgn, PPoint(@P));
|
||
end;
|
||
|
||
function RectInRegion(Rgn: QRegionH; const Rect: TRect): LongBool;
|
||
begin
|
||
try
|
||
Result := QRegion_contains(Rgn, PRect(@Rect));
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SetWindowRgn(Handle: QWidgetH; Region: QRegionH; Redraw: LongBool): Integer;
|
||
begin
|
||
Result := 0;
|
||
if Handle <> nil then
|
||
try
|
||
if Region <> nil then
|
||
begin
|
||
QWidget_setMask(Handle, Region);
|
||
DeleteObject(Region); // Windows owns the window region
|
||
end
|
||
else
|
||
QWidget_clearMask(Handle);
|
||
if Redraw then
|
||
UpdateWindow(Handle);
|
||
Result := 1;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function GetWindowRgn(Handle: QWidgetH; Region: QRegionH): Integer;
|
||
begin
|
||
if (Region <> nil) and (Handle <> nil) then
|
||
begin
|
||
try
|
||
// there is no QWidget_mask() function
|
||
// asn: note region without windows/X11 decoration
|
||
QWidget_childrenRegion(Handle, Region);
|
||
Result := GetRegionType(Region);
|
||
except
|
||
Result := ERROR;
|
||
end;
|
||
end
|
||
else
|
||
Result := ERROR;
|
||
end;
|
||
|
||
function LPtoDP(Handle: QPainterH; var Points; Count: Integer): LongBool;
|
||
var
|
||
P: PPoint;
|
||
begin
|
||
Result := True;
|
||
try
|
||
P := @Points;
|
||
while Count > 0 do
|
||
begin
|
||
Dec(Count);
|
||
QPainter_xForm(Handle, P, P);
|
||
Inc(P);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function DPtoLP(Handle: QPainterH; var Points; Count: Integer): LongBool;
|
||
var
|
||
P: PPoint;
|
||
begin
|
||
Result := True;
|
||
try
|
||
P := @Points;
|
||
while Count > 0 do
|
||
begin
|
||
Dec(Count);
|
||
QPainter_xFormDev(Handle, P, P);
|
||
Inc(P);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SetViewPortOrgEx(Handle: QPainterH; X, Y: Integer; OldOrg: PPoint): LongBool;
|
||
var
|
||
R :TRect;
|
||
begin
|
||
try
|
||
QPainter_viewport(Handle, @R);
|
||
if OldOrg <> nil then
|
||
begin
|
||
OldOrg.X := R.Left;
|
||
OldOrg.Y := R.Top;
|
||
end;
|
||
QPainter_setViewport(Handle, X, Y, R.Right - R.Left, R.Bottom - R.Top);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SetViewportExtEx(Handle: QPainterH; XExt, YExt: Integer; Size: PSize): LongBool;
|
||
var
|
||
R :TRect;
|
||
begin
|
||
Result := True;
|
||
try
|
||
QPainter_viewport(Handle, @R);
|
||
if size <> nil then
|
||
begin
|
||
Size.cx := R.Right - R.Left;
|
||
Size.cy := R.Bottom - R.Top;
|
||
end;
|
||
QPainter_setViewport(Handle, R.Left, R.Top, XExt, YExt);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetViewportExtEx(Handle: QPainterH; Size: PSize): LongBool;
|
||
var
|
||
R :TRect;
|
||
begin
|
||
Result := True;
|
||
try
|
||
QPainter_viewport(Handle, @R);
|
||
Size.cx := R.Right - R.Left;
|
||
Size.cy := R.Bottom - R.Top;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetWindowOrgEx(Handle: QPainterH; Org: PPoint): LongBool;
|
||
var
|
||
R :TRect;
|
||
begin
|
||
try
|
||
QPainter_window(Handle, @R);
|
||
Org.X := R.Left;
|
||
Org.Y := R.Top;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetWindowOrgEx(Handle: QPainterH; var Org: TPoint): LongBool;
|
||
begin
|
||
Result := GetWindowOrgEx(Handle, @Org);
|
||
end;
|
||
|
||
function SetWindowOrgEx(Handle: QPainterH; X, Y: Integer; OldOrg: PPoint): LongBool;
|
||
var
|
||
R :TRect;
|
||
begin
|
||
try
|
||
QPainter_window(Handle, @R);
|
||
with R do
|
||
begin
|
||
if OldOrg <> nil then
|
||
begin
|
||
OldOrg.X := Left;
|
||
OldOrg.Y := Top;
|
||
end;
|
||
QPainter_setWindow(Handle, X, Y, Right - Left, Bottom - Top);
|
||
end;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
procedure CopyMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
|
||
begin
|
||
Move(Src^, Dest^, Len);
|
||
end;
|
||
|
||
procedure FillMemory(Dest: Pointer; Len: Cardinal; Fill: Byte);
|
||
begin
|
||
FillChar(Dest^, Len, Fill);
|
||
end;
|
||
|
||
procedure MoveMemory(Dest: Pointer; Src: Pointer; Len: Cardinal);
|
||
begin
|
||
Move(Src^, Dest^, Len);
|
||
end;
|
||
|
||
procedure ZeroMemory(Dest: Pointer; Len: Cardinal);
|
||
begin
|
||
FillChar(Dest^, Len, 0);
|
||
end;
|
||
|
||
function GetDoubleClickTime: Cardinal;
|
||
begin
|
||
Result := QApplication_doubleClickInterval;
|
||
end;
|
||
|
||
function SetDoubleClickTime(Interval: Cardinal): LongBool;
|
||
begin
|
||
try
|
||
QApplication_setDoubleClickInterval(Interval);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function ReleaseCapture: LongBool;
|
||
var
|
||
Handle: QWidgetH;
|
||
begin
|
||
Handle := QWidget_mouseGrabber;
|
||
if Handle <> nil then
|
||
begin
|
||
QWidget_releaseMouse(Handle);
|
||
SetMouseGrabControl(nil); // inform CLX
|
||
Result := True;
|
||
end
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
function SetCapture(Widget: QWidgetH): QWidgetH;
|
||
begin
|
||
Result := QWidget_mouseGrabber;
|
||
ReleaseCapture;
|
||
if Widget <> nil then
|
||
QWidget_grabMouse(Widget);
|
||
end;
|
||
|
||
function GetCapture: QWidgetH;
|
||
begin
|
||
Result := QWidget_mouseGrabber;
|
||
end;
|
||
|
||
function SetCursor(Handle: QCursorH; Save: Boolean): QCursorH;
|
||
begin
|
||
Result := QApplication_overrideCursor;
|
||
if Handle <> nil then
|
||
QApplication_setOverrideCursor(Handle, Save)
|
||
else
|
||
QApplication_restoreOverrideCursor;
|
||
end;
|
||
|
||
// limited implementation of
|
||
function GetSystemMetrics(PropItem: TSysMetrics): Integer;
|
||
var
|
||
size: TSize;
|
||
begin
|
||
case PropItem of
|
||
SM_CXVSCROLL, SM_CXHSCROLL:
|
||
begin
|
||
QStyle_scrollBarExtent(QApplication_Style, @size);
|
||
Result := size.cx;
|
||
end;
|
||
SM_CYVSCROLL, SM_CYHSCROLL:
|
||
begin
|
||
QStyle_scrollBarExtent(QApplication_Style, @size);
|
||
Result := size.cy;
|
||
end;
|
||
SM_CXSMICON, SM_CYSMICON:
|
||
Result := 16;
|
||
SM_CXICON, SM_CYICON:
|
||
Result := 32;
|
||
SM_CXSCREEN:
|
||
Result := QWidget_width(QApplication_desktop);
|
||
SM_CYSCREEN:
|
||
Result := QWidget_height(QApplication_desktop);
|
||
SM_CXBORDER, SM_CYBORDER:
|
||
Result := 1;
|
||
// (ahuser) Windows returns "1"
|
||
//QStyle_DefaultFrameWidth(QApplication_style); // (probably) wrong ?
|
||
SM_CXFRAME, SM_CYFRAME, SM_CXDLGFRAME, SM_CYDLGFRAME:
|
||
Result := QStyle_DefaultFrameWidth(QApplication_style); // or this one
|
||
SM_CYCAPTION:
|
||
Result := 19;
|
||
else
|
||
raise Exception.Create('GetSystemMetrics: unsupported property')
|
||
end;
|
||
end;
|
||
|
||
{ limited implementation of}
|
||
|
||
function GetDeviceCaps(Handle: QPainterH; devcap: TDeviceCap): Integer;
|
||
begin
|
||
Result := GetDeviceCaps(QPainter_device(Handle), devcap);
|
||
end;
|
||
|
||
function GetDeviceCaps(Handle: QPaintDeviceH; devcap: TDeviceCap): Integer;
|
||
var
|
||
pdm: QPaintDeviceMetricsH;
|
||
begin
|
||
Result := 0;
|
||
pdm := QPaintDeviceMetrics_create(Handle);
|
||
if pdm <> nil then
|
||
begin
|
||
try
|
||
case devcap of
|
||
HORZSIZE:
|
||
Result := QPaintDeviceMetrics_widthMM(pdm);
|
||
VERTSIZE:
|
||
Result := QPaintDeviceMetrics_heightMM(pdm);
|
||
PHYSICALWIDTH, HORZRES:
|
||
Result := QPaintDeviceMetrics_width(pdm); // Horizontal width in pixels
|
||
BITSPIXEL:
|
||
Result := QPaintDeviceMetrics_Depth(pdm); // Number of bits per pixel
|
||
PLANES:
|
||
Result := 1;
|
||
NUMCOLORS:
|
||
Result := QPaintDeviceMetrics_numColors(pdm);
|
||
LOGPIXELSX:
|
||
Result := QPaintDeviceMetrics_logicalDpiX(pdm); // Logical pixelsinch in X
|
||
LOGPIXELSY:
|
||
Result := QPaintDeviceMetrics_logicalDpiY(pdm); // Logical pixelsinch in Y
|
||
PHYSICALOFFSETX:
|
||
Result := 0;
|
||
PHYSICALOFFSETY:
|
||
Result := 0;
|
||
PHYSICALHEIGHT, VERTRES:
|
||
Result := QPaintDeviceMetrics_height(pdm); // Vertical height in pixels
|
||
else
|
||
raise Exception.Create('QWindows.GetDeviceCaps: unsupported capability');
|
||
end;
|
||
finally
|
||
QPaintDeviceMetrics_destroy(pdm);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function pfDevice: TPixelFormat;
|
||
var
|
||
DC: QPaintDeviceH;
|
||
begin
|
||
DC := QWidget_to_QPaintDevice(QApplication_desktop);
|
||
case GetDeviceCaps(DC, BITSPIXEL) of
|
||
1: Result := pf1bit;
|
||
8: Result := pf8bit;
|
||
16: Result := pf16bit;
|
||
24: Result := pf24bit;
|
||
32: Result := pf32bit;
|
||
else
|
||
Result := pfCustom;
|
||
end;
|
||
end;
|
||
|
||
{ a very limited implementation of }
|
||
function GetTextMetrics(Handle: QPainterH; var tt: TTextMetric): Integer;
|
||
var
|
||
fm: QFontMetricsH;
|
||
fi: QFontInfoH;
|
||
begin
|
||
FillChar(tt, SizeOf(tt), 0);
|
||
with tt do
|
||
begin
|
||
fm := QFontMetrics_create(QPainter_font(Handle));
|
||
try
|
||
tmHeight := QFontMetrics_height(fm);
|
||
tmAscent := QFontMetrics_ascent(fm);
|
||
tmDescent := QFontMetrics_descent(fm);
|
||
tmAveCharWidth := QFontMetrics_width(fm, 'x');
|
||
tmMaxCharWidth := QFontMetrics_maxWidth(fm);
|
||
//tmInternalLeading := 0;
|
||
tmExternalLeading := QFontMetrics_leading(fm);
|
||
//tmOverhang := 0;
|
||
finally
|
||
QFontMetrics_destroy(fm);
|
||
end;
|
||
|
||
fi := QFontInfo_create(QPainter_font(Handle));
|
||
try
|
||
QPainter_fontInfo(Handle, fi);
|
||
case QFontInfo_weight(fi) of
|
||
25: // Light
|
||
tmWeight := 300;
|
||
50: // Normal:
|
||
tmWeight := 400;
|
||
63: // DemiBold
|
||
tmWeight := 600;
|
||
75: // Bold
|
||
tmWeight := 700;
|
||
87: // Black
|
||
tmWeight := 900;
|
||
else
|
||
tmWeight := Round(QFontInfo_weight(fi) * 9.5);
|
||
end;
|
||
|
||
tmItalic := Ord(QFontInfo_italic(fi));
|
||
tmUnderlined := Ord(QFontInfo_underline(fi));
|
||
tmStruckOut := Ord(QFontInfo_strikeOut(fi));
|
||
if QFontInfo_fixedPitch(fi) then
|
||
tmPitchAndFamily := FIXED_PITCH
|
||
else
|
||
tmPitchAndFamily := VARIABLE_PITCH;
|
||
tmCharSet := DEFAULT_CHARSET;
|
||
finally
|
||
QFontInfo_destroy(fi);
|
||
end;
|
||
end;
|
||
Result := 0;
|
||
end;
|
||
|
||
function ColorToRGB(Color: TColor; Instance: TWidgetControl = nil): TColor;
|
||
var
|
||
FColor: QColorH;
|
||
FColorGroup: QPaletteColorGroup;
|
||
|
||
FColorRole: QColorGroupColorRole;
|
||
FPalette: QPaletteH;
|
||
|
||
function GetPaletteHandle(Widget: TWidgetControl): QPaletteH;
|
||
begin
|
||
if Widget = nil then
|
||
Result := Application.Palette.Handle
|
||
else
|
||
begin
|
||
Result := THackedWidgetControl(Widget).Palette.Handle;
|
||
while (Result = nil) and (Widget.Parent <> nil) do
|
||
begin
|
||
Widget := Widget.Parent;
|
||
Result := THackedWidgetControl(Widget).Palette.Handle;
|
||
end;
|
||
if Result = nil then
|
||
Result := Application.Palette.Handle;
|
||
end;
|
||
end;
|
||
|
||
begin
|
||
case Color of
|
||
clColorTo..clForeground:
|
||
begin
|
||
if assigned(Instance) then
|
||
if not Instance.Enabled then
|
||
FColorGroup := QPaletteColorGroup_Disabled
|
||
else
|
||
if Instance.Focused then
|
||
FColorGroup := QPaletteColorGroup_Active
|
||
else
|
||
FColorGroup := QPaletteColorGroup_InActive
|
||
else
|
||
FColorGroup := QPaletteColorGroup_InActive ;
|
||
end;
|
||
clActiveColorTo..clActiveForeground,
|
||
clNormalColorTo..clNormalForeground,
|
||
clDisabledColorTo..clDisabledForeground:
|
||
FColorGroup := ColorGroup(Color);
|
||
else
|
||
Result := Color;
|
||
Exit;
|
||
end;
|
||
FColorRole := ColorRole(Color); {1..15}
|
||
FPalette := GetPaletteHandle(Instance);
|
||
FColor := QPalette_color(FPalette, FColorGroup, FColorRole);
|
||
Result := QColorColor(FColor);
|
||
// QColor_destroy(FColor); {not owned}
|
||
end;
|
||
|
||
|
||
function RGB(Red, Green, Blue: Integer): TColorRef;
|
||
begin
|
||
Result := (Blue shl 16) or (Green shl 8) or Red;
|
||
end;
|
||
|
||
function GetBValue(Col: TColorRef): Byte;
|
||
begin
|
||
Result := Byte((Col shr 16) and $FF);
|
||
end;
|
||
|
||
function GetGValue(Col: TColorRef): Byte;
|
||
begin
|
||
Result := Byte((Col shr 8) and $FF);
|
||
end;
|
||
|
||
function GetRValue(Col: TColorRef): Byte;
|
||
begin
|
||
Result := Byte(Col and $FF);
|
||
end;
|
||
|
||
function SetRect(var R: TRect; Left, Top, Right, Bottom: Integer): LongBool;
|
||
begin
|
||
R := Rect(Left, Top, Right, Bottom);
|
||
Result := True;
|
||
end;
|
||
|
||
function CopyRect(var Dst: TRect; const Src: TRect): LongBool;
|
||
begin
|
||
Dst := Src;
|
||
Result := True;
|
||
end;
|
||
|
||
function UnionRect(var Dst: TRect; R1, R2: TRect): LongBool;
|
||
begin
|
||
Result := True;
|
||
if IsRectEmpty(R1) then
|
||
begin
|
||
if IsRectEmpty(R2) then
|
||
Result := False // both empty
|
||
else
|
||
begin
|
||
Dst := R2;
|
||
Result := True;
|
||
end;
|
||
end
|
||
else if IsRectEmpty(R2) then
|
||
Dst := R1
|
||
else
|
||
with Dst do
|
||
begin
|
||
Left := Min(R1.Left, R2.Left);
|
||
Top := Min(R1.Top, R2.Top);
|
||
Right := Max(R1.Right, R2.Right);
|
||
Bottom := Max(R1.Bottom, R2.Bottom);
|
||
end;
|
||
end;
|
||
|
||
function IsRectEmpty(R: TRect): LongBool;
|
||
begin
|
||
with R do
|
||
Result := (Right <= Left) or (Bottom <= Top);
|
||
end;
|
||
|
||
function EqualRect(R1, R2: TRect): LongBool;
|
||
begin
|
||
Result := (R1.Left = R2.Left) and (R1.Right = R2.Right) and
|
||
(R1.Top = R2.Top) and (R1.Bottom = R2.Bottom)
|
||
end;
|
||
|
||
function EqualPoints(const P1: TPoint; const P2: TPoint): Boolean;
|
||
begin
|
||
Result := (P1.X = P2.X) and (P1.Y = P2.Y);
|
||
end;
|
||
|
||
function CenterRect(InnerRect, OuterRect: TRect): TRect;
|
||
var
|
||
w,h : Integer;
|
||
begin
|
||
w := InnerRect.Right - InnerRect.Left;
|
||
h := InnerRect.Bottom - InnerRect.Top;
|
||
Result.Left := (OuterRect.Right + OuterRect.Left - w)div 2;
|
||
Result.Top := (OuterRect.Bottom + OuterRect.Top - h)div 2;
|
||
Result := Bounds( Result.Left, Result.Top, w, h );
|
||
end;
|
||
|
||
function SubtractRect(var dR: TRect; const R1, R2: TRect): LongBool;
|
||
var
|
||
R3: TRect;
|
||
begin
|
||
try
|
||
dR := R1;
|
||
if IntersectRect(R3, R1, R2) then
|
||
begin
|
||
if EqualPoints(R3.BottomRight, R1.BottomRight) then
|
||
begin
|
||
if R3.Top = R1.Top
|
||
then
|
||
dR.Right := R3.Left
|
||
else if R3.Left = R1.Left
|
||
then
|
||
dR.Bottom := R3.Top
|
||
end
|
||
else
|
||
if EqualPoints(R3.TopLeft, R1.TopLeft) then
|
||
begin
|
||
if R3.Bottom = R1.Bottom
|
||
then
|
||
dR.Left := R3.Right
|
||
else if R3.Right = R1.Right
|
||
then
|
||
dR.Bottom := R3.Top;
|
||
end;
|
||
end;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function IntersectRect(var R: TRect; const R1, R2: TRect): LongBool;
|
||
begin
|
||
Result := Types.IntersectRect(R, R1, R2);
|
||
end;
|
||
|
||
function PtInRect(const R: TRect; X, Y: integer): LongBool;
|
||
begin
|
||
with R do
|
||
Result := (X >= Left) and (X <= Right) and
|
||
(Y >= Top) and (Y <= Bottom);
|
||
end;
|
||
|
||
function PtInRect(const R: TRect; pt: TPoint): LongBool;
|
||
begin
|
||
Result := PtInRect(R, pt.X, Pt.Y);
|
||
end;
|
||
|
||
function PtInEllipse(const R: TRect; pt: TPoint): LongBool;
|
||
begin
|
||
Result := PointInEllipse(pt, R);
|
||
end;
|
||
|
||
function PointInEllipse(pt: TPoint; BoundingRect: TRect): boolean;
|
||
var
|
||
p, q, r, s: integer;
|
||
begin
|
||
with BoundingRect do
|
||
begin
|
||
p := 2 * pt.X - (Left + Right);
|
||
p := p * p;
|
||
q := 2 * pt.Y - (Top + Bottom);
|
||
q := q * q;
|
||
r := Right - Left;
|
||
r := r * r;
|
||
s := Bottom - Top;
|
||
s := s * s;
|
||
Result := p * s + q * r <= s * r ;
|
||
end;
|
||
end;
|
||
|
||
procedure TextOutAngle(Handle: QPainterH; Angle, Left, Top: Integer; Text: WideString);
|
||
{ deprecated use DrawText instead }
|
||
begin
|
||
try
|
||
QPainter_save(Handle);
|
||
QPainter_translate(Handle, Left, Top);
|
||
QPainter_rotate(Handle, -Angle);
|
||
QPainter_drawText(Handle, 0, 0, @Text, -1);
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
end;
|
||
|
||
procedure RequiredState(ACanvas: TCanvas; State: TCanvasState);
|
||
begin
|
||
THackCanvas(Acanvas).RequiredState(State);
|
||
end;
|
||
|
||
procedure TextOutAngle(ACanvas: TCanvas; Angle, Left, Top: Integer; Text: WideString);
|
||
{ deprecated use DrawText instead }
|
||
begin
|
||
ACanvas.Start;
|
||
RequiredState(ACanvas, [csHandleValid, csFontValid, csBrushValid]);
|
||
TextOutAngle(ACanvas.Handle, Angle, Left, Top, Text);
|
||
ACanvas.Stop;
|
||
end;
|
||
|
||
function TextWidth(Handle: QPainterH; Caption: WideString;
|
||
QtFlags: Integer = 0): Integer;
|
||
var
|
||
R :TRect;
|
||
begin
|
||
QPainter_boundingRect(Handle, @R, @R, QtFlags, PWideString(@Caption), -1, nil);
|
||
Result := R.Right - R.Left;
|
||
end;
|
||
|
||
function TextHeight(Handle: QPainterH; Caption: WideString; R: TRect;
|
||
QtFlags: Integer = 0): Integer;
|
||
var
|
||
R1, R2: TRect;
|
||
begin
|
||
R1 := R;
|
||
R1.Bottom := MaxInt;
|
||
QPainter_boundingRect(Handle, @R1, @R2, QtFlags, PWideString(@Caption), -1, nil);
|
||
Result := R2.Bottom - R2.Top;
|
||
end;
|
||
|
||
function GetTextExtentPoint32(Handle: QPainterH; const Text: WideString; Len: Integer;
|
||
var Size: TSize): LongBool;
|
||
var
|
||
R: TRect;
|
||
begin
|
||
try
|
||
QPainter_boundingRect(Handle, @R, @R, 0, @Text, Len, nil);
|
||
with R do
|
||
begin
|
||
Size.cx := Right - Left;
|
||
Size.cy := Bottom - Top;
|
||
end;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetTextExtentPoint32(Handle: QPainterH; pText: PChar; Len: Integer;
|
||
var Size: TSize): LongBool;
|
||
var
|
||
Text: WideString;
|
||
begin
|
||
Text := pText;
|
||
Result := GetTextExtentPoint32(Handle, Text, Len, Size);
|
||
end;
|
||
|
||
function GetTextExtentPoint32(Canvas: TCanvas; const Text: WideString; Len: Integer;
|
||
var Size: TSize): LongBool;
|
||
begin
|
||
Canvas.Start;
|
||
RequiredState(Canvas, [csHandleValid, csFontValid, csBrushValid]);
|
||
Result := GetTextExtentPoint32W(Canvas.Handle, PWideChar(Text), Len, Size);
|
||
Canvas.Stop;
|
||
end;
|
||
|
||
function GetTextExtentPoint32W(Handle: QPainterH; pText: PWideChar; Len: Integer;
|
||
var Size :TSize): LongBool;
|
||
var
|
||
Text: WideString;
|
||
begin
|
||
Text := pText;
|
||
Result := GetTextExtentPoint32(Handle, Text, Len, Size);
|
||
end;
|
||
|
||
function TextExtent(Handle: QPainterH; const Caption: WideString; R: TRect;
|
||
QtFlags: Integer): TRect;
|
||
var
|
||
R2: TRect;
|
||
begin
|
||
R2 := R;
|
||
R2.Bottom := MaxInt;
|
||
QPainter_boundingRect(Handle, @R2, @Result, QtFlags, PWideString(@Caption), -1, nil);
|
||
|
||
// QPainter_boundingRect(Handle, @Result, @Result, Flags, PWideString(@Caption), -1, nil);
|
||
end;
|
||
|
||
const
|
||
Ellipses = '...';
|
||
|
||
function NameEllipsis(const Name: WideString; Handle: QPainterH;
|
||
MaxLen: Integer; QtFlags: integer = 0): WideString;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
if TextWidth(Handle, Name, QtFlags) > MaxLen then
|
||
begin
|
||
Result := Ellipses;
|
||
I := 0;
|
||
while TextWidth(Handle, Result, QtFlags) <= MaxLen do
|
||
begin
|
||
Inc(I);
|
||
Result := LeftStr(Name, I) + Ellipses;
|
||
end;
|
||
if I <> 0 then
|
||
Result := LeftStr(Name, I-1) + Ellipses;
|
||
end
|
||
else
|
||
Result := name;
|
||
end;
|
||
|
||
function WordEllipsis(Words: WideString; Handle: QPainterH; const R: TRect;
|
||
QtFlags: Integer = 0): WideString;
|
||
var
|
||
R2, R1: TRect;
|
||
ShortedText: WideString;
|
||
I: Integer;
|
||
|
||
function RectInsideRect(const R1, R2: TRect): Boolean;
|
||
begin
|
||
with R1 do
|
||
Result := (Left >= R2.Left) and (Right <= R2.Right) and
|
||
(Top >= R2.Top) and (Bottom <= R2.Bottom);
|
||
end;
|
||
|
||
begin
|
||
Result := ShortedText;
|
||
R1 := R;
|
||
R1.Bottom := MaxInt;
|
||
QPainter_boundingRect(Handle, @R1, @R2, QtFlags, PWideString(@Result), -1, nil);
|
||
if not RectInsideRect(R2, R) then
|
||
begin
|
||
I := 1;
|
||
ShortedText := '';
|
||
while RectInsideRect(R2, R) and (I <= Length(Words)) do
|
||
begin
|
||
repeat // one more word
|
||
ShortedText := LeftStr(Words, I);
|
||
if Words[I] = ' ' then
|
||
Break;
|
||
Inc(I);
|
||
until I > Length(Words);
|
||
Result := ShortedText + '...';
|
||
QPainter_boundingRect(Handle, @R1, @R2, QtFlags, PWideString(@Result), -1, nil);
|
||
end;
|
||
While not RectInsideRect(R2, R) and (I > 0) do
|
||
begin
|
||
repeat // one word less
|
||
Dec(I);
|
||
ShortedText := LeftStr(Words, I);
|
||
if ShortedText[I] = ' ' then
|
||
Break;
|
||
until I <= 1;
|
||
Result := ShortedText + Ellipses;
|
||
QPainter_boundingRect(Handle, @R1, @R2, QtFlags, PWideString(@Result), -1, nil);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function FileEllipsis(const FilePath: AnsiString; Handle: QPainterH; MaxLen: Integer): string;
|
||
var
|
||
Paths: TStrings;
|
||
k, i, Start: Integer;
|
||
CurPath, F: AnsiString;
|
||
begin
|
||
if TextWidth(Handle, FilePath, SingleLine) <= MaxLen then
|
||
Result := FilePath
|
||
else
|
||
begin // FilePath too long
|
||
F := FilePath;
|
||
{$IFDEF LINUX}
|
||
CurPath := IncludeTrailingPathDelimiter(GetEnvironmentVariable('HOME'));
|
||
if AnsiStartsStr(CurPath, FilePath) then
|
||
begin
|
||
F := '~/' + AnsiRightStr(FilePath, Length(FilePath) - Length(CurPath));
|
||
if TextWidth(Handle, F, SingleLine) <= MaxLen then
|
||
begin
|
||
Result := F;
|
||
Exit;
|
||
end
|
||
end;
|
||
{$ENDIF LINUX}
|
||
Paths := TStringList.Create;
|
||
try
|
||
Paths.Delimiter := PathDelim;
|
||
Paths.DelimitedText := F; // splits the filepath
|
||
if Paths[0] = '' then
|
||
Start := 1 // absolute path
|
||
else
|
||
Start := 0; // relative path
|
||
for k := Start to Paths.Count - 2 do
|
||
begin
|
||
CurPath := Paths[k];
|
||
if Length(CurPath) > 2 then // this excludes '~' '..'
|
||
begin
|
||
Paths[k] := CurPath; // replace with ellipses
|
||
I := Length(CurPath);
|
||
while (I > 0) and (TextWidth(Handle, Paths.DelimitedText, SingleLine) > MaxLen) do
|
||
begin
|
||
Dec(I);
|
||
Paths[k] := LeftStr(CurPath, I) + Ellipses;// remove a character
|
||
end;
|
||
if TextWidth(Handle, Paths.DelimitedText, SingleLine) <= MaxLen then
|
||
begin
|
||
Result := Paths.DelimitedText;
|
||
Exit;
|
||
end;
|
||
end
|
||
end;
|
||
// not succeeded.
|
||
// replace /.../.../.../<filename> with .../<filename>
|
||
// before starting to minimize filename
|
||
for k := Paths.Count - 2 downto 1 do
|
||
Paths.Delete(k);
|
||
Paths[0] := Ellipses;
|
||
if TextWidth(Handle, Paths.DelimitedText, SingleLine) > MaxLen then
|
||
begin
|
||
CurPath := Paths[1];
|
||
Paths[1] := Ellipses; // replace with ellipses
|
||
//I := 1;
|
||
//Paths[1] := CurPath; // replace with ellipses
|
||
I:= Length(CurPath);
|
||
while (I > 0) and (TextWidth(Handle, Paths.DelimitedText, SingleLine) > MaxLen) do
|
||
begin
|
||
Dec(I);
|
||
Paths[I] := LeftStr(CurPath, I) + Ellipses;// remove a character
|
||
end;
|
||
end;
|
||
Result := Paths.DelimitedText; // will be something .../Progr...
|
||
finally
|
||
Paths.Free;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TruncatePath(const FilePath: string; Canvas: TCanvas; MaxLen: Integer): string;
|
||
begin
|
||
Canvas.Start;
|
||
try
|
||
Result := FileEllipsis(FilePath, Canvas.Handle, MaxLen);
|
||
finally
|
||
Canvas.Stop;
|
||
end;
|
||
end;
|
||
|
||
function TruncateName(const Name: WideString; Canvas: TCanvas; MaxLen: Integer; QtFlags: integer = 0): WideString;
|
||
begin
|
||
Canvas.Start;
|
||
try
|
||
Result := NameEllipsis(Name, Canvas.Handle, MaxLen, QtFlags);
|
||
finally
|
||
Canvas.Stop;
|
||
end;
|
||
end;
|
||
|
||
function DrawText2(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
var R: TRect; WinFlags: Integer): Integer;
|
||
var
|
||
Flags: Integer;
|
||
R2: TRect; // bliep bliep bl...
|
||
Caption: WideString;
|
||
FontSaved, FontSet: QFontH;
|
||
|
||
function HidePrefix(const Text: WideString): WideString;
|
||
var
|
||
i, Len: Integer;
|
||
begin
|
||
Result := Text;
|
||
Len := Length(Result);
|
||
i := 1;
|
||
while i <= Len do
|
||
begin
|
||
if (Result[i] = '&') then
|
||
begin
|
||
Delete(Result, i, 1);
|
||
Dec(Len);
|
||
if (Result[i] = '&') and (Result[i + 1] = '&') then
|
||
begin
|
||
Delete(Result, i, 1);
|
||
Dec(Len);
|
||
end;
|
||
end;
|
||
Inc(i);
|
||
end;
|
||
end;
|
||
|
||
function OnlyPrefix(const Text: WideString): WideString;
|
||
var
|
||
i, Len: Integer;
|
||
begin
|
||
Result := Text;
|
||
Len := Length(Result);
|
||
i := 1;
|
||
while i <= Len do
|
||
begin
|
||
if (Result[i] = '&') then
|
||
begin
|
||
Delete(Result, i, 1);
|
||
Dec(Len);
|
||
if (Result[i] = '&') and (Result[i + 1] = '&') then
|
||
begin
|
||
Delete(Result, i, 1);
|
||
Dec(Len);
|
||
end;
|
||
Result[i] := '&';
|
||
end
|
||
else
|
||
Result[i] := ' ';
|
||
Inc(i);
|
||
end;
|
||
end;
|
||
|
||
function CheckTabStop(WinFlags: Integer): Integer;
|
||
var
|
||
Size: Integer;
|
||
begin
|
||
if WinFlags and DT_TABSTOP <> 0 then
|
||
begin
|
||
Size := WinFlags and $FF00;
|
||
WinFlags := WinFlags - Size;
|
||
Size := (Size shr 8) and $FF;
|
||
QPainter_setTabStops(Handle, Size);
|
||
end;
|
||
Result := WinFlags;
|
||
end;
|
||
|
||
begin
|
||
FontSaved := nil;
|
||
FontSet := nil;
|
||
if len > 0 then
|
||
Caption := LeftStr(Text, len)
|
||
else
|
||
Caption := Text;
|
||
if WinFlags and DT_INTERNAL <> 0 then
|
||
begin
|
||
FontSaved := QPainter_Font(Handle);
|
||
QApplication_font(FontSet, nil);
|
||
QPainter_setFont(Handle, FontSet);
|
||
end;
|
||
Flags := Win2QtAlign(CheckTabStop(WinFlags));
|
||
if WinFlags and DT_PREFIXONLY <> 0 then
|
||
begin
|
||
Flags := Flags or ShowPrefix;
|
||
Caption := OnlyPrefix(Caption);
|
||
end
|
||
else if WinFlags and DT_HIDEPREFIX <> 0 then
|
||
begin
|
||
Flags := Flags and not ShowPrefix;
|
||
Caption := HidePrefix(Caption);
|
||
end;
|
||
if WinFlags and DT_CALCRECT = 0 then
|
||
begin
|
||
if Flags and ClipName <> 0 then
|
||
Caption := NameEllipsis(Caption, Handle, R.Right - R.Left, Flags)
|
||
else if Flags and ClipPath <> 0 then
|
||
Caption := FileEllipsis(Caption, Handle, R.Right - R.Left)
|
||
else if Flags and ClipToWord <> 0 then
|
||
Caption := WordEllipsis(Caption, Handle, R, Flags);
|
||
QPainter_save(Handle);
|
||
if Flags and DontClip = 0 then // clipping
|
||
IntersectClipRect(Handle, R); // QPainter::drawText() does not clip left/top border
|
||
QPainter_DrawText(Handle, @R, Flags, PWideString(@Caption), -1, @R2, nil);
|
||
QPainter_restore(Handle);
|
||
if ModifyString and Flags <> 0 then
|
||
begin
|
||
if len > 0 then
|
||
Caption := Caption + RightStr(Text, Length(Text)-len);
|
||
Text := Caption;
|
||
end;
|
||
Result := R2.Bottom - R2.Top;
|
||
end
|
||
else
|
||
begin
|
||
R2.Left := R.Left;
|
||
R2.Top := R.Top;
|
||
QPainter_boundingRect(Handle, @R, @R, Flags and not $3F{Alignment},
|
||
PWideString(@Caption), -1, nil);
|
||
if R.Left <> R2.Left then
|
||
OffsetRect(R, R2.Left, 0);
|
||
if R.Top <> R2.Top then
|
||
OffsetRect(R, 0, R2.Top);
|
||
// QPainter_boundingRect(Handle, @R, @R, Flags and not $3F{Alignment},
|
||
// @Caption, -1, nil);
|
||
Result := R.Bottom - R.Top;
|
||
end;
|
||
if WinFlags and DT_INTERNAL <> 0 then
|
||
QPainter_setFont(Handle, FontSaved);
|
||
end;
|
||
|
||
function DrawText(Handle :QPainterH; Text: PAnsiChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer;
|
||
var
|
||
WText: WideString;
|
||
AText: string;
|
||
begin
|
||
WText := Text;
|
||
Result := DrawTextW(Handle, PWideChar(WText), Len, R, WinFlags, 0);
|
||
if (DT_MODIFYSTRING and WinFlags <> 0) and (Text <> nil) then
|
||
begin
|
||
AText := WText;
|
||
StrCopy(Text, PChar(AText));
|
||
end;
|
||
end;
|
||
|
||
function DrawText(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
x,y, w, h: Integer; WinFlags: Integer; Angle: Integer): Integer;
|
||
var
|
||
R2: TRect;
|
||
begin
|
||
R2 := Bounds(x,y,w,h);
|
||
Result := DrawTextW(Handle, PWideChar(Text), Len, R2, WinFlags, Angle);
|
||
end;
|
||
|
||
function DrawTextW(Handle :QPainterH; Text: PWideChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: integer = 0): Integer;
|
||
var
|
||
WText: WideString;
|
||
R2: TRect;
|
||
begin
|
||
WText := Text;
|
||
|
||
R2:= R;
|
||
OffsetRect(R2, -R.Left, -R.Top);
|
||
try
|
||
QPainter_save(Handle);
|
||
QPainter_translate(Handle, R.Left, R.Top);
|
||
QPainter_rotate(Handle, -Angle);
|
||
Result := DrawText2(Handle, WText, Len, R2, WinFlags);
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
OffsetRect(R2, R.Left, R.Top);
|
||
R := R2;
|
||
if (DT_MODIFYSTRING and WinFlags <> 0) and (Text <> nil) then
|
||
begin
|
||
Move(WText[1], Text^, Length(WText) * SizeOf(WideChar));
|
||
//WStrCopy(Text, PChar(AText));
|
||
end;
|
||
end;
|
||
|
||
function DrawTextW(Canvas :TCanvas; Text: PWideChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: integer = 0): Integer;
|
||
begin
|
||
with Canvas do
|
||
begin
|
||
Start;
|
||
RequiredState(Canvas, [csHandleValid, csBrushValid, csFontValid]);
|
||
Result := DrawTextW(Handle, Text, Len, R, WinFlags, Angle);
|
||
Stop;
|
||
end;
|
||
end;
|
||
|
||
function DrawText(Canvas :TCanvas; Text: PAnsiChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer;
|
||
begin
|
||
with Canvas do
|
||
begin
|
||
Start;
|
||
RequiredState(Canvas, [csHandleValid, csBrushValid, csFontValid]);
|
||
Result := DrawText(Handle, Text, Len, R, WinFlags, Angle);
|
||
Stop;
|
||
end;
|
||
end;
|
||
|
||
function DrawText(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer;
|
||
var
|
||
R2: TRect;
|
||
begin
|
||
R2:= R;
|
||
OffsetRect(R2, -R.Left, -R.Top);
|
||
try
|
||
QPainter_save(Handle);
|
||
QPainter_translate(Handle, R.Left, R.Top);
|
||
QPainter_rotate(Handle, -Angle);
|
||
Result := DrawText2(Handle, Text, Len, R2, WinFlags);
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
OffsetRect(R2, R.Left, R.Top);
|
||
R := R2;
|
||
end;
|
||
|
||
function DrawText(Canvas: TCanvas; Text: TCaption; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: integer = 0): Integer;
|
||
begin
|
||
with Canvas do
|
||
begin
|
||
Start;
|
||
RequiredState(Canvas, [csHandleValid, csBrushValid, csFontValid]);
|
||
Result := DrawTextW(Handle, PWideChar(Text), Len, R, WinFlags, Angle);
|
||
Stop;
|
||
end;
|
||
end;
|
||
|
||
function DrawText(Handle: QPainterH; Text: TCaption; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; Angle: Integer = 0): Integer; overload;
|
||
begin
|
||
Result := DrawTextW(Handle, PWideChar(Text), Len, R, WinFlags, Angle);
|
||
end;
|
||
|
||
function DrawTextEx(Handle: QPainterH; var Text: WideString; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; DTParams: Pointer): Integer;
|
||
begin
|
||
Result := DrawTextW(Handle, PWideChar(Text), Len, R, WinFlags);
|
||
end;
|
||
|
||
function DrawTextEx(Handle: QPainterH; Text: PChar; Len: Integer;
|
||
var R: TRect; WinFlags: Integer; DTParams: Pointer): Integer;
|
||
begin
|
||
Result := DrawText(Handle, Text, Len, R, WinFlags);
|
||
end;
|
||
|
||
function ExtTextOut(Handle: QPainterH; X, Y: Integer; WinFlags: Cardinal;
|
||
R: PRect; const Text: WideString; Len: Integer; lpDx: Pointer): LongBool;
|
||
var
|
||
WS: WideString;
|
||
Index, Width: Integer;
|
||
Dx: PInteger;
|
||
RR{, CellRect}: TRect;
|
||
TextLen: Integer;
|
||
Canvas: TCanvas;
|
||
TextFlags: Integer;
|
||
CursorPos: TPoint;
|
||
begin
|
||
Result := False;
|
||
if (Text = '') then
|
||
Exit;
|
||
if (WinFlags and ETO_CLIPPED <> 0) and (R = nil) then
|
||
WinFlags := WinFlags and not ETO_CLIPPED;
|
||
|
||
TextFlags := GetTextAlign(Handle);
|
||
|
||
QPainter_save(Handle);
|
||
Canvas := TCanvas.Create;
|
||
try
|
||
Canvas.Handle := Handle;
|
||
Canvas.Start(False);
|
||
with Canvas do
|
||
begin
|
||
Result := True;
|
||
if WinFlags and ETO_OPAQUE <> 0 then
|
||
begin
|
||
if Brush.Style <> bsSolid then
|
||
Brush.Style := bsSolid;
|
||
if R <> nil then
|
||
FillRect(R^);
|
||
end
|
||
else
|
||
if Brush.Style = bsSolid then
|
||
Brush.Style := bsClear;
|
||
|
||
if lpDx = nil then
|
||
begin
|
||
if (WinFlags and ETO_CLIPPED <> 0) then
|
||
TextRect(R^, X, Y, Text, TextFlags and $0FFF)
|
||
else
|
||
TextOut(X, Y, Text);
|
||
end
|
||
else
|
||
begin
|
||
// put each char into its cell
|
||
TextLen := Length(Text);
|
||
if (WinFlags and ETO_OPAQUE <> 0) and (R = nil) then
|
||
begin
|
||
Dx := lpDx;
|
||
Width := 0;
|
||
for Index := 1 to TextLen do
|
||
begin
|
||
Inc(Width, Dx^);
|
||
Inc(Dx);
|
||
end;
|
||
RR.Left := X;
|
||
RR.Right := X + Width;
|
||
RR.Top := Y;
|
||
RR.Bottom := Y + TextHeight(Text);
|
||
FillRect(RR);
|
||
end;
|
||
|
||
Dx := lpDx;
|
||
SetLength(WS, 1);
|
||
for Index := 1 to TextLen do
|
||
begin
|
||
if (R <> nil) and (X >= R^.Right) then
|
||
Break;
|
||
|
||
WS[1] := Text[Index];
|
||
if WinFlags and ETO_CLIPPED <> 0 then
|
||
begin
|
||
{CellRect.Left := X;
|
||
CellRect.Right := X + Dx^;
|
||
CellRect.Top := R^.Top;
|
||
CellRect.Bottom := R^.Bottom;
|
||
if CellRect.Right > R^.Right then
|
||
CellRect.Right := R^.Right;}
|
||
TextRect(RR, X, Y, WS, TextFlags and $0FFF);
|
||
end
|
||
else
|
||
TextOut(X, Y, WS);
|
||
|
||
if Index = TextLen then
|
||
Break;
|
||
|
||
Inc(X, Dx^);
|
||
Inc(Dx);
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
Canvas.Stop;
|
||
Canvas.Free;
|
||
QPainter_pos(Handle, @CursorPos);
|
||
QPainter_restore(Handle);
|
||
if WinFlags and TA_UPDATECP <> 0 then
|
||
QPainter_moveTo(Handle, @CursorPos);
|
||
end;
|
||
end;
|
||
|
||
function ExtTextOut(Handle: QPainterH; X, Y: Integer; WinFlags: Cardinal;
|
||
R: PRect; pText: PChar; Len: Integer; lpDx: Pointer): LongBool;
|
||
var
|
||
ws: WideString;
|
||
begin
|
||
ws := pText;
|
||
Result := ExtTextOut(Handle, X, Y, WinFlags, R, ws, Len, lpDx);
|
||
end;
|
||
|
||
function ExtTextOutW(Handle: QPainterH; X, Y: Integer; WinFlags: Cardinal;
|
||
R: PRect; pText: PWideChar; Len: Integer; lpDx: Pointer): LongBool;
|
||
var
|
||
ws: WideString;
|
||
begin
|
||
ws := pText;
|
||
Result := ExtTextOut(Handle, X, Y, WinFlags, R, ws, Len, lpDx);
|
||
end;
|
||
|
||
function GetTextAlign(Handle: QPainterH): Cardinal;
|
||
var
|
||
P: PPainterInfo;
|
||
begin
|
||
if GetPainterInfo(Handle, P) then
|
||
Result := P.TextAlignment
|
||
else
|
||
Result := TA_LEFT or TA_TOP;
|
||
end;
|
||
|
||
function SetTextAlign(Handle: QPainterH; Mode: Cardinal): Cardinal;
|
||
begin
|
||
Result := GetTextAlign(Handle);
|
||
if Result <> Mode then
|
||
SetPainterInfo(Handle).TextAlignment := Mode;
|
||
end;
|
||
|
||
function FillRect(Handle: QPainterH; const R: TRect; Brush: QBrushH): LongBool;
|
||
begin
|
||
try
|
||
QPainter_fillRect(Handle, @R, Brush);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function DrawIcon(Handle: QPainterH; X, Y: Integer; hIcon: QPixmapH): LongBool;
|
||
var
|
||
Pt: TPoint;
|
||
begin
|
||
Pt.X := X;
|
||
Pt.Y := Y;
|
||
try
|
||
QPainter_drawPixmap(Handle, @Pt, hIcon);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function DrawIconEx(Handle: QPainterH; X, Y: Integer; hIcon: QPixmapH; W, H: Integer;
|
||
istepIfAniCur: Integer; hbrFlickerFreeDraw: QBrushH; diFlags: Cardinal): LongBool;
|
||
var
|
||
TempDC: QPainterH;
|
||
R: TRect;
|
||
begin
|
||
if diFlags = DI_DEFAULTSIZE then
|
||
begin
|
||
if W = 0 then
|
||
begin
|
||
W := GetSystemMetrics(SM_CYICON);
|
||
istepIfAniCur := 0;
|
||
end;
|
||
if H = 0 then
|
||
H := GetSystemMetrics(SM_CXICON);
|
||
end
|
||
else
|
||
begin // DI_NORMAL / DI_IMAGE / DI_MASK
|
||
if W = 0 then
|
||
begin
|
||
W := QPixmap_width(hIcon);
|
||
istepIfAniCur := 0;
|
||
end;
|
||
if H = 0 then
|
||
H := QPixmap_height(hIcon);
|
||
if (DiFlags and DI_MASK) = 0 then // DI_NORMAL / DT_IMAGE
|
||
QPixmap_setMask(hIcon, nil);
|
||
end;
|
||
|
||
if QPixmap_width(hIcon) < ((istepIfAniCur + 1) * W) then
|
||
istepIfAniCur := 0;
|
||
|
||
if hbrFlickerFreeDraw <> nil then
|
||
begin
|
||
R := Bounds(0, 0, W, H);
|
||
try
|
||
TempDC := CreateCompatibleDC(Handle, W, H);
|
||
try
|
||
FillRect(TempDC, R, hbrFlickerFreeDraw);
|
||
QPainter_drawPixmap(TempDC, 0, 0, hIcon, istepIfAniCur * W, 0, W, H);
|
||
BitBlt(Handle, X, Y, W, H, TempDC, 0, 0, RasterOp_CopyRop);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
DeleteObject(TempDC);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
try
|
||
QPainter_drawPixmap(Handle, X, Y, hIcon, istepIfAniCur * W, 0, W, H);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function InvertRect(Handle: QPainterH; const R: TRect): LongBool;
|
||
begin
|
||
with R do
|
||
Result := BitBlt(Handle, Left, Top, Right - Left, Bottom-Top,
|
||
Handle, Left, Top, DSTINVERT);
|
||
end;
|
||
|
||
function Rectangle(Handle: QPainterH; Left, Top, Right, Bottom: Integer): LongBool;
|
||
begin
|
||
try
|
||
QPainter_drawRect(Handle, Left, Top, Right, Bottom);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function RoundRect(Handle: QPainterH; Left, Top, Right, Bottom, X3, Y3: Integer): LongBool;
|
||
begin
|
||
try
|
||
QPainter_drawRoundRect(Handle, Left, Top, Right, Bottom, X3, Y3);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function Ellipse(Handle: QPainterH; Left, Top, Right, Bottom: Integer): LongBool;
|
||
begin
|
||
try
|
||
QPainter_drawEllipse(Handle, Left, Top, Right, Bottom);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function FrameRect(Handle: QPainterH; const R: TRect; Brush: QBrushH): LongBool;
|
||
var
|
||
Pen: QPenH;
|
||
begin
|
||
Result := False;
|
||
if (Handle = nil) or (R.Right - R.Left <= 0) or (R.Bottom - R.Top <= 0) or
|
||
(Brush = nil) then
|
||
Exit;
|
||
try
|
||
Pen := nil;
|
||
QPainter_save(Handle);
|
||
try
|
||
Pen := QPen_create(QBrush_color(Brush), 1, PenStyle_SolidLine);
|
||
QPainter_setPen(Handle, Pen);
|
||
QPainter_setBrush(Handle, BrushStyle_NoBrush);
|
||
QPainter_drawRect(Handle, @R);
|
||
finally
|
||
if Assigned(Pen) then
|
||
QPen_destroy(Pen);
|
||
QPainter_restore(Handle);
|
||
end;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
procedure FrameRect(Canvas: TCanvas; const R: TRect);
|
||
begin
|
||
Canvas.Start;
|
||
try
|
||
FrameRect(Canvas.Handle, R, Canvas.Brush.Handle);
|
||
finally
|
||
Canvas.Stop;
|
||
end;
|
||
end;
|
||
|
||
function DrawFocusRect(Handle: QPainterH; const R: TRect): LongBool;
|
||
begin
|
||
try
|
||
QPainter_drawWinFocusRect(Handle, @R);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function DrawFrameControl(Handle: QPainterH; const Rect: TRect; uType, uState: Longword): LongBool;
|
||
|
||
function GetColorGroup(uState: LongWord): QColorGroupH;
|
||
begin
|
||
if uState and DFCS_INACTIVE <> 0 then
|
||
Result := Application.Palette.ColorGroup(cgDisabled)
|
||
else if uState and DFCS_HOT <> 0 then
|
||
Result := Application.Palette.ColorGroup(cgActive)
|
||
else
|
||
Result := Application.Palette.ColorGroup(cgInActive);
|
||
end;
|
||
|
||
const
|
||
Mask = $00FF;
|
||
var
|
||
InnerRect, R: TRect;
|
||
Brush: QBrushH;
|
||
Pen: QPenH;
|
||
Font: QFontH;
|
||
Size: TSize;
|
||
QC: QColorH;
|
||
oBkMode: Integer;
|
||
MaskPainter, Painter: QPainterH;
|
||
MaskBitmap: QBitmapH;
|
||
Pixmap: QPixmapH;
|
||
// FInstance: TControl;
|
||
// FObject: TObject;
|
||
begin
|
||
Result := False;
|
||
if (Handle = nil) or (not QPainter_isActive(Handle)) then
|
||
Exit;
|
||
|
||
QPainter_save(Handle);
|
||
try
|
||
if uState and DFCS_TRANSPARENT <> 0 then
|
||
begin
|
||
Brush := nil;
|
||
oBkMode := SetBkMode(Handle, TRANSPARENT);
|
||
end
|
||
else
|
||
begin
|
||
oBkMode := SetBkMode(Handle, OPAQUE);
|
||
Brush := QPainter_brush(Handle);
|
||
|
||
if uState and DFCS_INACTIVE <> 0 then
|
||
QC := QColor(clDisabledButton)
|
||
else if uState and DFCS_HOT <> 0 then
|
||
QC := QColor(clActiveButton)
|
||
else
|
||
QC := QColor(clNormalButton);
|
||
QPainter_setBackgroundColor(Handle, QC);
|
||
QBrush_setColor(Brush, QC);
|
||
QColor_destroy(QC);
|
||
QPainter_eraseRect(Handle, @Rect);
|
||
end;
|
||
try
|
||
R := Rect;
|
||
case uType of
|
||
DFC_CAPTION:
|
||
begin
|
||
// draw button
|
||
Result := DrawFrameControl(Handle, Rect, DFC_BUTTON,
|
||
DFCS_BUTTONPUSH or (uState and not Mask));
|
||
if Result then
|
||
begin
|
||
// draw image
|
||
Pen := CreatePen(PS_SOLID, 1, clBlack);
|
||
QPainter_setPen(Handle, Pen);
|
||
QPen_destroy(Pen);
|
||
SetBkMode(Handle, TRANSPARENT);
|
||
case uState and Mask of
|
||
DFCS_CAPTIONCLOSE:
|
||
begin
|
||
SetRect(R, 0, 0, 6, 6);
|
||
R := CenterRect(R, Rect);
|
||
if (uState and DFCS_PUSHED) = 0 then
|
||
OffsetRect(R, -1, -1);
|
||
QPainter_moveTo(Handle, R.Left , R.Top);
|
||
QPainter_lineTo(Handle, R.Right, R.Bottom);
|
||
QPainter_moveTo(Handle, R.Left , R.Bottom);
|
||
QPainter_lineTo(Handle, R.Right, R.Top);
|
||
OffsetRect(R, 1, 0);
|
||
QPainter_moveTo(Handle, R.Left , R.Top);
|
||
QPainter_lineTo(Handle, R.Right, R.Bottom);
|
||
QPainter_moveTo(Handle, R.Left , R.Bottom);
|
||
QPainter_lineTo(Handle, R.Right, R.Top);
|
||
end;
|
||
DFCS_CAPTIONMIN:
|
||
begin
|
||
SetRect(R, 0, 0, 9, 9);
|
||
R := CenterRect(R, Rect);
|
||
if (uState and DFCS_PUSHED) <> 0 then
|
||
OffsetRect(R, 1, 1);
|
||
// Inc(R.Left, 4);
|
||
// Dec(R.Right, 6);
|
||
// Dec(R.Bottom, 4);
|
||
QPainter_moveTo(Handle, R.Left , R.Bottom - 1);
|
||
QPainter_lineTo(Handle, R.Right, R.Bottom - 1);
|
||
QPainter_moveTo(Handle, R.Left , R.Bottom );
|
||
QPainter_lineTo(Handle, R.Right, R.Bottom );
|
||
end;
|
||
DFCS_CAPTIONMAX:
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
// InflateRect(R, -4, -4);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
// InflateRect(R, -3, -2);
|
||
{$ENDIF LINUX}
|
||
SetRect(R, 0, 0, 9, 9);
|
||
R := CenterRect(R, Rect);
|
||
if (uState and DFCS_PUSHED) <> 0 then
|
||
OffsetRect(R, 1, 1);
|
||
QPainter_drawRect(Handle, @R);
|
||
QPainter_moveTo(Handle, R.Left, R.Top + 1);
|
||
QPainter_lineTo(Handle, R.Right - 1, R.Top + 1);
|
||
end;
|
||
DFCS_CAPTIONRESTORE:
|
||
begin
|
||
QPainter_save(Handle);
|
||
SetRect(R, 0, 0, 6, 6);
|
||
R := CenterRect(R, Rect);
|
||
if (uState and DFCS_PUSHED) <> 0 then
|
||
OffsetRect(R, 1, 1);
|
||
OffsetRect(R, -2, 1);
|
||
ExcludeClipRect(Handle, R.Left, R.Top, R.Right, R.Bottom);
|
||
OffsetRect(R, 2, -3);
|
||
QPainter_drawRect(Handle, @R);
|
||
QPainter_moveTo(Handle, R.Left + 1, R.Top + 1);
|
||
QPainter_lineTo(Handle, R.Right - 1, R.Top + 1);
|
||
QPainter_restore(Handle);
|
||
|
||
OffsetRect(R, -2, 3);
|
||
QPainter_drawRect(Handle, @R);
|
||
QPainter_moveTo(Handle, R.Left + 1, R.Top + 1);
|
||
QPainter_lineTo(Handle, R.Right - 1, R.Top + 1);
|
||
QPainter_restore(Handle);
|
||
end;
|
||
DFCS_CAPTIONHELP:
|
||
begin
|
||
Font := QFont_create(Application.Font.Handle);
|
||
QFont_setBold(Font, True);
|
||
QPainter_setFont(Handle, Font);
|
||
QFont_destroy(Font);
|
||
if (uState and DFCS_PUSHED) = 0 then
|
||
OffsetRect(R, -1, -1);
|
||
OffsetRect(R, -1, 0);
|
||
DrawText(Handle, '?', 1, R, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
|
||
end;
|
||
end; // case of
|
||
end;
|
||
end; // DFC_CAPTION
|
||
|
||
DFC_MENU:
|
||
begin
|
||
// white background color. Windows paints it so we must paint it, too.
|
||
QC := QColor(clWhite);
|
||
QPainter_setBrush(Handle, QC);
|
||
QColor_destroy(QC);
|
||
|
||
case uState and Mask of
|
||
DFCS_MENUARROW: // (ahuser) this is the submenu arrow that points left-to-right !
|
||
begin
|
||
QStyle_drawArrow(Application.Style.Handle, Handle,
|
||
ArrowType_RightArrow,
|
||
uState and DFCS_PUSHED <> 0,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_INACTIVE = 0,
|
||
Brush);
|
||
Result := True;
|
||
end;
|
||
DFCS_MENUARROWRIGHT: // (ahuser) this is the right submenu arrow that points right-to-left !
|
||
begin
|
||
QStyle_drawArrow(Application.Style.Handle, Handle,
|
||
ArrowType_LeftArrow,
|
||
uState and DFCS_PUSHED <> 0,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_INACTIVE = 0,
|
||
Brush);
|
||
Result := True;
|
||
end;
|
||
DFCS_MENUCHECK:
|
||
begin
|
||
QPainter_fillRect(Handle, @R, QPainter_brush(Handle));
|
||
QStyle_drawCheckMark(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_CHECKED <> 0,
|
||
uState and DFCS_INACTIVE <> 0
|
||
);
|
||
Result := True;
|
||
end;
|
||
DFCS_MENUBULLET:
|
||
begin
|
||
QPainter_fillRect(Handle, @R, QPainter_brush(Handle));
|
||
R := Types.Rect(0, 0, 7, 7);
|
||
OffsetRect(R,
|
||
((Rect.Right - Rect.Left) - R.Right) div 2 + Rect.Left,
|
||
((Rect.Bottom - Rect.Top) - R.Bottom) div 2 + Rect.Top);
|
||
SetDCBrushColor(Handle, clBlack);
|
||
SetDCPenColor(Handle, clBlack);
|
||
QPainter_drawEllipse(Handle, @R);
|
||
Result := True;
|
||
end;
|
||
end;
|
||
end; // DFC_MENU
|
||
|
||
DFC_SCROLL:
|
||
begin
|
||
DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONPUSH or (uState and not Mask));
|
||
InflateRect(R, -2,-2);
|
||
case uState and Mask of
|
||
DFCS_SCROLLUP:
|
||
begin
|
||
QStyle_drawArrow(Application.Style.Handle, Handle,
|
||
ArrowType_UpArrow,
|
||
uState and DFCS_PUSHED <> 0,
|
||
R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_INACTIVE = 0,
|
||
Brush);
|
||
Result := True;
|
||
end;
|
||
DFCS_SCROLLCOMBOBOX, // looks equal to DFCS_SCROLLDOWN
|
||
DFCS_SCROLLDOWN:
|
||
begin
|
||
QStyle_drawArrow(Application.Style.Handle, Handle,
|
||
ArrowType_DownArrow,
|
||
uState and DFCS_PUSHED <> 0,
|
||
R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_INACTIVE = 0,
|
||
Brush);
|
||
Result := True;
|
||
end;
|
||
DFCS_SCROLLLEFT:
|
||
begin
|
||
QStyle_drawArrow(Application.Style.Handle, Handle,
|
||
ArrowType_LeftArrow,
|
||
uState and DFCS_PUSHED <> 0,
|
||
R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_INACTIVE = 0,
|
||
Brush);
|
||
Result := True;
|
||
end;
|
||
DFCS_SCROLLRIGHT:
|
||
begin
|
||
QStyle_drawArrow(Application.Style.Handle, Handle,
|
||
ArrowType_RightArrow,
|
||
uState and DFCS_PUSHED <> 0,
|
||
R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_INACTIVE = 0,
|
||
Brush);
|
||
Result := True;
|
||
end;
|
||
else
|
||
raise Exception.Create('not implemented');
|
||
end;
|
||
end; // DFC_SCROLL
|
||
|
||
DFC_BUTTON:
|
||
case uState and Mask of
|
||
DFCS_BUTTONRADIO:
|
||
begin
|
||
QStyle_exclusiveIndicatorSize(Application.Style.Handle, @Size);
|
||
OffsetRect(R, (R.Right - R.Left - Size.cx) div 2,
|
||
(R.Bottom - R.Top - Size.cy) div 2);
|
||
Pixmap := CreateCompatibleBitmap(Handle, R.Right - R.Left, R.Bottom - R.Top);
|
||
try
|
||
MaskBitmap := QBitmap_create(R.Right - R.Left, R.Bottom - R.Top,
|
||
False, QPixmapOptimization_DefaultOptim);
|
||
try
|
||
QC := QColor(clBlack);
|
||
QPixmap_fill(MaskBitmap, QC);
|
||
QColor_destroy(QC);
|
||
MaskPainter := QPainter_create(MaskBitmap);
|
||
QStyle_drawExclusiveIndicatorMask(Application.Style.Handle, MaskPainter,
|
||
0, 0, QPixmap_width(MaskBitmap), QPixmap_height(MaskBitmap),
|
||
uState and DFCS_CHECKED <> 0);
|
||
QPainter_destroy(MaskPainter);
|
||
QPixmap_setMask(Pixmap, MaskBitmap);
|
||
finally
|
||
QBitmap_destroy(MaskBitmap);
|
||
end;
|
||
|
||
Painter := QPainter_create(Pixmap);
|
||
QStyle_drawExclusiveIndicator(
|
||
Application.Style.Handle, Painter,
|
||
0, 0, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_CHECKED <> 0,
|
||
uState and DFCS_INACTIVE <> 0,
|
||
True);
|
||
QPainter_destroy(Painter);
|
||
QPainter_drawPixmap(Handle, R.Left, R.Top, Pixmap, 0, 0,
|
||
QPixmap_width(Pixmap), QPixmap_height(Pixmap));
|
||
finally
|
||
DeleteObject(Pixmap);
|
||
end;
|
||
Result := True;
|
||
end;
|
||
DFCS_BUTTONCHECK:
|
||
begin
|
||
QStyle_drawIndicatorMask(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top, 0);
|
||
|
||
if uState and DFCS_INACTIVE = 0 then
|
||
QStyle_drawIndicator(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
Application.Palette.ColorGroup(cgActive), //GetColorGroup(cgInActive),
|
||
0, False, True)
|
||
else
|
||
QStyle_drawIndicator(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
Application.Palette.ColorGroup(cgActive), //GetColorGroup(cgInActive),
|
||
0, True, True);
|
||
InflateRect(R, -2, -2);
|
||
if uState and DFCS_CHECKED <> 0 then
|
||
DrawFrameControl(Handle, R, DFC_MENU, DFCS_MENUCHECK or (uState and not Mask));
|
||
Result := True;
|
||
end;
|
||
DFCS_BUTTONPUSH:
|
||
begin
|
||
R := Rect;
|
||
InnerRect := Rect;
|
||
InflateRect(InnerRect, -2, -2);
|
||
if uState and DFCS_ADJUSTRECT <> 0 then
|
||
PRect(@Rect)^ := InnerRect;
|
||
if uState and DFCS_FLAT <> 0 then
|
||
begin
|
||
if uState and (DFCS_PUSHED or DFCS_HOT) <> 0 then
|
||
begin
|
||
QStyle_drawButton(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_PUSHED <> 0,
|
||
Brush
|
||
);
|
||
{QStyle_drawPanel(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_PUSHED <> 0,
|
||
1,
|
||
Brush);}
|
||
InflateRect(R, -1, -1);
|
||
end;
|
||
Result := True;
|
||
end
|
||
else if uState and DFCS_MONO = 0 then
|
||
begin
|
||
QStyle_drawButton(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState),
|
||
uState and DFCS_PUSHED <> 0,
|
||
Brush);
|
||
InflateRect(R, -2, -2);
|
||
Result := True;
|
||
end
|
||
else
|
||
begin
|
||
SetDCPenColor(Handle, clBlack);
|
||
QPainter_drawRect(Handle, @R);
|
||
InflateRect(R, -1, -1);
|
||
Result := True;
|
||
end;
|
||
end;
|
||
else
|
||
// not implemented
|
||
raise Exception.Create('QWindows.DrawFrameControl: not implemented');
|
||
end;
|
||
|
||
DFC_POPUPMENU:
|
||
begin
|
||
//
|
||
QStyle_drawPopupPanel(Application.Style.Handle, Handle,
|
||
R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
|
||
GetColorGroup(uState), 2, Brush);
|
||
end;
|
||
end;
|
||
finally
|
||
SetBkMode(Handle, oBkMode);
|
||
end;
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
end;
|
||
|
||
function DrawFrameControl(Canvas: TCanvas; const Rect: TRect; uType, uState: Longword): LongBool;
|
||
begin
|
||
with Canvas do
|
||
begin
|
||
Start;
|
||
RequiredState(Canvas, [csHandleValid, csBrushValid, csPenValid]);
|
||
Result := DrawFrameControl(Canvas.Handle, Rect, uType, uState);
|
||
Stop;
|
||
end;
|
||
end;
|
||
|
||
|
||
function DrawEdge(Handle: QPainterH; var Rect: TRect; Edge: Cardinal;
|
||
Flags: Cardinal): LongBool;
|
||
var
|
||
Brush: QBrushH;
|
||
ColorDark, ColorLight: TColor;
|
||
ClientRect: TRect;
|
||
|
||
procedure DrawLine(X1, Y1, X2, Y2: Integer);
|
||
begin
|
||
QPainter_moveTo(Handle, X1, Y1);
|
||
QPainter_lineTo(Handle, X2, Y2);
|
||
end;
|
||
|
||
procedure DoDrawEdge(Outer: Boolean; const R: TRect);
|
||
var
|
||
X1, Y1, X2, Y2: Integer;
|
||
ColorLeftTop, ColorRightBottom: TColor;
|
||
begin
|
||
X1 := R.Left;
|
||
Y1 := R.Top;
|
||
X2 := R.Right;
|
||
Y2 := R.Bottom;
|
||
ColorLeftTop := clNone;
|
||
ColorRightBottom := clNone;
|
||
|
||
if Outer then
|
||
begin
|
||
if Edge and BDR_RAISEDOUTER <> 0 then
|
||
begin
|
||
ColorLeftTop := ColorLight;
|
||
ColorRightBottom := ColorDark;
|
||
end
|
||
else if Edge and BDR_SUNKENOUTER <> 0 then
|
||
begin
|
||
ColorLeftTop := ColorDark;
|
||
ColorRightBottom := ColorLight;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
if Edge and BDR_RAISEDINNER <> 0 then
|
||
begin
|
||
ColorLeftTop := ColorLight;
|
||
ColorRightBottom := ColorDark;
|
||
end
|
||
else if Edge and BDR_SUNKENINNER <> 0 then
|
||
begin
|
||
ColorLeftTop := ColorDark;
|
||
ColorRightBottom := ColorLight;
|
||
end;
|
||
end;
|
||
|
||
if Flags and BF_DIAGONAL = 0 then
|
||
begin
|
||
SetDCPenColor(Handle, ColorLeftTop);
|
||
if Flags and BF_LEFT <> 0 then
|
||
DrawLine(X1, Y1, X1, Y2);
|
||
if Flags and BF_TOP <> 0 then
|
||
DrawLine(X1, Y1, X2, Y1);
|
||
|
||
SetDCPenColor(Handle, ColorRightBottom);
|
||
if Flags and BF_RIGHT <> 0 then
|
||
DrawLine(X2, Y1, X2, Y2);
|
||
if Flags and BF_BOTTOM <> 0 then
|
||
DrawLine(X1, Y2, X2, Y2);
|
||
end
|
||
else
|
||
begin
|
||
// diagonal (does not really work properly with Qt's line algorithm)
|
||
SetDCPenColor(Handle, ColorLeftTop);
|
||
if (Flags and BF_DIAGONAL_ENDTOPLEFT = BF_DIAGONAL_ENDTOPLEFT) or
|
||
(Flags and BF_DIAGONAL_ENDBOTTOMRIGHT = BF_DIAGONAL_ENDBOTTOMRIGHT) then
|
||
DrawLine(X1, Y1, X2, Y2)
|
||
else
|
||
{if (Flags and BF_DIAGONAL_ENDBOTTOMLEFT = BF_DIAGONAL_ENDBOTTOMLEFT) or
|
||
(Flags and BF_DIAGONAL_ENDTOPRIGHT = BF_DIAGONAL_ENDTOPRIGHT) then} // default
|
||
DrawLine(X1, Y2, X2, Y1);
|
||
end;
|
||
end;
|
||
|
||
begin
|
||
Result := False;
|
||
if Handle = nil then
|
||
Exit;
|
||
try
|
||
ClientRect := Rect;
|
||
QPainter_save(Handle);
|
||
try
|
||
ColorDark := ColorToRGB(clDark);
|
||
ColorLight := ColorToRGB(clBtnHighlight);
|
||
if Flags and BF_FLAT <> 0 then
|
||
ColorLight := clSilver;
|
||
if Flags and BF_MONO <> 0 then
|
||
begin
|
||
ColorDark := clBlack;
|
||
ColorLight := clWhite;
|
||
end;
|
||
try
|
||
if Edge and (BDR_SUNKENOUTER or BDR_RAISEDOUTER) <> 0 then
|
||
DoDrawEdge(True, Rect); // outer
|
||
InflateRect(ClientRect, -1, -1); // remove outer rect
|
||
if Flags and BF_MONO = 0 then
|
||
ColorDark := ColorToRGB(clMid);
|
||
if Edge and (BDR_SUNKENINNER or BDR_RAISEDINNER) <> 0 then
|
||
begin
|
||
DoDrawEdge(False, ClientRect); // inner
|
||
InflateRect(ClientRect, -1, -1); // remove inner rect
|
||
end;
|
||
finally
|
||
|
||
end;
|
||
|
||
if Flags and BF_MIDDLE <> 0 then
|
||
begin
|
||
// fill interior rect
|
||
Brush := CreateSolidBrush(clButton);
|
||
try
|
||
FillRect(Handle, ClientRect, Brush);
|
||
finally
|
||
DeleteObject(Brush);
|
||
end;
|
||
end;
|
||
|
||
if Flags and BF_ADJUST <> 0 then
|
||
Rect := ClientRect;
|
||
|
||
Result := True;
|
||
finally
|
||
QPainter_restore(Handle);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetCurrentPositionEx(Handle: QPainterH; pos: PPoint): LongBool;
|
||
begin
|
||
try
|
||
QPainter_pos(Handle, pos);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function LineTo(Handle: QPainterH; X, Y:Integer): LongBool;
|
||
begin
|
||
try
|
||
QPainter_lineTo(Handle, X, Y);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function MoveToEx(Handle: QPainterH; X, Y:Integer; Point: PPoint): LongBool;
|
||
begin
|
||
try
|
||
if Point <> nil then
|
||
QPainter_pos(Handle, Point);
|
||
QPainter_moveTo(Handle, X, Y);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetDC(Handle: QWidgetH): QPainterH;
|
||
var
|
||
PaintDevice: QPaintDeviceH;
|
||
begin
|
||
try
|
||
if Handle = nil then
|
||
Handle := QApplication_desktop;
|
||
PaintDevice := QWidget_to_QPaintDevice(Handle);
|
||
Result := QPainter_create(PaintDevice, Handle);
|
||
if not QPainter_isActive(Result) then
|
||
QPainter_begin(Result, PaintDevice, Handle);
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
function GetDC(Handle: Integer): QPainterH;
|
||
begin
|
||
Result := GetDC(QWidgetH(Handle));
|
||
end;
|
||
|
||
function GetWindowDC(Handle: QWidgetH): QPainterH;
|
||
begin
|
||
Result := GetDC(Handle);
|
||
end;
|
||
|
||
function ReleaseDC(wdgtH: QWidgetH; Handle: QPainterH): Integer;
|
||
begin
|
||
try
|
||
// asn: wdgtH ignored
|
||
QPainter_end(Handle);
|
||
QPainter_destroy(Handle);
|
||
Result := 1;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function ReleaseDC(wdgtH: Integer; Handle: QPainterH): Integer;
|
||
begin
|
||
Result := ReleaseDC(QWidgetH(wdgtH), Handle);
|
||
end;
|
||
|
||
function DeleteDC(Handle: QPainterH): LongBool;
|
||
var
|
||
P: PPainterInfo;
|
||
begin
|
||
if GetPainterInfo(Handle, P) and P.IsCompatibleDC then
|
||
Result := DeleteObject(Handle)
|
||
else
|
||
Result := ReleaseDC(0, Handle) = 1;
|
||
end;
|
||
|
||
function CreateCompatibleDC(Handle: QPainterH; Width: Integer = 1; Height: Integer = 1): QPainterH;
|
||
var
|
||
Pixmap: QPixmapH;
|
||
DesktopPainter: Boolean;
|
||
begin
|
||
Result := nil;
|
||
try
|
||
if Handle = nil then
|
||
begin
|
||
Handle := GetDC(0);
|
||
DesktopPainter := True;
|
||
end
|
||
else
|
||
DesktopPainter := False;
|
||
try
|
||
Pixmap := CreateCompatibleBitmap(Handle, Width, Height);
|
||
if Pixmap = nil then
|
||
Exit;
|
||
Result := QPainter_create(Pixmap);
|
||
try
|
||
SetPainterInfo(Result).IsCompatibleDC := True;
|
||
QPainter_setPen(Result, QPainter_pen(Handle));
|
||
QPainter_setBackgroundColor(Result, QPainter_BackgroundColor(Handle));
|
||
QPainter_setFont(Result, QPainter_Font(Handle));
|
||
|
||
if not QPainter_isActive(Result) then
|
||
QPainter_begin(Result, QPainter_device(Result));
|
||
except
|
||
DeleteObject(Result);
|
||
Result := nil;
|
||
end;
|
||
finally
|
||
if DesktopPainter then
|
||
ReleaseDC(0, Handle);
|
||
end;
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
|
||
function CreateCompatibleBitmap(Handle: QPainterH; Width, Height: Integer): QPixmapH;
|
||
var
|
||
pdm: QPaintDeviceMetricsH;
|
||
DesktopPainter: Boolean;
|
||
begin
|
||
Result := nil;
|
||
if (Width <= 0) or (Height <= 0) then
|
||
Exit;
|
||
if Handle = nil then
|
||
begin
|
||
Handle := GetDC(0);
|
||
DesktopPainter := True;
|
||
end
|
||
else
|
||
DesktopPainter := False;
|
||
try
|
||
if QPainter_device(Handle) <> nil then
|
||
begin
|
||
try
|
||
pdm := QPaintDeviceMetrics_create(QPainter_device(Handle));
|
||
Result := QPixmap_create(Width, Height, QPaintDeviceMetrics_depth(pdm),
|
||
QPixmapOptimization_DefaultOptim);
|
||
QPaintDeviceMetrics_destroy(pdm);
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
try
|
||
Result := QPixmap_create(Width, Height, -1, QPixmapOptimization_DefaultOptim);
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
finally
|
||
if DesktopPainter then
|
||
ReleaseDC(0, Handle);
|
||
end;
|
||
end;
|
||
|
||
function Convert24To32(Bits: PByte; PixelCount: Cardinal): PByte;
|
||
var
|
||
i: Integer;
|
||
P: PByte;
|
||
begin
|
||
GetMem(Result, PixelCount * 4);
|
||
P := Result;
|
||
for i := 0 to PixelCount - 1 do
|
||
begin
|
||
P^ := PByte(Bits)^;
|
||
Inc(Bits);
|
||
Inc(P);
|
||
P^ := PByte(Bits)^;
|
||
Inc(Bits);
|
||
Inc(P);
|
||
P^ := PByte(Bits)^;
|
||
Inc(Bits);
|
||
Inc(P);
|
||
P^ := 0;
|
||
Inc(P);
|
||
end;
|
||
end;
|
||
|
||
function CreateBitmap(Width, Height: Integer; Planes, BitCount: Longint; Bits: Pointer): QPixmapH;
|
||
var
|
||
Image: QImageH;
|
||
Data: PByte;
|
||
begin
|
||
if (Width <= 0) or (Height <= 0) or (Planes <= 0) or (BitCount <= 0) then
|
||
Result := nil
|
||
else
|
||
begin
|
||
try
|
||
Data := PByte(Bits);
|
||
if BitCount = 24 then
|
||
begin
|
||
BitCount := 32;
|
||
if Bits <> nil then
|
||
// convert InitBits
|
||
Data := Convert24To32(Bits, Width * Height);
|
||
end;
|
||
try
|
||
if Data = nil then
|
||
Result := QPixmap_create(Width, Height, BitCount, QPixmapOptimization_DefaultOptim)
|
||
else
|
||
begin
|
||
Image := QImage_create(Width, Height, BitCount, 0, QImageEndian_IgnoreEndian);
|
||
try
|
||
Move(Data^, QImage_bits(Image)^, (Width * Height * BitCount + 7) div 8);
|
||
Result := QPixmap_create;
|
||
try
|
||
QPixmap_convertFromImage(Result, Image, QPixmapColorMode_Auto);
|
||
except
|
||
QPixmap_destroy(Result);
|
||
Result := nil;
|
||
end;
|
||
finally
|
||
QImage_destroy(Image);
|
||
end;
|
||
end;
|
||
finally
|
||
if Data <> Bits then
|
||
FreeMem(Data);
|
||
end;
|
||
except
|
||
Result := nil;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function CreateDIBitmap(Handle: QPainterH; var InfoHeader: TBitmapInfoHeader;
|
||
dwUsage: Longword; InitBits: PChar; var InitInfo: TBitmapInfo; wUsage: Cardinal): QPixmapH;
|
||
var
|
||
Image: QImageH;
|
||
Data: PByte;
|
||
NumColors: Integer;
|
||
begin
|
||
with InfoHeader do
|
||
begin
|
||
if (biWidth <= 0) or (biHeight <= 0) or (biPlanes <> 1) or (biBitCount <= 0) then
|
||
Result := nil
|
||
else
|
||
begin
|
||
Data := PByte(InitBits);
|
||
if biBitCount = 24 then
|
||
begin
|
||
biBitCount := 32;
|
||
if (InitBits <> nil) and (dwUsage = CBM_INIT) then
|
||
// convert InitBits
|
||
Data := Convert24To32(PByte(InitBits), biWidth * biHeight);
|
||
end;
|
||
try
|
||
try
|
||
case biBitCount of
|
||
1: NumColors := 1;
|
||
4: NumColors := 16; // (ahuser) is this supported by Qt ?
|
||
8: NumColors := 256;
|
||
else
|
||
NumColors := 0;
|
||
end;
|
||
Image := QImage_create(biWidth, biHeight, biBitCount, NumColors, QImageEndian_IgnoreEndian);
|
||
try
|
||
if (dwUsage = CBM_INIT) then
|
||
begin
|
||
if (InitBits <> nil) then
|
||
Move(Data^, QImage_bits(Image)^, (biWidth * biHeight * biBitCount + 7) div 8);
|
||
case biBitCount of
|
||
1: Move(InitInfo.bmiColors[0], QImage_colorTable(Image)^, 1 * SizeOf(QRgb));
|
||
4: Move(InitInfo.bmiColors[0], QImage_colorTable(Image)^, 16 * SizeOf(QRgb)); // (ahuser) is this supported by Qt ?
|
||
8: Move(InitInfo.bmiColors[0], QImage_colorTable(Image)^, 256 * SizeOf(QRgb));
|
||
end;
|
||
end;
|
||
|
||
Result := QPixmap_create;
|
||
try
|
||
QPixmap_convertFromImage(Result, Image, QPixmapColorMode_Auto);
|
||
except
|
||
QPixmap_destroy(Result);
|
||
Result := nil;
|
||
end;
|
||
finally
|
||
QImage_destroy(Image);
|
||
end;
|
||
except
|
||
Result := nil;
|
||
end;
|
||
finally
|
||
if Data <> PByte(InitBits) then
|
||
FreeMem(Data);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function GetBitmapBits(Bitmap: QPixmapH; Count: Longint; Bits: Pointer): Longint;
|
||
var
|
||
Image: QImageH;
|
||
begin
|
||
Result := 0;
|
||
if (Bitmap = nil) or (Count <= 0) then
|
||
Exit;
|
||
try
|
||
Image := QImage_create;
|
||
try
|
||
QPixmap_convertToImage(Bitmap, Image);
|
||
Result := (QImage_width(Image) * QImage_height(Image) * QImage_depth(Image) + 7) div 8;
|
||
if Count < Result then
|
||
Result := Count;
|
||
if Result > 0 then
|
||
Move(QImage_bits(Image)^, Bits^, Result);
|
||
finally
|
||
QImage_destroy(Image);
|
||
end;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function SetBitmapBits(Bitmap: QPixmapH; Count: Longint; Bits: Pointer): Longint;
|
||
var
|
||
Image: QImageH;
|
||
begin
|
||
Result := 0;
|
||
if (Bitmap = nil) or (Count <= 0) then
|
||
Exit;
|
||
try
|
||
Image := QImage_create;
|
||
try
|
||
QPixmap_convertToImage(Bitmap, Image);
|
||
Result := (QImage_width(Image) * QImage_height(Image) * QImage_depth(Image) + 7) div 8;
|
||
if Count < Result then
|
||
Result := Count;
|
||
if Result > 0 then
|
||
Move(Bits^, QImage_bits(Image)^, Result);
|
||
QPixmap_convertFromImage(Bitmap, Image, QPixmapColorMode_Auto);
|
||
finally
|
||
QImage_destroy(Image);
|
||
end;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function GetObject(Handle: QPixmapH; Size: Cardinal; Data: PtagBITMAP): Boolean;
|
||
begin
|
||
Result := False;
|
||
if (Handle <> nil) and (Size > 0) and (Data <> nil) then
|
||
begin
|
||
try
|
||
Data.bmWidth := QPixmap_width(Handle);
|
||
Data.bmHeight := QPixmap_height(Handle);
|
||
Data.bmBitsPixel := QPixmap_depth(Handle);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function GetObject(Handle: QPenH; Size: Cardinal; Data: PLogPen): Boolean;
|
||
begin
|
||
Result := False;
|
||
if (Handle <> nil) and (Size > 0) and (Data <> nil) then
|
||
begin
|
||
try
|
||
Data.lopnStyle := Cardinal(QPen_style(Handle));
|
||
Data.lopnWidth := Point(QPen_width(Handle), 0);
|
||
Data.lopnColor := QColorColor(QPen_color(Handle));
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function SetPixel(Handle: QPainterH; X, Y: Integer; Color: TColor): TColorRef;
|
||
var
|
||
Brush: QBrushH;
|
||
OldRop: RasterOp;
|
||
R: TRect;
|
||
begin
|
||
R := Bounds(X, Y, 1, 1);
|
||
Brush := CreateSolidBrush(Color);
|
||
OldRop := QPainter_rasterOp(Handle);
|
||
if OldRop <> RasterOp_CopyROP then
|
||
QPainter_setRasterOp(Handle, RasterOp_CopyROP);
|
||
FillRect(Handle, R, Brush);
|
||
if OldRop <> RasterOp_CopyROP then
|
||
QPainter_setRasterOp(Handle, OldRop);
|
||
QBrush_destroy(Brush);
|
||
Result := GetPixel(Handle, X, Y);
|
||
end;
|
||
|
||
function GetPixel(Handle: QPainterH; X, Y: Integer): TColorRef;
|
||
var
|
||
depth: Integer;
|
||
pixmap: QPixmapH;
|
||
pdm: QPaintDeviceMetricsH;
|
||
tempDC: QPainterH;
|
||
img: QImageH;
|
||
begin
|
||
try
|
||
pdm := QPaintDeviceMetrics_create(QPainter_device(Handle));
|
||
depth := QPaintDeviceMetrics_depth(pdm);
|
||
QPaintDeviceMetrics_destroy(pdm);
|
||
img := nil;
|
||
tempdc := nil;
|
||
pixmap := nil;
|
||
try
|
||
pixmap := QPixmap_create(2, 2, depth, QPixmapOptimization_NoOptim);
|
||
tempDC := QPainter_create(pixmap);
|
||
BitBlt(tempDC, 0, 0, 2, 2, Handle, X, Y, SRCCOPY);
|
||
img := QImage_create;
|
||
QPixmap_convertToImage(pixmap, img);
|
||
Result := QImage_pixelIndex(img, 0, 0);
|
||
finally
|
||
if Assigned(img) then
|
||
QImage_destroy(img);
|
||
if Assigned(tempdc) then
|
||
QPainter_destroy(tempdc);
|
||
if Assigned(pixmap) then
|
||
QPixmap_destroy(pixmap);
|
||
end;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
function DeleteObject(Handle: QPainterH): LongBool;
|
||
var
|
||
Pixmap: QPaintDeviceH;
|
||
P: PPainterInfo;
|
||
IsCompatible: Boolean;
|
||
begin
|
||
if Handle = nil then
|
||
Result := False
|
||
else
|
||
try
|
||
Pixmap := QPainter_device(Handle); // get paintdevice
|
||
if QPainter_isActive(Handle) then
|
||
QPainter_end(Handle);
|
||
|
||
IsCompatible := GetPainterInfo(Handle, P) and (P.IsCompatibleDC);
|
||
if P <> nil then
|
||
DeletePainterInfo(Handle);
|
||
QPainter_destroy(Handle); // destroy painter
|
||
if IsCompatible then
|
||
QPixmap_destroy(QPixmapH(Pixmap)); // destroy pixmap paintdevice
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function DeleteObject(Handle: QPixmapH): LongBool;
|
||
begin
|
||
try
|
||
// if not TStockObjectList.ReleaseStockObject(Handle) then
|
||
QPixmap_destroy(Handle);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function SaveDC(Handle: QPainterH): Integer;
|
||
begin
|
||
try
|
||
QPainter_save(Handle);
|
||
Result := -1;
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
|
||
{ only negative and zero values of nSaveDC are supported }
|
||
function RestoreDC(Handle: QPainterH; nSavedDC: Integer): LongBool;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
if nSavedDC < 0 then
|
||
begin
|
||
try
|
||
for i:= nSavedDC - 1 to 0 do // nSavedDC
|
||
QPainter_restore(Handle);
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end
|
||
else // limited implementation
|
||
Result := True;
|
||
end;
|
||
|
||
function HWND_DESKTOP: QWidgetH;
|
||
begin
|
||
Result := QApplication_desktop;
|
||
end;
|
||
|
||
function GetDesktopWindow: QWidgetH;
|
||
begin
|
||
Result := HWND_DESKTOP;
|
||
end;
|
||
|
||
function GetActiveWindow: QWidgetH;
|
||
begin
|
||
Result := QApplication_activeWindow(Application.Handle);
|
||
end;
|
||
|
||
function GetForegroundWindow: QWidgetH;
|
||
begin
|
||
// is this correct ?
|
||
Result := QApplication_focusWidget(Application.Handle);
|
||
end;
|
||
|
||
procedure SetActiveWindow(Handle: QWidgetH);
|
||
begin
|
||
QWidget_setActiveWindow(Handle);
|
||
end;
|
||
|
||
// maps DT_ alignment flags to Qt (extended) alignment flags
|
||
function Win2QtAlign(Flags: Integer): Integer;
|
||
begin
|
||
Result := 0;
|
||
// Singleline & multiline
|
||
if Flags and DT_SINGLELINE <> 0 then
|
||
Result := SingleLine
|
||
// multiline:
|
||
else if Flags and DT_WORDBREAK <> 0 then
|
||
Result := Result or WordBreak;
|
||
// else
|
||
// Result := Result or BreakAnywhere;
|
||
// <tab> and '&' prefix
|
||
if Flags and DT_EXPANDTABS <> 0 then
|
||
Result := Result or ExpandTabs;
|
||
if Flags and DT_NOPREFIX = 0 then
|
||
Result := Result or ShowPrefix;
|
||
// Horizontal alignment
|
||
if Flags and DT_RIGHT <> 0 then
|
||
Result := Result or AlignRight
|
||
else if Flags and DT_CENTER <> 0 then
|
||
Result := Result or AlignHCenter
|
||
else
|
||
Result := Result or AlignLeft; // default
|
||
// vertical alignment
|
||
if Flags and DT_BOTTOM <> 0 then
|
||
Result := Result or AlignTop
|
||
else if Flags and DT_VCENTER <> 0 then
|
||
Result := Result or AlignVCenter
|
||
else
|
||
Result := Result or AlignTop; // default
|
||
// extended Qt alignments
|
||
if Flags and DT_CALCRECT <> 0 then
|
||
Result := Result or CalcRect
|
||
else
|
||
begin
|
||
if Flags and DT_ELLIPSIS <> 0 then
|
||
Result := Result or ClipName or SingleLine
|
||
else if Flags and DT_PATH_ELLIPSIS <> 0 then
|
||
Result := Result or ClipPath or SingleLine
|
||
else if Flags and DT_WORD_ELLIPSIS <> 0 then
|
||
Result := Result or ClipToWord;
|
||
if Flags and DT_MODIFYSTRING <> 0 then
|
||
Result := Result or ModifyString;
|
||
end;
|
||
if Flags and DT_NOCLIP <> 0 then
|
||
Result := Result or DontClip;
|
||
end;
|
||
|
||
{ strips Qt extended alignment from flags }
|
||
function QtStdAlign(Flags: Integer): Word;
|
||
begin
|
||
Result := Word(Flags and QtAlignMask);
|
||
end;
|
||
|
||
|
||
function IsCharAlpha(Ch: Char): LongBool;
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
Result := Windows.IsCharAlpha(Ch);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Result := IsAlpha(cardinal(ch)) <> 0 ;
|
||
{$ENDIF LINUX}
|
||
end;
|
||
|
||
function IsCharAlphaNumeric(Ch: Char): LongBool;
|
||
begin
|
||
Result := (Ch in ['0'..'9']) or IsCharAlpha(Ch);
|
||
end;
|
||
|
||
{ IP Address edit control }
|
||
|
||
function MAKEIPRANGE(low, high: Byte): integer;
|
||
begin
|
||
Result := high;
|
||
Result := (Result shl 8) + low;
|
||
end;
|
||
|
||
function MAKEIPADDRESS(b1, b2, b3, b4: cardinal): integer;
|
||
begin
|
||
Result := (b1 shl 24) + (b2 shl 16) + (b3 shl 8) + b4;
|
||
end;
|
||
|
||
function FIRST_IPADDRESS(x: cardinal): cardinal;
|
||
begin
|
||
Result := (x shr 24) and $FF;
|
||
end;
|
||
|
||
function SECOND_IPADDRESS(x: cardinal): cardinal;
|
||
begin
|
||
Result := (x shr 16) and $FF;
|
||
end;
|
||
|
||
function THIRD_IPADDRESS(x: cardinal): cardinal;
|
||
begin
|
||
Result := (x shr 8) and $FF;
|
||
end;
|
||
|
||
function FOURTH_IPADDRESS(x: cardinal): cardinal;
|
||
begin
|
||
Result := x and $FF;
|
||
end;
|
||
|
||
{$IFDEF LINUX}
|
||
function FileGetAttr(const FileName: string): Integer;
|
||
var
|
||
sr: TSearchRec;
|
||
valid: Boolean;
|
||
begin
|
||
Result := 0;
|
||
valid := FindFirst(FileName, faAnyFile, sr) = 0;
|
||
if valid then
|
||
begin
|
||
Result := sr.attr;
|
||
FindClose(sr);
|
||
end;
|
||
end;
|
||
|
||
function FileGetSize(const FileName: string): Cardinal;
|
||
var
|
||
sr: TSearchRec;
|
||
valid: Boolean;
|
||
begin
|
||
Result := 0;
|
||
valid := FindFirst(FileName, faAnyFile, sr) = 0;
|
||
if valid then
|
||
begin
|
||
Result := sr.size;
|
||
FindClose(sr);
|
||
end;
|
||
end;
|
||
|
||
function FileGetTime(const FileName: string): Integer;
|
||
var
|
||
sr: TSearchRec;
|
||
valid: Boolean;
|
||
begin
|
||
Result := 0;
|
||
valid := FindFirst(FileName, faAnyFile, sr) = 0;
|
||
if valid then
|
||
begin
|
||
Result := sr.time;
|
||
FindClose(sr);
|
||
end;
|
||
end;
|
||
|
||
function CopyFile(const Source, Destination: string; FailIfExists: Boolean): LongBool;
|
||
const
|
||
ChunkSize = 8192;
|
||
var
|
||
CopyBuffer: Pointer;
|
||
Src, Dest: Integer;
|
||
{FSize,} BytesCopied {, TotalCopied}: Longint;
|
||
DestName: string;
|
||
begin
|
||
Result := False;
|
||
if DirectoryExists(Destination) then
|
||
DestName := IncludeTrailingPathDelimiter(Destination) + ExtractFileName(Source)
|
||
else
|
||
DestName := Destination;
|
||
if FailIfExists and FileExists(DestName) then
|
||
Exit;
|
||
Result := ForceDirectories(ExtractFilePath(Destination));
|
||
if Result then
|
||
begin
|
||
GetMem(CopyBuffer, ChunkSize);
|
||
try
|
||
Dest := FileCreate(DestName);
|
||
if Dest < 0 then
|
||
raise EFCreateError.CreateFmt(SFCreateError, [DestName]);
|
||
try
|
||
// TotalCopied := 0;
|
||
Src := FileOpen(source, fmShareDenyWrite);
|
||
if Src < 0 then
|
||
raise EFOpenError.CreateFmt(SFOpenError, [source]);
|
||
try
|
||
//FSize := GetFileSize(source);
|
||
repeat
|
||
BytesCopied := FileRead(Src, CopyBuffer^, ChunkSize);
|
||
if BytesCopied = -1 then
|
||
raise EReadError.Create(SReadError);
|
||
// TotalCopied := TotalCopied + BytesCopied;
|
||
if BytesCopied > 0 then
|
||
begin
|
||
if FileWrite(Dest, CopyBuffer^, BytesCopied) = -1 then
|
||
raise EWriteError.Create(SWriteError);
|
||
end;
|
||
until BytesCopied < ChunkSize;
|
||
FileSetDate(DestName, FileGetDate(Src));
|
||
Result := True;
|
||
finally
|
||
FileClose(Src);
|
||
end;
|
||
finally
|
||
FileClose(Dest);
|
||
end;
|
||
finally
|
||
FreeMem(CopyBuffer, ChunkSize);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function CopyFile(lpExistingFileName, lpNewFileName: PChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
var
|
||
EF, NF: string;
|
||
begin
|
||
EF := lpExistingFileName;
|
||
NF := lpNewFilename;
|
||
Result := CopyFile(EF, NF, Boolean(bFailIfExists));
|
||
end;
|
||
|
||
function CopyFileA(lpExistingFileName, lpNewFileName: PAnsiChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
var
|
||
EF, NF: string;
|
||
begin
|
||
EF := lpExistingFileName;
|
||
NF := lpNewFilename;
|
||
Result := CopyFile(EF, NF, Boolean(bFailIfExists));
|
||
end;
|
||
|
||
function CopyFileW(lpExistingFileName, lpNewFileName: PWideChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
var
|
||
EF, NF: string;
|
||
begin
|
||
EF := lpExistingFileName;
|
||
NF := lpNewFilename;
|
||
Result := CopyFile(EF, NF, bFailIfExists);
|
||
end;
|
||
|
||
function GetComputerName(Buffer: PChar; var Size: Cardinal): LongBool;
|
||
var
|
||
S: string;
|
||
begin
|
||
Result := True;
|
||
try
|
||
SetLength(S, 255);
|
||
if gethostname(PChar(S), Length(S)) <> -1 then
|
||
begin
|
||
SetLength(S, StrLen(PChar(S)));
|
||
Size := Length(S) + 1;
|
||
Result := S <> '';
|
||
if Result and (Buffer <> nil) then
|
||
StrLCopy(Buffer, PChar(S), Size - 1);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function GetUserName(Buffer: PChar; var Size: Cardinal): LongBool;
|
||
var
|
||
S: string;
|
||
psswrd: PPasswordRecord;
|
||
begin
|
||
Result := False;
|
||
try
|
||
psswrd := getpwuid(getuid); // static no need to free
|
||
if psswrd <> nil then
|
||
begin
|
||
S := psswrd.pw_gecos; // user's real name? or pwd.pw_name
|
||
Size := Length(S) + 1;
|
||
Result := S <> '';
|
||
if Result and (Buffer <> nil) then
|
||
StrLCopy(Buffer, PChar(S), Size - 1);
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function MakeIntResource(Value: Integer): PChar;
|
||
begin
|
||
Result := PChar(Value and $0000ffff);
|
||
end;
|
||
|
||
function MakeWord(A, B: Byte): Word;
|
||
begin
|
||
Result := A or B shl 8;
|
||
end;
|
||
|
||
function MakeLong(A, B: Word): Longint;
|
||
begin
|
||
Result := A or B shl 16;
|
||
end;
|
||
|
||
function HiWord(L: DWORD): Word;
|
||
begin
|
||
Result := L shr 16;
|
||
end;
|
||
|
||
function HiByte(W: Word): Byte;
|
||
begin
|
||
Result := W shr 8;
|
||
end;
|
||
|
||
procedure MessageBeep(Value: Integer);
|
||
begin
|
||
QApplication_beep;
|
||
end;
|
||
|
||
procedure OutputDebugString(OutputString: AnsiString);
|
||
begin
|
||
WriteLn(ErrOutput, Format('%s %s (%d)', [OutputString, ExtractFilename(Application.ExeName), GetCurrentThreadID]));
|
||
end;
|
||
|
||
procedure OutputDebugString(lpOutputString: PAnsiChar);
|
||
begin
|
||
OutputDebugString(string(lpOutputString));
|
||
end;
|
||
|
||
function GetCurrentProcess: THandle;
|
||
begin
|
||
Result := THandle(0);
|
||
end;
|
||
|
||
function CheckThreadError(ErrCode: Integer): Integer;
|
||
begin
|
||
if ErrCode <> 0 then
|
||
raise EThread.CreateResFmt(@SQThreadError, [SysErrorMessage(ErrCode), ErrCode]);
|
||
Result := ErrCode;
|
||
end;
|
||
|
||
function TerminateThread(ThreadID: TThreadID; RetVal: Integer): LongBool;
|
||
begin
|
||
case RetVal of
|
||
0:
|
||
Result := CheckThreadError(pthread_kill(ThreadID, SIGQUIT)) = 0;
|
||
130:
|
||
Result := CheckThreadError(pthread_kill(ThreadID, SIGABRT)) = 0; /// CTRL_C
|
||
else
|
||
Result := CheckThreadError(pthread_kill(ThreadID, SIGKILL))= 0; // unmaskable
|
||
end;
|
||
end;
|
||
|
||
function SuspendThread(ThreadID: TThreadID): LongBool;
|
||
begin
|
||
Result := CheckThreadError(pthread_kill(ThreadID, SIGSTOP)) = 0;
|
||
end;
|
||
|
||
function ResumeThread(ThreadID: TThreadID): LongBool;
|
||
begin
|
||
Result := CheckThreadError(pthread_kill(ThreadID, SIGCONT)) = 0;
|
||
end;
|
||
|
||
function GetThreadPolicy(ThreadID: TThreadID): Integer;
|
||
var
|
||
SP: TSchedParam;
|
||
begin
|
||
CheckThreadError(pthread_getschedparam(ThreadID, Result, SP));
|
||
end;
|
||
|
||
procedure SetThreadPolicy(ThreadID: TThreadID; value: Integer);
|
||
var
|
||
SP: TSchedParam;
|
||
begin
|
||
if Value <> GetThreadPolicy(ThreadID) then
|
||
begin
|
||
SP.sched_priority := GetThreadPriority(ThreadID);
|
||
CheckThreadError(pthread_setschedparam(ThreadID, Value, @SP));
|
||
end;
|
||
end;
|
||
|
||
function GetThreadPriority(ThreadID: TThreadID): TThreadPriority;
|
||
var
|
||
P: Integer;
|
||
SP: TSchedParam;
|
||
begin
|
||
if CheckThreadError(pthread_getschedparam(ThreadID, P, SP)) <> 0
|
||
then
|
||
Result := THREAD_PRIORITY_ERROR_RETURN
|
||
else
|
||
Result := SP.sched_priority;
|
||
end;
|
||
|
||
function SetThreadPriority(ThreadID: TThreadID; priority: Integer): LongBool; // handle to the thread
|
||
var
|
||
SP: TSchedParam;
|
||
P: Integer;
|
||
begin
|
||
if priority <> GetThreadPriority(ThreadID) then
|
||
begin
|
||
SP.sched_priority := priority;
|
||
P:= GetThreadPolicy(ThreadID);
|
||
CheckThreadError(pthread_setschedparam(ThreadID, P, @SP));
|
||
Result := errno = 0;
|
||
end
|
||
else
|
||
Result := True;
|
||
end;
|
||
|
||
function VirtualProtect(lpAddress: Pointer; dwSize, flNewProtect: Cardinal;
|
||
lpflOldProtect: Pointer): LongBool; overload;
|
||
var
|
||
AlignedAddress: Cardinal;
|
||
PageSize, ProtectSize: Cardinal;
|
||
begin
|
||
if lpflOldProtect <> nil then
|
||
begin
|
||
// (ahuser) I have not found a Libc function for that
|
||
PCardinal(lpflOldProtect)^ := PAGE_EXECUTE_READWRITE;
|
||
end;
|
||
|
||
PageSize := Cardinal(Libc.getpagesize);
|
||
AlignedAddress := Cardinal(lpAddress) and not (PageSize - 1); // start memory page
|
||
// get the number of needed memory pages
|
||
ProtectSize := PageSize;
|
||
while Cardinal(lpAddress) + dwSize > AlignedAddress + ProtectSize do
|
||
Inc(ProtectSize, PageSize);
|
||
Result := mprotect(Pointer(AlignedAddress), ProtectSize, flNewProtect) = 0;
|
||
end;
|
||
|
||
function VirtualProtect(lpAddress: Pointer; dwSize, flNewProtect: Cardinal;
|
||
var OldProtect: Cardinal): LongBool; overload;
|
||
begin
|
||
Result := VirtualProtect(lpAddress, dwSize, flNewProtect, @OldProtect);
|
||
end;
|
||
|
||
function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
|
||
lpBuffer: Pointer; nSize: LongWord; var lpNumberOfBytesRead: Cardinal): LongBool;
|
||
var
|
||
OldProt, Dummy: Cardinal;
|
||
begin
|
||
Result := False;
|
||
lpNumberOfBytesRead := 0;
|
||
if (hProcess = GetCurrentProcess) and (lpBuffer <> nil) then
|
||
begin
|
||
if nSize = 0 then
|
||
Result := True
|
||
else
|
||
if VirtualProtect(lpBaseAddress, nSize, PAGE_EXECUTE_READWRITE, OldProt) then
|
||
begin
|
||
try
|
||
Move(lpBaseAddress^, lpBuffer^, nSize);
|
||
lpNumberOfBytesRead := nSize;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
VirtualProtect(lpBaseAddress, nSize, OldProt, Dummy);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
|
||
lpBuffer: Pointer; nSize: LongWord; var lpNumberOfBytesWritten: Longword): LongBool;
|
||
var
|
||
OldProt, Dummy: Cardinal;
|
||
begin
|
||
Result := False;
|
||
lpNumberOfBytesWritten := 0;
|
||
if (hProcess = GetCurrentProcess) and (lpBuffer <> nil) then
|
||
begin
|
||
if nSize = 0 then
|
||
Result := True
|
||
else
|
||
if VirtualProtect(lpBaseAddress, nSize, PAGE_EXECUTE_READWRITE, OldProt) then
|
||
begin
|
||
try
|
||
Move(lpBuffer^, lpBaseAddress^, nSize);
|
||
lpNumberOfBytesWritten := nSize;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
VirtualProtect(lpBaseAddress, nSize, OldProt, Dummy);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure FlushInstructionCache(PID: cardinal; OrgCalProc: Pointer; size: Integer);
|
||
asm
|
||
JMP @@Exit
|
||
// 64 Bytes:
|
||
DD 0, 0, 0, 0, 0, 0, 0, 0
|
||
DD 0, 0, 0, 0, 0, 0, 0, 0
|
||
@@Exit:
|
||
end;
|
||
|
||
function GetKeyState(nVirtKey: Integer): SmallInt;
|
||
begin
|
||
Result := 0;
|
||
case nVirtKey of
|
||
Key_Shift:
|
||
if ssShift in Application.KeyState then
|
||
Result := -32768; // = $8000
|
||
Key_Control:
|
||
if ssCtrl in Application.KeyState then
|
||
Result := -32768;
|
||
Key_Menu:
|
||
if ssAlt in Application.KeyState then
|
||
Result := -32768;
|
||
end;
|
||
end;
|
||
|
||
function GetAsyncKeyState(vKey: Integer): SmallInt;
|
||
var
|
||
Root: Window;
|
||
Child: Window;
|
||
RootX, RootY, WinX, WinY: Longint;
|
||
Mask: Cardinal;
|
||
begin
|
||
XQueryPointer(Application.Display,
|
||
XRootWindow(Application.Display, XDefaultScreen(Application.Display)),
|
||
@Root, @Child, @RootX, @RootY, @WinX, @WinY, @Mask);
|
||
Result := 0;
|
||
case vKey of
|
||
VK_SHIFT:
|
||
if Mask and ShiftMask <> 0 then
|
||
Result := -32768; // = $8000
|
||
VK_CONTROL:
|
||
if Mask and ControlMask <> 0 then
|
||
Result := -32768;
|
||
VK_MENU:
|
||
if Mask and Mod1Mask <> 0 then
|
||
Result := -32768;
|
||
end;
|
||
end;
|
||
|
||
|
||
// Handle-Values and IPC
|
||
type
|
||
THandleObjectList = class;
|
||
|
||
THandleObject = class(TObject)
|
||
private
|
||
FRefCount: Integer;
|
||
FName: string;
|
||
FList: THandleObjectList;
|
||
public
|
||
constructor Create(AList: THandleObjectList; const AName: string);
|
||
destructor Destroy; override;
|
||
procedure AddRef;
|
||
procedure Release;
|
||
|
||
property Name: string read FName;
|
||
property List: THandleObjectList read FList;
|
||
end;
|
||
|
||
TWaitObject = class(THandleObject)
|
||
constructor Create(const AName: string);
|
||
function WaitFor(Timeout: Longword): Cardinal; virtual; abstract;
|
||
end;
|
||
|
||
THandleObjectList = class(TObjectList)
|
||
private
|
||
FLockHandle: TSemaphore;
|
||
function GetItems(Index: Integer): THandleObject;
|
||
public
|
||
constructor Create;
|
||
destructor Destroy; override;
|
||
procedure Enter;
|
||
procedure Leave;
|
||
function Find(const AName: string): THandleObject;
|
||
property Items[Index: Integer]: THandleObject read GetItems;
|
||
end;
|
||
|
||
TSemaphoreWaitObject = class(TWaitObject)
|
||
private
|
||
FOwnSem: Boolean;
|
||
FSemId: Integer;
|
||
public
|
||
constructor Create(InitialCount, Max: Integer; const AName: string; Open: Boolean);
|
||
destructor Destroy; override;
|
||
function WaitFor(Timeout: Longword): Cardinal; override;
|
||
function ReleaseSemaphore(ReleaseCount: Integer; PreviousCount: PInteger): Boolean;
|
||
end;
|
||
|
||
TEventWaitObject = class(TWaitObject)
|
||
private
|
||
FManualReset: Boolean;
|
||
FEvent: TEvent;
|
||
FSignaled: Boolean;
|
||
public
|
||
constructor Create(EventAttributes: PSecurityAttributes;
|
||
ManualReset, InitialState: LongBool; const AName: string);
|
||
destructor Destroy; override;
|
||
function WaitFor(Timeout: Longword): Cardinal; override;
|
||
function SetEvent: Boolean;
|
||
function ResetEvent: Boolean;
|
||
end;
|
||
|
||
TEventTimeoutThread = class(TThread)
|
||
private
|
||
FStopped: Boolean;
|
||
FEvent: TEventWaitObject;
|
||
FTimeout: Integer;
|
||
protected
|
||
procedure Execute; override;
|
||
public
|
||
constructor Create(AEvent: TEventWaitObject; ATimeout: Integer);
|
||
property Stopped: Boolean read FStopped write FStopped;
|
||
end;
|
||
|
||
TMutexWaitObject = class(TSemaphoreWaitObject)
|
||
private
|
||
FOwnerThreadId: Cardinal;
|
||
FThreadLocks: Integer;
|
||
FCritSect: TRTLCriticalSection;
|
||
public
|
||
constructor Create(const AName: string; Open: Boolean);
|
||
destructor Destroy; override;
|
||
function WaitFor(Timeout: Longword): Cardinal; override;
|
||
function ReleaseMutex: Boolean;
|
||
end;
|
||
|
||
var
|
||
WaitObjectList: THandleObjectList;
|
||
|
||
{ THandleObject }
|
||
|
||
constructor THandleObject.Create(AList: THandleObjectList; const AName: string);
|
||
begin
|
||
inherited Create;
|
||
FList := AList;
|
||
FName := AName;
|
||
FRefCount := 0;
|
||
if Assigned(FList) then
|
||
FList.Add(Self);
|
||
AddRef;
|
||
end;
|
||
|
||
destructor THandleObject.Destroy;
|
||
begin
|
||
if Assigned(FList) then
|
||
FList.Extract(Self);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure THandleObject.AddRef;
|
||
begin
|
||
Inc(FRefCount);
|
||
end;
|
||
|
||
procedure THandleObject.Release;
|
||
begin
|
||
Dec(FRefCount);
|
||
if FRefCount <= 0 then
|
||
Free;
|
||
end;
|
||
|
||
{ TWaitObject }
|
||
|
||
constructor TWaitObject.Create(const AName: string);
|
||
begin
|
||
inherited Create(WaitObjectList, AName);
|
||
end;
|
||
|
||
{ THandleObjectList }
|
||
|
||
constructor THandleObjectList.Create;
|
||
begin
|
||
inherited Create;
|
||
sem_init(FLockHandle, False, 1);
|
||
end;
|
||
|
||
destructor THandleObjectList.Destroy;
|
||
begin
|
||
sem_destroy(FLockHandle);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure THandleObjectList.Enter;
|
||
begin
|
||
sem_wait(FLockHandle);
|
||
end;
|
||
|
||
procedure THandleObjectList.Leave;
|
||
begin
|
||
sem_post(FLockHandle);
|
||
end;
|
||
|
||
function THandleObjectList.GetItems(Index: Integer): THandleObject;
|
||
begin
|
||
Result := THandleObject(inherited Items[Index]);
|
||
end;
|
||
|
||
function THandleObjectList.Find(const AName: string): THandleObject;
|
||
var
|
||
I: Integer;
|
||
begin
|
||
if AName <> '' then
|
||
begin
|
||
for I := 0 to Count - 1 do
|
||
begin
|
||
Result := Items[I];
|
||
if Result.Name = AName then
|
||
Exit;
|
||
end;
|
||
end;
|
||
Result := nil;
|
||
end;
|
||
|
||
{ TSemaphoreWaitObject }
|
||
|
||
// asn: documented, but (afaics) not in libc.so.6
|
||
//function semtimedop; external libcmodulename name 'semtimedop';
|
||
|
||
function semtimedop(semid: Integer; sops: PSemaphoreBuffer;
|
||
nsops: size_t;timeout: PTimeSpec): Integer;
|
||
var
|
||
sem: TSemaphoreBuffer;
|
||
psem: PSemaphoreBuffer;
|
||
i: Integer;
|
||
WaitTicks, StartTicks: cardinal;
|
||
begin
|
||
if timeout = nil then
|
||
Result := semop(semid, sops, nsops)
|
||
else
|
||
begin
|
||
Result := 0; // incase nsops = 0
|
||
WaitTicks := 1000 * timeout.tv_sec + timeout.tv_nsec div 1000000;
|
||
psem := sops;
|
||
StartTicks := GetTickCount ;
|
||
try
|
||
for i:= 0 to nsops-1 do
|
||
begin
|
||
sem := psem^ ;
|
||
sem.sem_flg := sem.sem_flg OR IPC_NOWAIT;
|
||
|
||
// process one sem
|
||
while (GetTickCount - StartTicks) <= WaitTicks do
|
||
begin
|
||
Result := semop(semid, @sem, 1);
|
||
if Result <> -1 then
|
||
begin
|
||
inc(psem); // succes, next semaphore
|
||
break;
|
||
end
|
||
else
|
||
begin
|
||
if (errno = EAGAIN) and ((psem^.sem_flg and IPC_NOWAIT) = 0)
|
||
then
|
||
Sleep(10) // try again
|
||
else
|
||
Exit; // no wait allowed or other error
|
||
end;
|
||
end; // while
|
||
|
||
if (Result = -1) and (errno <> EAGAIN) then
|
||
break;
|
||
end; // for i:= 0 to ..
|
||
except
|
||
Result := -1;
|
||
// errno := EFAULT;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function GetIPCKey(const AName: string; What: Integer): Integer;
|
||
var
|
||
Filename: string;
|
||
begin
|
||
if AName = '' then
|
||
Result := IPC_PRIVATE
|
||
else
|
||
begin
|
||
Filename := IpcDirectory + PathDelim + AName;
|
||
ForceDirectories(IpcDirectory);
|
||
if not FileExists(Filename) then
|
||
FileClose(FileCreate(Filename));
|
||
Result := ftok(PChar(Filename), What);
|
||
end;
|
||
end;
|
||
|
||
type
|
||
TSemUnion = record
|
||
case Integer of
|
||
0: (val: Integer);
|
||
1: (buf: PSemaphoreIdDescriptor);
|
||
2: (ary: PWord);
|
||
3: (__buf: PSemaphoreInfo);
|
||
end;
|
||
|
||
constructor TSemaphoreWaitObject.Create(InitialCount, Max: Integer; const AName: string;
|
||
Open: Boolean);
|
||
const
|
||
AccessMode = S_IREAD or S_IWRITE or S_IRGRP or S_IWGRP;
|
||
var
|
||
Arg: TSemUnion;
|
||
IPCKey: Integer;
|
||
begin
|
||
inherited Create(AName);
|
||
IPCKey := GetIPCKey(Name, 1);
|
||
if not Open then
|
||
FSemId := semget(IPCKey, 1, IPC_CREAT or IPC_EXCL or AccessMode)
|
||
else
|
||
FSemId := -1; // open
|
||
|
||
if FSemId = -1 then
|
||
begin
|
||
// open sempahore
|
||
FOwnSem := False;
|
||
FSemId := semget(IPCKey, 0, SEM_UNDO);
|
||
if FSemId = -1 then
|
||
RaiseLastOSError;
|
||
end
|
||
else
|
||
begin
|
||
FOwnSem := True;
|
||
Arg.val := Max - InitialCount;
|
||
if semctl(FSemId, 0, SETVAL, Arg) = -1 then
|
||
RaiseLastOSError;
|
||
end;
|
||
end;
|
||
|
||
destructor TSemaphoreWaitObject.Destroy;
|
||
begin
|
||
if FOwnSem then
|
||
begin
|
||
semctl(FSemId, 0, IPC_RMID);
|
||
if Name <> '' then
|
||
DeleteFile(IpcDirectory + PathDelim + Name); // only if allowed
|
||
end;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TSemaphoreWaitObject.WaitFor(Timeout: Longword): Cardinal;
|
||
var
|
||
Buf: TSemaphoreBuffer;
|
||
RetValue: Integer;
|
||
timespec: TTimeSpec;
|
||
begin
|
||
Buf.sem_num := 0;
|
||
Buf.sem_op := -1;
|
||
Buf.sem_flg := SEM_UNDO;
|
||
if Timeout = INFINITE then
|
||
// RetValue := semop(FSemId, @Buf, 1)
|
||
Timeout := 2000000;
|
||
// else
|
||
if Timeout = 0 then
|
||
begin
|
||
Buf.sem_flg := Buf.sem_flg or IPC_NOWAIT;
|
||
RetValue := semop(FSemId, @Buf, 1);
|
||
end
|
||
else
|
||
begin
|
||
timespec.tv_sec := Timeout div 1000;
|
||
timespec.tv_nsec := (Timeout mod 1000) * 1000000;
|
||
RetValue := semtimedop(FSemId, @Buf, 1, @timespec); // Timeout=0 -> INFINTE
|
||
end;
|
||
|
||
if RetValue = -1 then
|
||
begin
|
||
if errno = EAGAIN then
|
||
Result := WAIT_TIMEOUT
|
||
else
|
||
Result := WAIT_FAILED;
|
||
end
|
||
else
|
||
Result := WAIT_OBJECT_0;
|
||
end;
|
||
|
||
function TSemaphoreWaitObject.ReleaseSemaphore(ReleaseCount: Integer; PreviousCount: PInteger): Boolean;
|
||
var
|
||
Buf: TSemaphoreBuffer;
|
||
Arg: TSemUnion;
|
||
begin
|
||
Result := False;
|
||
if ReleaseCount >= 0 then
|
||
begin
|
||
if PreviousCount <> nil then
|
||
begin
|
||
Result := semctl(FSemId, 0, GETVAL, @Arg) = 0;
|
||
PreviousCount^ := Arg.val;
|
||
end;
|
||
if ReleaseCount > 0 then
|
||
begin
|
||
Buf.sem_num := 0;
|
||
Buf.sem_op := ReleaseCount;
|
||
Buf.sem_flg := SEM_UNDO;
|
||
Result := semop(FSemId, @Buf, 1) = 0;
|
||
end;
|
||
end
|
||
end;
|
||
|
||
{ TEventTimeoutThread }
|
||
|
||
constructor TEventTimeoutThread.Create(AEvent: TEventWaitObject; ATimeout: Integer);
|
||
begin
|
||
FEvent := AEvent;
|
||
FTimeout := ATimeout;
|
||
FStopped := False;
|
||
inherited Create(False);
|
||
end;
|
||
|
||
procedure TEventTimeoutThread.Execute;
|
||
var
|
||
StartTime, CurrentTime: Int64;
|
||
begin
|
||
StartTime := GetTickCount;
|
||
while not FStopped do
|
||
begin
|
||
CurrentTime := GetTickCount;
|
||
if CurrentTime < StartTime then
|
||
Inc(CurrentTime, $100000000);
|
||
if CurrentTime - StartTime > FTimeout then
|
||
begin
|
||
FStopped := True;
|
||
FEvent.SetEvent;
|
||
Break;
|
||
end;
|
||
Sleep(10);
|
||
end;
|
||
end;
|
||
|
||
{ TEventWaitObject }
|
||
|
||
type
|
||
TPrivateEvent = class(TEvent)
|
||
protected
|
||
FEvent: TSemaphore;
|
||
{...}
|
||
end;
|
||
|
||
constructor TEventWaitObject.Create(EventAttributes: PSecurityAttributes;
|
||
ManualReset, InitialState: LongBool; const AName: string);
|
||
begin
|
||
inherited Create(AName);
|
||
FManualReset := ManualReset;
|
||
FEvent := TEvent.Create(EventAttributes,
|
||
False, // ManualReset: handled by this class
|
||
InitialState, AName);
|
||
FSignaled := False;
|
||
end;
|
||
|
||
destructor TEventWaitObject.Destroy;
|
||
begin
|
||
sem_destroy(TPrivateEvent(FEvent).FEvent);
|
||
FEvent.Free;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TEventWaitObject.WaitFor(Timeout: Longword): Cardinal;
|
||
var
|
||
TimeoutThread: TEventTimeoutThread;
|
||
begin
|
||
Result := WAIT_FAILED;
|
||
TimeoutThread := nil;
|
||
if Timeout <> INFINITE then
|
||
{ POSIX semaphores do not support a timeout value. Here we use a
|
||
second thread that produces a timeout by releasing the semaphore. }
|
||
TimeoutThread := TEventTimeoutThread.Create(Self, Integer(Timeout));
|
||
try
|
||
case FEvent.WaitFor(INFINITE) of
|
||
wrSignaled:
|
||
Result := WAIT_OBJECT_0;
|
||
wrTimeout:
|
||
Result := WAIT_TIMEOUT; // POSIX semaphores do not have a timeout
|
||
wrAbandoned:
|
||
Result := WAIT_ABANDONED; // for events ?
|
||
end;
|
||
finally
|
||
if Assigned(TimeoutThread) then
|
||
begin
|
||
if TimeoutThread.Stopped then
|
||
Result := WAIT_TIMEOUT;
|
||
TimeoutThread.Stopped := True;
|
||
TimeoutThread.WaitFor;
|
||
TimeoutThread.Free;
|
||
end;
|
||
if FManualReset then
|
||
begin
|
||
FSignaled := True;
|
||
SetEvent; // do not auto-reset
|
||
end
|
||
else
|
||
FSignaled := False;
|
||
end;
|
||
end;
|
||
|
||
function TEventWaitObject.SetEvent: Boolean;
|
||
begin
|
||
FEvent.SetEvent;
|
||
Result := True;
|
||
end;
|
||
|
||
function TEventWaitObject.ResetEvent: Boolean;
|
||
begin
|
||
if FSignaled then
|
||
begin
|
||
FSignaled := False;
|
||
WaitFor(INFINITE); // auto-reset
|
||
end;
|
||
FEvent.ResetEvent;
|
||
Result := True;
|
||
end;
|
||
|
||
{ TMutexWaitObject }
|
||
|
||
constructor TMutexWaitObject.Create(const AName: string; Open: Boolean);
|
||
begin
|
||
inherited Create(0, 1, AName, Open);
|
||
FOwnerThreadId := 0;
|
||
FThreadLocks := 0;
|
||
InitializeCriticalSection(FCritSect);
|
||
end;
|
||
|
||
destructor TMutexWaitObject.Destroy;
|
||
begin
|
||
if FOwnerThreadId <> 0 then
|
||
ReleaseSemaphore(1, nil);
|
||
DeleteCriticalSection(FCritSect);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TMutexWaitObject.WaitFor(Timeout: Longword): Cardinal;
|
||
var
|
||
CurThreadId: Cardinal;
|
||
begin
|
||
CurThreadId := GetCurrentThreadID;
|
||
if CurThreadId = FOwnerThreadId then
|
||
begin
|
||
InterlockedIncrement(FThreadLocks);
|
||
Result := WAIT_OBJECT_0;
|
||
end
|
||
else
|
||
begin
|
||
Result := inherited WaitFor(Timeout);
|
||
if Result = WAIT_OBJECT_0 then
|
||
begin
|
||
EnterCriticalSection(FCritSect);
|
||
try
|
||
FOwnerThreadId := CurThreadId;
|
||
InterlockedIncrement(FThreadLocks);
|
||
finally
|
||
LeaveCriticalSection(FCritSect);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TMutexWaitObject.ReleaseMutex: Boolean;
|
||
begin
|
||
if GetCurrentThreadId = FOwnerThreadId then
|
||
begin
|
||
EnterCriticalSection(FCritSect);
|
||
try
|
||
InterlockedDecrement(FThreadLocks);
|
||
if FThreadLocks <= 0 then
|
||
begin
|
||
Result := ReleaseSemaphore(1, nil);
|
||
FOwnerThreadId := 0;
|
||
FThreadLocks := 0;
|
||
end
|
||
else
|
||
Result := True;
|
||
finally
|
||
LeaveCriticalSection(FCritSect);
|
||
end;
|
||
end
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
// ======= IPC API functions =======
|
||
|
||
function CreateEvent(EventAttributes: PSecurityAttributes;
|
||
ManualReset, InitialState: LongBool; Name: PChar): THandle;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
Result := THandle(WaitObjectList.Find(Name));
|
||
if Result <> 0 then
|
||
begin
|
||
if THandleObject(Result) is TEventWaitObject then
|
||
THandleObject(Result).AddRef
|
||
else
|
||
Result := 0;
|
||
end
|
||
else
|
||
Result := THandle(TEventWaitObject.Create(EventAttributes, ManualReset,
|
||
InitialState, Name));
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function OpenEvent(DesiredAccess: Longword; InheritHandle: LongBool;
|
||
Name: PChar): THandle;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
Result := THandle(WaitObjectList.Find(Name));
|
||
if (Result <> 0) and (THandleObject(Result) is TEventWaitObject) then
|
||
THandleObject(Result).AddRef
|
||
else
|
||
Result := 0;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function SetEvent(Event: THandle): LongBool;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
try
|
||
Result := (Event <> 0) and (THandleObject(Event) is TEventWaitObject);
|
||
if Result then
|
||
TEventWaitObject(Event).SetEvent;
|
||
except
|
||
Result := False;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function ResetEvent(Event: THandle): LongBool;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
try
|
||
Result := (Event <> 0) and (THandleObject(Event) is TEventWaitObject);
|
||
if Result then
|
||
TEventWaitObject(Event).ResetEvent;
|
||
except
|
||
Result := False;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function PulseEvent(Event: THandle): LongBool;
|
||
begin
|
||
// not implemented
|
||
Result := SetEvent(Event);
|
||
end;
|
||
|
||
function CreateMutex(MutexAttributes: PSecurityAttributes; InitialOwner: LongBool;
|
||
Name: PChar): THandle;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
Result := THandle(WaitObjectList.Find(Name));
|
||
if Result <> 0 then
|
||
begin
|
||
if THandleObject(Result) is TMutexWaitObject then
|
||
THandleObject(Result).AddRef
|
||
else
|
||
Result := 0; // no mutex
|
||
end
|
||
else
|
||
begin
|
||
try
|
||
Result := THandle(TMutexWaitObject.Create(Name, False));
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
|
||
if (Result <> 0) and InitialOwner then
|
||
WaitForSingleObject(Result, INFINITE);
|
||
end;
|
||
|
||
function OpenMutex(DesiredAccess: Longword; InheritHandle: Boolean;
|
||
Name: PChar): THandle;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
Result := THandle(WaitObjectList.Find(Name));
|
||
if (Result <> 0) and (THandleObject(Result).ClassType = TMutexWaitObject) then
|
||
THandleObject(Result).AddRef
|
||
else
|
||
begin
|
||
try
|
||
Result := THandle(TMutexWaitObject.Create(Name, True));
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function ReleaseMutex(Mutex: THandle): LongBool;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
try
|
||
Result := (Mutex <> 0) and (THandleObject(Mutex).ClassType = TMutexWaitObject);
|
||
if Result then
|
||
TMutexWaitObject(Mutex).ReleaseMutex;
|
||
except
|
||
Result := False;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function CreateSemaphore(SemaphoreAttributes: PSecurityAttributes;
|
||
InitialCount, MaximumCount: Longint; Name: PChar): THandle;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
Result := THandle(WaitObjectList.Find(Name));
|
||
if Result <> 0 then
|
||
begin
|
||
if THandleObject(Result).ClassType = TSemaphoreWaitObject then
|
||
THandleObject(Result).AddRef
|
||
else
|
||
Result := 0; // no semaphore
|
||
end
|
||
else
|
||
begin
|
||
if (InitialCount < 0) or (MaximumCount <= 0) or (InitialCount > MaximumCount) then
|
||
Result := 0 // invalid
|
||
else
|
||
begin
|
||
try
|
||
Result := THandle(TSemaphoreWaitObject.Create(InitialCount, MaximumCount,
|
||
Name, False));
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function OpenSemaphore(DesiredAccess: Longword; InheritHandle: LongBool;
|
||
Name: PChar): THandle;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
Result := THandle(WaitObjectList.Find(Name));
|
||
if (Result <> 0) and (THandleObject(Result).ClassType = TSemaphoreWaitObject) then
|
||
THandleObject(Result).AddRef
|
||
else
|
||
begin
|
||
try
|
||
Result := THandle(TSemaphoreWaitObject.Create(0, 0, Name, True));
|
||
except
|
||
Result := 0;
|
||
end;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function ReleaseSemaphore(Semaphore: THandle; ReleaseCount: Longint;
|
||
PreviousCount: PInteger): LongBool;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
try
|
||
Result := (Semaphore <> 0) and (THandleObject(Semaphore).ClassType = TSemaphoreWaitObject);
|
||
if Result then
|
||
TSemaphoreWaitObject(Semaphore).ReleaseSemaphore(ReleaseCount, PreviousCount);
|
||
except
|
||
Result := False;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
// common handle functions
|
||
|
||
function WaitForSingleObject(Handle: THandle; Milliseconds: Cardinal): Cardinal;
|
||
begin
|
||
Result := WAIT_FAILED;
|
||
try
|
||
if (Handle <> 0) and (THandleObject(Handle) is TWaitObject) then
|
||
begin
|
||
TWaitObject(Handle).AddRef;
|
||
try
|
||
Result := TWaitObject(Handle).WaitFor(Milliseconds);
|
||
finally
|
||
TWaitObject(Handle).Release;
|
||
end;
|
||
end;
|
||
except
|
||
Result := WAIT_FAILED;
|
||
end;
|
||
end;
|
||
|
||
// The WaitForMultipleObjects function returns when one of the following occurs:
|
||
//
|
||
// <20> Either any one or all of the specified objects are in the signaled state.
|
||
// <20> The time-out interval elapses.
|
||
function WaitForMultipleObjects(Count: Cardinal; Handles: PWOHandleArray;
|
||
WaitAll: LongBool; Milliseconds: Cardinal): Cardinal;
|
||
var
|
||
i: Integer;
|
||
startticks: int64;
|
||
ticks: Integer;
|
||
begin
|
||
startticks := GetTickCount;
|
||
Result := WAIT_OBJECT_0;
|
||
if WaitAll then
|
||
begin
|
||
for i := 0 to Count - 1 do
|
||
begin
|
||
ticks := Milliseconds - (GetTickCount - StartTicks);
|
||
if ticks < 0 then
|
||
begin
|
||
Result := WAIT_TIMEOUT;
|
||
Exit;
|
||
end
|
||
else
|
||
begin
|
||
Result := WaitForSingleObject(Handles[i], Ticks);
|
||
if Result <> WAIT_OBJECT_0 then
|
||
begin
|
||
Inc(Result, i);
|
||
Exit;
|
||
end;
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
begin //
|
||
while True do
|
||
begin
|
||
for i := 0 to Count-1 do
|
||
begin
|
||
Result := WaitForSingleObject(Handles[i], 0);
|
||
case Result of
|
||
WAIT_FAILED, WAIT_ABANDONED, WAIT_OBJECT_0:
|
||
begin
|
||
Inc(Result, i);
|
||
Exit;
|
||
end;
|
||
else
|
||
if (startticks - GetTickCount) > MilliSeconds then
|
||
begin
|
||
Result := WAIT_TIMEOUT;
|
||
Exit;
|
||
end;
|
||
end;
|
||
end;
|
||
Sleep(5);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
// all Handles are THandleObject derived classes
|
||
function CloseHandle(hObject: THandle): LongBool;
|
||
begin
|
||
WaitObjectList.Enter;
|
||
try
|
||
try
|
||
if (hObject <> 0) then
|
||
THandleObject(hObject).Release;
|
||
Result := True;
|
||
except
|
||
Result := False;
|
||
end;
|
||
finally
|
||
WaitObjectList.Leave;
|
||
end;
|
||
end;
|
||
|
||
function GlobalAllocPtr(Flags: Integer; Bytes: Longint): Pointer;
|
||
begin
|
||
Result := GlobalLock(GlobalAlloc(Flags, Bytes));
|
||
end;
|
||
|
||
function GlobalReAllocPtr(P: Pointer; Bytes: Longint; Flags: Integer): Pointer;
|
||
var
|
||
hMem: Cardinal;
|
||
begin
|
||
hMem := GlobalHandle(P);
|
||
GlobalUnlock(hMem);
|
||
Result := GlobalLock(GlobalReAlloc(hMem, Bytes, Flags));
|
||
end;
|
||
|
||
function GlobalFreePtr(P: Pointer): THandle;
|
||
var
|
||
hMem: Cardinal;
|
||
begin
|
||
hMem := GlobalHandle(P);
|
||
GlobalUnlock(hMem);
|
||
Result := GlobalFree(hMem);
|
||
end;
|
||
|
||
type
|
||
PGlobalBlock = ^TGlobalBlock;
|
||
TGlobalBlock = packed record
|
||
Start: Pointer;
|
||
Size: Longword;
|
||
end;
|
||
|
||
function GlobalAlloc(uFlags: Cardinal; dwBytes: Longword): Cardinal;
|
||
var
|
||
Info: PGlobalBlock;
|
||
Start, P: PByte;
|
||
begin
|
||
Result := 0;
|
||
if dwBytes > 0 then
|
||
begin
|
||
GetMem(P, SizeOf(TGlobalBlock) + dwBytes + 16);
|
||
Start := P;
|
||
Inc(P, SizeOf(TGlobalBlock) + $0F);
|
||
P := Pointer(Cardinal(P) and not $0F);
|
||
Info := Pointer(Cardinal(P) - SizeOf(TGlobalBlock));
|
||
Info^.Start := Start;
|
||
Info^.Size := dwBytes;
|
||
|
||
if uFlags and GMEM_ZEROINIT <> 0 then
|
||
FillChar(P^, dwBytes, 0);
|
||
|
||
Result := Cardinal(P);
|
||
end;
|
||
end;
|
||
|
||
function GlobalReAlloc(hMem: Cardinal; dwBytes: Longword; uFlags: Cardinal): Cardinal;
|
||
var
|
||
CurSize: Longword;
|
||
Offset: Cardinal;
|
||
Start: Pointer;
|
||
Info: PGlobalBlock;
|
||
P: PChar;
|
||
begin
|
||
if dwBytes = 0 then
|
||
begin
|
||
GlobalFree(hMem);
|
||
Result := 0;
|
||
Exit;
|
||
end;
|
||
if hMem = 0 then
|
||
Result := GlobalAlloc(uFlags, dwBytes)
|
||
else
|
||
begin
|
||
CurSize := GlobalSize(hMem);
|
||
Start := PGlobalBlock(hMem - SizeOf(TGlobalBlock))^.Start;
|
||
Offset := hMem - Cardinal(Start);
|
||
ReallocMem(Start, SizeOf(TGlobalBlock) + dwBytes + 16);
|
||
hMem := Cardinal(Start) + Offset;
|
||
P := Pointer(hMem);
|
||
|
||
if hMem and $0F <> 0 then
|
||
begin
|
||
P := Start;
|
||
Inc(P, SizeOf(TGlobalBlock) + $0F);
|
||
P := Pointer(Cardinal(P) and not $0F);
|
||
Info := Pointer(Cardinal(P) - SizeOf(TGlobalBlock));
|
||
Move(Pointer(hMem)^, P^, CurSize); // move data
|
||
hMem := Cardinal(P);
|
||
Info^.Start := Start;
|
||
Info^.Size := dwBytes;
|
||
end;
|
||
|
||
PGlobalBlock(hMem - SizeOf(TGlobalBlock))^.Size := dwBytes;
|
||
if uFlags and GMEM_ZEROINIT <> 0 then
|
||
if CurSize < dwBytes then
|
||
FillChar(P[CurSize], dwBytes - CurSize, 0);
|
||
Result := hMem;
|
||
end;
|
||
end;
|
||
|
||
function GlobalSize(hMem: Cardinal): Longword;
|
||
begin
|
||
if hMem > 0 then
|
||
Result := PGlobalBlock(hMem - SizeOf(TGlobalBlock))^.Size
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function GlobalLock(hMem: Cardinal): Pointer;
|
||
begin
|
||
Result := Pointer(hMem);
|
||
end;
|
||
|
||
function GlobalHandle(Mem: Pointer): Cardinal;
|
||
begin
|
||
Result := Cardinal(Mem);
|
||
end;
|
||
|
||
function GlobalUnlock(hMem: Cardinal): LongBool;
|
||
begin
|
||
Result := hMem <> 0;
|
||
end;
|
||
|
||
function GlobalFree(hMem: Cardinal): Cardinal;
|
||
begin
|
||
if hMem <> 0 then
|
||
begin
|
||
FreeMem(PGlobalBlock(hMem - SizeOf(TGlobalBlock))^.Start);
|
||
Result := 0;
|
||
end
|
||
else
|
||
Result := GMEM_INVALID_HANDLE;
|
||
end;
|
||
|
||
|
||
var
|
||
StartTimeVal: TTimeVal;
|
||
|
||
// linux systems tend to run for months,
|
||
// rolls over after 49.7 days since application start
|
||
// predictable !
|
||
// return value: number of milliseconds since application start
|
||
|
||
function GetTickCount: Cardinal;
|
||
var
|
||
TimeVal: TTimeVal;
|
||
begin
|
||
gettimeofday(TimeVal, nil);
|
||
Result := 1000 * (TimeVal.tv_sec - StartTimeVal.tv_sec) +
|
||
(TimeVal.tv_usec - StartTimeVal.tv_usec) div 1000;
|
||
end;
|
||
|
||
procedure InitGetTickCount;
|
||
begin
|
||
gettimeofday(StartTimeVal, nil);
|
||
end;
|
||
|
||
function QueryPerformanceCounter(var PerformanceCount: int64): LongBool;
|
||
var
|
||
TimeVal: TTimeVal;
|
||
begin
|
||
gettimeofday(TimeVal, nil);
|
||
PerformanceCount := CLOCKS_PER_SEC * TimeVal.tv_sec + Timeval.tv_usec;
|
||
Result := true;
|
||
end;
|
||
|
||
function QueryPerformanceFrequency(var Frequency: int64): LongBool;
|
||
begin
|
||
Frequency := CLOCKS_PER_SEC; // 1 Mhz resolution gettimeofday
|
||
Result := True;
|
||
end;
|
||
|
||
procedure GetLocalTime(var st: TSystemTime);
|
||
var
|
||
dt: TDateTime;
|
||
begin
|
||
dt := Now;
|
||
DecodeDateTime(dt, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
|
||
st.wSecond, st.wMilliseconds);
|
||
st.wDayOfWeek := DayOfTheWeek(dt);
|
||
end;
|
||
|
||
// Provider helpers
|
||
|
||
function Succeeded(Res: HResult): Boolean;
|
||
begin
|
||
Result := Res and $80000000 = 0;
|
||
end;
|
||
|
||
function Failed(Res: HResult): Boolean;
|
||
begin
|
||
Result := Res and $80000000 <> 0;
|
||
end;
|
||
|
||
function ResultCode(Res: HResult): Integer;
|
||
begin
|
||
Result := Res and $0000FFFF;
|
||
end;
|
||
|
||
function CoCreateGUID(out Guid: TGUID): HResult;
|
||
begin
|
||
Result := CreateGuid(Guid);
|
||
end;
|
||
|
||
{$ENDIF LINUX}
|
||
|
||
// for ShellExecute(0, ..
|
||
function ShellExecute(Handle: Integer; Operation, FileName, Parameters,
|
||
Directory: PChar; ShowCmd: Integer): THandle;
|
||
begin
|
||
Result := ShellExecute(QWidgetH(Handle), Operation, FileName,
|
||
Parameters, Directory, ShowCmd);
|
||
end;
|
||
|
||
function ShellExecute(Handle: QWidgetH; Operation, FileName, Parameters,
|
||
Directory: PChar; ShowCmd: Integer): THandle;
|
||
var
|
||
Name: string;
|
||
Dir: string;
|
||
Par: string;
|
||
begin
|
||
if Directory <> nil then
|
||
Dir := Directory;
|
||
if Parameters <> nil then
|
||
Par := Parameters;
|
||
if Filename <> nil then
|
||
Name := FileName;
|
||
Result := ShellExecute(Handle, Operation, Name, Par, Dir, ShowCmd);
|
||
end;
|
||
|
||
function ShellExecute(Handle: QWidgetH; const Operation, FileName, Parameters,
|
||
Directory: string; ShowCmd: Integer): THandle;
|
||
var
|
||
{$IFDEF MSWINDOWS}
|
||
WinId: Integer;
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Line: string;
|
||
{$ENDIF LINUX}
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
if Handle = nil then
|
||
WinId := 0
|
||
else
|
||
WinId := QWidget_winID(Handle);
|
||
Result := ShellAPI.ShellExecute(WinId, PChar(Operation),
|
||
PChar(FileName), PChar(Parameters),
|
||
PChar(Directory), ShowCmd);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
if (Operation = 'open') or (Operation = '') then
|
||
Line := Format('%s "%s" %s',[Shell, Filename, Parameters])
|
||
else
|
||
if Operation = 'browse' then
|
||
Line := Format('%s "%s" %s',
|
||
[GetEnvironmentVariable('BROWSER'), Filename, Parameters])
|
||
else
|
||
begin
|
||
Result := THandle(HINSTANCE_ERROR);
|
||
Exit;
|
||
end;
|
||
Line := Trim(Line)+ '&';
|
||
if Directory <> '' then
|
||
Line := Format('cd "%s";', [Directory]) + Line;
|
||
if Libc.system(PChar(Line)) <> -1 then
|
||
Result := THandle(HINSTANCE_OK)
|
||
else
|
||
Result := THandle(HINSTANCE_ERROR)
|
||
{$ENDIF LINUX}
|
||
end;
|
||
|
||
function InterlockedIncrement(var I: Integer): Integer;
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
Result := Windows.InterlockedIncrement(I);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Result := SysUtils.InterlockedIncrement(I);
|
||
{$ENDIF LINUX}
|
||
end;
|
||
|
||
function InterlockedDecrement(var I: Integer): Integer;
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
Result := Windows.InterlockedDecrement(I);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Result := SysUtils.InterlockedDecrement(I);
|
||
{$ENDIF LINUX}
|
||
end;
|
||
|
||
function InterlockedExchange(var A: Integer; B: Integer): Integer;
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
Result := Windows.InterlockedExchange(A, B);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Result := SysUtils.InterlockedExchange(A, B);
|
||
{$ENDIF LINUX}
|
||
end;
|
||
|
||
function InterlockedExchangeAdd(var A: Integer; B: Integer): Integer;
|
||
begin
|
||
{$IFDEF MSWINDOWS}
|
||
Result := Windows.InterlockedExchangeAdd(A, B);
|
||
{$ENDIF MSWINDOWS}
|
||
{$IFDEF LINUX}
|
||
Result := SysUtils.InterlockedExchangeAdd(A, B);
|
||
{$ENDIF LINUX}
|
||
end;
|
||
|
||
{$IFDEF MSWINDOWS}
|
||
{ wrappers to windows}
|
||
|
||
function CopyFile(lpExistingFileName, lpNewFileName: PChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
begin
|
||
Result := Windows.CopyFile(lpExistingFileName, lpNewFileName, bFailIfExists);
|
||
end;
|
||
|
||
function CopyFileA(lpExistingFileName, lpNewFileName: PAnsiChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
begin
|
||
Result := Windows.CopyFileA(lpExistingFileName, lpNewFileName, bFailIfExists);
|
||
end;
|
||
|
||
function CopyFileW(lpExistingFileName, lpNewFileName: PWideChar;
|
||
bFailIfExists: LongBool): LongBool;
|
||
begin
|
||
Result := Windows.CopyFileW(lpExistingFileName, lpNewFileName, bFailIfExists);
|
||
end;
|
||
|
||
function GetUserName(Buffer: PChar; var Size: Cardinal): LongBool;
|
||
begin
|
||
Result := Windows.GetUserName(Buffer,Size);
|
||
end;
|
||
|
||
function GetComputerName(Buffer: PChar; var Size: Cardinal): LongBool;
|
||
begin
|
||
Result := Windows.GetComputerName(Buffer,Size);
|
||
end;
|
||
|
||
function GetTickCount: Cardinal;
|
||
begin
|
||
Result := Windows.GetTickCount;
|
||
end;
|
||
|
||
function QueryPerformanceCounter(var PerformanceCount: int64): LongBool;
|
||
begin
|
||
Result := Windows.QueryPerformanceCounter(PerformanceCount);
|
||
end;
|
||
|
||
function QueryPerformanceFrequency(var Frequency: int64): LongBool;
|
||
begin
|
||
Result := Windows.QueryPerformanceFrequency(Frequency);
|
||
end;
|
||
|
||
function SetEvent(Event: THandle): LongBool;
|
||
begin
|
||
Result := Windows.SetEvent(Event);
|
||
end;
|
||
|
||
function ResetEvent(Event: THandle): LongBool;
|
||
begin
|
||
Result := Windows.ResetEvent(Event);
|
||
end;
|
||
|
||
function PulseEvent(Event: THandle): LongBool;
|
||
begin
|
||
Result := Windows.PulseEvent(Event);
|
||
end;
|
||
|
||
procedure OutputDebugString(OutputString: AnsiString);
|
||
begin
|
||
Windows.OutputDebugString(PAnsiChar(OutputString));
|
||
end;
|
||
|
||
procedure OutputDebugString(lpOutputString: PAnsiChar);
|
||
begin
|
||
Windows.OutputDebugString(lpOutputString);
|
||
end;
|
||
|
||
function GetKeyState(nVirtKey: Integer): SmallInt;
|
||
begin
|
||
Result := Windows.GetKeyState(nVirtKey);
|
||
end;
|
||
|
||
//
|
||
// Taken from QDialogs.
|
||
//
|
||
type
|
||
PTaskWindow = ^TTaskWindow;
|
||
TTaskWindow = record
|
||
Next: PTaskWindow;
|
||
Window: Windows.HWnd;
|
||
end;
|
||
|
||
var
|
||
TaskActiveWindow: Windows.HWnd = 0;
|
||
TaskFirstWindow: Windows.HWnd = 0;
|
||
TaskFirstTopMost: Windows.HWnd = 0;
|
||
TaskWindowList: PTaskWindow = nil;
|
||
|
||
function DoDisableWindow(Window: Windows.HWnd; Data: Longint): Bool; stdcall;
|
||
var
|
||
P: PTaskWindow;
|
||
begin
|
||
if (Window <> TaskActiveWindow) and Windows.IsWindowVisible(Window) and
|
||
Windows.IsWindowEnabled(Window) then
|
||
begin
|
||
New(P);
|
||
P^.Next := TaskWindowList;
|
||
P^.Window := Window;
|
||
TaskWindowList := P;
|
||
Windows.EnableWindow(Window, False);
|
||
end;
|
||
Result := True;
|
||
end;
|
||
|
||
procedure EnableTaskWindows(WindowList: Pointer);
|
||
var
|
||
P: PTaskWindow;
|
||
begin
|
||
while WindowList <> nil do
|
||
begin
|
||
P := WindowList;
|
||
if Windows.IsWindow(P^.Window) then Windows.EnableWindow(P^.Window, True);
|
||
WindowList := P^.Next;
|
||
Dispose(P);
|
||
end;
|
||
end;
|
||
|
||
function DisableTaskWindows(ActiveWindow: Windows.HWnd): Pointer;
|
||
var
|
||
SaveActiveWindow: Windows.HWND;
|
||
SaveWindowList: Pointer;
|
||
begin
|
||
Result := nil;
|
||
SaveActiveWindow := TaskActiveWindow;
|
||
SaveWindowList := TaskWindowList;
|
||
TaskActiveWindow := ActiveWindow;
|
||
TaskWindowList := nil;
|
||
try
|
||
try
|
||
EnumThreadWindows(GetCurrentThreadID, @DoDisableWindow, 0);
|
||
Result := TaskWindowList;
|
||
except
|
||
EnableTaskWindows(TaskWindowList);
|
||
raise;
|
||
end;
|
||
finally
|
||
TaskWindowList := SaveWindowList;
|
||
TaskActiveWindow := SaveActiveWindow;
|
||
end;
|
||
end;
|
||
{$ENDIF MSWINDOWS}
|
||
|
||
function IgnoreMouseEvents(Handle: QObjectH; Event: QEventH): boolean;
|
||
begin
|
||
case QEvent_type(Event) of
|
||
QEventType_MouseButtonPress,
|
||
QEventType_MouseButtonRelease,
|
||
QEventType_MouseButtonDblClick,
|
||
QEventType_MouseMove,
|
||
QEventType_Enter,
|
||
QEventType_Leave,
|
||
QEventType_Wheel:
|
||
Result := true;
|
||
else
|
||
Result := false;
|
||
end;
|
||
end;
|
||
|
||
function GetCursorPos(var P: TPoint): LongBool;
|
||
begin
|
||
Result := True;
|
||
try
|
||
QCursor_pos(@P);
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
procedure SetCursorPos(X, Y: integer);
|
||
var
|
||
Value: TPoint;
|
||
begin
|
||
Value.X := X;
|
||
Value.Y := Y;
|
||
QCursor_setPos(@Value);
|
||
end;
|
||
|
||
{ ------------ Caret -------------- }
|
||
type
|
||
TEmulatedCaret = class(TComponent)
|
||
private
|
||
FTimer: TTimer;
|
||
FWndId: Cardinal;
|
||
FWidget: QWidgetH;
|
||
FPixmap: QPixmapH;
|
||
FWidth, FHeight: Integer;
|
||
FPos: TPoint;
|
||
FVisible: Boolean;
|
||
FShown: Boolean;
|
||
FCritSect: TRTLCriticalSection;
|
||
procedure SetPos(const Value: TPoint);
|
||
protected
|
||
procedure DoTimer(Sender: TObject);
|
||
procedure DrawCaret; virtual;
|
||
function CreateColorPixmap(Color: Cardinal): QPixmapH;
|
||
procedure SetWidget(AWidget: QWidgetH);
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
|
||
procedure Lock;
|
||
procedure Unlock;
|
||
|
||
function CreateCaret(AWidget: QWidgetH; Pixmap: QPixmapH; Width, Height: Integer): Boolean;
|
||
function DestroyCaret: Boolean;
|
||
|
||
function IsValid: Boolean;
|
||
|
||
function Show(AWidget: QWidgetH): Boolean;
|
||
function Hide: Boolean;
|
||
|
||
property Timer: TTimer read FTimer;
|
||
property Pos: TPoint read FPos write SetPos;
|
||
end;
|
||
|
||
var
|
||
GlobalCaret: TEmulatedCaret = nil ;
|
||
|
||
procedure GlobalCaretNeeded;
|
||
begin
|
||
if GlobalCaret = nil then
|
||
begin
|
||
GlobalCaret := TEmulatedCaret.Create(nil);
|
||
OutputDebugString('Global caret created.');
|
||
end;
|
||
end;
|
||
|
||
function CreateCaret(Widget: QWidgetH; Pixmap: QPixmapH; Width, Height: Integer): Boolean;
|
||
begin
|
||
GlobalCaretNeeded;
|
||
GlobalCaret.Lock;
|
||
try
|
||
Result := GlobalCaret.CreateCaret(Widget, Pixmap, Width, Height);
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end;
|
||
|
||
function CreateCaret(Widget: QWidgetH; ColorCaret: Cardinal; Width, Height: Integer): Boolean;
|
||
begin
|
||
Result := CreateCaret(Widget, QPixmapH(ColorCaret), Width, Height);
|
||
end;
|
||
|
||
function GetCaretBlinkTime: Cardinal;
|
||
begin
|
||
Result := QApplication_cursorFlashTime;
|
||
end;
|
||
|
||
function SetCaretBlinkTime(uMSeconds: Cardinal): LongBool;
|
||
begin
|
||
Result := True;
|
||
try
|
||
QApplication_setCursorFlashTime(uMSeconds);
|
||
if assigned(GlobalCaret) then
|
||
begin
|
||
GlobalCaret.Lock;
|
||
try
|
||
GlobalCaret.Timer.Interval := GetCaretBlinkTime;
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end;
|
||
except
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
function HideCaret(Widget: QWidgetH): Boolean;
|
||
begin
|
||
GlobalCaretNeeded;
|
||
if Assigned(GlobalCaret) then
|
||
begin
|
||
GlobalCaret.Lock;
|
||
try
|
||
Result := GlobalCaret.Hide;
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end
|
||
else
|
||
Result := false;
|
||
end;
|
||
|
||
function ShowCaret(Widget: QWidgetH): Boolean;
|
||
begin
|
||
GlobalCaretNeeded;
|
||
GlobalCaret.Lock;
|
||
try
|
||
Result := GlobalCaret.Show(Widget);
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end;
|
||
|
||
function SetCaretPos(X, Y: Integer): Boolean;
|
||
begin
|
||
Result := True;
|
||
GlobalCaretNeeded;
|
||
GlobalCaret.Lock;
|
||
try
|
||
GlobalCaret.Pos := Point(X, Y);
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end;
|
||
|
||
function GetCaretPos(var Pt: TPoint): Boolean;
|
||
begin
|
||
Result := True;
|
||
GlobalCaretNeeded;
|
||
GlobalCaret.Lock;
|
||
try
|
||
Pt := GlobalCaret.Pos;
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end;
|
||
|
||
function DestroyCaret: Boolean;
|
||
begin
|
||
if Assigned(GlobalCaret) then
|
||
begin
|
||
GlobalCaret.Lock;
|
||
try
|
||
Result := GlobalCaret.DestroyCaret;
|
||
finally
|
||
GlobalCaret.Unlock;
|
||
end;
|
||
end
|
||
else
|
||
Result := False;
|
||
end;
|
||
|
||
{ TEmulatedCaret }
|
||
|
||
constructor TEmulatedCaret.Create(AOwner: TComponent);
|
||
begin
|
||
inherited Create(AOwner);
|
||
InitializeCriticalSection(FCritSect);
|
||
|
||
FTimer := TTimer.Create(self);
|
||
FTimer.Enabled := False;
|
||
FTimer.Interval := GetCaretBlinkTime;
|
||
FTimer.OnTimer := DoTimer;
|
||
end;
|
||
|
||
destructor TEmulatedCaret.Destroy;
|
||
begin
|
||
DestroyCaret;
|
||
DeleteCriticalSection(FCritSect);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function TEmulatedCaret.CreateCaret(AWidget: QWidgetH; Pixmap: QPixmapH;
|
||
Width, Height: Integer): Boolean;
|
||
begin
|
||
DestroyCaret;
|
||
SetWidget(AWidget);
|
||
FWidth := Width;
|
||
FHeight := Height;
|
||
if Cardinal(Pixmap) > $FFFF then
|
||
FPixmap := QPixmap_create(Pixmap)
|
||
else
|
||
FPixmap := CreateColorPixmap(Integer(Pixmap));
|
||
|
||
Result := IsValid;
|
||
end;
|
||
|
||
function TEmulatedCaret.DestroyCaret: Boolean;
|
||
begin
|
||
Hide;
|
||
if Assigned(FPixmap) then
|
||
QPixmap_destroy(FPixmap);
|
||
FWidget := nil;
|
||
FPixmap := nil;
|
||
FWidth := 0;
|
||
FHeight := 0;
|
||
Result := not IsValid;
|
||
end;
|
||
|
||
procedure TEmulatedCaret.DrawCaret;
|
||
var
|
||
DestDev: QPaintDeviceH;
|
||
R: TRect;
|
||
begin
|
||
if IsValid then
|
||
begin
|
||
|
||
DestDev := QWidget_to_QPaintDevice(FWidget);
|
||
R := Rect(0, 0, QPixmap_width(FPixmap), QPixmap_height(FPixmap));
|
||
|
||
Qt.bitBlt(DestDev, @FPos, FPixmap, @R, RasterOp_CopyROP);
|
||
FShown := not FShown;
|
||
end;
|
||
end;
|
||
|
||
function TEmulatedCaret.Show(AWidget: QWidgetH): Boolean;
|
||
begin
|
||
if FWidget <> AWidget then
|
||
Hide;
|
||
SetWidget(AWidget);
|
||
Result := IsValid;
|
||
if Result then
|
||
begin
|
||
FVisible := True;
|
||
FTimer.Enabled := True;
|
||
DrawCaret;
|
||
end;
|
||
end;
|
||
|
||
function TEmulatedCaret.Hide: Boolean;
|
||
begin
|
||
Result := IsValid;
|
||
if Result then
|
||
begin
|
||
FVisible := False;
|
||
FTimer.Enabled := False;
|
||
if FShown then
|
||
DrawCaret;
|
||
FShown := False;
|
||
end;
|
||
end;
|
||
|
||
procedure TEmulatedCaret.SetPos(const Value: TPoint);
|
||
begin
|
||
if FVisible then
|
||
begin
|
||
Hide;
|
||
try
|
||
FPos := Value;
|
||
finally
|
||
Show(FWidget);
|
||
end;
|
||
end
|
||
else
|
||
FPos := Value;
|
||
end;
|
||
|
||
procedure TEmulatedCaret.DoTimer(Sender: TObject);
|
||
begin
|
||
DrawCaret;
|
||
end;
|
||
|
||
procedure TEmulatedCaret.Lock;
|
||
begin
|
||
EnterCriticalSection(FCritSect);
|
||
end;
|
||
|
||
procedure TEmulatedCaret.Unlock;
|
||
begin
|
||
LeaveCriticalSection(FCritSect);
|
||
end;
|
||
|
||
function TEmulatedCaret.CreateColorPixmap(Color: Cardinal): QPixmapH;
|
||
var
|
||
QC: QColorH;
|
||
begin
|
||
if (FWidth <= 0) or (FHeight <= 0) then
|
||
Result := nil
|
||
else
|
||
begin
|
||
case Color of
|
||
0: QC := QColor(clBlack);
|
||
1: QC := QColor(clGray);
|
||
else
|
||
Result := nil;
|
||
Exit;
|
||
end;
|
||
try
|
||
Result := QPixmap_create(FWidth, FHeight, -1, QPixmapOptimization_MemoryOptim);
|
||
try
|
||
QPixmap_fill(Result, QC);
|
||
except
|
||
QPixmap_destroy(Result);
|
||
Result := nil;
|
||
end;
|
||
finally
|
||
QColor_destroy(QC);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TEmulatedCaret.IsValid: Boolean;
|
||
begin
|
||
Result := (FWidget <> nil) and (FPixmap <> nil) and
|
||
(QWidget_find(FWndId) <> nil);
|
||
end;
|
||
|
||
procedure TEmulatedCaret.SetWidget(AWidget: QWidgetH);
|
||
begin
|
||
FWidget := AWidget;
|
||
if FWidget <> nil then
|
||
FWndId := QWidget_winId(FWidget)
|
||
else
|
||
FWndId := 0;
|
||
end;
|
||
|
||
|
||
type
|
||
TCriticalSections = class(TComponent)
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
end;
|
||
|
||
constructor TCriticalSections.Create(AOwner: TComponent);
|
||
begin
|
||
inherited Create(AOwner);
|
||
InitializeCriticalSection(StockObjectListCritSect);
|
||
end;
|
||
|
||
destructor TCriticalSections.Destroy;
|
||
begin
|
||
DeleteCriticalSection(StockObjectListCritSect);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function Perform(Control: TControl; Msg: Cardinal; WPar, LPar: Longint): Longint;
|
||
var
|
||
Mesg: TMessage;
|
||
begin
|
||
Mesg.Msg := Msg;
|
||
Mesg.WParam := WPar;
|
||
Mesg.LParam := LPar;
|
||
Mesg.Result := 0;
|
||
Control.Dispatch(Mesg);
|
||
Result := Mesg.Result;
|
||
end;
|
||
|
||
function SendMessage(Receiver: QWidgetH; MsgId: Integer; WPar, LPar: Longint): Integer;
|
||
var
|
||
Event: QCustomEventH;
|
||
Mesg: TMessage;
|
||
begin
|
||
AppEventHookNeeded;
|
||
with Mesg do
|
||
begin
|
||
Msg := MsgId;
|
||
wParam := WPar;
|
||
lParam := LPar;
|
||
Result := 0;
|
||
end;
|
||
Event := QCustomEvent_create(QEventType_Message, @Mesg);
|
||
QApplication_sendEvent(Receiver, Event);
|
||
Result := Mesg.Result;
|
||
QEvent_destroy(Event);
|
||
end;
|
||
|
||
function SendMessage(AControl: TWidgetControl; MsgId: Integer; WPar, LPar: Longint): Integer;
|
||
begin
|
||
// OutputDebugString(Pchar(Format('%s: %s Sended message %x', [AControl.Name, AControl.ClassName, MsgId ])));
|
||
Result := SendMessage(AControl.Handle, MsgId, WPar, LPar);
|
||
end;
|
||
|
||
type
|
||
TCustomMsg = packed record
|
||
Msg: integer;
|
||
WParam: integer;
|
||
LParam: integer;
|
||
Result: integer;
|
||
Pt: TPoint;
|
||
end;
|
||
|
||
function PostMessage(Receiver: QWidgetH; MsgId: Integer; WPar, LPar: Longint): LongBool;
|
||
var
|
||
Mesg: PMessage;
|
||
Event: QCustomEventH;
|
||
begin
|
||
AppEventHookNeeded;
|
||
New(Mesg);
|
||
with Mesg^ do
|
||
begin
|
||
Msg := MsgId;
|
||
WParam := WPar;
|
||
LParam := LPar;
|
||
Result := 0; //or GetTickCount?;
|
||
end;
|
||
Event := QCustomEvent_Create(QEventType_Message, Mesg);
|
||
try
|
||
QApplication_postEvent(Receiver, QEventH(Event));
|
||
Result := true;
|
||
except
|
||
QCustomEvent_Destroy(Event);
|
||
Result := false;
|
||
end;
|
||
end;
|
||
|
||
function PostMessage(AControl: TWidgetControl; MsgId: Integer; WPar, LPar: Longint): LongBool;
|
||
begin
|
||
// OutputDebugString(Pchar(Format('%s: %s Posted message %x', [AControl.Name, AControl.ClassName, MsgId ])));
|
||
Result := PostMessage(AControl.Handle, MsgId, WPar, LPar);
|
||
end;
|
||
|
||
{
|
||
implements
|
||
- WMTimer dispatch
|
||
- Handles messages posted through QCustomEvent_message
|
||
}
|
||
|
||
type
|
||
TWinTimer = class(TComponent)
|
||
private
|
||
FWMTimer: Cardinal;
|
||
FQtTimer: Cardinal;
|
||
FTimerProc: TTimerProc;
|
||
public
|
||
constructor Create(AOwner: TComponent); override;
|
||
class function CreateTimer(AOwner: TWinControl; WMTimerId: Cardinal;
|
||
Elapse: Cardinal; Proc: TTimerProc): TWinTimer;
|
||
destructor Destroy; override;
|
||
property WMTimer: Cardinal read FWMTimer;
|
||
property QtTimer: Cardinal read FQtTimer;
|
||
property TimerProc: TTimerProc read FTimerProc write FTimerProc;
|
||
end;
|
||
|
||
constructor TWinTimer.Create(AOwner: TComponent);
|
||
begin
|
||
inherited Create(AOwner);
|
||
FWMTimer := 0;
|
||
FQtTimer := 0;
|
||
FTimerProc := nil;
|
||
end;
|
||
|
||
class function TWinTimer.CreateTimer(AOwner: TWinControl; WMTimerId: Cardinal;
|
||
Elapse: Cardinal; Proc: TTimerProc): TWinTimer;
|
||
begin
|
||
AppEventHookNeeded;
|
||
Result := Create(AOwner);
|
||
with Result do
|
||
begin
|
||
FWMTimer := WMTimerId;
|
||
FTimerProc := Proc;
|
||
FQtTimer := QObject_startTimer(AOwner.Handle, Elapse);
|
||
end;
|
||
end;
|
||
|
||
destructor TWinTimer.Destroy;
|
||
begin
|
||
QObject_killTimer(TWinControl(Owner).Handle, FQtTimer);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
function FindTimer(Receiver: QWidgetH; QtTimerID: Cardinal): TWinTimer;
|
||
var
|
||
I: Integer;
|
||
Instance: TWinControl;
|
||
begin
|
||
Result := nil;
|
||
Instance := FindControl(Receiver);
|
||
if Assigned(Instance) then
|
||
with Instance do
|
||
for I := 0 to ComponentCount - 1 do
|
||
if (Components[I] is TWinTimer) and
|
||
(TWinTimer(Components[I]).QtTimer = QtTimerID) then
|
||
begin
|
||
Result := TWinTimer(Components[I]);
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
function FindWMTimer(Receiver: QWidgetH; WinTimerID: Longword): TWinTimer;
|
||
var
|
||
I: Integer;
|
||
Instance: TComponent;
|
||
begin
|
||
Result := nil;
|
||
Instance := FindControl(Receiver);
|
||
if Assigned(Instance) then
|
||
with Instance do
|
||
for I := 0 to ComponentCount - 1 do
|
||
if (Components[I] is TWinTimer) and
|
||
(TWinTimer(Components[I]).WMTimer = WinTimerID) then
|
||
begin
|
||
Result := TWinTimer(Components[I]);
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
function SetTimer(Instance: TWidgetControl; WMTimerID, Elapse: Cardinal;
|
||
TimerFunc: TTimerProc): Cardinal;
|
||
var
|
||
FWinTimer: TWinTimer;
|
||
begin
|
||
if Assigned(AppEventHook) then
|
||
begin
|
||
FWinTimer := FindWMTimer(Instance.Handle, WMTimerId);
|
||
if Assigned(FWinTimer) then
|
||
FWinTimer.Destroy;
|
||
end
|
||
else
|
||
AppEventHookNeeded;
|
||
|
||
FWinTimer := TWinTimer.CreateTimer(Instance, WMTimerID, Elapse, TimerFunc);
|
||
Result := FWinTimer.WMTimer;
|
||
end;
|
||
|
||
function SetTimer(Wnd: QWidgetH; WMTimerID, Elapse: Cardinal;
|
||
TimerFunc: TTimerProc): Cardinal;
|
||
var
|
||
Instance: TWidgetControl;
|
||
begin
|
||
Instance := FindControl(Wnd);
|
||
if assigned(Instance) then
|
||
Result := SetTimer(Instance, WMTimerID, Elapse, TimerFunc)
|
||
else
|
||
Result := 0;
|
||
end;
|
||
|
||
function KillTimer(Instance: TWidgetControl; WMTimerId: Cardinal): LongBool;
|
||
begin
|
||
Result := KillTimer(Instance.Handle, WMTimerId);
|
||
end;
|
||
|
||
function KillTimer(Wnd: QWidgetH; WMTimerId: Cardinal): LongBool;
|
||
var
|
||
WinTimer: TWinTimer;
|
||
begin
|
||
WinTimer := FindWMTimer(Wnd, WMTimerId);
|
||
if Assigned(WinTimer) then
|
||
begin
|
||
WinTimer.Destroy;
|
||
Result := true;
|
||
end
|
||
else
|
||
Result := false;
|
||
end;
|
||
|
||
function TAppEventHook.EventFilter(Receiver: QObjectH; Event: QEventH): Boolean;
|
||
var
|
||
WinTimer: TWinTimer;
|
||
Mesg: TMessage;
|
||
Id: Integer;
|
||
Instance: TWidgetControl;
|
||
begin
|
||
Result := false;
|
||
case QEvent_Type(Event) of
|
||
|
||
QEventType_Message:
|
||
begin
|
||
Instance := FindControl(QWidgetH(Receiver));
|
||
if Assigned(Instance) and not (csDestroying in Instance.ComponentState) then
|
||
begin
|
||
Mesg := TMessage(QCustomEvent_data(QCustomEventH(Event))^);
|
||
Mesg.Result := 0;
|
||
Instance.Dispatch(Mesg);
|
||
end;
|
||
Result := True;
|
||
end;
|
||
|
||
QEventType_Timer:
|
||
begin
|
||
if not QObject_isWidgetType(Receiver) then
|
||
Exit;
|
||
Id := QTimerEvent_timerId(QTimerEventH(Event));
|
||
WinTimer := FindTimer(QWidgetH(Receiver), Id );
|
||
if Assigned(WinTimer) then
|
||
with WinTimer do
|
||
begin
|
||
if Assigned(TimerProc) then
|
||
TimerProc(QWidgetH(Receiver), WM_TIMER, WMTimer, GetTickCount);
|
||
with Mesg do
|
||
begin
|
||
Mesg.Msg := WM_TIMER;
|
||
Mesg.WParam := WMTimer;
|
||
Mesg.LParam := Integer(@TimerProc);
|
||
Mesg.Result := 0;
|
||
WinTimer.Owner.Dispatch(Mesg);
|
||
end;
|
||
Result := True;
|
||
end;
|
||
end;
|
||
|
||
end; // case EventType of
|
||
end;
|
||
|
||
function InstallApplicationEventHook(EventFilter: TEventFilterMethod): QApplication_hookH;
|
||
var
|
||
Method: TMethod;
|
||
begin
|
||
Result := QApplication_hook_create(Application.Handle);
|
||
TEventFilterMethod(Method) := EventFilter;
|
||
Qt_hook_hook_events(Result, Method);
|
||
end;
|
||
|
||
constructor TAppEventHook.Create(AOwner: TComponent);
|
||
var
|
||
Method: TMethod;
|
||
begin
|
||
inherited Create(AOwner);
|
||
FHook := QApplication_hook_create(Application.Handle);
|
||
TEventFilterMethod(Method) := EventFilter;
|
||
Qt_hook_hook_events(FHook, Method);
|
||
end;
|
||
|
||
destructor TAppEventHook.Destroy;
|
||
begin
|
||
if Assigned(FHook) then
|
||
begin
|
||
QApplication_hook_destroy(FHook);
|
||
end;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
initialization
|
||
//OutputDebugString('Loading QWindows.pas');
|
||
{$IFDEF LINUX}
|
||
InitGetTickCount;
|
||
WaitObjectList := THandleObjectList.Create;
|
||
{$ENDIF LINUX}
|
||
// TCriticalSections.Create(Application);
|
||
|
||
finalization
|
||
{$IFDEF LINUX}
|
||
WaitObjectList.Free;
|
||
{$ENDIF LINUX}
|
||
AppEventHook.Free;
|
||
GlobalCaret.Free;
|
||
//OutputDebugString('Unloaded QWindows.pas');
|
||
end.
|
||
|
||
|
||
|