2952 lines
92 KiB
Plaintext
2952 lines
92 KiB
Plaintext
type TWinControl = class(tcontrol)
|
|
///////////平台判断////////
|
|
{$ifdef linux}
|
|
{$define gtkpaint}
|
|
{$define linuxgtk}
|
|
{$else}
|
|
{$define gdipaint}
|
|
{$endif}
|
|
uses utslvclauxiliary,utslvclmemstruct,utslvclbase,utslvclevent,utslvclgdi,uvclthreadworker,utslvclaction,utslvclmenu;//,utslvclstdctl;
|
|
{**
|
|
@explan(说明) 窗口控件 %%
|
|
**}
|
|
private //成员变量
|
|
[weakref] ftrackmenu;
|
|
__wstyle; //窗口样式
|
|
__wexstyle; //窗口扩展样式
|
|
//__wstylestruct; //样式消息结构体
|
|
__clientsize; //客户区大小
|
|
//__oldclientsize; //旧客户区大小
|
|
factivated;
|
|
FClientleft;
|
|
FClientTop;
|
|
FClientWdith;
|
|
FClientHeight;
|
|
FWsPopUp;
|
|
//FTtageDrawItem; //已经移除
|
|
FWMNCHITTEST;
|
|
FImageList;
|
|
fchildsizing;
|
|
//FTRACKMOUSEEVENT;
|
|
FHandle:HWND; //窗口句柄
|
|
private //窗口相关
|
|
FBorderStyle;
|
|
FParentWindow:HWND; //父窗口句柄
|
|
static FDefaultProc; //windows默认句柄处理
|
|
FWndproc; //消息句柄
|
|
protected //消息
|
|
FDefWndproc; //默认消息句柄
|
|
private //时间指针
|
|
weakref
|
|
FonKillFocus;
|
|
FonSetFocus;
|
|
foncreated;
|
|
FControlStyle; //控件样式
|
|
FOnClose;
|
|
FOnDesinedsel;
|
|
FOnDesigDBLClick;
|
|
FOnDesinedRclick;
|
|
FOnActivate;
|
|
FOnKeyDown;
|
|
FOnKeyPress;
|
|
fonsyskeydown;
|
|
fonsyskeyup;
|
|
FOnSysKeyPress;
|
|
FOnKeyUp;
|
|
factivecontrol;
|
|
autoref
|
|
FTabStop;
|
|
FWsCaption;
|
|
FWsSizeBox;
|
|
FWsSysMenu;
|
|
FWsDlgModalFrame;
|
|
private //模态相关
|
|
//*******showmodal******************
|
|
FModaling;
|
|
FModalCode;
|
|
FMinWidth;
|
|
FMinHeigt;
|
|
//Ftagminmaxinfo;
|
|
FMaxWidth;
|
|
FMaxHeight;
|
|
FGtkEventOjbect; //gtkobject
|
|
private //窗口属性
|
|
function SetMaxWidth(v);
|
|
begin
|
|
if v>0 and FMaxWidth <> V then
|
|
begin
|
|
FMaxWidth := v;
|
|
end
|
|
end
|
|
function SetMaxHeight(v);
|
|
begin
|
|
if v>0 and FMaxHeight <> v then
|
|
begin
|
|
FMaxHeight := v;
|
|
end
|
|
end
|
|
function SetMinWidth(v);
|
|
begin
|
|
if v>0 and FMinWidth <> v then
|
|
begin
|
|
FMinWidth := v;
|
|
if FMinWidth>width then width := FMinWidth;
|
|
end
|
|
end
|
|
function SetMinHeight(v);
|
|
begin
|
|
if v>0 and FMinHeigt <> v then
|
|
begin
|
|
FMinHeigt := v;
|
|
if FMinHeigt>height then height := FMinHeigt;
|
|
end
|
|
end
|
|
function DoModal()
|
|
begin
|
|
//标识处于模态状态中
|
|
if not WsPopUp then
|
|
begin
|
|
exit;
|
|
end
|
|
{$ifdef gtkpaint}
|
|
if FModaling then exit;
|
|
if _wapi.gtk_window_showmodal(self(true))then
|
|
begin
|
|
FModaling := true;
|
|
app := class(tUIglobalData).uigetdata("tuiapplication");
|
|
if app then app.run();
|
|
end
|
|
return FModalCode;
|
|
exit;
|
|
{$endif}
|
|
modp := parent;
|
|
{if not(modp is class(TWinControl)) then
|
|
begin
|
|
return -1;
|
|
end }
|
|
hWnd := Handle;
|
|
FModaling := TRUE;
|
|
FMSG := new TTagMSG();
|
|
msg := FMSG._getptr_;
|
|
//显示自己
|
|
_wapi.ShowWindow(hWnd,SW_SHOW);
|
|
_wapi.BringWindowToTop(hWnd);
|
|
//disable掉父窗口
|
|
FModalRootWnd := 0;
|
|
inabledlist := array();
|
|
inabledlistidx := 0;
|
|
if(modp is class(TWinControl))and modp.HandleAllocated()then
|
|
begin
|
|
hParentWnd := modp.Handle;
|
|
while(hParentWnd) do
|
|
begin
|
|
_wapi.EnableWindow(hParentWnd,FALSE);
|
|
inabledlist[inabledlistidx++] := hParentWnd;
|
|
wdobj := class(tUIglobalData).uigetdata("TGlobalComponentcache").getwndbyhwnd(hParentWnd);
|
|
if wdobj and wdobj.Modaling then
|
|
begin
|
|
FModalRootWnd := hParentWnd;
|
|
break;
|
|
end
|
|
hParentWnd := _wapi.GetParent(hParentWnd);
|
|
end
|
|
end
|
|
//接管消息循环
|
|
while(FModaling) do
|
|
begin
|
|
/////////////////////////////////////////////
|
|
if(_wapi.PeekMessageA(msg,0,0,0,0x1))then
|
|
begin
|
|
if FMSG.message=0x12 then
|
|
begin
|
|
return 1;
|
|
end else
|
|
begin
|
|
_wapi.TranslateMessage(msg);
|
|
_wapi.DispatchMessageA(msg);
|
|
end
|
|
end else
|
|
begin
|
|
tslprocessmessages(false);
|
|
sleep(10);
|
|
class(TCustomThreadworker).dispatch();
|
|
end
|
|
//////////////////////////////////////////
|
|
{if (not _wapi.GetMessageA(msg, 0, 0, 0)) then break;
|
|
_wapi.TranslateMessage(msg);
|
|
_wapi.DispatchMessageA(msg);}
|
|
end
|
|
//模态已经退出
|
|
//恢复父窗口的enable状态
|
|
///////////////////////////////////////////////////////////////////////////
|
|
for i:= length(inabledlist)-1 downto 0 do
|
|
begin
|
|
_wapi.EnableWindow(inabledlist[i],TRUE);
|
|
end
|
|
inabledlist := nil;
|
|
{if(modp is class(TWinControl))and modp.HandleAllocated()then
|
|
begin
|
|
hParentWnd := modp.Handle;
|
|
while(hParentWnd) do
|
|
begin
|
|
_wapi.EnableWindow(hParentWnd,TRUE);
|
|
if FModalRootWnd=hParentWnd then break;
|
|
hParentWnd := _wapi.GetParent(hParentWnd);
|
|
end
|
|
end}
|
|
///////////////////////////////////////////////////////////////////////
|
|
//将自己隐藏
|
|
_wapi.ShowWindow(hWnd,SW_HIDE);
|
|
return FModalCode;
|
|
end
|
|
private //窗口样式
|
|
function SetWSsizeBox(v);
|
|
begin
|
|
nv := v?true:false;
|
|
if nv <> FWsSizeBox then
|
|
begin
|
|
FWsSizeBox := nv;
|
|
if HandleAllocated()then RecreateWnd();
|
|
end
|
|
end
|
|
function setchildsizing(v);
|
|
begin
|
|
fchildsizing.setsizerinfo(v);
|
|
end
|
|
function GetWsSysMenu();virtual;
|
|
begin
|
|
return FWsSysMenu;
|
|
end
|
|
function SetWsSysMenu(v);virtual;
|
|
begin
|
|
nv := v?true:false;
|
|
if nv <> FWsSysMenu then
|
|
begin
|
|
FWsSysMenu := nv;
|
|
if HandleAllocated()then RecreateWnd();
|
|
end
|
|
end
|
|
function SetWsDlgModalFrame(v);virtual;
|
|
begin
|
|
nv := v?true:false;
|
|
if nv <> FWsDlgModalFrame then
|
|
begin
|
|
FWsDlgModalFrame := nv;
|
|
if HandleAllocated()then
|
|
begin
|
|
RecreateWnd();
|
|
end
|
|
end
|
|
end
|
|
protected
|
|
function SetWsPopUp(v);virtual;
|
|
begin
|
|
nv := v?true:false;
|
|
if nv <> FWsPopUp then
|
|
begin
|
|
factivated := false;
|
|
FWsPopUp := nv;
|
|
vb := Visible;
|
|
if HandleAllocated()then
|
|
begin
|
|
RecreateWnd();
|
|
if vb and nv then show(); //处理顶层窗口的显示
|
|
end
|
|
end
|
|
end
|
|
function GetWsPopUp();virtual;
|
|
begin
|
|
return FWsPopUp;
|
|
end
|
|
private
|
|
|
|
function CompareRect(orect,nrect);
|
|
begin
|
|
return orect=nrect;
|
|
end
|
|
|
|
function GetWsCaption(v);virtual;
|
|
begin
|
|
return FWsCaption;
|
|
end
|
|
function SetWsCaption(v);virtual;
|
|
begin
|
|
nv := v?true:false;
|
|
if nv <> FWsCaption then
|
|
begin
|
|
FWsCaption := nv;
|
|
if HandleAllocated()then RecreateWnd();
|
|
end
|
|
end
|
|
function GetHandle(); //type_twinctrol
|
|
begin
|
|
//if not HandleAllocated then DebugLn('TWinControl.GetHandle Creating handle on the fly: ',DbgSName(Self));
|
|
HandleNeeded();
|
|
return FHandle;
|
|
end;
|
|
procedure SetHandle(NewHandle); //type_twinctrol
|
|
begin
|
|
if {NewHandle and}not(FHandle)then FHandle := NewHandle;
|
|
//if (NewHandle=0) and (AnsiCompareText(ClassName,'TPAGE')=0) then
|
|
// RaiseGDBException('TWincontrol.SetHandle');
|
|
//FHandle:=NewHandle;
|
|
//InvalidatePreferredSize();
|
|
end;
|
|
function SetTabStop(v);
|
|
begin
|
|
nv := V?true:false;
|
|
if nv <> FTabStop then
|
|
begin
|
|
FTabStop := nv;
|
|
if HandleAllocated()then
|
|
begin
|
|
if nv then appendwstyle(WS_TABSTOP);
|
|
else minuswstyle(WS_TABSTOP);
|
|
end
|
|
end
|
|
end
|
|
function GetControlCount():Integer; //type_twinctrol
|
|
begin
|
|
return FControls.Count();
|
|
end;
|
|
procedure SetParentWindow(const AValue:HWND); //type_twinctrol
|
|
begin
|
|
{**
|
|
@ignore(忽略) %%
|
|
**}
|
|
if(ParentWindow=AValue)or Assigned(Parent)then Exit;
|
|
FParentWindow := AValue;
|
|
if HandleAllocated()then
|
|
begin
|
|
if(AValue <> 0)then //LCLIntf.SetParent(Handle, AValue)
|
|
else DestroyHandle();
|
|
end
|
|
UpdateControlState();
|
|
end
|
|
protected
|
|
function SetParentFont(v:bool);override;
|
|
begin
|
|
if inherited then
|
|
begin
|
|
InvalidateRect(nil,false);
|
|
end
|
|
end
|
|
function SetImageList(v);
|
|
begin
|
|
if FImageList=v then exit;
|
|
if FImageList is class(tcustomcontrolimagelist) then
|
|
begin
|
|
ti := FImageList;
|
|
FImageList := nil;
|
|
ti.deleteControl(self);
|
|
end
|
|
FImageList := v;
|
|
if v is class(tcustomcontrolimagelist) then v.addControl(self);
|
|
ImageChanged();
|
|
end
|
|
class function getwndbyhwnd(hwnd); //type_twinctrol
|
|
begin
|
|
return class(tUIglobalData).uigetdata("TGlobalComponentcache").getwndbyhwnd(hwnd);
|
|
end
|
|
class function registerhandle(handle,o); //type_twinctrol
|
|
begin
|
|
//注册对象 %%
|
|
return class(tUIglobalData).uigetdata("TGlobalComponentcache").registerhandle(handle,o);
|
|
end
|
|
class function unregisterhandle(handle); //type_twinctrol
|
|
begin
|
|
//删除对象 %%
|
|
return class(tUIglobalData).uigetdata("TGlobalComponentcache").unregisterhandle(handle);
|
|
end
|
|
class function sinit();override;
|
|
begin
|
|
{**
|
|
@explan(说明)初始化 %%
|
|
**}
|
|
if not _wapi then inherited;
|
|
if ifnil(FDefaultProc)then FDefaultProc := _wapi.getDefWindowProcA() ;
|
|
end
|
|
function SetBorder(v);override; //type_twinctrol
|
|
begin
|
|
nv := v?true:false;
|
|
if nv <> Border then
|
|
begin
|
|
inherited;
|
|
if nv then appendwstyle(WS_BORDER);
|
|
else minuswstyle(WS_BORDER);
|
|
Refresh();
|
|
end
|
|
end
|
|
procedure CreateHandle();virtual; //type_twinctrol
|
|
begin
|
|
if csCreating in ControlState then return;
|
|
if(not HandleAllocated())then
|
|
begin
|
|
includestate(ControlState,csCreating);
|
|
CreateWnd();
|
|
excludestate(ControlState,csCreating);
|
|
end
|
|
end;
|
|
function InitializeWnd();virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明) 窗口句柄初始化,在该函数设置窗口句柄的一些信息 %%
|
|
**}
|
|
//背景这些处理
|
|
if HandleAllocated()then
|
|
begin
|
|
//Canvas.Handle := _wapi.GetDC(self.Handle);
|
|
if(Parent is class(TWinControl))and Parent.HandleAllocated()then
|
|
begin
|
|
//if Align<>alNone then
|
|
Parent.DoControlAlign();
|
|
end
|
|
//ImageChanged();
|
|
// "id:",self.caption,_wapi.GetWindowLongPtrA(FHandle,GWLP_ID);
|
|
end
|
|
end
|
|
function GetBorderStyle();
|
|
begin
|
|
return FBorderStyle;
|
|
end
|
|
function SetBorderStyle(NewStyle);virtual;
|
|
begin
|
|
if FBorderStyle=NewStyle then exit;
|
|
if FBorderStyle in array(bsNone,bsSingle)then
|
|
begin
|
|
FBorderStyle := NewStyle;
|
|
if FBorderStyle=bsNone then
|
|
begin
|
|
minuswexstyle(WS_EX_CLIENTEDGE);
|
|
end else
|
|
appendwexstyle(WS_EX_CLIENTEDGE);
|
|
end
|
|
end
|
|
function CreateParams(p);virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)构架窗口句柄使用 %%
|
|
@param(p)(var TCreateParams) 变参返回 %%
|
|
**}
|
|
if not(p is class(TCreateParams))then p := new TCreateParams();
|
|
p.Caption := Caption;
|
|
//p.Style := WS_CHILD .| WS_CLIPSIBLINGS .| WS_CLIPCHILDREN ;
|
|
p.Style := WS_CHILD;
|
|
if FWsPopUp then
|
|
begin
|
|
p.Style := WS_POPUP;
|
|
end else
|
|
begin
|
|
p.Style := WS_CHILD;
|
|
end
|
|
//p.style .|= WS_CAPTION; //WS_SYSMENU .|
|
|
if WsCaption then p.style .|= WS_CAPTION;
|
|
if FWsSysMenu then P.Style .|= WS_CAPTION .| WS_SYSMENU;
|
|
if FWsSizeBox then p.style .|= WS_SIZEBOX;
|
|
if Border then p.Style := p.Style .| WS_BORDER;
|
|
if csAcceptsControls in FControlStyle then p.ExStyle := p.ExStyle .| WS_EX_CONTROLPARENT;
|
|
if BorderStyle=bsSingle then p.ExStyle := p.ExStyle .| WS_EX_CLIENTEDGE;
|
|
if WSDlgModalFrame then
|
|
begin
|
|
p.ExStyle .|= WS_EX_DLGMODALFRAME;
|
|
end
|
|
//if not fWsPopUp then p.ExStyle .|= WS_EX_LAYERED; //透明处理
|
|
if TabStop then p.Style .|= WS_TABSTOP;
|
|
//op := parent;
|
|
if not(Enabled)then p.Style .|= WS_DISABLED;
|
|
if Visible then p.Style .|= WS_VISIBLE;
|
|
if Parent is class(TWinControl)then //if Parent.HandleAllocated() then
|
|
p.WndParent := Parent.Handle;
|
|
else p.WndParent := ParentWindow;
|
|
p.X := Left;
|
|
p.Y := Top;
|
|
p.Width := Width;
|
|
p.Height := Height;
|
|
p.happ := happ;
|
|
p.Style .|= WS_CLIPSIBLINGS .| WS_CLIPCHILDREN;
|
|
p.cstyle := CS_HREDRAW .| CS_VREDRAW .| CS_OWNDC .| CS_DBLCLKS;
|
|
end
|
|
procedure RealSetText(Value:TCaption);override; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明) 设置标题 %%
|
|
@param(value)(string) 标题 %%
|
|
**}
|
|
if ifstring(Value)and(Caption <> Value)then
|
|
begin
|
|
inherited;
|
|
if HandleAllocated()then
|
|
begin
|
|
_wapi.SetWindowTextA(self.handle,self.Caption);
|
|
end
|
|
end
|
|
end
|
|
function createwndclass(p); //type_twinctrol
|
|
begin
|
|
{**
|
|
@param(p)(TCreateParams) 注册窗口类 %%
|
|
@explan(说明)注册窗口类 %%
|
|
**}
|
|
classobj := p.winclass; //new tagWNDCLASSA();
|
|
subclass := p.subclass;
|
|
uiproc := _wapi.getvclwindowprocA();
|
|
dfproc := _wapi.getDefWindowProcA() ;
|
|
p.subclasswndproc := dfproc;
|
|
tclass := new tagWNDCLASSA();
|
|
classobj._setvalue_("lpszclassname",p.WinClassName);
|
|
for i,v in classobj._getdata_() do
|
|
begin
|
|
if i="lpfnwndproc" then tclass._setvalue_(i,uiproc);
|
|
else tclass._setvalue_(i,v);
|
|
end
|
|
regptr := _wapi.GetClassInfoExA(p.happ,p.WinClassName,classobj._getptr_);
|
|
if not regptr then
|
|
begin
|
|
for i,v in tclass._getdata_() do
|
|
begin
|
|
classobj._setvalue_(i,v);
|
|
end
|
|
end
|
|
if ifstring(p.SubClassName)and p.SubClassName then //存在subclass
|
|
begin
|
|
tcn := p.SubClassName;
|
|
subregptr := _wapi.GetClassInfoExA(p.Happ,tcn,subclass._getptr_);
|
|
if subregptr then
|
|
begin
|
|
p.subclasswndproc := subclass._getvalue_("lpfnwndproc");
|
|
if p.subclasswndproc=uiproc then
|
|
begin
|
|
p.subclasswndproc := dfproc;
|
|
end
|
|
if not regptr then //窗口没有注册
|
|
begin
|
|
for i,v in subclass._getdata_() do //填充子窗口信息
|
|
begin
|
|
if i="lpfnwndproc" then
|
|
begin
|
|
classobj._setvalue_(i,uiproc);
|
|
end else
|
|
if i="lpszclassname" then
|
|
begin
|
|
tcn := p.WinClassName;
|
|
classobj._setvalue_(i,tcn);
|
|
end else
|
|
begin
|
|
classobj._setvalue_(i,v);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end else //不存在subclass 默认回调为 defaultproc
|
|
begin
|
|
if p.cstyle then classobj.style := p.cstyle;
|
|
p.subclasswndproc := dfproc;
|
|
end
|
|
if regptr then
|
|
begin
|
|
if uiproc <> classobj._getvalue_("lpfnwndproc")then
|
|
begin
|
|
messageboxA("窗口类注册冲突!","错误",1);
|
|
end
|
|
end else
|
|
begin
|
|
regptr := _wapi.RegisterClassExA(classobj._getptr_);
|
|
end
|
|
end
|
|
function UpdateControlState(); ////type_twinctrol
|
|
begin
|
|
end
|
|
procedure ChangeBounds(ALeft,ATop,AWidth,AHeight:integer;KeepBase:boolean);override; //type_twinctrol
|
|
begin
|
|
if ALeft=-32000 or ATop = -32000 then exit ;
|
|
if HandleAllocated()then
|
|
begin
|
|
//_wapi.MoveWindow(self.Handle,ALeft,ATop,AWidth,AHeight,true);
|
|
_wapi.SetWindowPos(self.Handle,0,integer(ALeft),integer(ATop),integer(AWidth),integer(AHeight),SWP_NOZORDER .| SWP_NOACTIVATE); //.| SWP_NOACTIVATE
|
|
end else
|
|
begin
|
|
inherited;
|
|
//class(tcontrol).ChangeBounds(ALeft, ATop, AWidth, AHeight,KeepBase);
|
|
end
|
|
end
|
|
function SetEnabled(v);override;
|
|
begin
|
|
inherited;
|
|
if HandleAllocated()then _wapi.EnableWindow(FHandle,v?true:false);
|
|
end
|
|
function SetVisible(v);override;
|
|
begin
|
|
inherited;
|
|
if HandleAllocated()then
|
|
begin
|
|
{
|
|
if v=SW_SHOWNOACTIVATE then
|
|
begin
|
|
_wapi.ShowWindow(FHandle,SW_SHOWNOACTIVATE);
|
|
end else
|
|
begin
|
|
_wapi.ShowWindow(FHandle,v?SW_SHOW:SW_HIDE);
|
|
end
|
|
if v=SW_SHOWNOACTIVATE then return ;
|
|
}
|
|
_wapi.ShowWindow(FHandle,v?SW_SHOW:SW_HIDE);
|
|
if(Parent is class(TWinControl))and parent.HandleAllocated()then
|
|
begin
|
|
if Align <> alNone then Parent.DoControlAlign();
|
|
end
|
|
{if V then
|
|
begin
|
|
DoControlAlign();
|
|
end }
|
|
end
|
|
end
|
|
function Hitcontrol(p);
|
|
begin
|
|
{**
|
|
@explan(说明) 命中控件 %%
|
|
**}
|
|
for i := ControlCount-1 downto 0 do
|
|
begin
|
|
it := Controls[i];
|
|
if it is class(TGraphicControl)then
|
|
begin
|
|
if it.Enabled and it.Visible and pointinrect(p,it.GetBoundsRect)then
|
|
begin
|
|
return it;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
function MouseHover(O,e);override;
|
|
begin
|
|
inself := true;
|
|
initem := 0;
|
|
for i := ControlCount-1 downto 0 do
|
|
begin
|
|
it := FControls[i];
|
|
if(it is class(TGraphicControl))and it.visible then
|
|
begin
|
|
if inself and pointinrect(array(e.lolparamsigned,e.hilparamsigned),it.GetBoundsRect)and it.Enabled then
|
|
begin
|
|
initem := it;
|
|
inself := false;
|
|
end else
|
|
begin
|
|
it.Perform(messagecreater(nil,WM_MOUSELEAVE,0,0));
|
|
end
|
|
end
|
|
end
|
|
if inself then return inherited;
|
|
else self.Perform(messagecreater(nil,WM_MOUSELEAVE,0,0));
|
|
if initem then initem.Perform(messagecreater(nil,WM_MOUSEHOVER,0,0));
|
|
end
|
|
public //消息绑定函数
|
|
function WMMouseMove(o,e):LM_MOUSEMOVE;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMMouseMove(it,new TMMouse(LM_MOUSEMOVE,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
//return it.Perform(new TMMouse(LM_MOUSEMOVE,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMLButtonUp(o,e):LM_LBUTTONUP;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMLButtonUp(it,new TMMouse(LM_LBUTTONUP,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMRButtonUp(o,e):LM_RBUTTONUP;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMRButtonUp(it,new TMMouse(LM_RBUTTONUP,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMMButtonUp(o,e):LM_MBUTTONUP;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMMButtonUp(it,new TMMouse(LM_MBUTTONUP,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMContextMenu(o,e):LM_CONTEXTMENU;override;
|
|
begin
|
|
ps := array(e.lolparamsigned,e.hilparamsigned);
|
|
_wapi.ScreenToClient(Handle,ps);
|
|
it := Hitcontrol(ps);
|
|
if it then
|
|
begin
|
|
ev := new TMMouse(e.msg,e.wparam,e.lparam);
|
|
r := it.Perform(ev);
|
|
e.Result := ev.Result;
|
|
e.skip := ev.skip;
|
|
end
|
|
return inherited;
|
|
end
|
|
function WMLButtonDown(o,e):LM_LBUTTONDOWN;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMLButtonDown(it,new TMMouse(LM_LBUTTONDOWN,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMRButtonDown(o,e):LM_RBUTTONDOWN;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMRButtonDown(it,new TMMouse(LM_RBUTTONDOWN,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
//return it.Perform(new TMMouse(LM_MOUSEMOVE,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMMButtonDown(o,e):LM_MBUTTONDOWN;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMMButtonDown(it,new TMMouse(LM_MBUTTONDOWN,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
function WMLButtonDBLCLK(o,e):LM_LBUTTONDBLCLK;override;
|
|
begin
|
|
it := Hitcontrol(e.pos);
|
|
if it then
|
|
begin
|
|
return it.WMLButtonDBLCLK(it,new TMMouse(LM_LBUTTONDBLCLK,e.wparam,makelong(e.xpos-it.left,e.ypos-it.top)));
|
|
end
|
|
inherited;
|
|
end
|
|
public //设计器相关杂项
|
|
class function CaptionHeight();
|
|
begin
|
|
{**
|
|
@explan(说明) caption的高度 %%
|
|
@return(integer) 高度 %%
|
|
**}
|
|
return _wapi.GetSystemMetrics(SM_CYCAPTION);
|
|
end
|
|
function DesigningSelect(v);
|
|
begin
|
|
if ifnil(FDesignSelect)then FDesignSelect := false;
|
|
if ifnil(v)then return FDesignSelect;
|
|
if WsPopUp then return;
|
|
if not(csDesigning in ComponentState)then return;
|
|
nv := v?true:false;
|
|
if nv=FDesignSelect then return;
|
|
FDesignSelect := nv;
|
|
{$ifdef linux}
|
|
return InvalidateRect(nil,false);
|
|
{$endif}
|
|
rec := array(left,top,left+width,top+height);
|
|
rec[2:3]+= 1;
|
|
SetBoundsRect(rec);
|
|
rec[2:3]-= 1;
|
|
SetBoundsRect(rec);
|
|
end
|
|
private
|
|
FDesignSelect;
|
|
public //消息绑定函数
|
|
function ImageChanged();virtual;
|
|
begin
|
|
end
|
|
function ncpaint(rec);virtual;
|
|
begin
|
|
return ;
|
|
ls := array((0,0),(rec[2]-rec[0]-1,0),(rec[2]-rec[0]-1,rec[3]-rec[1]-1),(0,rec[3]-rec[1]-1),(0,0));
|
|
cvs := Canvas;
|
|
cvs.moveto(ls[0]);
|
|
for i:= 1 to length(ls) do
|
|
begin
|
|
cvs.LineTo(ls[i]);
|
|
end
|
|
end
|
|
function WMNCPAINT(o,e):LM_NCPAINT;virtual;
|
|
begin
|
|
hWnd := Handle;
|
|
rec := zeros(4);
|
|
cvs := Canvas;
|
|
pc := cvs.pen.Color;
|
|
ps := cvs.Pen.Style;
|
|
pw := cvs.Pen.width;
|
|
if (csDesigning in ComponentState) and FDesignSelect then
|
|
begin
|
|
{$ifdef gtkpaint}
|
|
cvs.Handle := e.lparam;
|
|
cvs.Pen.Color := 244;//rgb(224,0,0);
|
|
cvs.Pen.Style := PS_SOLID;
|
|
cvs.Pen.width := 2;
|
|
_wapi.gtk_widget_get_allocation(hWnd,rec);
|
|
rec[0]:=0;rec[1] := 0;
|
|
cvs.Draw("Polyline",array((0,0),(rec[2]-rec[0]-1,0),(rec[2]-rec[0]-1,rec[3]-rec[1]-1),(0,rec[3]-rec[1]-1),(0,0)));
|
|
cvs.Pen.Color := pc; cvs.Pen.width := pw;cvs.Pen.Style := ps;cvs.Handle := 0;
|
|
return ;
|
|
{$endif}
|
|
_wapi.GetWindowRect(hwnd,rec);
|
|
region := new TRGNRECT();
|
|
region.Rect := rec;
|
|
if e.wparam <> 1 then _wapi.CombineRgn(region.Handle,e.wparam,nil,RGN_COPY);
|
|
hdc := _wapi.GetDCEx(hWnd, region.Handle, DCX_WINDOW .| DCX_CACHE .| DCX_INTERSECTRGN .| DCX_LOCKWINDOWUPDATE);
|
|
if hdc=0 then return ;
|
|
cvs.Handle := hdc;
|
|
cvs.Pen.Color := 244;//rgb(224,0,0);
|
|
cvs.Pen.Style := PS_SOLID;
|
|
cvs.Pen.width := 2;
|
|
defaulthandler(e);
|
|
cvs.Draw("Polyline",array((0,0),(rec[2]-rec[0]-1,0),(rec[2]-rec[0]-1,rec[3]-rec[1]-1),(0,rec[3]-rec[1]-1),(0,0)));
|
|
cvs.Pen.Color := pc; cvs.Pen.width := pw;cvs.Pen.Style := ps;cvs.Handle := 0;
|
|
_wapi.ReleaseDC(hWnd,hdc);
|
|
e.skip := true;e.Result := 0;
|
|
end else
|
|
begin
|
|
if not Border then return ;
|
|
if WsCaption or WSSizebox or WSsysMenu then return ;
|
|
|
|
{$ifdef gtkpaint}
|
|
_wapi.gtk_widget_get_allocation(hWnd,rec);rec[0]:=0;rec[1] := 0;
|
|
cvs.Handle := e.lparam;
|
|
{$else}
|
|
|
|
_wapi.GetWindowRect(hwnd,rec);
|
|
region := new TRGNRECT();
|
|
region.Rect := rec;//array(rec[0]-1,rec[1],rec[2],rec[3]);
|
|
if e.wparam <> 1 then _wapi.CombineRgn(region.Handle,e.wparam,nil,RGN_COPY);
|
|
hdc := _wapi.GetDCEx(hWnd, region.Handle, DCX_WINDOW .| DCX_CACHE .| DCX_INTERSECTRGN .| DCX_LOCKWINDOWUPDATE);
|
|
if hdc=0 then return ;
|
|
cvs.Handle := hdc;
|
|
defaulthandler(e);
|
|
{$endif}
|
|
cvs.pen.Color := 0;
|
|
cvs.Pen.Style := PS_SOLID;
|
|
cvs.Pen.width := 1;
|
|
ncpaint(rec);
|
|
cvs.Pen.Color := pc; cvs.Pen.width := pw;cvs.Pen.Style := ps;cvs.Handle := 0;
|
|
{$ifdef gtkpaint}
|
|
{$else}
|
|
_wapi.ReleaseDC(hWnd,hdc);
|
|
{$endif}
|
|
e.skip := true;e.Result := 0;
|
|
return ;
|
|
end
|
|
end
|
|
procedure FontChanged(Sender:TObject);override;
|
|
begin
|
|
inherited;
|
|
for i := 0 to ControlCount-1 do
|
|
begin
|
|
it := Controls[i];
|
|
if it and it.ParentFont then
|
|
begin
|
|
it.FontChanged(sender);
|
|
end
|
|
//InvalidateRect(nil,false);
|
|
//it.Perform(new tuieventbase(CM_PARENTFONTCHANGED,hd,1,0));
|
|
end
|
|
end
|
|
function CMPARENTFONTCHANGED(o,e):CM_PARENTFONTCHANGED;virtual;
|
|
begin
|
|
//if ParentFont then
|
|
//begin
|
|
// _send_(WM_SETFONT,e.wparam,1);
|
|
//end
|
|
end
|
|
function WMGETMINMAXINFO(o,e):WM_GETMINMAXINFO;virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 最小窗口设置 %%
|
|
**}
|
|
k := 0;
|
|
if FMinWidth>0 then
|
|
begin
|
|
k .|= 1;
|
|
end
|
|
if FMinHeigt>0 then
|
|
begin
|
|
k .|= 2;
|
|
end
|
|
if FMaxHeight>0 then
|
|
begin
|
|
k .|= 4;
|
|
end
|
|
if FMaxWidth>0 then
|
|
begin
|
|
k .|= 8;
|
|
end
|
|
if k then
|
|
begin
|
|
d := new Ttagminmaxinfo(e.lparam);
|
|
ts := d.ptmintracksize;
|
|
case k of
|
|
1:ts[0]:= FMinWidth;
|
|
2:ts[1]:= FMinHeigt;
|
|
3:ts := array(FMinWidth,FMinHeigt);
|
|
end;
|
|
d.ptmintracksize := ts;
|
|
end
|
|
end
|
|
function CMFONTCHANGED(o,e):CM_FONTCHANGED;virtual;
|
|
begin
|
|
hd := e.wparam;
|
|
for i := 0 to ControlCount-1 do
|
|
begin
|
|
it := Controls[i];
|
|
if it then it.Perform(new tuieventbase(CM_PARENTFONTCHANGED,hd,1,0));
|
|
end
|
|
end
|
|
function WMSETFONT(o,e):WM_SETFONT;virtual;
|
|
begin
|
|
//defaulthandler(e);
|
|
//Perform(new tuieventbase(CM_FONTCHANGED,e.wparam,e.lparam,0));
|
|
end
|
|
function WMACTIVATE(o,e):WM_ACTIVATE;virtual;
|
|
begin
|
|
factivated := e.wparam;
|
|
CallMessgeFunction(OnActivate,o,e);
|
|
if e.skip then return ;
|
|
defaulthandler(e);
|
|
if factivated and ContainsControl(factivecontrol) then
|
|
begin
|
|
factivecontrol.SetFocus();
|
|
end
|
|
end
|
|
function getwndclientrect();
|
|
begin
|
|
ret := array(0,0,FWidth,Height);
|
|
if HandleAllocated()then
|
|
begin
|
|
if ifnumber(FClientWdith)and ifnumber(FClientHeight)then
|
|
begin
|
|
ret := array(0,0,FClientWdith,FClientHeight);
|
|
end else
|
|
_wapi.GetClientRect(self.Handle,ret);
|
|
end
|
|
{$ifdef linuxgtk}
|
|
n := 0;
|
|
if WSDlgModalFrame or WSSizebox then
|
|
begin
|
|
n := 2;
|
|
end else
|
|
if Border then n := 1;
|
|
if n then //处理gtk的情况
|
|
begin
|
|
ret[0]+=n;
|
|
ret[1]+=n;
|
|
ret[2]-=n;
|
|
ret[3]-=n;
|
|
if ret[3]<ret[1] then ret[3] := ret[1];
|
|
if ret[2]<ret[0] then ret[2] := ret[0];
|
|
end
|
|
{$endif}
|
|
return ret;
|
|
end
|
|
function GetClientRect();override;
|
|
begin
|
|
{**
|
|
@explan(说明)获得客户区大小 %%
|
|
@return(array of integer) 客户区矩形 %%
|
|
**}
|
|
r := getwndclientrect();
|
|
return r;
|
|
end
|
|
#!begin //消息
|
|
function DoCNALIGN(o,e);override;
|
|
begin
|
|
if(wstyle().& WS_POPUP)=WS_POPUP then exit;
|
|
inherited;
|
|
end
|
|
function DoWMCLOSE(o,e);virtual;
|
|
begin
|
|
EndModal();
|
|
end
|
|
function WMCLOSE(o,e):WM_CLOSE;virtual;
|
|
begin
|
|
CallMessgeFunction(OnClose,o,e);
|
|
DoWMCLOSE(o,e);
|
|
end
|
|
function WMCREATE(o,e):WM_CREATE;virtual;
|
|
begin
|
|
if e.lparam then
|
|
begin
|
|
co := new TCREATESTRUCT(e.lparam);
|
|
__wstyle := co.style;
|
|
__wexstyle := co.dwexstyle;
|
|
end
|
|
end
|
|
function WMSHOWWINDOW(o,e):WM_SHOWWINDOW;virtual;
|
|
begin
|
|
FVisible := e.wparam?true:false;
|
|
end
|
|
function WMSETCURSOR(o,e):WM_SETCURSOR;virtual;
|
|
begin
|
|
if e.lolparam=HTCLIENT then
|
|
begin
|
|
ne := new tuieventbase(CM_CURSORCHANGED,0,0);
|
|
Perform(ne);
|
|
if ne.skip then
|
|
begin
|
|
e.skip := true;
|
|
e.result := true;
|
|
end
|
|
end
|
|
end
|
|
function WMSTYLECHANGING(o,e):WM_STYLECHANGING;virtual;
|
|
begin
|
|
end
|
|
function WMNCDESTROY(o,e):WM_NCDESTROY;virtual;
|
|
begin
|
|
FHandle := nil;
|
|
factivated := false;
|
|
for i := 0 to FControls.count-1 do
|
|
begin
|
|
item := FControls[i];
|
|
if(item is class(TWinControl))and item.WsPopUp then
|
|
begin
|
|
item.DestroyHandle();
|
|
end
|
|
end
|
|
end
|
|
function WMSTYLECHANGED(o,e):WM_STYLECHANGED;virtual;
|
|
begin
|
|
end
|
|
function WMNCCALCSIZE(o,e):WM_NCCALCSIZE;virtual;
|
|
begin
|
|
if(csDesigning in ComponentState)and FDesignSelect then
|
|
begin
|
|
wd := 1;
|
|
hwd := wd;
|
|
rc := new TCRect(e.lparam);
|
|
rc.top := rc.top + hwd;
|
|
rc.left := rc.left + wd;
|
|
rc.bottom := rc.bottom - wd;
|
|
rc.right := rc.right - wd;
|
|
end
|
|
end
|
|
function WMMOUSEHOVER(o,e):WM_MOUSEHOVER;virtual;
|
|
begin
|
|
MouseHover(o,e);
|
|
end
|
|
function WMMOUSELEAVE(o,e):WM_MOUSELEAVE;virtual;
|
|
begin
|
|
MouseLeave(o,e);
|
|
end
|
|
function WMMENURBUTTONUP(o,e):WM_MENURBUTTONUP;virtual;
|
|
begin
|
|
if PopupMenu and (PopupMenu is class(TcustomMenu))then PopupMenu.dispatch(e);
|
|
end
|
|
function WMMENUSELECT(o,e):WM_MENUSELECT;virtual;
|
|
begin
|
|
if PopupMenu and (PopupMenu is class(TcustomMenu))then PopupMenu.dispatch(e);
|
|
end
|
|
function WMINITMENUPOPUP(o,e):WM_INITMENUPOPUP;virtual;
|
|
begin
|
|
if PopupMenu and (PopupMenu is class(TcustomMenu))then PopupMenu.dispatch(e);
|
|
end
|
|
function WMERASEBKGND(o,e):WM_ERASEBKGND;override;
|
|
begin
|
|
{**
|
|
@explan(说明) 背景绘制 %%
|
|
**}
|
|
if not HandleAllocated()then return;
|
|
mtic;
|
|
//if not(csCustomPaint in ControlState) and not(e.lparam) then return ;
|
|
dc := e.wparam;
|
|
if dc {and e.lparam}then
|
|
begin
|
|
if Enabled then
|
|
begin
|
|
cl := Color;
|
|
end else
|
|
begin
|
|
cl := cldisabledbk;
|
|
end
|
|
rect := array(0,0,0,0);
|
|
if e.lparam=2 then
|
|
begin
|
|
rect := PAINTSTRUCT().rcpaint();
|
|
end
|
|
_wapi.GetClientRect(self.Handle,rect);
|
|
if ifnumber(cl)then
|
|
begin
|
|
Canvas.Brush.Color := cl;
|
|
Canvas.Handle := dc;
|
|
Canvas.FillRect(rect);
|
|
end else
|
|
begin
|
|
cl := _wapi.GetStockObject(WHITE_BRUSH);
|
|
_wapi.FillRect(dc,rect,cl);
|
|
end
|
|
if(BKBitmap is class(tcustombitmap))and BKBitmap.HandleAllocated()then
|
|
begin
|
|
Canvas.Handle := dc;
|
|
//Canvas.StretchDraw(rect,BKBitmap);
|
|
Canvas.DrawBitmap(self.BKBitmap,rect);
|
|
end
|
|
e.skip := true;
|
|
e.Result := 1;
|
|
end
|
|
end
|
|
Function WMDRAWITEM(o,e):WM_DRAWITEM;virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@ignore(忽略) %%
|
|
@explan(说明) 自绘制消息处理 %%
|
|
@param(o)(TWincontrol) 窗口控件 %%
|
|
@param(e)(TMDRAWITEM) 消息 %%
|
|
**}
|
|
e.canvas := canvas;
|
|
dc := e.hdc;
|
|
//dc := _wapi.GetDC(SELF.hANDLE);
|
|
//dcid := _wapi.SaveDC(dc);
|
|
canvas.handle := dc;
|
|
if(e.wparam=0)and(PopupMenu is class(TcustomMenu))then
|
|
begin
|
|
r := PopupMenu.dispatch(e);
|
|
if r then
|
|
begin
|
|
e.canvas := nil;
|
|
exit;
|
|
end
|
|
end
|
|
ctrl := getwndbyhwnd(e.hwndItem);
|
|
if ctrl then
|
|
begin
|
|
e.message := CN_DRAWITEM;
|
|
h := e.hwnd;
|
|
try
|
|
ctrl.Perform(const e);
|
|
except
|
|
end;
|
|
e.hwnd := h;
|
|
e.message := WM_DRAWITEM;
|
|
end
|
|
//if dcid then
|
|
// "\r\nrestor:",_wapi.RestoreDC(dc,-1);
|
|
e.canvas := nil;
|
|
// _wapi.ReleaseDC(Handle,Canvas.handle);
|
|
end
|
|
function WMMEASUREITEM(o,e):WM_MEASUREITEM;virtual;
|
|
begin
|
|
{**
|
|
@ignore(忽略) %%
|
|
@explan(说明) 测量消息处理 %%
|
|
@param(o)()控件本身 %%
|
|
@param(e)(TMMEASUREITEM)测量消息 %%
|
|
**}
|
|
if(e.wparam=0 and e.ctltype=ODT_MENU)and(PopupMenu is class(TcustomMenu))and PopupMenu.Dispatch(e)then exit;
|
|
for i := 0 to FControls.count-1 do
|
|
begin
|
|
it := FControls[i];
|
|
if it and it.getid=e.ctlid then
|
|
begin
|
|
h := e.hwnd;
|
|
e.message := CN_MEASUREITEM;
|
|
it.Perform(e);
|
|
e.message := WM_MEASUREITEM;
|
|
e.hwnd := h;
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
function WMNOTIFY(o,e):WM_NOTIFY;virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 子控件通知父控件 %%
|
|
@param(e)(TMNOTIFY) 通知消息 %%
|
|
**}
|
|
hd := e.hwndfrom;
|
|
if hd then
|
|
begin
|
|
ctrl := getwndbyhwnd(hd);
|
|
if ctrl then
|
|
begin
|
|
nr := new tuieventbase(CN_NOTIFY,e.code,e.lparam);
|
|
ctrl.Perform(nr);
|
|
e.skip := nr.skip;
|
|
end
|
|
end
|
|
end
|
|
function WMCTLCOLORBTN(o,e):WM_CTLCOLORBTN;virtual;
|
|
begin
|
|
hd := e.lparam;
|
|
if hd then
|
|
begin
|
|
ctrl := getwndbyhwnd(hd);
|
|
if ctrl then
|
|
begin
|
|
ce := new tuieventbase(CN_CTLCOLORBTN,e.wparam,e.lparam,e.lparam);
|
|
ctrl.Canvas.handle := e.lparam;
|
|
ctrl.Perform(ce);
|
|
if ce.Result then
|
|
begin
|
|
e.result := ce.result;
|
|
e.skip := true;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
function WMSYSCOMMAND(o,e):WM_SYSCOMMAND;virtual;
|
|
begin
|
|
//sysmenu.dispatch();
|
|
end
|
|
function WMCOMMAND(o,e):WM_COMMAND;virtual;
|
|
begin
|
|
if ftrackmenu and (ftrackmenu is class(TcustomMenu))and ftrackmenu.dispatch(e)then exit;
|
|
if PopupMenu and (popupmenu is class(TcustomMenu))and popupmenu.dispatch(e)then exit;
|
|
hd := e.lparam;
|
|
if hd then
|
|
begin
|
|
ctrl := getwndbyhwnd(hd);
|
|
if ctrl then
|
|
begin
|
|
wp := e.wparam;
|
|
ctrl.Perform(new tuieventbase(CN_COMMAND,wp,0));
|
|
end
|
|
end
|
|
end
|
|
function WMKEYDOWN(o,e):WM_KEYDOWN;virtual;
|
|
begin
|
|
CallMessgeFunction(FOnkeyDown,o,e);
|
|
if e.skip then return;
|
|
if HandleAllocated()and(e.wParam=VK_TAB)then
|
|
begin
|
|
cfoc := _wapi.GetFocus();
|
|
if Handle=cfoc then
|
|
begin
|
|
if TabStop then //发送给父控件
|
|
begin
|
|
if Parent then Parent._Send_(WM_KEYDOWN,VK_TAB,e.lparam,nil);
|
|
end
|
|
end else //遍历子控件 设置下一个focus
|
|
begin
|
|
cts := Controls;
|
|
Thec := false;
|
|
pc := 0;
|
|
for i := 0 to cts.Count-1 do
|
|
begin
|
|
ci := cts[i];
|
|
if ci and (ci is class(TWinControl))and ci.Enabled and ci.Visible and ci.TabStop and ci.HandleAllocated()then
|
|
begin
|
|
if ci.Handle=cfoc then //找到了当前
|
|
begin
|
|
Thec := true;
|
|
if pc and(ssShift in e.shiftstate)then
|
|
begin
|
|
pc.SetFocus();
|
|
break;
|
|
end
|
|
continue;
|
|
end
|
|
pc := ci;
|
|
if Thec then
|
|
begin
|
|
ci.SetFocus();
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return KeyDown(o,e);
|
|
end
|
|
function WMKEYUP(o,e):WM_KEYUP;virtual;
|
|
begin
|
|
CallMessgeFunction(FOnKeyUp,o,e);
|
|
keyup(o,e);
|
|
end
|
|
function WMSYSKEYUP(o,e):WM_SYSKEYUP;virtual;
|
|
begin
|
|
CallMessgeFunction(fonsyskeyup,o,e);
|
|
end
|
|
function WMSYSKEYDOWN(o,e):WM_SYSKEYDOWN;virtual;
|
|
begin
|
|
CallMessgeFunction(fonsyskeydown,o,e);
|
|
end
|
|
function WMSYSCHAR(o,e):WM_SYSCHAR;virtual;
|
|
begin
|
|
CallMessgeFunction(FOnSysKeyPress,o,e);
|
|
end
|
|
function WMCHAR(o,e):WM_CHAR;virtual;
|
|
begin
|
|
CallMessgeFunction(FOnKeyPress,o,e);
|
|
return keypress(o,e);
|
|
end
|
|
function WMSETFOCUS(o,e):WM_SETFOCUS;virtual;
|
|
begin
|
|
CallMessgeFunction(FonSetFocus,o,e);
|
|
dosetfocus(o,e);
|
|
end
|
|
function WMKILLFOCUS(o,e):WM_KILLFOCUS;virtual;
|
|
begin
|
|
CallMessgeFunction(FonKillFocus,o,e);
|
|
dokillfocus(o,e);
|
|
end
|
|
function WMPAINT(O,e):LM_PAINT;virtual;
|
|
begin
|
|
hd := e.hwnd;
|
|
if e.wparam then
|
|
begin
|
|
PaintHandler(e);
|
|
end else
|
|
if csCustomPaint in ControlState then
|
|
begin
|
|
ps := PaintStruct();
|
|
DC := _wapi.BeginPaint(hd,ps._getptr_);
|
|
if DC=0 then exit;
|
|
try
|
|
c := getwndclientrect() ;//ClientRect;
|
|
memdc := dc;
|
|
{$ifdef gdipaint}
|
|
mdc := _wapi.GetDC(0);
|
|
if not mdc then exit;
|
|
mbit := _wapi.CreateCompatibleBitmap(mdc,c[2],c[3]);
|
|
if not mbit then exit;
|
|
memdc := _wapi.CreateCompatibleDC(0);
|
|
if not memdc then exit;
|
|
oldmp := _wapi.SelectObject(memdc,mbit);
|
|
_wapi.SaveDC(memdc);
|
|
_wapi.SetGraphicsMode(memdc,2);
|
|
|
|
{$else}
|
|
cr := getwndclientrect();
|
|
//rc := ps._getvalue_("rcpaint");
|
|
img := _wapi.cairo_image_surface_create(1,cr[2]-cr[0]+1,cr[3]-cr[1]+1);
|
|
memdc := _wapi.cairo_create(img);
|
|
_wapi.gtk_object_set_data(memdc,nil);
|
|
_wapi.gtk_object_set_data(memdc,"-surface-",img);
|
|
rcpaint := ps.rcpaint;
|
|
|
|
_wapi.cairo_reset_clip(memdc);
|
|
rng := _wapi.CreateRectRgn(rcpaint[0],rcpaint[1],rcpaint[2],rcpaint[3]);
|
|
_wapi.SelectClipRgn(memdc,rng);
|
|
{$endif}
|
|
e.wparam := memdc;
|
|
if Color then
|
|
begin
|
|
Dispatch(o,new tuieventbase(LM_ERASEBKGND,memdc,2));
|
|
end
|
|
Dispatch(o,e);
|
|
e.wparam := 0;
|
|
rc := ps.rcpaint;
|
|
|
|
{$ifdef gdipaint}
|
|
_wapi.RestoreDC(memdc,-1);
|
|
_wapi.BitBlt(dc,rc[0],rc[1],rc[2]-rc[0],rc[3]-rc[1],memdc,rc[0],rc[1],SRCCOPY); //_wapi.BitBlt(dc,c[0],c[1],c[2],c[3],memdc,0,0,SRCCOPY);
|
|
global g_save_wind;
|
|
if ifarray(g_save_wind) and g_save_wind["handle"]= hd then
|
|
begin
|
|
gsi := g_save_wind;
|
|
g_save_wind := nil;
|
|
fn := gsi["file"];
|
|
if fn and ifstring(fn) then
|
|
begin
|
|
tp := gsi["type"];
|
|
if not(tp in array("png","bmp")) then tp := "png";
|
|
if parseregexpr("\\."$tp$"$",fn,"",m,mp,ml)<>1 then fn+="."$tp;
|
|
try
|
|
ndc := _wapi.CreateCompatibleDC(memdc);
|
|
bthandle := _wapi.CreateCompatibleBitmap(memdc,c[2]-c[0],c[3]-c[1]);
|
|
oldb := _wapi.SelectObject(ndc,bthandle);
|
|
_wapi.BitBlt(ndc,0,0,c[2]-c[0],c[3]-c[1],dc,0,0,SRCCOPY);
|
|
if oldb then _wapi.SelectObject(ndc,oldb);
|
|
nmg := new tcustomimage();
|
|
nmg.FromHBitmap(bthandle);
|
|
nmg.SavetoFile(fn,tp);
|
|
finally
|
|
_wapi.DeleteDC(ndc);
|
|
_wapi.DeleteObject(bthandle);
|
|
end;
|
|
end
|
|
end
|
|
{$else}
|
|
_wapi.SelectClipRgn(memdc,0);
|
|
_wapi.cairo_set_source_surface(dc, img, 0, 0);
|
|
_wapi.cairo_rectangle(dc,rc[0],rc[1],rc[2]-rc[0],rc[3]-rc[1]);
|
|
_wapi.cairo_clip(dc);
|
|
_wapi.cairo_paint(dc);
|
|
_wapi.cairo_surface_destroy(img);
|
|
_wapi.cairo_destroy(memdc);
|
|
|
|
{$endif}
|
|
finally
|
|
_wapi.EndPaint(hd,ps._getptr_);
|
|
{$ifdef gdipaint}
|
|
_wapi.ReleaseDC(0,mdc);
|
|
_wapi.SelectObject(memdc,oldmp);
|
|
_wapi.DeleteDC(memdc);
|
|
_wapi.DeleteObject(mbit);
|
|
|
|
{$else}
|
|
|
|
{$endif}
|
|
end
|
|
end else
|
|
begin
|
|
{$ifdef gdipaint3}
|
|
ctls := Controls;
|
|
if not ctls then return; // e.skip := false;
|
|
if ctls.Count<1 then return; // e.skip := false ;
|
|
flag := true;
|
|
for i := 0 to ctls.Count-1 do
|
|
begin
|
|
ci := ctls[i];
|
|
if ci and (ci is class(TGraphicControl))then
|
|
begin
|
|
flag := false;
|
|
break;
|
|
end
|
|
end
|
|
if flag then
|
|
begin
|
|
return;
|
|
end
|
|
rec := zeros(4);
|
|
_wapi.GetUpdateRect(hd,rec,false);
|
|
defaulthandler(e);
|
|
dc := _wapi.GetDC(hd);
|
|
if not dc then
|
|
begin
|
|
return e.skip := true;
|
|
end
|
|
e.wparam := dc;
|
|
try
|
|
pts := PaintStruct();
|
|
pts._setvalue_("rcpaint",rec);
|
|
pts._setvalue_("hdc",dc);
|
|
//Perform(e);
|
|
Dispatch(o,e);
|
|
finally
|
|
_wapi.ReleaseDC(hd,dc);
|
|
e.wparam := 0;
|
|
e.skip := true;
|
|
end
|
|
{$endif}
|
|
end
|
|
e.skip := true;
|
|
e.result := true;
|
|
end
|
|
|
|
#!end
|
|
function KeyUp(o,e);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) key 松开 %%
|
|
@param(o)(TWinControl) 控件自身 %%
|
|
@Param(e)(TMKEY) 消息对象 %%
|
|
**}
|
|
end
|
|
function KeyDown(o,e);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) key 按下 %%
|
|
@param(o)(TWinControl) 控件自身 %%
|
|
@Param(e)(TMKEY) 消息对象 %%
|
|
**}
|
|
end
|
|
function keypress(o,e);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) char 消息处理 %%
|
|
@param(o)(TWinControl) 控件自身 %%
|
|
@Param(e)(TMKEY) 消息对象 %%
|
|
**}
|
|
end
|
|
function dosetfocus(o,e);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 控件获得焦点 %%
|
|
@param(o)(TWinControl) 控件自身 %%
|
|
@Param(e)(tuieventbase) 消息对象 %%
|
|
**}
|
|
end
|
|
function dokillfocus(o,e);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 控件失去焦点 %%
|
|
@param(o)(TWinControl) 控件自身 %%
|
|
@Param(e)(tuieventbase) 消息对象 %%
|
|
**}
|
|
end
|
|
protected //样式相关
|
|
function SetColor(v);override;
|
|
begin
|
|
if not ifnumber(v) then return ;
|
|
oc := color;
|
|
inherited;
|
|
if oc <> Color then
|
|
begin
|
|
if HandleAllocated()then invalidaterect(nil,false);
|
|
end
|
|
end
|
|
function SetBitmap(v);override;
|
|
begin
|
|
if v <> BKBitmap then
|
|
begin
|
|
inherited;
|
|
if HandleAllocated()then invalidaterect(nil,false);
|
|
end
|
|
end
|
|
function Refresh();
|
|
begin
|
|
if HandleAllocated()then
|
|
begin
|
|
_wapi.SetWindowPos(self.Handle,0,0,0,0,0,SWP_DEFERERASE .| SWP_NOMOVE .| SWP_NOSIZE .| SWP_NOZORDER .| SWP_NOSENDCHANGING .| SWP_NOACTIVATE .| SWP_DRAWFRAME);
|
|
end
|
|
end
|
|
procedure PaintControls(DC:HDC;First:TControl); //type_twinctrol
|
|
begin
|
|
end
|
|
procedure PaintHandler(var TheMessage:TLMPaint); //type_twinctrol
|
|
begin
|
|
hdc := TheMessage.wparam;
|
|
PaintWindow(TheMessage.wparam);
|
|
//c := ClientRect;
|
|
c := array(0,0); //设置基准点,为00 20201112 修改
|
|
rcpaint := PaintStruct().rcpaint;
|
|
if sum(rcpaint)<4 then exit;
|
|
//rgC := _wapi.CreateRectRgn(0,0,10,10);
|
|
//rga := _wapi.CreateRectRgn(rcpaint[0],rcpaint[1],rcpaint[2],rcpaint[3]);
|
|
try
|
|
for i := 0 to ControlCount-1 do
|
|
begin
|
|
it := FControls[i];
|
|
if it is class(TGraphicControl)then
|
|
begin
|
|
if not(it.Visible)then continue;
|
|
itbounds := it.GetBoundsRect();
|
|
if not(intersectrect(itbounds,rcpaint,outrect))then
|
|
begin
|
|
continue;
|
|
end
|
|
rgb := _wapi.CreateRectRgn(outrect[0],outrect[1],outrect[2],outrect[3]); //控件区域
|
|
bkrg := _wapi.SelectClipRgn(TheMessage.wparam,rgb); //裁剪区域
|
|
try
|
|
pts := it.PaintStruct();
|
|
pts._setvalue_("rcpaint",array(outrect[0]-itbounds[0],outrect[1]-itbounds[1],outrect[2]-itbounds[0],outrect[3]-itbounds[1]));
|
|
pts._setvalue_("hdc",TheMessage.wparam);
|
|
ne := new tuieventbase(LM_PAINT,TheMessage.wparam,TheMessage.lparam,TheMessage.hwnd);
|
|
_wapi.SetViewportOrgEx(TheMessage.wparam,itbounds[0],itbounds[1],nil);
|
|
it.Perform(ne);
|
|
_wapi.SetViewportOrgEx(TheMessage.wparam,c[0],c[1],nil); //恢复基准点
|
|
finally
|
|
_wapi.SelectClipRgn(TheMessage.wparam,bkrg); //恢复区域
|
|
_wapi.DeleteObject(rgb); //销毁区域
|
|
end;
|
|
end
|
|
end
|
|
finally
|
|
//_wapi.DeleteObject(rga);
|
|
//_wapi.DeleteObject(rgc);
|
|
end;
|
|
end
|
|
procedure PaintWindow(DC:HDC);virtual;
|
|
begin
|
|
end
|
|
function SetTempCursor(Value);override;
|
|
begin
|
|
if(Value is class(tcustomcursor))and Value.HandleAllocated()and HandleAllocated()and Enabled and Visible then
|
|
begin
|
|
return Value.Show();
|
|
end
|
|
end
|
|
//public
|
|
function wstyle(v);
|
|
begin
|
|
{
|
|
@explan(说明)设置或者获取样式 %%
|
|
@param(v)(integer)为空获取样式,为整数 设置样式%%
|
|
@return(integer)当前样式
|
|
}
|
|
if v and ifnumber(v)then
|
|
begin
|
|
if(v <> __wstyle)and HandleAllocated()then _wapi.SetWindowLongPtrA(FHandle,GWL_STYLE,v);
|
|
end else
|
|
return __wstyle;
|
|
end
|
|
function wexstyle(v);
|
|
begin
|
|
{
|
|
@explan(说明)设置或者获取扩展样式 %%
|
|
@param(v)(integer)为空获取样式,为整数 设置样式%%
|
|
@return(integer)当前扩展样式
|
|
}
|
|
if v and ifnumber(v)then
|
|
begin
|
|
if(v <> __wexstyle)and HandleAllocated()then _wapi.SetWindowLongPtrA(FHandle,GWL_EXSTYLE,v);
|
|
end else
|
|
return __wexstyle;
|
|
end
|
|
function minuswstyle(v);
|
|
begin
|
|
{
|
|
@explan(说明)剔除样式 %%
|
|
@param(v)(integer) 剔除的样式 %%
|
|
}
|
|
if ifnumber(v)then
|
|
begin
|
|
s := wstyle();
|
|
ns := bitcombination(s,v,2);
|
|
if ns <> s then
|
|
begin
|
|
wstyle(ns);
|
|
end
|
|
end
|
|
end
|
|
function appendwstyle(v);
|
|
begin
|
|
{
|
|
@explan(说明)在原有样式中追加 样式%%
|
|
@param(v)(integer) 追加的样式 %%
|
|
}
|
|
if ifnumber(v)then
|
|
begin
|
|
s := wstyle();
|
|
ns := bitcombination(s,v,0);
|
|
if ns <> s then
|
|
begin
|
|
wstyle(ns);
|
|
end
|
|
end
|
|
end
|
|
function minuswexstyle(v);
|
|
begin
|
|
{
|
|
@explan(说明)剔除扩展样式 %%
|
|
@param(v)(integer) 剔除的样式 %%
|
|
}
|
|
if ifnumber(v)then
|
|
begin
|
|
s := wexstyle();
|
|
ns := bitcombination(s,v,2);
|
|
if ns <> s then
|
|
begin
|
|
wexstyle(ns);
|
|
end
|
|
end
|
|
end
|
|
function appendminuswstyple(ap,mi);
|
|
begin
|
|
{
|
|
@explan(说明)添加and剔除样式 %%
|
|
@param(ap)(integer) 添加的样式 %%
|
|
@param(mi)(integer) 剔除的样式 %%
|
|
}
|
|
if ifnumber(ap)or ifnumber(mi)then
|
|
begin
|
|
s := wstyle();
|
|
ns := s;
|
|
if ifnumber(ap)then ns := bitcombination(ns,ap,0);
|
|
if ifnumber(mi)then ns := bitcombination(ns,mi,2);
|
|
if ns <> s then
|
|
begin
|
|
wstyle(ns);
|
|
end
|
|
end
|
|
end
|
|
|
|
function appendminuswexstyple(ap,mi);
|
|
begin
|
|
{
|
|
@explan(说明)添加and剔除样式 %%
|
|
@param(ap)(integer) 添加的样式 %%
|
|
@param(mi)(integer) 剔除的样式 %%
|
|
}
|
|
if ifnumber(ap)or ifnumber(mi)then
|
|
begin
|
|
s := wexstyle();
|
|
ns := s;
|
|
if ifnumber(ap)then ns := bitcombination(ns,ap,0);
|
|
if ifnumber(mi)then ns := bitcombination(ns,mi,2);
|
|
if ns <> s then
|
|
begin
|
|
wexstyle(ns);
|
|
end
|
|
end
|
|
end
|
|
function appendwexstyle(v);
|
|
begin
|
|
{
|
|
@explan(说明)在原有扩展样式中追加 样式%%
|
|
@param(v)(integer) 追加的样式 %%
|
|
}
|
|
if ifnumber(v)then
|
|
begin
|
|
s := wexstyle();
|
|
ns := bitcombination(s,v,0);
|
|
if ns <> s then
|
|
begin
|
|
wexstyle(ns);
|
|
end
|
|
end
|
|
end
|
|
public //常用接口
|
|
function MonitorHandle();
|
|
begin
|
|
if HandleAllocated()then
|
|
begin
|
|
return _wapi.MonitorFromWindow(self.Handle,MONITOR_DEFAULTTONEAREST);
|
|
end
|
|
return 0;
|
|
end
|
|
function clienttowindow(x,y);
|
|
begin
|
|
{**
|
|
@explan(说明) 客户区坐标到窗口坐标的转换%%
|
|
**}
|
|
if WsPopUp and HandleAllocated()then
|
|
begin
|
|
xy := clienttoscreen(0,0);
|
|
rect := zeros(4);
|
|
_wapi.GetWindowRect(self.Handle,rect);
|
|
nxy := xy-rect[0:1];
|
|
r := array(x,y)+nxy;
|
|
return r;
|
|
end
|
|
return array(x,y);
|
|
end
|
|
function ClientToScreen(x,y);override;
|
|
begin
|
|
ps := array(x,y);
|
|
if HandleAllocated()then
|
|
begin
|
|
_wapi.ClientToScreen(self.Handle,ps);
|
|
end
|
|
return ps;
|
|
end
|
|
function ScreenToClient(x,y);override;
|
|
begin
|
|
ps := array(x,y);
|
|
if HandleAllocated()then
|
|
begin
|
|
_wapi.ScreenToClient(self.Handle,ps);
|
|
end
|
|
return ps;
|
|
end
|
|
function show(sw);
|
|
begin
|
|
{**
|
|
@explan(说明) 显示窗口 %%
|
|
@param(sw)(nil) 空 %%
|
|
**}
|
|
if ifnil(sw)then sw := SW_SHOW;
|
|
if not(sw >= 0)then return;
|
|
h := self.Handle;
|
|
if SW=SW_SHOW then return Visible := true;
|
|
if SW=SW_HIDE then return Visible := false;
|
|
//Visible := sw;
|
|
_wapi.ShowWindow(h,sw);
|
|
class(TControl).Visible := true;
|
|
end
|
|
function showmodal();virtual;
|
|
begin
|
|
return DoModal();
|
|
end
|
|
function EndModal(endc);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明)关闭模态窗口 %%
|
|
@param(endc)(any) 为非nil 将作为EndModalCode %%
|
|
**}
|
|
if not ifnil(endc)then EndModalCode := endc;
|
|
{$ifdef gtkpaint}
|
|
if FModaling then
|
|
begin
|
|
if HandleAllocated()then _wapi.gtk_window_endmodal(self(true));
|
|
FModaling := false;
|
|
global G_O_TSWIN32API_;
|
|
if G_O_TSWIN32API_ then G_O_TSWIN32API_.PostQuitMessage(0);
|
|
end
|
|
return EndModalCode;
|
|
{$endif}
|
|
if not FModaling then return EndModalCode;
|
|
FModaling := FALSE;
|
|
if not HandleAllocated()then return EndModalCode;
|
|
_wapi.PostMessageA(0,0,0,0);
|
|
if Parent and Parent.HandleAllocated()then
|
|
begin
|
|
hParentWndt := parent.Handle;
|
|
hParentWnd := hParentWndt;
|
|
while(hParentWnd) do
|
|
begin
|
|
hParentWndt := _wapi.GetParent(hParentWnd);
|
|
if not hParentWndt then
|
|
begin
|
|
_wapi.BringWindowToTop(hParentWnd);
|
|
end
|
|
hParentWnd := hParentWndt;
|
|
end
|
|
end
|
|
return EndModalCode;
|
|
end
|
|
function UpdateWindow();
|
|
begin
|
|
{**
|
|
@explan(说明) 刷新窗口客户区 %%
|
|
@return(integer) 非0 成功 %%
|
|
**}
|
|
if HandleAllocated()then return _wapi.UpdateWindow(self.Handle);
|
|
end
|
|
function SetFocus();virtual;
|
|
begin
|
|
if HandleAllocated()then
|
|
begin
|
|
r := _wapi.SetFocus(self.Handle);
|
|
return r;
|
|
end
|
|
end
|
|
function setactive(); virtual;
|
|
begin
|
|
if not(factivated) and WsPopUp and HandleAllocated() then
|
|
begin
|
|
_wapi.SetActiveWindow(self.Handle);
|
|
end
|
|
end
|
|
function DescendantHwnd(hwnd);
|
|
begin
|
|
{
|
|
@explan(说明)判断窗口句柄是否为当前窗口句柄的子窗口 %%
|
|
}
|
|
if not _wapi.IsWindow(hwnd)then return 0;
|
|
if not HandleAllocated()then return 0;
|
|
shd := self.Handle;
|
|
wnd := hwnd;
|
|
while wnd do
|
|
begin
|
|
if wnd=shd then return true;
|
|
nwnd := _wapi.GetParent(wnd);
|
|
wnd := nwnd;
|
|
end
|
|
return false;
|
|
end
|
|
function MoveControlOrder(Acomponent,n);
|
|
begin
|
|
{**
|
|
|
|
@explan(说明) 移动控件的层 %%
|
|
@param(Acomponent)(tcontrol) 控件 %%
|
|
@param(n)(integer) 次序 %%
|
|
**}
|
|
dqid := FControls.IndexOf(Acomponent);
|
|
odp := FControls[n];
|
|
if n <> dqid and n >= 0 then
|
|
begin
|
|
FControls.setorder(dqid,n);
|
|
end
|
|
if odp is class(TWincontrol)and Acomponent is class(TWincontrol)and(Acomponent.HandleAllocated())and(odp.HandleAllocated())then
|
|
begin
|
|
_wapi.SetWindowPos(Acomponent.Handle,odp.Handle,0,0,0,0,SWP_NOMOVE .| SWP_NOSIZE);
|
|
end
|
|
if HandleAllocated()and(Acomponent.Align <> alNone)then
|
|
begin
|
|
DoControlAlign();
|
|
end
|
|
end
|
|
function BeginUpDate();
|
|
begin
|
|
FUpDateCount++;
|
|
end
|
|
function IsUpDating();
|
|
begin
|
|
return FUpDateCount;
|
|
end
|
|
function EndUpDate();
|
|
begin
|
|
if FUpDateCount>0 then
|
|
begin
|
|
FUpDateCount--;
|
|
DoEndUpDate();
|
|
end
|
|
end
|
|
function DoEndUpDate();virtual;
|
|
begin
|
|
if FUpDateCount=0 then
|
|
begin
|
|
if FPaintRects then
|
|
begin
|
|
if HandleAllocated()then
|
|
begin
|
|
ValidFlag := true;
|
|
for i,v in FPaintRects do
|
|
begin
|
|
if ifnil(v)then
|
|
begin
|
|
_wapi.InvalidateRect2(FHandle,nil,0);
|
|
ValidFlag := false;
|
|
break;
|
|
end
|
|
end
|
|
if ValidFlag then
|
|
begin
|
|
{$ifdef linux}
|
|
nrec := FPaintRects[0];
|
|
for i,v in FPaintRects do
|
|
begin
|
|
nrec := array(
|
|
min(nrec[0],v[0]),
|
|
min(nrec[1],v[1]),
|
|
max(nrec[2],v[2]),
|
|
max(nrec[3],v[3]),
|
|
);
|
|
end
|
|
_wapi.InvalidateRect(FHandle,nrec,f);
|
|
{$else}
|
|
for i,v in FPaintRects do
|
|
begin
|
|
_wapi.InvalidateRect(FHandle,v,f);
|
|
end
|
|
{$endif}
|
|
end
|
|
end
|
|
FPaintRects := array();
|
|
end
|
|
end
|
|
end
|
|
function InvalidateRect(rec,f);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明)设置窗口区域无效 %%
|
|
@param(rec)(array) 无效区域,nil表示窗口整体无效,array(左上右下) %%
|
|
@param(f)(bool) 是否重画 %%
|
|
**}
|
|
if HandleAllocated()then
|
|
begin
|
|
if IsUpDating()then
|
|
begin
|
|
if not ifarray(FPaintRects)then FPaintRects := array();
|
|
FPaintRects[length(FPaintRects)]:= rec;
|
|
return;
|
|
end
|
|
if not(ifarray(rec)and rec)then r := _wapi.InvalidateRect2(FHandle,nil,f);
|
|
else r := _wapi.InvalidateRect(FHandle,rec,f);
|
|
return r;
|
|
end
|
|
end
|
|
function ContainsControl(Control_:TControl):bool;//包含控件
|
|
begin
|
|
Control := Control_;
|
|
while(Control is class(TWinControl)) and(Control <> Self) do Control := Control.Parent;
|
|
return Control=Self;
|
|
end
|
|
function create(aowner);override; //type_twinctrol
|
|
begin
|
|
inherited;
|
|
fchildsizing := new t_children_sizer(self(true));
|
|
//fbordercolor := rgb(190,190,190);
|
|
AfterConstruction();
|
|
if foncreated then
|
|
begin
|
|
e := new tuieventbase(0,0,0,0);
|
|
e.sender := (self(true));
|
|
CallMessgeFunction(foncreated,self(true),e);
|
|
end
|
|
end
|
|
function AfterConstruction();virtual;
|
|
begin
|
|
FUpDateCount := 0;
|
|
FTabStop := false;
|
|
FBorderStyle := bsNone;
|
|
//FTRACKMOUSEEVENT := NEW TTRACKMOUSEEVENT();
|
|
FWsPopUp := false;
|
|
FWsSysMenu := false;
|
|
FWsCapton := false;
|
|
WSSizebox := FALSE;
|
|
__wstyle := 0; //窗口样式
|
|
__wexstyle := 0; //窗口扩展样式
|
|
FWsDlgModalFrame := false;
|
|
//FTtageDrawItem := new TtageDrawItem(); //移除了
|
|
FWMNCHITTEST := new TWMNCHITTEST();
|
|
FMinWidth := 1; //添加最小限制
|
|
FMinHeigt := 1;
|
|
end
|
|
function destroy();override; //type_twinctrol
|
|
begin
|
|
inherited;
|
|
end
|
|
function Recycling();override;
|
|
begin
|
|
DestroyHandle();
|
|
//FTtageDrawItem := nil;
|
|
FOnClose := nil;
|
|
FOnDesinedsel := nil;
|
|
FOnDesigDBLClick := nil;
|
|
FOnDesinedRclick := nil;
|
|
FOnDesignBeginMove := nil;
|
|
FOnDesignEndMove := nil;
|
|
FOnActivate := nil;
|
|
FOnKeyDown := nil;
|
|
FOnKeyPress := nil;
|
|
FOnKeyUp := nil;
|
|
ImageList := nil;
|
|
FonSetFocus := nil;
|
|
FonKillFocus := nil;
|
|
factivecontrol := nil;
|
|
inherited;
|
|
end
|
|
function RecreateWnd();virtual;
|
|
begin
|
|
if csDestroying in ComponentState then exit;
|
|
if HandleAllocated()then
|
|
begin
|
|
DestroyHandle();
|
|
HandleNeeded();
|
|
end
|
|
end
|
|
function CreateWnd();virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)构建窗口句柄 %%
|
|
**}
|
|
//if not(Parent and Parent.HandleAllocated or (self(true) is class(tapplicationwindow))) then exit;
|
|
if not(parent) and not(csDesigning in ComponentState) and not(WsPopUp and (WsCaption or FWsSysMenu or FWsSizeBox)) then return ;
|
|
CreateParams(p);
|
|
//_wapi.GetSystemMetrics(SM_CXSCREEN) DIV 2;
|
|
//此处处理构造句柄
|
|
id := 0;
|
|
if p.style .& WS_CHILD then id := getid();
|
|
tcc := p.Caption;
|
|
stl := p.style;
|
|
x := p.x;
|
|
y := p.y;
|
|
sx := p.width;
|
|
sy := p.height;
|
|
selfid := integer(self(true));//int64
|
|
saveobj := new TGlobalValues(selfid,self(true));
|
|
createwndclass(p);
|
|
FDefWndproc := p.subclasswndproc;
|
|
tcn := P.WinClassName;
|
|
f := _wapi.CreateWindowExA(p.ExStyle,tcn,tcc,stl,x,y,sx,sy,p.WndParent,id,p.happ,selfid);
|
|
InitializeWnd();
|
|
if HandleAllocated()then
|
|
begin
|
|
ControlCreateWnd();
|
|
//处理初始化active的问题
|
|
if factivated and factivecontrol and ContainsControl(factivecontrol) then factivecontrol.SetFocus();
|
|
end
|
|
end
|
|
function TrackPopupMenu(mu,x,y); //弹出菜单
|
|
begin
|
|
ftrackmenu := mu;
|
|
if not(ifnumber(x) and ifnumber(y) ) then return 0;
|
|
if not(ftrackmenu and (ftrackmenu is class(TcustomMenu))) then return 0;
|
|
if HandleAllocated() then
|
|
begin
|
|
xy := ClientToScreen(x,y);
|
|
uf := TPM_LEFTALIGN .| TPM_TOPALIGN .| TPM_RIGHTBUTTON;
|
|
_wapi.TrackPopupMenu(ftrackmenu.Handle,uf,xy[0],xy[1],0,self.Handle,nil);
|
|
end
|
|
end
|
|
function Notification(ac,op);override;
|
|
begin
|
|
if op=opRecycling then
|
|
begin
|
|
if ac = factivecontrol then factivecontrol := nil;
|
|
if ac = ftrackmenu then ftrackmenu := nil;
|
|
end
|
|
inherited;
|
|
end
|
|
protected
|
|
function drawdesigninggrid();
|
|
begin
|
|
if csDesigning in ComponentState then
|
|
begin
|
|
cv := canvas;
|
|
if not(cv.HandleAllocated()) then return ;
|
|
rc := getwndclientrect();
|
|
dx := 20;
|
|
dy := 20;
|
|
x := 0;
|
|
y := 0;
|
|
c := 0;
|
|
while y<rc[3] do
|
|
begin
|
|
y+=dx;
|
|
x := 0;
|
|
while x<rc[2] do
|
|
begin
|
|
x+=dx;
|
|
cv.SetPixel(array(x,y),c);
|
|
end
|
|
end
|
|
ctls := controls;
|
|
rcs := array();
|
|
sel := -1;
|
|
selr := 0;
|
|
len := ctls.count-1 ;
|
|
ct := 0;
|
|
for i:= 0 to len do
|
|
begin
|
|
vi := ctls[i];
|
|
if vi and (vi is class(TWinControl)) then
|
|
begin
|
|
if vi.WsPopUp then continue;
|
|
if not(vi.Visible) then continue;
|
|
rcs[i] := vi.BoundsRect;
|
|
if vi.DesigningSelect() then
|
|
begin
|
|
sel := i;
|
|
selr := rcs[i];
|
|
end
|
|
ct++;
|
|
end
|
|
end
|
|
if (sel >=0) and (ct>1) then
|
|
begin
|
|
pc := cv.pen.color;
|
|
pct := cv.pen.style;
|
|
pcw := cv.pen.width;
|
|
cv.pen.Style := PS_DOT;
|
|
cv.pen.color := 0x3f3f3f;
|
|
for i := 0 to len do
|
|
begin
|
|
if i=sel then continue;
|
|
rc := rcs[i];
|
|
if not rc then continue;
|
|
if rc[0] = selr[0] then
|
|
begin
|
|
cv.moveto(array(rc[0],min(rc[1],selr[1])));
|
|
cv.LineTo(array(rc[0],max(rc[1],selr[1])));
|
|
end
|
|
if rc[1]=selr[1] then
|
|
begin
|
|
cv.moveto(array(min(rc[0],selr[0]),rc[1]));
|
|
cv.LineTo(array(max(rc[0],selr[0]),rc[1]));
|
|
end
|
|
if rc[2] = selr[2] then
|
|
begin
|
|
cv.moveto(array(rc[2],min(rc[1],selr[1])));
|
|
cv.LineTo(array(rc[2],max(rc[1],selr[1])));
|
|
end
|
|
if rc[3] = selr[3] then
|
|
begin
|
|
cv.moveto(array(min(rc[0],selr[0]),rc[3]));
|
|
cv.LineTo(array(max(rc[0],selr[0]),rc[3]));
|
|
end
|
|
end
|
|
cv.pen.color := pc;
|
|
cv.pen.style := pct;
|
|
cv.pen.width := pcw;
|
|
end
|
|
end
|
|
end
|
|
function ControlCreateWnd();
|
|
begin
|
|
for i := 0 to FControls.count-1 do
|
|
begin
|
|
item := FControls[i];
|
|
if(item is class(TWinControl))then
|
|
begin
|
|
item.HandleNeeded();
|
|
end
|
|
end
|
|
end
|
|
public
|
|
function HandleAllocated(); //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)构建窗口句柄是否构造 %%
|
|
@param(bool)
|
|
**}
|
|
//return ifnumber(FHandle) and _wapi.IsWindow(FHandle);
|
|
return ifnumber(FHandle)and(FHandle <> 0);
|
|
end;
|
|
function DestroyHandle();virtual;
|
|
begin
|
|
{**
|
|
@explan(说明)析构窗口句柄 %%
|
|
**}
|
|
EndModal();
|
|
factivated := false;
|
|
if HandleAllocated()then
|
|
begin
|
|
{FTRACKMOUSEEVENT.hwndtrack := handle;
|
|
if OnMouseEnter or OnMouseLeave then
|
|
begin
|
|
FTRACKMOUSEEVENT.dwflags := TME_CANCEL .| TME_HOVER .| TME_LEAVE;
|
|
_wapi.TrackMouseEvent(FTRACKMOUSEEVENT._getptr_);
|
|
end }
|
|
bv := FVisible;
|
|
_wapi.DestroyWindow(self.Handle);
|
|
FVisible := bv;
|
|
end
|
|
FHandle := 0;
|
|
end
|
|
procedure HandleNeeded();virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)构建窗口句柄,以及子控件句柄 %%
|
|
@return(pointer) 窗口句柄
|
|
**}
|
|
{if (not HandleAllocated()) then
|
|
begin
|
|
if self.Parent = Self then
|
|
begin
|
|
|
|
end
|
|
else begin
|
|
if (Parent is class(TWinControl)) then
|
|
begin
|
|
Parent.HandleNeeded();
|
|
if HandleAllocated() then exit;
|
|
end;
|
|
end;
|
|
CreateHandle();
|
|
end; }
|
|
|
|
if(not HandleAllocated())and(not(csDestroying in ComponentState))then
|
|
begin
|
|
if self.Parent=Self then
|
|
begin
|
|
end else
|
|
begin
|
|
if {(Parent <> nil)}(Parent is class(TWinControl))then
|
|
begin
|
|
Parent.HandleNeeded();
|
|
if HandleAllocated()then exit;
|
|
end;
|
|
end;
|
|
CreateHandle();
|
|
end;
|
|
end
|
|
function SetParent(NewParent);override; //type_twinctrol
|
|
begin
|
|
ih := HandleAllocated();
|
|
if(NewParent=parent)and(NewParent is class(TWinControl))then //避免wrapcontrol句柄发生改变的问题
|
|
begin
|
|
if ih and NewParent.HandleAllocated()then
|
|
begin
|
|
if _wapi.GetParent(self.Handle)=NewParent.Handle then return;
|
|
end
|
|
end
|
|
if NewParent is class(TWinControl)then
|
|
begin
|
|
//if not CheckNewParent(NewParent) then return ;
|
|
//都有句柄
|
|
callparent := false;
|
|
callalocate := false;
|
|
ph := NewParent.HandleAllocated();
|
|
if ih and ph then
|
|
begin
|
|
if WsPopUp then
|
|
begin
|
|
DestroyHandle();
|
|
callalocate := true;
|
|
end else
|
|
if _wapi.SetParent(FHandle,NewParent.handle)then callparent := true;
|
|
end else
|
|
if ih and not(ph)then
|
|
begin
|
|
DestroyHandle();
|
|
callparent := true;
|
|
end else
|
|
if not(ih)and ph then
|
|
begin
|
|
callparent := true;
|
|
callalocate := true;
|
|
end else
|
|
begin
|
|
callparent := true;
|
|
end
|
|
if callparent then
|
|
begin
|
|
inherited SetParent(NewParent);//class(tcontrol).SetParent(NewParent);
|
|
if Align <> alNone then
|
|
begin
|
|
NewParent.DoControlAlign();
|
|
end
|
|
end
|
|
if callalocate then HandleNeeded();
|
|
end else
|
|
begin
|
|
if ih then DestroyHandle();
|
|
inherited SetParent(NewParent);
|
|
end
|
|
end
|
|
procedure SetBounds(ALeft,ATop,AWidth,AHeight:integer);override; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)设置窗口矩形区域 %%
|
|
**}
|
|
//设置bonds
|
|
OldBounds := BoundsRect;
|
|
OldBounds := array(OldBounds[0],OldBounds[1],OldBounds[2]-OldBounds[0],OldBounds[3]-OldBounds[1]);
|
|
newbounds := array(ALeft,ATop,AWidth,AHeight);
|
|
if not(CompareRect(OldBounds,newbounds))then
|
|
begin
|
|
inherited;
|
|
//class(tcontrol).SetBounds(ALeft, ATop, AWidth, AHeight);
|
|
end
|
|
end
|
|
private //绘制相关成员
|
|
FPaintRects;
|
|
FUpDateCount;
|
|
public
|
|
function gethitstyle(x,y);
|
|
begin
|
|
return FWMNCHITTEST.hitstyle2(self(true),x,y);
|
|
end
|
|
Procedure SetDesigning(Value,SetChildren);virtual; //设置设计状态
|
|
begin
|
|
inherited;
|
|
end;
|
|
public //消息分发
|
|
function MainWndProc(hwnd,message,wparam,lparam);virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)窗口主循环 %%
|
|
**}
|
|
//if message=0x85 and not( WsCaption or border or WsDlgModalFrame) then return ;
|
|
e := messagecreater(hwnd,message,wparam,lparam);
|
|
e.sender := self(true);
|
|
if message = WM_SYSKEYDOWN or message = WM_KEYDOWN then //快捷键实现
|
|
begin
|
|
WndProc(const e);
|
|
if e.skip then return 1;
|
|
////////////解析热键/////////////////////
|
|
ec := e.CharCode;
|
|
sa := array();
|
|
if ec>=65 and ec<=90 then
|
|
begin
|
|
sa["w"] := chr(ec);
|
|
end
|
|
if ec>=0x70 and ec<=0x7b then
|
|
begin
|
|
sa["f"] := "F"+inttostr(ec-0x6F);
|
|
end
|
|
st := e.shiftstate;
|
|
if ssCtrl in st then sa["c"] := 1;
|
|
if ssAlt in st then sa["a"] := 1;
|
|
if ssShift in st then sa["s"] := 1;
|
|
if sa["w"] and (sa["c"] or sa["a"] or sa["s"]) then
|
|
begin
|
|
st := sa;
|
|
end else
|
|
if sa["f"] then
|
|
begin
|
|
st := sa;
|
|
end else
|
|
st := array();
|
|
|
|
if st then
|
|
begin
|
|
st := formatshortcut(st);
|
|
if st then
|
|
begin
|
|
if dispatchctlshortcut(self(true),st)= "havedoshortcut" then return 1; //执行本控件
|
|
if dispatchshortcut(class(tUIglobalData).uigetdata("tuiapplication"),st) = "havedoshortcut" then
|
|
begin
|
|
return 1;
|
|
end
|
|
end
|
|
end
|
|
//热键处理完成
|
|
return defaulthandler(e);
|
|
end
|
|
if message=WM_NCCREATE then
|
|
begin
|
|
FHandle := hwnd;
|
|
//echo "\r\nsethandle:",hwnd;
|
|
class(tUIglobalData).uigetdata("TGlobalComponentcache").registerhandle(hwnd,self(true));
|
|
end else
|
|
if message=WM_SIZE then
|
|
begin
|
|
x := e.lolparamsigned();
|
|
if x <> 0 then
|
|
begin
|
|
//dxsize := x-FClientWdith;
|
|
cc := 0;
|
|
if FClientWdith <> x then
|
|
begin
|
|
FClientWdith := x;
|
|
cc := true;
|
|
end
|
|
y := e.hilparamsigned();
|
|
//dysize := y-FClientHeight;
|
|
if FClientHeight <> y then
|
|
begin
|
|
FClientHeight := y;
|
|
cc := true;
|
|
end
|
|
if true then
|
|
begin
|
|
DoControlAnchor();
|
|
DoControlAlign();
|
|
end
|
|
end
|
|
end else
|
|
{if message=WM_MOVE then
|
|
begin
|
|
x := e.lolparamsigned();
|
|
if FClientLeft <> x then FClientLeft := x;
|
|
y := e.hilparamsigned();
|
|
if FClientTop <> y then FClientTop := y;
|
|
end else}
|
|
//if message = WM_MOUSEMOVE then
|
|
if message=WM_NCHITTEST then //
|
|
begin
|
|
{if OnMouseEnter or OnMouseLeave then
|
|
begin
|
|
FTRACKMOUSEEVENT.hwndtrack := hwnd;
|
|
FTRACKMOUSEEVENT.dwflags := TME_HOVER .| TME_LEAVE;
|
|
FTRACKMOUSEEVENT.dwhovertime := 600;
|
|
_wapi.TrackMouseEvent(FTRACKMOUSEEVENT._getptr_);
|
|
end }
|
|
end else
|
|
if message=WM_STYLECHANGED then
|
|
begin
|
|
if e.wparam=GWL_EXSTYLE then
|
|
begin
|
|
__wexstyle := e.stylenew;
|
|
end else
|
|
begin
|
|
__wstyle := e.stylenew;
|
|
end
|
|
end
|
|
(**else
|
|
if message = WM_NCCALCSIZE then
|
|
begin
|
|
if e.wparam=1 then
|
|
begin
|
|
dt := new tNCCALCSIZE_PARAMS(e.lparam)._getvalue_("rgrc");
|
|
if dt[0]=-32000 then
|
|
begin
|
|
//echo "\r\n隐藏到工具栏";
|
|
end
|
|
else if dt[4] = -32000 then
|
|
begin
|
|
//echo "\r\n从工具栏弹出";
|
|
end
|
|
else
|
|
begin
|
|
//rect1 := dt[0:3];
|
|
//rect2 := dt[4:7];
|
|
//rect3 := dt[8:];
|
|
{dx := dt[2]-dt[0]-(dt[6]-dt[4]);
|
|
dy := dt[3]-dt[1]-(dt[7]-dt[5]);
|
|
__clientsize := array(dt[10]-dt[8]+dx,dt[11]-dt[9]+dy);
|
|
x := __clientsize[0];
|
|
dxsize := x-FClientWdith;
|
|
if FClientWdith<> x then FClientWdith := x;
|
|
y := __clientsize[1];
|
|
dysize := y-FClientHeight;
|
|
if FClientHeight <> y then FClientHeight := y;
|
|
DoControlAnchor(array(dxsize,dysize));
|
|
DoControlAlign(array(0,0,x,y));}
|
|
//__oldclientsize := array(dt[10]-dt[8],dt[11]-dt[9]);
|
|
end
|
|
|
|
end
|
|
else
|
|
begin
|
|
//echo "\r\n++++calc:",caption,tostn(new tcrect(e.lparam)._getdata_);
|
|
end
|
|
//echo "\r\ncalcsize:",o.caption,"****",e.wparam;
|
|
//echo "\r\nleft:", new tcrect(e.lparam).left;
|
|
end
|
|
**)
|
|
WndProc(const e);
|
|
if not(e.skip)then
|
|
begin
|
|
ret := defaulthandler(e);
|
|
end else
|
|
begin
|
|
{$ifdef linuxgtk}
|
|
if WM_NCHITTEST=e.msg then return e.Result;
|
|
return true;
|
|
{$endif}
|
|
ret := e.Result;
|
|
end
|
|
return ret;
|
|
end
|
|
function DesigningSizer();virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 设计模式下面是否可以调整大小 %%
|
|
@return(bool)
|
|
**}
|
|
return true;
|
|
end
|
|
function DesigningClick();virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 设计模式下面是否可以响应原有的点击消息 %%
|
|
@return(bool)
|
|
**}
|
|
return false;
|
|
end
|
|
function DesigningMove();virtual;
|
|
begin
|
|
{**
|
|
@explan(说明) 设计模式下面是否可以移动 %%
|
|
@return(bool)
|
|
**}
|
|
return true;
|
|
end
|
|
function HitWindowborder(o,e,hit);virtual;
|
|
begin
|
|
{if not(WsSizeBox)and DesigningSizer()and(Align=alNone)then
|
|
begin
|
|
e.Result := hit;
|
|
e.skip := true;
|
|
end}
|
|
al := Align;
|
|
if not(WsSizeBox)and DesigningSizer() and(al<>alClient)then
|
|
begin
|
|
if (al = alNone) or
|
|
(hit= HTTOP and al =alBottom) or
|
|
(hit= HTBOTTOM and al =alTop) or
|
|
(hit= HTRIGHT and al =alLeft) or
|
|
(hit= HTLEFT and al =alRight)
|
|
then
|
|
begin
|
|
e.Result := hit;
|
|
e.skip := true;
|
|
if (csDesigning in ComponentState) then
|
|
begin
|
|
if al <> alNone then _send_(WM_USER,1644,1644,1);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
private //设计器相关,消息
|
|
FClickTime;
|
|
FClickPos;
|
|
public //消息分发
|
|
procedure WndProc(e);override; //type_twinctrol
|
|
begin
|
|
//WM_NCHITTEST
|
|
if (csDesigning in ComponentState) then
|
|
begin
|
|
msg := e.msg;
|
|
if msg = WM_NCHITTEST then
|
|
begin
|
|
|
|
r := FWMNCHITTEST.hitstyle(self(true),e);
|
|
if r<>HTCLIENT then
|
|
begin
|
|
HitWindowborder(self(true),e,r);
|
|
end else
|
|
begin
|
|
return e.Result := Wnddefaulthandler(e);
|
|
end
|
|
end else
|
|
if msg= WM_LBUTTONDOWN then
|
|
begin
|
|
if not(WsCaption) and DesigningMove() and (Align=alNone) then
|
|
begin
|
|
_Send_(WM_NCLBUTTONDOWN,HTCAPTION,0,0);
|
|
e.skip := true;
|
|
end
|
|
CallMessgeFunction(OnDesignClick,self(true),e);
|
|
//保留原有的点击消息
|
|
{if DesigningClick() then
|
|
begin
|
|
CallMessgeFunction(FOnMouseUp,self(true),e);
|
|
end }
|
|
end else
|
|
if msg = WM_LBUTTONDBLCLK then
|
|
begin
|
|
CallMessgeFunction(OnDesignDBLClick,self(true),e);
|
|
end else
|
|
if msg = WM_RBUTTONDOWN then
|
|
begin
|
|
CallMessgeFunction(OnDesignRClick,self(true),e);
|
|
end else
|
|
if msg = WM_USER then
|
|
begin
|
|
if e.wparam=1644 and e.lparam=1644 then
|
|
begin
|
|
//Align=alNone;
|
|
al := Align;
|
|
|
|
if al in array(alLeft,alRight,alTop,alBottom) then
|
|
begin
|
|
bs := UnAlignBounds;
|
|
bs2 := BoundsRect;
|
|
if bs <> bs2 then
|
|
begin
|
|
Align := alNone;
|
|
Align := al;
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
end
|
|
inherited;
|
|
end;
|
|
function AdjustSize();override;
|
|
begin
|
|
if autosizing then
|
|
begin
|
|
return ;
|
|
end
|
|
if not HandleAllocated() then return ;
|
|
if IsUpDating() then
|
|
begin
|
|
return ;
|
|
end
|
|
cs := childsizing;
|
|
if cs and cs.layout>0 then return cs.AdjustSize();
|
|
if autosize then
|
|
begin
|
|
a := Align ;
|
|
if a<>alClient then
|
|
begin
|
|
GetPreferredSize(w,h);
|
|
if a=alNone then
|
|
begin
|
|
b := BoundsRect;
|
|
b[2] := b[0]+w;
|
|
b[3] := b[1]+h;
|
|
BoundsRect := b;
|
|
end else
|
|
if a=alLeft or a=alRight then
|
|
begin
|
|
width := w;
|
|
end else
|
|
if a=alTop or a=alBottom then
|
|
begin
|
|
height := h;
|
|
end
|
|
end
|
|
end
|
|
if WsPopUp then return ;
|
|
inherited;
|
|
end
|
|
function GetPreferredSize(w,h);override;
|
|
begin
|
|
brec := BoundsRect;
|
|
crec := ClientRect;
|
|
dw := (brec[2]-brec[0])-(crec[2]-crec[0]);
|
|
dh := (brec[3]-brec[1])-(crec[3]-crec[1]);
|
|
cts := Controls;
|
|
w := 0;
|
|
h := 0;
|
|
aw := 0;
|
|
ah := 0;
|
|
for i := 0 to ControlCount-1 do
|
|
begin
|
|
it := cts[i];
|
|
if not it then continue;
|
|
if not it.Visible then continue;
|
|
if (it is class(TWinControl)) and it.WsPopUp then continue;
|
|
ita := it.Align;
|
|
if ita=alNone then
|
|
begin
|
|
ibrc := it.BoundsRect;
|
|
w := max(ibrc[2],w);
|
|
h := max(ibrc[3],h);
|
|
end else
|
|
if (ita=alLeft or ita=alRight )then
|
|
begin
|
|
aw+=it.width;
|
|
end else
|
|
if( ita=alTop or ita = alBottom )then
|
|
begin
|
|
ah+=it.height;
|
|
end else
|
|
if(ita=alClient) then
|
|
begin
|
|
try
|
|
bs := it.UnAlignBounds;
|
|
except
|
|
end;
|
|
if bs then
|
|
begin
|
|
ah += bs[3]-bs[1];
|
|
aw +=(bs[2]-bs[0]);
|
|
end
|
|
|
|
end
|
|
end
|
|
w := max(w,aw);
|
|
h := max(h,ah);
|
|
w+=dw;
|
|
h+=dh;
|
|
end
|
|
procedure DoControlAlign({rect});override;
|
|
begin
|
|
{**
|
|
@explan(说明) 控件对齐 %%
|
|
**}
|
|
if not HandleAllocated()then exit;
|
|
cs := childsizing;
|
|
if cs and cs.layout>0 then return ;
|
|
if not ifarray(rect)then
|
|
begin
|
|
rect := ClientRect;
|
|
end
|
|
e := new TMALIGN(CN_ALIGN,0,0,0);
|
|
E.left := rect[0];
|
|
e.top := rect[1];
|
|
e.width := rect[2]-rect[0];
|
|
e.height := rect[3]-rect[1];
|
|
for i := 0 to ControlCount-1 do
|
|
begin
|
|
it := Controls[i];
|
|
if it and (it is class(tcontrol))then
|
|
begin
|
|
//if it.Align=alNone then continue;
|
|
it.Dispatch(it,e);
|
|
//it.Perform(e);
|
|
end
|
|
end
|
|
end
|
|
procedure DoControlAnchor();override;
|
|
begin
|
|
{**
|
|
@explan(说明) 控件锚定调整 %%
|
|
**}
|
|
if not HandleAllocated()then exit;
|
|
cs := childsizing;
|
|
if cs and cs.layout>0 then return ;
|
|
e := new TMANCHOR(CN_ANCHOR,0,0,0);
|
|
c := ClientRect;
|
|
for i := 0 to ControlCount-1 do
|
|
begin
|
|
it := Controls[i];
|
|
if not it then continue;
|
|
if it.Align <> alNone then continue;
|
|
if not ifarray(it.Anchors)then continue;
|
|
if it is class(TWinControl)then
|
|
begin
|
|
if it.WsPopUp then continue;
|
|
end
|
|
e.prec := c;
|
|
it.Dispatch(it,e);
|
|
end
|
|
end
|
|
function Wnddefaulthandler(e); //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明)win32默认消息处理函数 %%
|
|
@param(e)(tuieventbase)
|
|
**}
|
|
r := _wapi.CallWindowProcA(FDefaultProc,e.Hwnd,e.msg,e.wparam,e.lparam);
|
|
e.skip := true;
|
|
return r;
|
|
end
|
|
function defaulthandler(e);override;
|
|
begin
|
|
{**
|
|
@explan(说明) 执行默认句柄 %%
|
|
@param(e)(tuieventbase)
|
|
**}
|
|
r := _wapi.CallWindowProcA(FDefWndproc,e.Hwnd,e.msg,e.wparam,e.lparam);
|
|
e.skip := true;
|
|
return r;
|
|
end
|
|
procedure BroadCast(e);
|
|
begin
|
|
{**
|
|
@explan(说明) 广播消息 %%
|
|
@param(e)(tuieventbase)
|
|
**}
|
|
for I := 0 to ControlCount-1 do
|
|
begin
|
|
it := Controls[I];
|
|
if it then
|
|
begin
|
|
it.WindowProc(e);
|
|
if e.skip then Exit;
|
|
if not ifnil(e.Result)then Exit;
|
|
end
|
|
end;
|
|
end;
|
|
procedure NotifyControls(Msg); //type_twinctrol
|
|
begin
|
|
ToAllMessage := new tuieventbase(msg,0,0,0);
|
|
Broadcast(ToAllMessage);
|
|
end
|
|
function _send_(msg,wparam,lparam,f,d);virtual; //type_twinctrol
|
|
begin
|
|
{**
|
|
@explan(说明) 发送消息给窗口 %%
|
|
@param(msg)(integer)消息号 %%
|
|
@param(wparam)(integer)wparam %%
|
|
@param(lparam)(integer)lparam %%
|
|
@param(param)(bool) true 采用post false 采用send %%
|
|
@return(pointer)
|
|
|
|
**}
|
|
if not(ifnumber(msg)and ifnumber(wparam)and ifnumber(lparam))then
|
|
begin
|
|
//messagebox("参数必须为数字,如果字符串参数,请用tslcstructre构造然后传入指针!","提示",1);
|
|
exit;
|
|
end
|
|
if HandleAllocated()then
|
|
begin
|
|
if f then
|
|
begin
|
|
return _wapi.PostMessageA(FHandle,msg,wparam,lparam {$ifdef linux},d {$endif});
|
|
end else
|
|
begin
|
|
return _wapi.SendMessageA(FHandle,msg,wparam,lparam);
|
|
end
|
|
end else
|
|
begin
|
|
e := messagecreater(nil,msg,wparam,lparam);
|
|
Perform(e);
|
|
return e.result;
|
|
end
|
|
end
|
|
function setwndhandle(h);
|
|
begin
|
|
{**
|
|
@ignore 忽略 %%
|
|
**}
|
|
DestroyHandle();
|
|
if _wapi.IsWindow(h)then
|
|
begin
|
|
ph := _wapi.SetWindowLongPtrA(h,_wapi.GWLP_WNDPROC,_wapi.getvclwindowprocA());
|
|
FDefWndproc := ph;
|
|
MainWndProc(h,WM_NCCREATE,0,0);
|
|
end
|
|
end
|
|
published //对外property
|
|
///////////////////////////////////////////////
|
|
property MinWidth read FMinWidth write SetMinWidth; //:natural
|
|
property MinHeight read FMinHeigt write SetMinHeight; //:natural
|
|
//property MaxWidth:integer read FMaxWidth write SetMaxWidth;
|
|
//property MaxHeight:integer read FMaXHeight write SetMaxHeight;
|
|
property BorderStyle read GetBorderStyle write SetBorderStyle;
|
|
//property ParentWindow read FParentWindow write SetParentWindow;
|
|
property Handle read GetHandle write SetHandle;
|
|
property TabStop:bool read FTabStop write SetTabStop;
|
|
property ControlCount read GetControlCount;
|
|
property OnActivate:eventhandler read FOnActivate write FOnActivate;
|
|
property OnClose:eventhandler read FOnClose write FOnClose;
|
|
property OnKeyDown:eventhandler read FOnKeyDown write FOnKeyDown;
|
|
property OnsysKeyDown:eventhandler read FOnsysKeyDown write FOnsysKeyDown;
|
|
property OnKeyUp:eventhandler read FOnKeyUp write FOnKeyUp;
|
|
property OnsysKeyUp:eventhandler read FOnsysKeyUp write FOnsysKeyUp;
|
|
property OnKeyPress:eventhandler read FOnKeyPress write FOnKeyPress;
|
|
property OnSysKeyPress:eventhandler read FOnSysKeyPress write FOnSysKeyPress;
|
|
property OnDesignClick read FOnDesinedsel write FOnDesinedsel;
|
|
property OnDesignDBLClick read FOnDesigDBLClick write FOnDesigDBLClick;
|
|
property OnDesignRClick read FOnDesinedRclick write FOnDesinedRclick;
|
|
property WsPopUp:bool read GetWsPopUp write SetWsPopUp;
|
|
property WsDlgModalFrame:bool read FWsDlgModalFrame write SetWsDlgModalFrame;
|
|
property WsCaption:bool read GetWsCaption write SetWsCaption;
|
|
Property WSSizebox:bool read FWsSizeBox Write SetWSsizeBox;
|
|
property WSsysMenu:bool read FWsSysMenu write SetWsSysMenu;
|
|
property EndModalCode read FModalCode write FModalCode;
|
|
property ImageList:tcontrolimagelist read FImageList write SetImageList;
|
|
property onKillFocus:eventhandler read FonKillFocus write FonKillFocus;
|
|
property onSetFocus:eventhandler read FonSetFocus write fonSetFocus;
|
|
property oncreated:eventhandler read foncreated write foncreated;
|
|
property ActiveControl read getactivecontrol write setactivecontrol;
|
|
property Active read factivated;//是否获活动窗口
|
|
property childsizing:tchildsizing read fchildsizing write setchildsizing;
|
|
private //模态相关
|
|
property Modaling read FModaling;
|
|
{**
|
|
@param(BorderStyle)(bsNone|bsSingle) 边框样式 %%
|
|
@param(Handle)(pointer) 窗口句柄 %%
|
|
@param(WsDlgModalFrame)(bool) dlg边框效果 %%
|
|
@param(ControlCount)(integer) 子控件数量 %%
|
|
@param(OnClose)(function[TWincontrol,tuieventbase]) 窗口关闭消息回调 %%
|
|
@param(OnKeyDown)(function[TWincontrol,TMKEY]) 按键按下回调 %%
|
|
@param(OnKeyUp)(function[TWincontrol,TMKEY]) 按键松开 %%
|
|
@param(OnKeyPress)(function[TWincontrol,TMKEY]) 字符消息 %%
|
|
**}
|
|
private //ShortCut
|
|
function dispatchshortcut(c,st); //快捷键分发
|
|
begin
|
|
if not st then return 0;
|
|
if c then
|
|
begin
|
|
ctb := class(tUIglobalData).uigetdata("G_T_TOOLBAR_");
|
|
if (c is class(TcustomMenu)) or (c is ctb) or (c is class(TCustomAction)) then
|
|
begin
|
|
if c.ExecuteCommand("doshortcut",st)="havedoshortcut" then return "havedoshortcut";
|
|
end
|
|
cc := c.Components ;
|
|
for i:= 0 to cc.count-1 do
|
|
begin
|
|
if dispatchshortcut(cc[i],st) then return "havedoshortcut";
|
|
end
|
|
end
|
|
return 0;
|
|
end
|
|
function dispatchctlshortcut(o,st); //控件分发热键
|
|
begin
|
|
if o is class(tcontrol) then
|
|
begin
|
|
if dispatchmenushortcut(o.Action,st) then return "havedoshortcut";
|
|
if dispatchmenushortcut(o.PopupMenu,st) then return "havedoshortcut";
|
|
end
|
|
w := class(tUIglobalData).uigetdata("G_T_TVCFORM_");//主窗口
|
|
if w and (o is w ) then
|
|
begin
|
|
if dispatchmenushortcut(o.MainMenu,st) then return "havedoshortcut";
|
|
end
|
|
w := class(tUIglobalData).uigetdata("G_T_TOOLBAR_");//工具条
|
|
if w and (o is w ) then
|
|
begin
|
|
if dispatchmenushortcut(o.MainMenu,st) then return "havedoshortcut";
|
|
end
|
|
end
|
|
function dispatchmenushortcut(mu,st); //菜单分发热键
|
|
begin
|
|
if mu is class(TcustomMenu) then
|
|
begin
|
|
if mu.ItemCount>0 then
|
|
begin
|
|
for i := 0 to mu.ItemCount-1 do
|
|
begin
|
|
if dispatchmenushortcut(mu.GetItemByIndex(i),st)="havedoshortcut" then return "havedoshortcut";
|
|
end
|
|
end else
|
|
begin
|
|
if mu.ExecuteCommand("doshortcut",st)="havedoshortcut" then return "havedoshortcut";
|
|
end
|
|
//if mu.ItemCount
|
|
end else
|
|
if mu is class(TCustomAction) then
|
|
begin
|
|
if mu.ExecuteCommand("doshortcut",st)="havedoshortcut" then return "havedoshortcut";
|
|
end
|
|
end
|
|
function setactivecontrol(ctl);virtual;
|
|
begin
|
|
if WsPopUp then
|
|
begin
|
|
if factivecontrol = ctl then return ;
|
|
if ctl is class(TWinControl) then
|
|
begin
|
|
factivecontrol := ctl;
|
|
if factivated then
|
|
begin
|
|
ctl.SetFocus();
|
|
end
|
|
end else
|
|
begin
|
|
factivecontrol := nil;
|
|
end
|
|
end else
|
|
begin
|
|
p := parent ;
|
|
if p then return p.ActiveControl := ctl;
|
|
end
|
|
end
|
|
function getactivecontrol();
|
|
begin
|
|
if WsPopUp then return factivecontrol;
|
|
factivecontrol := nil;
|
|
end
|
|
|
|
|
|
end |