www.pudn.com > VCLSkin.4.81.rar > WinSkinDlg.pas
unit WinSkinDlg;
{$I Compilers.Inc}
{$WARNINGS OFF}
{$HINTS OFF}
{$RANGECHECKS OFF}
interface
uses windows,Messages,SysUtils,Classes,Graphics,WinSkinMenu,
forms,ExtCtrls;
const
skin_Creating=0;
skin_Active=1;
skin_uninstall=2;
skin_change=3;
skin_Destory=4;
skin_Updating=5;
skin_Deleted=6;
skin_update=7;
m_popup=0;
m_systemmenu=2;
m_menuitem=1;
Type
TSkinThread = class(TObject)
public
hook:HHook;
ThreadID:integer;
end;
TSBAPI1=function(ahwnd:hwnd): HResult; stdcall;
TSBAPI2= function() :HResult; stdcall;
TSkinManage = class(Tobject)
protected
Timer : TTimer;
SBLib :Thandle;
pinitApp,pUninitApp:TSBAPI2;
pinitSB,pUninitSb:TSBAPI1;
HookCallback,WndCallBack,WndCallRet : HHOOK;
//function FindSkinForm(aHwnd:THandle):boolean;
function FindSkinForm(aHwnd:THandle):dword;
procedure DeleteAllForms;
function AddMenu(aHwnd:THandle):boolean;
function FindSkinMenu(aHwnd:THandle):boolean;
function DeleteMenu(aHwnd:THandle):boolean;
procedure DeleteAllMenus;
function FindTForm(ahwnd:Thandle):Tform;
procedure OnTimer(Sender: TObject);
function NestedForm(ahwnd:Thandle):boolean;
procedure FindSkindata(var adata:pointer;ahwnd:Thandle);
function OnBeforeSkin(ahwnd:Thandle;aname:string):boolean;
procedure DeleteAllThreads;
procedure ActiveForm(aform:Tform);
procedure DeleteDeleted;
function IsDllForm(ahwnd:Thandle):boolean;
procedure DeleteAllSub;
procedure DeleteSubForm(amode:integer);
// function AddForm(aHwnd:THandle):boolean;
procedure WndProc(var Msg: TMessage);
public
Flist:Tlist;
Mlist:Tlist;
Dlist:Tlist;
Threadlist:Tlist;
sublist:Tlist;
active:boolean;
skinchildform:boolean;
state:integer;
menutype:integer;
menuactive:boolean;
MDIMax:boolean;
WMSetDraw:boolean;
clienthwnd:Thandle;
MDIForm : Tform;
action:integer;
UpdateData:pointer;
SBinstall :boolean;
MainData: pointer;
mode:integer;
handle : HWND;
lpara : integer;
mmgr:TSkinmanage;
constructor Create(amode:integer=0);
destructor Destroy; override;
procedure InstallHook;
function AddForm(aHwnd:THandle):boolean;
// function AddMDIForm(atform:Tform):boolean;
function DeleteForm(aHwnd:THandle):boolean;
function GetMenuBg(amenu:Hmenu):Tbitmap;
procedure UpdateSkinMenu(amenu:Hmenu);
procedure FindPopupMenu(amenu:Hmenu);
procedure SetMDIMax(b:boolean);
procedure SetMDIMax2(b:boolean);
procedure SetCaption(b:boolean);
function GetMDIChildNum:integer;
procedure SetAction(acode:integer;Interval:integer=250);
procedure AddSkinData(adata: Pointer);
procedure RemoveSkinData(adata: Pointer);
procedure DeleteSysbtn;
procedure InstallThread(aThreadID:integer);
procedure UnInstallThread(aThreadID:integer);
function initsb(ahwnd:Thandle):boolean;
function Uninitsb(ahwnd:Thandle):boolean;
procedure SetPopMenu;
procedure DeleteForm2(aHwnd:THandle);
procedure DeleteForm3;
procedure AssignData(adata: Pointer);
procedure SetHMenu(hmenu:Thandle);
procedure DeleteSub(p:Pointer);
end;
//var HookCallback,WndCallBack,WndCallRet : HHOOK;
var SkinManager:TSkinManage;
RM_GetObjectInstance: DWORD;
ControlAtom: TAtom;
PropName:string;
myinstance:dword;
function SkinHookCallback(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
function SkinHookCallRet(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;stdcall;
function SkinHookCBT(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
function SkinHookCBT2(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
implementation
uses winskinform ,WinSkinData,menus,winsubclass;
function SkinHookCallRet(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
var pwp:PCWPRETSTRUCT;
s:string;
begin
if code= HC_ACTION then begin
pwp:=PCWPRETSTRUCT (lparam);
case pwp.message of
WM_DRAWITEM: begin
// SkinManager.WMDRAWITEM(PDrawItemStruct(pwp.lparam));
end;
end;
end;
result:=CallNextHookEx( SkinManager.WndCallRet, Code, wParam, lParam );
end;
function SkinHookCallback(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
var pwp:PCWPSTRUCT;
s:string;
msg:Tmessage;
begin
if code= HC_ACTION then begin
pwp:=PCWPSTRUCT(lparam);
{ if skincanlog then begin
msg.msg:=pwp.message;
msg.wparam:=pwp.wparam;
msg.lparam:=pwp.lparam;
skinaddlog('Hook:'+msgtostr(msg));
end; }
case pwp.message of
WM_CREATE:SkinManager.AddMenu(pwp.hwnd);
WM_DESTROY,WM_NCDESTROY:SkinManager.DeleteMenu(pwp.hwnd);
WM_INITMENU: begin
// skinaddlog('WH_CALLWNDPROC : WM_INITMENU');
skinmanager.FindPopupMenu(pwp^.wparam);
end;
{ WM_DRAWITEM: begin
skinaddlog('WH_CALLWNDPROC : WM_DRAWITEM');
end;}
end;
end;
result:=CallNextHookEx( SkinManager.WndCallback, Code, wParam, lParam );
end;
function SkinHookCBT(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
var s:string;
hwnd:Thandle;
ptr:^CBT_CREATEWND;
sf: dword;
sd:Tskindata;
begin
//message box WM_ACTIVATE TMessageForm
//Dlg ****WM_ACTIVATE #32770 WA_ACTIVE
if (code>=0) {and skinmanager.active} then begin
case code of
HCBT_ACTIVATE :begin
if skinmanager.state=skin_creating then
inc(skinmanager.state);
hwnd := Thandle(wParam);
if SkinManager.addform(hwnd) then begin
end;
end;
HCBT_DESTROYWND : begin
hwnd := Thandle(wParam);
SkinManager.DeleteMenu(hwnd);
//if SkinManager.deleteform(hwnd) then begin
//end;
end;
HCBT_CREATEWND : begin
hwnd := Thandle(wParam);
ptr:=pointer(lparam);
s:= getwindowclassname(hwnd);
// skinAddlog(format('***HCBT_CREATEWND %s %1x,%1x',[s,hwnd,ptr^.lpcs^.hwndParent]));
if (s='ScrollBar') and ((ptr^.lpcs^.style and sbs_sizegrip)>0) then begin
s:= getwindowclassname(ptr^.lpcs^.hwndParent);
sf:= SkinManager.findskinform(ptr^.lpcs^.hwndParent);
if (sf>0) then begin // and (s='#32770')
Twinskinform(sf).addcontrolh(hwnd);
// skinAddlog(format('*****Scrollbar %s %1x,%1x',[s,hwnd,ptr^.lpcs^.hwndParent]));
// result:=10;
// exit;
end;
end ;
if (ptr^.lpcs^.style and ws_child)=0 then begin
//skinAddlog(format('***Form Creater %s %1x (%1d,%1d)',[s,hwnd,ptr^.lpcs^.cx,ptr^.lpcs^.cy]));
s:= getwindowclassname(hwnd);
if (s='#32768') and (skinmanager.mmgr=nil) then
SkinManager.AddMenu(hwnd) ;
// sd:=SkinManager.maindata;
// sd.DoDebug(s);
{ if (sd<>nil) and assigned(sd.OnNewform) then
try
sd.OnNewform(sd,hwnd,s);
except
end; }
end;
if (ptr^.lpcs^.dwExStyle and ws_ex_mdichild)>0 then begin
SkinManager.addform(hwnd);
end;
end;
{ HCBT_MINMAX : begin
hwnd := Thandle(wParam);
if lparam = SW_MAXIMIZE then
skinAddlog(format('***Form MAXIMIZE %1x ',[hwnd]));
end;}
end;//endcase
end else begin
if (code=HCBT_ACTIVATE) and (skinmanager.state=skin_creating) then
inc(skinmanager.state);
end;
result:=CallNextHookEx( SkinManager.HookCallback, Code, wParam, lParam );
end;
function SkinHookCBT2(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
var s:string;
hwnd:Thandle;
ptr:^CBT_CREATEWND;
begin
//message box WM_ACTIVATE TMessageForm
//Dlg ****WM_ACTIVATE #32770 WA_ACTIVE
if code>=0 then begin
case code of
HCBT_ACTIVATE :begin
if skinmanager.state=skin_creating then
inc(skinmanager.state);
hwnd := Thandle(wParam);
if SkinManager.addform(hwnd) then begin
// s:='****HCBT_ACTIVATE '+s;
// skinAddlog(s);
end;
end;
HCBT_DESTROYWND : begin
hwnd := Thandle(wParam);
SkinManager.DeleteMenu(hwnd);
if SkinManager.deleteform(hwnd) then begin
end;
end;
HCBT_CREATEWND : begin
hwnd := Thandle(wParam);
ptr:=pointer(lparam);
s:= getwindowclassname(hwnd);
// skinAddlog(format('***HCBT_CREATEWND %s %1x,%1x',[s,hwnd,ptr^.lpcs^.hwndParent]));
if (s='ScrollBar') and (SkinManager.findskinform(ptr^.lpcs^.hwndParent)>0) then begin
// skinAddlog(format('***Scrollbar %s %1x,%1x',[s,hwnd,ptr^.lpcs^.hwndParent]));
result:=10;
exit;
end ;
if s='#32768' then
SkinManager.AddMenu(hwnd); //don't create scrollbar
end;
end;//endcase
end;
result:=CallNextHookEx( SkinManager.HookCallback, Code, wParam, lParam );
end;
constructor TSkinManage.Create(amode:integer=0);
begin
inherited create();
if amode=0 then begin
flist:=Tlist.create;
Mlist:=Tlist.create;
dlist:=Tlist.create;
threadlist:=Tlist.create;
sublist:=Tlist.create;
mode:=0;
end else
mode := HInstance;
active:=false;
menuactive:=false;
MDIMax:=false;
menutype:=0;
mmgr:=nil;
Timer := TTimer.create(nil);
timer.Interval:=100;
timer.Ontimer:=Ontimer;
timer.enabled:=false;
SBinstall :=false;
skinchildform:=false;
wmsetdraw:=false;//true;
maindata:=nil;
state:=skin_creating;
// Handle := Classes.AllocateHWnd(WndProc);
SBLib:=0;
// SBLib := LoadLibrary('C:\MyFile\MySkin\ARTICLE\coolsb_src\coolsb2\Release\coolsb2.dll');
// SBLib := LoadLibrary('coolsb2.dll');
pinitapp:=nil;
sbinstall:=false;
if SBLib<>0 then begin
pinitApp:=GetProcAddress(SBLib,'CoolSB_InitializeApp');
pUninitApp:= GetProcAddress(SBLib,'CoolSB_UninitializeApp');
pinitSB:=GetProcAddress(SBLib,'InitializeCoolSB');
pUninitSb:=GetProcAddress(SBLib,'UninitializeCoolSB');
end;
if @pinitapp<>nil then
SBinstall := boolean(pinitapp);
// installhook;
end;
destructor TSkinManage.Destroy;
begin
state:=skin_destory;
active:=false;
Timer.free;
if @pUninitapp<>nil then pUninitapp;
if (sblib<>0) then
FreeLibrary(sblib);
if mode=0 then begin
DeleteAllThreads;
if (sublist.Count>0) or (flist.Count>0) then
deleteallforms;
if flist<>nil then flist.free;
deleteallmenus;
dlist.free;
deleteallsub;
end else if HookCallback<>0 then begin
if assigned(mmgr) then begin
mmgr.DeleteSub(self);
mmgr.DeleteSubForm(mode);
end;
//AssignData(nil);
end;
// Classes.DeallocateHWnd(Handle);
if HookCallback<>0 then
UnhookWindowsHookEx( HookCallback );
inherited destroy;
end;
procedure TSkinManage.InstallHook;
var dwThreadID:DWORD;
begin
winversion:=GetVersion();
// skinaddlog(format('Windows Version %1x',[winversion]));
// skinaddlog(format('Windows Version %1d %1d',[Win32MajorVersion,Win32MinorVersion]));
// skinaddlog(format('winversion %1x',[winversion]));
dwThreadID := GetCurrentThreadId;
// WndCallback :=SetWindowsHookEx( WH_CALLWNDPROC,SkinHookCallback,0,dwThreadID);
// WndCallRet :=SetWindowsHookEx( WH_CALLWNDPROCRET,SkinHookCallRet,0,dwThreadID);
HookCallback :=SetWindowsHookEx( WH_CBT,SkinHookCBT,0,dwThreadID);
// skinaddlog(format('ThreadId %1x',[dwThreadId]));
// skinaddlog(format('HookCallback %1x',[HookCallback]));
end;
procedure TSkinManage.InstallThread(aThreadID:integer);
var obj:TSkinThread;
b: boolean;
i:integer;
begin
b:=false;
for i:= 0 to threadlist.count-1 do begin
obj:= TSkinThread(threadlist[i]);
if obj.threadID=aThreadID then begin
b:=true;
break;
end;
end;
if b then exit;
obj:=TSkinThread.create;
obj.threadID:=aThreadID;
obj.hook :=SetWindowsHookEx( WH_CBT,SkinHookCBT2,0,aThreadID);
threadlist.add(obj);
end;
procedure TSkinManage.UnInstallThread(aThreadID:integer);
var obj:TSkinThread;
i:integer;
begin
for i:= 0 to threadlist.count-1 do begin
obj:= TSkinThread(threadlist[i]);
if obj.threadID=aThreadID then begin
UnhookWindowsHookEx( obj.hook);
threadlist.delete(i);
break;
end;
end;
end;
procedure TSkinManage.DeleteAllThreads;
var obj:TSkinThread;
i:integer;
begin
for i:= 0 to threadlist.count-1 do begin
obj:= TSkinThread(threadlist[i]);
UnhookWindowsHookEx( obj.Hook );
obj.free;
end;
threadlist.clear;
threadlist.free;
end;
function Tskinmanage.nestedform(ahwnd:Thandle):boolean;
var style:longword;
s:string;
phwnd:Thandle;
begin
result:=false;
Style := GetWindowLong( ahwnd, GWL_STYLE );
if (style and ws_child)=0 then exit;
Style := GetWindowLong( ahwnd, GWL_EXSTYLE );
if (style and ws_ex_mdichild)>0 then exit;
phwnd:=getparent(ahwnd);
s:=lowercase(getwindowclassname(phwnd));
if s='mdiclient' then exit;
result:=true;
end;
procedure Tskinmanage.FindSkindata(var adata:pointer;ahwnd:Thandle);
var s:string;
function FindOnlyThisForm:boolean;
var i:integer;
sd:Tskindata;
sf:Tform;
begin
result:=false;
for i:= 0 to dlist.count-1 do begin
sd:=Tskindata(dlist.items[i]);
sf:=Tform(sd.owner);
if (sd.skinformtype=sfOnlyThisForm) and (sf.handle=ahwnd) then begin
adata:=sd;
result:=true;
end;
end;
end;
function FindData(atype:TSkinFormType):boolean;
var i:integer;
sd:Tskindata;
begin
result:=false;
for i:= 0 to dlist.count-1 do begin
sd:=Tskindata(dlist.items[i]);
if (sd.skinformtype=atype) then begin
adata:=sd;
result:=true;
end;
end;
end;
begin
if FindOnlyThisForm then exit;
s:=lowercase(getwindowclassname(ahwnd));
if ((s='tmessageform') or (s='#32770')) and finddata(sfDialog) then exit;
if finddata(sfMainform) then exit;
if dlist.count>0 then adata:=dlist.items[0]
else adata:=nil;
end;
function TSkinManage.OnBeforeSkin(ahwnd:Thandle;aname:string):boolean;
var b:boolean;
i:integer;
sd:Tskindata;
s:string;
dwstyle:Dword;
begin
b:=true;
if maindata<>nil then begin
if not (xoPreview in TSkindata(maindata).Options) then begin
s:= lowercase(aname);
if (pos('preview',s)>0) then b:=false;
end;
dwstyle := GetWindowLong( ahwnd, GWL_STYLE );
//file download dialog
if (aname='#32770') and ((dwstyle and DS_SETFOREGROUND)>0) then b:=false;
TSkindata(maindata).DoFormSkin(ahwnd,aname,b);
end;
{ for i:= 0 to dlist.count-1 do begin
sd:=Tskindata(dlist.items[i]);
if (sd.skinformtype=sfMainform) then begin
sd.DoFormSkin(aname,b);
break;
end;
end;}
result:=b;
end;
procedure TSkinManage.ActiveForm(aform:Tform);
var dwstyle:dword;
b:boolean;
begin
dwstyle := GetWindowLong( aform.handle, GWL_STYLE );
b:= (dwstyle and ws_child)>0; //child
//if aform.formstyle=fsmdichild then b:=false;//mdichild
if not aform.Visible then b:=true;
if not b then addform(aform.handle);
end;
function TSkinManage.AddForm(aHwnd:THandle):boolean;
var aform:TWinskinform;
atform:TForm;
r:Trect;
s:string;
aptr:pointer;
adata:Tskindata;
isskin:integer;
dw:dword;
b:boolean;
begin
result:=false;
if not active then exit;
DeleteDeleted;
isskin:=sendmessage(ahwnd,CN_IsSkined,0,0);
// {$IFDEF demo}
// atform:=findtform(ahwnd);
// if atform<>nil then
// setproperty(atform,'Caption',' ');
// {$endif}
if isskin=1 then exit;
if findskinform(ahwnd)<>0 then exit;
atform:=findtform(ahwnd);
if (not skinchildform) and nestedform(ahwnd) then exit;
// b:= (s='#32770') {or (s='TMessageForm')};
s:=getwindowclassname(ahwnd);
dw:=GetWindowLong(ahwnd,GWL_HINSTANCE);
if (atform=nil) and (dw<>myinstance) and (s<>'#32770') then exit;
// if (not b) and (atform=nil) and (not isdllform(ahwnd)) then exit;
// if not isdllform(ahwnd) then exit;
// TSkindata(maindata).DoDebug(s);
getwindowrect(ahwnd,r);
offsetrect(r,-r.left,-r.top);
dw:=GetWindowLong(ahwnd, GWL_EXSTYLE);
if (r.right*r.bottom=0) and ((dw and ws_ex_mdichild)=0) then exit;
if (atform<>nil) and (atform.tag=99) then exit;
if pos('TcxPopupEditPopupWindow',s)>0 then exit;
if pos('TTERenderWindow',s)>0 then exit;
if s='TApplication' then exit;
// if s='TQRStandardPreview' then exit; //quickreport preview form
if not OnBeforeSkin(ahwnd,s) then exit;
FindSkindata(aptr,ahwnd);
if aptr=nil then exit;
adata:=Tskindata(aptr);
if adata.empty then exit;
if atform<>nil then begin
aform:=Twinskinform.create(atform);
aform.hwnd:=ahwnd;
aform.mode:=mode;
aform.formclass:=s;
aform.InitTform(adata,atform);
end else begin
aform:=Twinskinform.create(nil);
aform.hwnd:=ahwnd;
aform.mode:=mode;
aform.formclass:=s;
aform.initDlg(adata);
end;
flist.add(aform);
// LockWindowUpdate(ahwnd);
postMessage(ahwnd, CN_NewForm, 0, 1000);
result:=true;
end;
{function TSkinManage.AddMDIForm(atform:Tform):boolean;
var aform:TWinskinform;
r:Trect;
s:string;
aptr:pointer;
adata:Tskindata;
isskin:integer;
ahwnd:Thandle;
begin
result:=false;
if not active then exit;
DeleteDeleted;
ahwnd:=atform.handle;
isskin:=sendmessage(ahwnd,CN_IsSkined,0,0);
if isskin=1 then exit;
if not OnBeforeSkin(s) then exit;
FindSkindata(aptr,ahwnd);
if aptr=nil then exit;
adata:=Tskindata(aptr);
if adata.empty then exit;
if atform<>nil then begin
aform:=Twinskinform.create(atform);
aform.hwnd:=ahwnd;
aform.InitTform(adata,atform);
flist.add(aform);
postMessage(ahwnd, CN_NewForm, 0, 1000);
result:=true;
end;
end; }
function TSkinManage.DeleteForm(aHwnd:THandle):boolean;
var i: integer;
sf :TWinSkinform;
begin
if (state=skin_destory) then exit;
result:=false;
for i:=0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.hwnd=ahwnd then begin
if sf.FForm = nil then exit;
sf.Skinstate:=skin_Destory;
sf.unsubclass;
flist.delete(i);
sf.free;
sf:=nil;
result:=true;
break;
end;
end;
end;
procedure TSkinManage.DeleteForm2(aHwnd:THandle);
var i: integer;
sf :TWinSkinform;
begin
if (state=skin_destory) then exit;
for i:=0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.hwnd=ahwnd then begin
flist.delete(i);
break;
end;
end;
end;
procedure TSkinManage.DeleteDeleted;
var i: integer;
sf :TWinSkinform;
begin
if (state=skin_destory) then exit;
for i:=flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
if IsBadReadPtr(sf, InstanceSize) then begin
flist.delete(i);
end else if (sf.skinstate=skin_Deleted) and (sf.mode=mode) then begin
//sf.UnSubclass3;
flist.delete(i);
sf.free;
end;
end;
end;
procedure TSkinManage.DeleteAllForms;
var i: integer;
sf :TWinSkinform;
begin
active:=false;
// DeleteDeleted;
for i:=flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
if IsBadReadPtr(sf, InstanceSize) then continue;
//?? remove dialog
if sf.mode<>mode then continue;
//sf.Skinstate:=skin_Destory;
flist.delete(i);
sf.unsubclass3;
sf.free;
end;
end;
procedure TSkinManage.DeleteSubForm(amode:integer);
var i: integer;
sf :TWinSkinform;
begin
for i:=flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
if IsBadReadPtr(sf, InstanceSize) then continue;
if sf.mode<>amode then continue;
//sf.Skinstate:=skin_Destory;
flist.delete(i);
sf.FForm.Free;
//sf.unsubclass3;
//sf.free;
end;
end;
procedure TSkinManage.DeleteForm3;
var i: integer;
sf :TWinSkinform;
begin
if (state=skin_destory) then exit;
for i:=flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
if sf.skinstate=skin_deleted then begin
flist.delete(i);
sf.free;
end;
end;
end;
procedure TSkinManage.AddSkinData(adata: Pointer);
begin
dlist.add(adata);
if (maindata=nil) and (TSkindata(adata).skinformtype=sfmainform) then
maindata:=adata;
end;
procedure TSkinManage.RemoveSkinData(adata: Pointer);
var i:integer;
begin
i:= dlist.indexof(adata);
if i<>-1 then begin
dlist[i]:=nil;
dlist.delete(i);
end;
end;
procedure TSkinManage.AssignData(adata: Pointer);
var d:TSkinmanage;
begin
if adata<>nil then begin
d:=TskinManage(adata);
flist:=d.Flist;
Mlist:=d.Mlist;
dlist:=d.Dlist;
threadlist:=d.Threadlist;
maindata:=d.MainData;
mmgr:=d;
state:=1;
active:=d.active;
//active:=false;
d.sublist.Add(self);
end else begin
flist:=nil;
Mlist:=nil;
dlist:=nil;
threadlist:=nil;
maindata:=nil;
active:=false;
state:=skin_destory;
if HookCallback<>0 then
UnhookWindowsHookEx( HookCallback );
HookCallback:=0;
end;
end;
procedure TSkinManage.DeleteAllMenus;
var i: integer;
sm :TWinSkinPopMenu;
begin
for i:=0 to mlist.count-1 do begin
sm:=TWinSkinPopMenu(mlist[i]);
sm.free;
end;
mlist.clear;
mlist.free;
mlist:=nil;
end;
procedure TSkinManage.DeleteAllSub;
var i: integer;
sm :TSkinmanage;
begin
for i:=0 to sublist.count-1 do begin
sm:=TSkinManage(sublist[i]);
if not IsBadReadPtr(TSkinManage(sublist[i]), InstanceSize) then
sm.Assigndata(nil);
// sm.Assigndata(nil);
//sm.Free;
end;
sublist.clear;
sublist.free;
sublist:=nil;
end;
procedure TSkinManage.DeleteSub(p:Pointer);
var i: integer;
begin
for i:=0 to sublist.count-1 do begin
if sublist[i]=p then begin
sublist.delete(i);
break;
end;
end;
end;
procedure TSkinManage.SetPopMenu;
var i: integer;
sm :TWinSkinPopMenu;
begin
// i:= mlist.count;
// if i=0 then exit;
for i:=0 to mlist.count-1 do begin
sm:=TWinSkinPopMenu(mlist[i]);
sm.ownerdraw:=true;
end;
end;
procedure TSkinManage.SetHMenu(hmenu:Thandle);
var i: integer;
sm :TWinSkinPopMenu;
begin
// i:= mlist.count;
// if i=0 then exit;
for i:= mlist.count-1 downto 0 do begin
sm:=TWinSkinPopMenu(mlist[i]);
if sm.hmenu=0 then begin
sm.hmenu:=hmenu;
break;
end;
end;
end;
function TSkinManage.FindSkinForm(aHwnd:THandle):dword;
var i: integer;
sf :TWinSkinform;
begin
result:=0;
for i:=0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.hwnd=ahwnd then begin
result:=dword(sf);
break;
end;
end;
end;
function TSkinManage.AddMenu(aHwnd:THandle):boolean;
var amenu:TWinSkinPopMenu;
s:string;
adata:Tskindata;
aptr:pointer;
isskin:integer;
begin
result:=false;
if not active then exit;
isskin:=sendmessage(ahwnd,CN_IsSkined,0,0);
if isskin=1 then exit;
if findskinMenu(ahwnd) then exit;
FindSkindata(aptr,ahwnd);
if aptr=nil then exit;
adata:=Tskindata(aptr);
// if (adata.empty) or (not(xcMainmenu in adata.SkinControls)) then exit;
if (adata.empty) then exit;
case menutype of
m_popup : if (not(xcPopupmenu in adata.SkinControls)) then exit;
m_menuitem : if (not(xcMainmenu in adata.SkinControls)
and not(xcMenuitem in adata.SkinControls)) then exit;
m_systemmenu: if (not(xcSystemmenu in adata.SkinControls)) then exit;
end;
amenu:=TWinSkinPopMenu.create;
amenu.InitSkin(ahwnd,adata,0);
Mlist.add(amenu);
if menuactive then amenu.ownerdraw:=true;
end;
function TSkinManage.DeleteMenu(aHwnd:THandle):boolean;
var i: integer;
sm :TWinSkinPopMenu;
begin
result:=false;
// if mlist=nil then exit;
if IsBadReadPtr(mlist, InstanceSize) then exit;
for i:=0 to mlist.count-1 do begin
sm:=TWinSkinPopMenu(mlist[i]);
if sm.hwnd=ahwnd then begin
sm.unsubclass;
mlist.delete(i);
sm.free;
result:=true;
break;
end;
end;
if mlist.count=0 then begin
menuactive:=false;
menutype:=0;
end;
end;
function TSkinManage.FindSkinMenu(aHwnd:THandle):boolean;
var i: integer;
sm :TWinSkinPopMenu;
begin
result:=false;
for i:=0 to mlist.count-1 do begin
sm:=TWinSkinPopMenu(mlist[i]);
if sm.hwnd=ahwnd then begin
result:=true;
break;
end;
end;
end;
procedure TSkinManage.UpdateSkinMenu(amenu:Hmenu);
var i: integer;
mh:Thandle;
begin
{ mh:=FindWindowex(0,0,'#32768',nil);
if (mh<>0) and (mh<>smenu.hwnd) then begin
smenu.InitSkin(mh,GSkinData,amenu);
end;}
end;
function TSkinManage.GetMenuBg(amenu:Hmenu):Tbitmap;
var i: integer;
begin
result:=nil;
for I:= 0 to mlist.count-1 do
if TWinSkinPopMenu(mlist[i]).hmenu=amenu then begin
result:=TWinSkinPopMenu(mlist[i]).menubg;
break;
end;
end;
procedure TSkinManage.FindPopupMenu(amenu:Hmenu);
var i: integer;
begin
for I:= 0 to PopupList.count-1 do
if TPopupMenu(PopupList[i]).handle=amenu then begin
menuactive:=true;
break;
end;
end;
procedure TSkinManage.SetMDIMax(b:boolean);
var i: integer;
sf:Twinskinform;
sd:TSkinData;
begin
if mdimax=b then exit;
mdimax:=b;
sd:=SkinManager.maindata;
if (xoMDIChildBorder in sd.Options) then exit;
for I:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.formstyle=sfsmdichild then begin
if b then begin
if sf.crop then sf.Uncropwindow;
sf.EnableSysbtn(b);
end else begin
if sf.windowstate<>swsmin then begin
sf.windowstate:=swsnormal;
sf.cropwindow;
sf.EnableSysbtn(b);
if not sf.crop then sf.refresh;
end else sf.EnableSysbtn(true);
end;
end;
end;
// if b then skinaddlog('***** SetMdiMax True')
// else skinaddlog('***** SetMdiMax Flase');
end;
procedure TSkinManage.SetMDIMax2(b:boolean);
var i: integer;
sf:Twinskinform;
begin
if mdimax=b then exit;
mdimax:=b;
for I:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.formstyle=sfsmdichild then begin
if b then begin
if sf.crop then sf.Uncropwindow;
sf.EnableSysbtn(b);
end else begin
if sf.windowstate<>swsmin then begin
sf.windowstate:=swsnormal;
sf.cropwindow;
sf.EnableSysbtn(b);
if not sf.crop then sf.refresh;
end else sf.EnableSysbtn(true);
end;
end;
end;
if b then skinaddlog('***** SetMdiMax True')
else skinaddlog('***** SetMdiMax Flase');
end;
procedure TSkinManage.SetCaption(b:boolean);
var i: integer;
sf:Twinskinform;
dwstyle:Dword;
begin
for I:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.formstyle=sfsmdichild then begin
dwstyle := GetWindowLong( sf.hwnd, GWL_STYLE );
dwstyle := dwstyle or WS_CAPTION;
SetWindowLong( sf.hwnd, GWL_STYLE, dwstyle );
end;
end;
end;
function TSkinManage.GetMDIChildNum:integer;
var i: integer;
sf:Twinskinform;
begin
result:=0;
for I:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.formstyle=sfsmdichild then
inc(result);
end;
end;
{function EnumProp(ahwnd:HWND;prop:Pchar;data:Thandle):boolean;stdcall;
var s:string;
p:dword;
buf: array[0..31] of Char;
begin
//p:=GetProp(ahwnd,prop);
// s:=format('%4x',[data]);
// if pos('FF',s)=1 then exit;
// StrCopy(buf,prop);
result:=true;
if ATOM(prop) = dword(prop) then exit;
result:=true;
s:=format('%s',[prop]);
if pos('ControlOfs',s)=1 then begin
// b:=true;
result:=false;
end;
end; }
function TSkinManage.IsDllForm(ahwnd:Thandle):boolean;
var b:boolean;
i:integer;
function EnumProp(ahwnd:HWND;prop:Pchar;data:Thandle):boolean;stdcall;
var s:string;
p:^integer;
begin
result:=true;
if ATOM(prop) = dword(prop) then exit;
s:=strpas(prop);
if pos('ControlOfs',s)=1 then begin
result:=false;
end;
end;
begin
b:=true;
i:=0;
i:=EnumProps(ahwnd,@enumprop);
if i=0 then result:=false
else result:=true;
end;
function TSkinManage.FindTForm(ahwnd:Thandle):TForm;
var i:integer;
aform:TForm;
begin
aform:=nil;
for I := 0 to Screen.FormCount - 1 do begin
if Screen.Forms[I].handle=ahwnd then begin
aform := Screen.Forms[I];
break;
end;
end;
if aform=nil then
aform:=Tform(FindControlx(ahwnd));
result:=aform;
// Result := TForm(SendMessage(ahwnd, RM_GetObjectInstance, 0, 0)) ;
end;
procedure TSkinManage.SetAction(acode:integer;Interval:integer=250);
var i:integer;
sm:Tskinmanage;
begin
action:=acode;
timer.Interval:=interval;
if (state=skin_creating) then begin
if acode=skin_Active then active:=true
else if acode=skin_uninstall then active:=false;
end else begin
if mode=0 then begin
//other skinmanager
for i:=0 to sublist.count-1 do begin
sm:=TSkinManage(sublist[i]);
sm.UpdateData:=UpdateData;
if acode=skin_Active then begin
sm.active:=true ;
sm.SetAction(skin_Active,300)
end else if acode=skin_change then begin
//sm.SetAction(skin_change,300)
end else if acode=skin_uninstall then
sm.active:=false;
end;
end;
timer.enabled:=true;
end;
end;
function EnumWindow(ahwnd :HWND;lParam: LPARAM):boolean;stdcall;
var s:string;
r:Trect;
begin
result:=false;
// if (GetParent(ahwnd)= lparam) then begin
s:=getwindowclassname(ahwnd);
getwindowrect(ahwnd,r);
// skinaddlog(format('***enumWindow %1x,%s (%1d,%1d,%1d,%1d)',
// [ahwnd,s,r.left,r.top,r.right,r.bottom]));
result:=true;
// end;
end;
function EnumAddWindow(ahwnd :HWND;lParam: LPARAM):boolean;stdcall;
var s:string;
r:Trect;
begin
result:=true;
Skinmanager.addform(ahwnd);
end;
procedure TSkinManage.DeleteSysbtn;
var i: integer;
sf :TWinSkinform;
begin
for i:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if sf.fsd=updatedata then
sf.DeleteSysbtn;
end;
end;
function TSkinManage.initsb(ahwnd:Thandle):boolean;
begin
result:=false;
if SBinstall and (@pinitsb<>nil) then
result := boolean(pinitsb(ahwnd));
end;
function TSkinManage.Uninitsb(ahwnd:Thandle):boolean;
begin
result:=false;
if SBinstall and (@pUninitsb<>nil) then
result := boolean(pUninitsb(ahwnd));
end;
procedure TSkinManage.WndProc(var Msg: TMessage);
var ahwnd:hwnd;
sf :TWinSkinform;
begin
if (msg.Msg = CN_SkinNotify ) then begin
ahwnd:=msg.LParam;
if (msg.WParam=skin_update) then begin
sf := TWinSkinform(findskinform(ahwnd));
if sf<>nil then begin
application.ProcessMessages();
sleep(10);
sf.UnSubclass();
sf.skinstate:=skin_Deleted;
deleteDeleted;
sleep(10);
application.ProcessMessages();
AddForm(ahwnd);
end;
end;
msg.result:=0;
end else
msg.Result := DefWindowProc(handle, msg.msg, msg.wParam, msg.lParam);
end;
procedure TSkinManage.OnTimer(Sender: TObject);
var i: integer;
sf :TWinSkinform;
sd: TSkindata;
sm:Tskinmanage;
ahwnd:Thandle;
begin
timer.enabled:=false;
if UpdateData=nil then exit;
sd := TSkindata(updateData);
if sd.SkinFormtype = sfOnlyThisForm then begin
case action of
skin_uninstall:begin
active:=false;
DeleteDeleted;
for i:= flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
if sf.fsd = sd then begin
sf.unsubclass;
sf.repaint(sf.hwnd);
flist.delete(i);
sf.free;
break;
end;
end;
end;
skin_change:begin
DeleteDeleted;
for i:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if (sf.fsd = sd) then begin
sf.DeleteSysbtn;
sf.InitSkinData;
sf.skinchange;
break;
end;
end;
end;
skin_Active: begin
active:=true;
skinchildform:=true;
// EnumThreadWindows(GetCurrentThreadId,@EnumAddWindow,0);
for I := Screen.FormCount - 1 downto 0 do begin
if Screen.Forms[I]=sd.Owner then begin
activeform(Screen.Forms[I]);
break;
end;
end;
skinchildform:=false;
end;
skin_deleted : deleteform3;
end;//endcase
sd.doskinchanged;
UpdateData:=nil;
end else begin
case action of
skin_Active: begin
active:=true;
wmsetdraw:=false;
skinchildform:=true;
// EnumThreadWindows(GetCurrentThreadId,@EnumAddWindow,0);
DeleteDeleted;
for I := Screen.FormCount - 1 downto 0 do begin
ActiveForm(Screen.Forms[I]);
end;
skinchildform:=false;
if mode=0 then begin
for i:=0 to sublist.count-1 do begin
sm:=TSkinManage(sublist[i]);
sm.UpdateData:=UpdateData;
sm.active:=true ;
sm.SetAction(skin_Active,300)
end;
end;
end;
skin_uninstall:begin
active:=false;
DeleteDeleted;
{ for i:= flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
sf.unsubclass;
sf.repaint(sf.hwnd);
flist.delete(i);
sf.free;
end;}
while flist.count>0 do begin
sf:=TWinSkinform(flist[0]);
sf.unsubclass;
sf.repaint(sf.hwnd);
flist.delete(0);
sf.free;
end;
if mode=0 then begin
for i:=0 to sublist.count-1 do begin
sm:=TSkinManage(sublist[i]);
sm.active:=false ;
end;
end;
{ for i:= flist.count-1 downto 0 do begin
sf:=TWinSkinform(flist[i]);
sf.unsubclass;
sf.repaint(sf.hwnd);
flist.delete(i);
sf.free;
end;}
end;
skin_change:begin
DeleteDeleted;
for i:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if (sf.fsd = sd) {and (sf.mode=mode)} then begin
sf.DeleteSysbtn;
sf.InitSkinData;
end;
end;
// for i:= flist.count-1 downto 0 do begin
for i:= 0 to flist.count-1 do begin
sf:=TWinSkinform(flist[i]);
if (sf.fsd = sd) {and (sf.mode=mode)}then
sf.skinchange;
end;
end;
skin_deleted : deleteform3;
skin_update : begin
ahwnd:=lpara;
sf := TWinSkinform(findskinform(ahwnd));
if sf<>nil then begin
sf.UnSubclass();
sf.skinstate:=skin_Deleted;
deleteDeleted;
AddForm(ahwnd);
end;
exit;
end;
end;//endcase
sd.doskinchanged;
UpdateData:=nil;
end;
end;
function LCIDToCodePage(ALcid: LCID): Cardinal;
var
Buf: array[0..6] of AnsiChar;
begin
GetLocaleInfo(ALcid, LOCALE_IDefaultAnsiCodePage, Buf, 6);
Result := StrToIntDef(Buf, GetACP);
end;
procedure InitMsg;
var AtomText: array[0..31] of Char;
begin
PropName := Format('ControlOfs%.8X%.8X', [HInstance, GetCurrentThreadID]);
RM_GetObjectInstance := RegisterWindowMessage(PChar(PropName));
DefaultUserCodePage := CP_ACP;
myinstance:=HInstance;
// DefaultUserCodePage := 3; //CP_THREAD_ACP
ControlAtom := GlobalAddAtom(
StrFmt(AtomText, 'ControlOfs%.8X%.8X', [HInstance, GetCurrentThreadID]));
end;
Procedure Fini;
var i:integer;
begin
if skinmanager<>nil then
SkinManager.free;
SkinManager:=nil;
end;
initialization
Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT);
InitMsg;
// Win32PlatformIsUnicode := false;
// skinmanager := TSkinManage.create;
// skinmanager.installhook;
finalization
fini;
// if skinmanager<>nil then
// SkinManager.free;
// SkinManager:=nil;
end.