📄 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]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -