lazarus/lcl/interfaces/win32/win32object.inc

796 lines
24 KiB
PHP

{%MainUnit win32int.pp}
{
*****************************************************************************
* *
* This file is part of the Lazarus Component Library (LCL) *
* *
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
}
{$IFOPT C-}
// Uncomment for local trace
// {$C+}
// {$DEFINE ASSERT_IS_ON}
{$ENDIF}
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.Create
Params: None
Returns: Nothing
Constructor for the class.
------------------------------------------------------------------------------}
constructor TWin32WidgetSet.Create;
begin
FPendingWaitHandlerIndex := -1;
inherited Create;
FTimerData := TList.Create;
FMetrics.cbSize := SizeOf(FMetrics);
FMetricsFailed := not Windows.SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
SizeOf(FMetrics), @FMetrics, 0);
if FMetricsFailed then
begin
FMetrics.iMenuHeight := GetSystemMetrics(SM_CYMENU);
FDefaultFont := GetStockObject(DEFAULT_GUI_FONT);
end
else
begin
FDefaultFont := Windows.CreateFontIndirect(FMetrics.lfMessageFont);
end;
OnClipBoardRequest := nil;
Pointer(InitCommonControlsEx) := GetProcAddress(GetModuleHandle(comctl32), 'InitCommonControlsEx');
FCommonControlsVersion := GetFileVersion(comctl32);
FDotsPatternBitmap := 0;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.Destroy
Params: None
Returns: Nothing
Destructor for the class.
------------------------------------------------------------------------------}
destructor TWin32WidgetSet.Destroy;
var
n: integer;
TimerInfo : PWin32TimerInfo;
begin
n := FTimerData.Count;
if (n > 0) then
begin
DebugLn(Format('[TWin32WidgetSet.Destroy] WARNING: There are %d TimerInfo structures left, I''ll free them' ,[n]));
while (n > 0) do
begin
dec(n);
TimerInfo := PWin32Timerinfo(FTimerData[n]);
Dispose(TimerInfo);
FTimerData.Delete(n);
end;
end;
FTimerData.Free;
if FDotsPatternBitmap <> 0 then
DeleteObject(FDotsPatternBitmap);
if FAppHandle <> 0 then
begin
{$ifdef RedirectDestroyMessages}
SetWindowLong(FAppHandle, GWL_WNDPROC, PtrInt(@DestroyWindowProc));
{$endif}
DestroyWindow(FAppHandle);
end;
if UnicodeEnabledOS then
begin
Windows.UnregisterClassW(@ClsNameW, System.HInstance);
Windows.UnregisterClassW(@ClsHintNameW, System.HInstance);
end
else
begin
Windows.UnregisterClass(@ClsName, System.HInstance);
Windows.UnregisterClass(@ClsHintName, System.HInstance);
end;
if FDefaultFont <> 0 then
Windows.DeleteObject(FDefaultFont);
inherited Destroy;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppInit
Params: None
Returns: Nothing
Initialize Windows
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppInit(var ScreenInfo: TScreenInfo);
const
Win32ClassesToInit: array[0..5] of DWord = (ICC_DATE_CLASSES,
ICC_UPDOWN_CLASS, ICC_TAB_CLASSES, ICC_PROGRESS_CLASS, ICC_BAR_CLASSES,
ICC_PAGESCROLLER_CLASS);
var
ICC: TINITCOMMONCONTROLSEX;
Handle: HWND;
DC: HDC;
AIcon: HICON;
i: integer;
begin
if not WinRegister then
begin
DebugLn('Trace:Win32Object.Init - Register Failed');
Exit;
end;
OleInitialize(nil);
//TODO: Remove when the WS interface is implemented
// Common controls only need to be initialized when used
// So they are initialized in the CreateHandle for common controls
InitCommonControls;
if InitCommonControlsEx <> nil then
begin
ICC.dwSize := SizeOf(TINITCOMMONCONTROLSEX);
for i := Low(Win32ClassesToInit) to High(Win32ClassesToInit) do
begin
ICC.dwICC := Win32ClassesToInit[i];
InitCommonControlsEx(@ICC);
end;
end;
// Create parent of all windows, 'button on taskbar'
if not IsLibrary then
begin
CreateAppHandle;
// set nice main icon
AIcon := Windows.LoadIcon(MainInstance, 'MAINICON');
AppSetIcon(AIcon, AIcon);
end;
// initialize ScreenInfo
Handle := GetDesktopWindow;
DC := Windows.GetDC(Handle);
ScreenInfo.PixelsPerInchX := GetDeviceCaps(DC, LOGPIXELSX);
ScreenInfo.PixelsPerInchY := GetDeviceCaps(DC, LOGPIXELSY);
ScreenInfo.ColorDepth := GetDeviceCaps(DC, BITSPIXEL);
Windows.ReleaseDC(Handle, DC);
// Thread.Synchronize support
WakeMainThread := @HandleWakeMainThread;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppMinimize
Params: None
Returns: Nothing
Minimizes the whole application to the taskbar
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppMinimize;
begin
if Assigned(Application) and Application.MainFormOnTaskBar then
Windows.SendMessage(Application.MainFormHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0)
else
Windows.SendMessage(FAppHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0)
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppRestore
Params: None
Returns: Nothing
Restore minimized whole application from taskbar
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppRestore;
begin
if Assigned(Application) and Application.MainFormOnTaskBar then
Windows.SendMessage(Application.MainFormHandle, WM_SYSCOMMAND, SC_RESTORE, 0)
else
Windows.SendMessage(FAppHandle, WM_SYSCOMMAND, SC_RESTORE, 0);
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppBringToFront
Params: None
Returns: Nothing
Brings the entire application on top of all other non-topmost programs
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppBringToFront;
begin
if (FAppHandle <> 0) and not (Assigned(Application) and Application.MainFormOnTaskBar) then
Windows.SetForegroundWindow(FAppHandle);
end;
procedure TWin32WidgetSet.SetDesigning(AComponent: TComponent);
begin
//if Data<>nil then EnableWindow((AComponent As TWinControl).Handle, boolean(Data^));
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.SetCallback
Params: Msg - message for which to set a callback
Sender - object to which callback will be sent
Returns: nothing
Applies a Message to the sender
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.SetCallback(Msg: LongInt; Sender: TObject);
var
Window: HWnd;
begin
if Sender is TControlCanvas then
Window := TControlCanvas(Sender).Handle
else
Window := TWinControl(Sender).Handle;
if Window = 0 then Exit;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.RemoveCallbacks
Params: Sender - object from which to remove callbacks
Returns: nothing
Removes Call Back Signals from the sender
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.RemoveCallbacks(Sender: TObject);
var
Window: HWnd;
begin
if Sender is TControlCanvas then
Window := TControlCanvas(Sender).Handle
else
if Sender is TCustomForm then
Window := TCustomForm(Sender).Handle
else
Window := (Sender as TWinControl).Handle;
if Window = 0 then Exit;
end;
function TWin32WidgetSet.InitStockFont(AFont: TObject; AStockFont: TStockFont): Boolean;
var
Font: TFont absolute AFont;
LogFont: TLogFont;
procedure AssignDefault;
var
LogFont: TLogFont;
begin
GetObject(DefaultFont, SizeOf(LogFont), @LogFont);
Font.Assign(LogFont);
end;
begin
case AStockFont of
sfSystem:
AssignDefault;
sfHint:
begin
if FMetricsFailed then
AssignDefault
else
Font.Assign(FMetrics.lfStatusFont);
Font.Color := clInfoText;
end;
sfIcon:
begin
if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(LogFont), @LogFont, 0) then
Font.Assign(LogFont)
else
AssignDefault
end;
sfMenu:
begin
if FMetricsFailed then
AssignDefault
else
Font.Assign(FMetrics.lfMenuFont);
Font.Color := clMenuText;
end;
end;
Result := True;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppProcessMessages
Params: None
Returns: Nothing
Handle all pending messages
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppProcessMessages;
var
AMessage: TMsg;
retVal, index: dword;
pHandles: Windows.LPHANDLE;
procedure CallWaitHandler;
begin
FWaitHandlers[index].OnEvent(FWaitHandlers[index].UserData, 0);
end;
begin
repeat
if FPendingWaitHandlerIndex >= 0 then
begin
index := FPendingWaitHandlerIndex;
FPendingWaitHandlerIndex := -1;
CallWaitHandler;
end;
{$ifdef DEBUG_ASYNCEVENTS}
if Length(FWaitHandles) > 0 then
DebugLn('[ProcessMessages] WaitHandleCount=', IntToStr(FWaitHandleCount),
', WaitHandle[0]=', IntToHex(FWaitHandles[0], 8));
{$endif}
if FWaitHandleCount > 0 then
pHandles := @FWaitHandles[0]
else
pHandles := nil;
retVal := Windows.MsgWaitForMultipleObjects(FWaitHandleCount,
pHandles, False, 0, QS_ALLINPUT);
if (WAIT_OBJECT_0 <= retVal) and (retVal < WAIT_OBJECT_0 + FWaitHandleCount) then
begin
index := retVal-WAIT_OBJECT_0;
CallWaitHandler;
end else
if retVal = WAIT_OBJECT_0 + FWaitHandleCount then
begin
while PeekMessage(AMessage, HWnd(nil), 0, 0, PM_REMOVE) do
begin
if AMessage.message = WM_QUIT then
begin
PostQuitMessage(AMessage.wParam);
break;
end;
TranslateMessage(@AMessage);
{$IFDEF WindowsUnicodeSupport}
if UnicodeEnabledOS then
DispatchMessageW(@AMessage)
else
DispatchMessage(@AMessage);
{$ELSE}
DispatchMessage(@AMessage);
{$ENDIF}
end;
end else
if retVal = WAIT_TIMEOUT then
begin
// check for pending to-be synchronized methods
CheckSynchronize;
CheckPipeEvents;
break;
end else
if retVal = $FFFFFFFF then
begin
DebugLn('[TWin32WidgetSet.AppProcessMessages] MsgWaitForMultipleObjects returned: ', IntToStr(GetLastError));
break;
end;
until false;
end;
procedure TWin32WidgetSet.CheckPipeEvents;
var
lHandler: PPipeEventInfo;
lBytesAvail: dword;
SomethingChanged: Boolean;
ChangedCount:integer;
begin
lHandler := FWaitPipeHandlers;
ChangedCount:=0;
while (lHandler <> nil) and (ChangedCount<10) do
begin
SomethingChanged:=true;
if Windows.PeekNamedPipe(lHandler^.Handle, nil, 0, nil, @lBytesAvail, nil) then
begin
if lBytesAvail <> 0 then
lHandler^.OnEvent(lHandler^.UserData, [prDataAvailable])
else
SomethingChanged := false;
end else
lHandler^.OnEvent(lHandler^.UserData, [prBroken]);
if SomethingChanged then
lHandler := FWaitPipeHandlers
else begin
lHandler := lHandler^.Next;
ChangedCount := 0;
end;
inc(ChangedCount);
end;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppWaitMessage
Params: None
Returns: Nothing
Passes execution control to Windows
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppWaitMessage;
var
retVal, timeout: DWord;
pHandles: Windows.LPHANDLE;
begin
RedrawMenus;
if FWaitPipeHandlers <> nil then
timeout := 100
else
timeout := INFINITE;
if FWaitHandleCount > 0 then
pHandles := @FWaitHandles[0]
else
pHandles := nil;
retVal := Windows.MsgWaitForMultipleObjects(FWaitHandleCount, pHandles,
false, timeout, QS_ALLINPUT);
if (WAIT_OBJECT_0 <= retVal) and (retVal < WAIT_OBJECT_0 + FWaitHandleCount) then
FPendingWaitHandlerIndex := retVal-WAIT_OBJECT_0;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.AppTerminate
Params: None
Returns: Nothing
Tells Windows to halt and destroy
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.AppTerminate;
begin
OleUninitialize;
end;
procedure TWin32WidgetSet.AppSetIcon(const Small, Big: HICON);
begin
if FAppHandle <> 0 then
begin
Windows.SendMessage(FAppHandle, WM_SETICON, ICON_SMALL, LPARAM(Small));
SetClassLong(FAppHandle, GCL_HICONSM, LONG(Small));
Windows.SendMessage(FAppHandle, WM_SETICON, ICON_BIG, LPARAM(Big));
SetClassLong(FAppHandle, GCL_HICON, LONG(Big));
end;
end;
procedure TWin32WidgetSet.AppSetTitle(const ATitle: string);
begin
if FAppHandle <> 0 then
begin
{$ifdef WindowsUnicodeSupport}
if UnicodeEnabledOS then
Windows.SetWindowTextW(FAppHandle, PWideChar(UTF8ToUTF16(ATitle)))
else
Windows.SetWindowText(FAppHandle, PChar(Utf8ToAnsi(ATitle)));
{$else}
Windows.SetWindowText(FAppHandle, PChar(ATitle));
{$endif}
end;
end;
procedure TWin32WidgetSet.AppSetVisible(const AVisible: Boolean);
begin
if (FAppHandle <> 0) and not (Assigned(Application) and Application.MainFormOnTaskBar) then
begin
if AVisible then
Windows.ShowWindow(FAppHandle, SW_SHOW)
else
Windows.ShowWindow(FAppHandle, SW_HIDE);
end;
end;
function TWin32WidgetSet.AppRemoveStayOnTopFlags(const ASystemTopAlso: Boolean = False): Boolean;
begin
if not IsLibrary then
RemoveStayOnTopFlags(FAppHandle, ASystemTopAlso);
Result := True;
end;
function TWin32WidgetSet.AppRestoreStayOnTopFlags(const ASystemTopAlso: Boolean = False): Boolean;
begin
if not IsLibrary then
RestoreStayOnTopFlags(FAppHandle);
Result := True;
end;
procedure TWin32WidgetSet.AppSetMainFormOnTaskBar(const DoSet: Boolean);
begin
// 1. Update the visibility of the TaskBar window
if DoSet then
ShowWindow(AppHandle, SW_HIDE)
else
ShowWindow(AppHandle, SW_SHOW);
// 2. Recreate the main form - so it will (not) have an own taskbar item and WndParent = 0 (AppHandle)
if Assigned(Application.MainForm) and Application.MainForm.HandleAllocated then
RecreateWnd(Application.MainForm);
end;
function TWin32WidgetSet.LCLPlatform: TLCLPlatform;
begin
Result:= lpWin32;
end;
function TWin32WidgetSet.GetLCLCapability(ACapability: TLCLCapability): PtrUInt;
begin
case ACapability of
lcAsyncProcess: Result := LCL_CAPABILITY_YES;
lcModalWindow: Result := LCL_CAPABILITY_NO;
lcDragDockStartOnTitleClick: Result := LCL_CAPABILITY_YES;
lcApplicationWindow: Result := LCL_CAPABILITY_YES;
lcLMHelpSupport: Result := LCL_CAPABILITY_YES;
lcNeedMininimizeAppWithMainForm: Result := LCL_CAPABILITY_NO;
else
Result := inherited;
end;
end;
{------------------------------------------------------------------------------
function: CreateTimer
Params: Interval:
TimerFunc: Callback
Returns: a Timer id (use this ID to destroy timer)
Design: A timer which calls TimerCallBackProc, is created.
The TimerCallBackProc calls the TimerFunc.
------------------------------------------------------------------------------}
function TWin32WidgetSet.CreateTimer(Interval: integer; TimerFunc: TWSTimerProc) : THandle;
var
TimerInfo: PWin32TimerInfo;
begin
Result := 0;
if (Interval > 0) and (TimerFunc <> nil) then begin
New(TimerInfo);
TimerInfo^.TimerFunc := TimerFunc;
TimerInfo^.TimerID := Windows.SetTimer(0, 0, Interval, @TimerCallBackProc);
if TimerInfo^.TimerID=0 then
dispose(TimerInfo)
else begin
FTimerData.Add(TimerInfo);
Result := TimerInfo^.TimerID;
end;
end;
end;
{------------------------------------------------------------------------------
function: DestroyTimer
Params: TimerHandle
Returns:
------------------------------------------------------------------------------}
function TWin32WidgetSet.DestroyTimer(TimerHandle: THandle) : boolean;
var
n : integer;
TimerInfo : PWin32Timerinfo;
begin
Result:= false;
n := FTimerData.Count;
while (n>0) do begin
dec(n);
TimerInfo := FTimerData[n];
if (TimerInfo^.TimerID=UINT(TimerHandle)) then
begin
Result := Boolean(Windows.KillTimer(0, UINT(TimerHandle)));
FTimerData.Delete(n);
Dispose(TimerInfo);
end;
end;
end;
procedure TWin32WidgetSet.HandleWakeMainThread(Sender: TObject);
begin
// wake up GUI thread by sending a message to it
if FAppHandle <> 0 then
Windows.PostMessage(FAppHandle, WM_NULL, 0, 0);
end;
{ Private methods (in no significant order) }
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.WinRegister
Params: None
Returns: If the window was successfully registered
Registers the main window class
------------------------------------------------------------------------------}
function TWin32WidgetSet.WinRegister: Boolean;
var
WindowClass: WndClass;
WindowClassW: WndClassW;
begin
if UnicodeEnabledOS then
begin
with WindowClassW do
begin
Style := CS_DBLCLKS;
LPFnWndProc := @WindowProc;
CbClsExtra := 0;
CbWndExtra := 0;
hInstance := System.HInstance;
hIcon := Windows.LoadIcon(MainInstance, 'MAINICON');
if hIcon = 0 then
hIcon := Windows.LoadIcon(0, IDI_APPLICATION);
hCursor := Windows.LoadCursor(0, IDC_ARROW);
hbrBackground := 0;
LPSzMenuName := nil;
LPSzClassName := @ClsNameW;
end;
Result := Windows.RegisterClassW(@WindowClassW) <> 0;
if Result then
begin
with WindowClassW do
begin
style := style or CS_SAVEBITS;
if WindowsVersion >= wvXP then
style := style or CS_DROPSHADOW;
hIcon := 0;
hbrBackground := 0;
LPSzClassName := @ClsHintNameW;
end;
Result := Windows.RegisterClassW(@WindowClassW) <> 0;
end;
end
else begin
with WindowClass do
begin
Style := CS_DBLCLKS{CS_HRedraw or CS_VRedraw};
LPFnWndProc := @WindowProc;
CbClsExtra := 0;
CbWndExtra := 0;
hInstance := System.HInstance;
hIcon := Windows.LoadIcon(MainInstance, 'MAINICON');
if hIcon = 0 then
hIcon := Windows.LoadIcon(0, IDI_APPLICATION);
hCursor := Windows.LoadCursor(0, IDC_ARROW);
hbrBackground := 0;
LPSzMenuName := nil;
LPSzClassName := @ClsName;
end;
Result := Windows.RegisterClass(@WindowClass) <> 0;
if Result then
begin
with WindowClass do
begin
style := style or CS_SAVEBITS;
if WindowsVersion >= wvXP then
style := style or CS_DROPSHADOW;
hIcon := 0;
hbrBackground := 0;
LPSzClassName := @ClsHintName;
end;
Result := Windows.RegisterClass(@WindowClass) <> 0;
end;
end;
end;
procedure TWin32WidgetSet.CreateAppHandle;
var
SysMenu: HMENU;
begin
{$ifdef WindowsUnicodeSupport}
if UnicodeEnabledOS then
FAppHandle := CreateWindowW(@ClsNameW,
PWideChar(UTF8ToUTF16(Application.Title)),
WS_POPUP or WS_CLIPSIBLINGS or WS_SYSMENU or WS_MINIMIZEBOX,
0, {Windows.GetSystemMetrics(SM_CXSCREEN) div 2,}
0, {Windows.GetSystemMetrics(SM_CYSCREEN) div 2,}
0, 0, HWND(nil), HMENU(nil), HInstance, nil)
else
FAppHandle := CreateWindow(@ClsName, PChar(Utf8ToAnsi(Application.Title)),
WS_POPUP or WS_CLIPSIBLINGS or WS_SYSMENU or WS_MINIMIZEBOX,
0, {Windows.GetSystemMetrics(SM_CXSCREEN) div 2,}
0, {Windows.GetSystemMetrics(SM_CYSCREEN) div 2,}
0, 0, HWND(nil), HMENU(nil), HInstance, nil);
{$else}
FAppHandle := CreateWindow(@ClsName, PChar(Application.Title), WS_POPUP or
WS_CLIPSIBLINGS or WS_SYSMENU or WS_MINIMIZEBOX,
0, {Windows.GetSystemMetrics(SM_CXSCREEN) div 2,}
0, {Windows.GetSystemMetrics(SM_CYSCREEN) div 2,}
0, 0, HWND(nil), HMENU(nil), HInstance, nil);
{$endif}
AllocWindowInfo(FAppHandle);
// remove useless menuitems from sysmenu
SysMenu := Windows.GetSystemMenu(FAppHandle, False);
Windows.DeleteMenu(SysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
Windows.DeleteMenu(SysMenu, SC_SIZE, MF_BYCOMMAND);
Windows.DeleteMenu(SysMenu, SC_MOVE, MF_BYCOMMAND);
end;
function TWin32WidgetSet.CreateThemeServices: TThemeServices;
begin
Result := TWin32ThemeServices.Create;
end;
function TWin32WidgetSet.GetAppHandle: THandle;
begin
Result:= FAppHandle;
end;
procedure TWin32WidgetSet.SetAppHandle(const AValue: THandle);
begin
// Do it only if handle is not yet created (for example for DLL initialization)
// if handle is already created we can't reassign it
if AppHandle = 0 then
FAppHandle := AValue;
end;
function TWin32WidgetSet.GetDotsPatternBitmap: HBitmap;
const
Dots: array[0..3] of Word = ($55, $AA, $55, $AA);
begin
if FDotsPatternBitmap = 0 then
FDotsPatternBitmap := CreateBitmap(4, 4, 1, 1, @Dots);
Result := FDotsPatternBitmap;
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.DCReDraw
Params: CanvasHandle - HDC to redraw
Returns: Nothing
Redraws (the window of) a canvas
------------------------------------------------------------------------------}
procedure TWin32WidgetSet.DCRedraw(CanvasHandle: HDC);
begin
// TODO: implement me!
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.SetPixel
Params: Canvas - canvas to set color on
X, Y - position
AColor - new color for specified position
Returns: nothing
Set the color of the specified pixel on the canvas
------------------------------------------------------------------------------}
var
IntSetPixel : function (DC:HDC; X, Y:longint; cl:Windows.COLORREF):Windows.COLORREF; stdcall = nil;
function VistaSetPixel(DC:HDC; X,Y:longint; cl:Windows.COLORREF):Windows.COLORREF; stdcall;
var
pen, oldpen: HPEN;
p : Windows.TPOINT;
begin
if x and $100=0 then
Result:=Windows.SetPixel(DC,X,Y,cl)
else
begin
pen := Windows.CreatePen(PS_SOLID, 1, ColorToRGB(cl));
oldpen := Windows.SelectObject(DC, pen);
Windows.MoveToEx(DC, X, Y, @p);
Windows.LineTo(DC, X, Y + 1);
Windows.SelectObject(DC, oldpen);
Windows.DeleteObject(pen);
Windows.MoveToEx(DC, P.X, P.Y, nil);
Result:=cl;
end;
end;
procedure TWin32WidgetSet.DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor);
begin
IntSetPixel(CanvasHandle, X, Y, ColorToRGB(AColor));
end;
{------------------------------------------------------------------------------
Method: TWin32WidgetSet.GetPixel
Params: Canvas - canvas to get color from
X, Y - position
Returns: Color at specified point
Get the color of the specified pixel on the canvas
-----------------------------------------------------------------------------}
function TWin32WidgetSet.DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor;
begin
Result := Windows.GetPixel(CanvasHandle, X, Y);
end;
{$IFDEF ASSERT_IS_ON}
{$UNDEF ASSERT_IS_ON}
{$C-}
{$ENDIF}