Componentes.Terceros.jvcl/official/3.36/archive/QWindows.pas
2009-02-27 12:23:32 +00:00

8878 lines
249 KiB
ObjectPascal
Raw Blame History

{-------------------------------------------------------------------------------
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.