📄 winskinform.pas
字号:
Inc(I);
Result := Bar.Buttons[I];
end else begin
if I = 0 then
I := Count - 1
else
Dec(I);
Result := Bar.Buttons[I];
end;
end else Result := nil;
end;
begin
if LastMenuItem <> nil then begin
ParentMenu := LastMenuItem.GetParentMenu;
if ParentMenu <> nil then begin
if ParentMenu.IsRightToLeft then
if Msg.WParam = VK_LEFT then
Msg.WParam := VK_RIGHT
else if Msg.WParam = VK_RIGHT then
Msg.WParam := VK_LEFT;
end;
end;
Result := CallNextHookEx(MenuHook, Code, WParam, Longint(@Msg));
if Result <> 0 then Exit;
if (Code = MSGF_MENU) then begin
Target := nil;
if not InitDone then begin
InitDone := True;
PostMessage(Msg.Hwnd, WM_KEYDOWN, VK_DOWN, 0);
end;
case Msg.Message of
WM_MENUSELECT:
begin
if (HiWord(Msg.WParam) = $FFFF) and (Msg.LParam = 0) then begin
if not StillModal then Skinform.CancelMenu;
Exit;
end else StillModal := False;
FindKind := fkCommand;
if HiWord(Msg.WParam) and MF_POPUP <> 0 then FindKind := fkHandle;
if FindKind = fkHandle then
Item := GetSubMenu(Msg.LParam, LoWord(Msg.WParam))
else
Item := LoWord(Msg.WParam);
if skinform.menu.menu<>nil then
LastMenuItem := Skinform.menu.menu.FindItem(Item, FindKind);
end;
WM_SYSKEYDOWN:
if Msg.WParam = VK_MENU then begin
SkinForm.CancelMenu;
Exit;
end;
WM_KEYDOWN:begin
if Msg.WParam = VK_RETURN then
// Skinform.FMenuResult := True
StillModal := false
else if Msg.WParam = VK_ESCAPE then
StillModal := false
else if (Msg.WParam = VK_RIGHT) then begin
if (LastMenuItem = nil) or (LastMenuItem.Count = 0) then
Target := FindButton(True);
end else if (Msg.WParam = VK_LEFT) then begin
if (LastMenuItem = nil) then
Target := FindButton(False)
else if ((LastMenuItem.Parent.handle=skinform.activemenu)
or (LastMenuItem.handle=skinform.activemenu)) then
Target := FindButton(False);
end else Target := nil;
if Target <> nil then
P := Point(Target.Bounds.left+1,Target.Bounds.top+1);
end;
WM_MOUSEMOVE:
begin
P := Msg.pt;
if (P.X <> LastMousePos.X) or (P.Y <> LastMousePos.Y) then begin
p:= SkinForm.GetWinxy(p.x,p.y);
Target := Tmenubtn(SKinForm.Menu.findbtn(P));
LastMousePos := P;
end;
end;
end;
if (Target <> nil) and (Target is TMenuBtn) and
(Target.Index <> MenuButtonIndex) then begin
StillModal := True;
// SkinForm.FCaptureChangeCancels := False;
// SkinForm.ClickButton(Target);
SkinForm.ClickButton(Target);
end;
end;
end;
procedure InitMenuHooks;
begin
StillModal := False;
InitDone := False;
GetCursorPos(LastMousePos);
if MenuHook = 0 then
MenuHook := SetWindowsHookEx(WH_MSGFILTER, @ToolMenuGetMsgHook, 0,
GetCurrentThreadID);
end;
procedure ReleaseMenuHooks;
begin
if MenuHook <> 0 then UnhookWindowsHookEx(MenuHook);
MenuHook := 0;
LastMenuItem := nil;
MenuBar := nil;
MenuButtonIndex := -1;
InitDone := False;
end;
{procedure TWinSkinForm.ClearTempMenu;
var
I: Integer;
Item: TMenuItem;
begin
if (FTempMenu <> nil) and (FButtonMenu<>nil) then begin
for I := FTempMenu.Items.Count - 1 downto 0 do
begin
Item := FTempMenu.Items[I];
FTempMenu.Items.Delete(I);
if item.tag<>c_windowid then
FButtonMenu.Insert(0, Item);
end;
FTempMenu.Free;
FTempMenu := nil;
FButtonMenu := nil;
end;
end;}
procedure TWinSkinForm.ClickButton(Button: TMenuBtn);
var
P: TPoint;
begin
// FCaptureChangeCancels := False;
GetWindowRect(hwnd, WTR);
P := Point(Button.bounds.left+1+wtr.left,
Button.bounds.top+1+wtr.top);
// timer.enabled:=true;
PostMessage(hwnd, WM_NCLBUTTONDOWN, MK_LBUTTON,
Longint(PointToSmallPoint(P)));
end;
function TWinSkinForm.FindButtonFromAccel(Accel: Word): TMenuBtn;
var
I: Integer;
begin
result:=nil;
if menu=nil then exit;
for I := 0 to menu.Count - 1 do begin
Result :=Menu.Buttons[I];
if Result.Enabled and
IsAccel(Accel, Result.Caption) then
Exit;
end;
Result := nil;
end;
procedure TWinSkinForm.CancelMenu;
begin
if FInMenu then begin
// ReleaseMenuKeyHooks;
// MouseCapture := False;
end;
FInMenu := False;
// FCaptureChangeCancels := False;
end;
procedure TWinSkinForm.SelectMDIform(Sender: TObject);
var s:string;
j:integer;
b:boolean;
WS: TWindowState;
begin
if not Assigned(Application.MainForm) then exit;
s:= Tmenuitem(sender).caption;
s:= StringReplace(s,'&','',[]);
with Application.MainForm do
if (FormStyle = fsMDIForm) and (MDIChildCount>0) then begin
for j:= 0 to MDIChildCount-1 do begin
if MDIChildren[j].caption=s then begin
WS:=Application.MainForm.ActiveMDIChild.WindowState;
// b:=MDIChildren[j].windowstate=wsmaximized;
// MDIChildren[j].show;
SendMessage(ClientHandle,WM_MDIACTIVATE ,MDIChildren[j].handle,0);
MDIChildren[j].windowstate:=ws;
break;
end;
end;
end;
end;
function CopyHMenu(amenu:Hmenu):Hmenu;
var hMenuOurs:Hmenu;
nID: UINT; // The ID of the menu.
uMenuState :UINT ; // The menu state.
hSubMenu: HMENU ; // A submenu.
s:string;
nmenu:integer;
szBuf:array[0..127] of char;
begin
hMenuOurs := CreatePopupMenu;
nmenu :=0;
uMenuState :=GetMenuState(aMenu,nMenu,MF_BYPOSITION);
while uMenustate<>$FFFFFFFF do begin
GetMenuString(aMenu,nMenu, szBuf,sizeof(szBuf),MF_BYPOSITION);
if (LOBYTE(uMenuState) and MF_POPUP)>0 then begin
hSubMenu := GetSubMenu(aMenu,nMenu);
AppendMenu(hMenuOurs,uMenuState,hSubMenu,szBuf);
end else begin
nID := GetMenuItemID(aMenu,nMenu);
AppendMenu(hMenuOurs,uMenuState,nID,szBuf);
end;
inc(nmenu);
uMenuState :=GetMenuState(aMenu,nMenu,MF_BYPOSITION);
end;
result:=hmenuours;
end;
procedure DeleteHMenu(amenu:Hmenu);
var b:boolean;
begin
b:=RemoveMenu(amenu,0,MF_BYPOSITION);
while b do
b:=RemoveMenu(amenu,0,MF_BYPOSITION);
DestroyMenu(amenu);
end;
function TWinSkinForm.CheckMenu(Button: TMenuBtn): Boolean;
var
Hook: Boolean;
I: Integer;
APoint: TPoint;
aflags:integer;
begin
Result := False;
if (button=nil) then Exit;
postmessage(hwnd,wm_command,button.mid,0);
if (Button.hsubmenu=0) then begin
Exit;
end;
MenuButtonIndex := Button.Index;
SkinForm := Self;
GetWindowRect(hwnd, WTR);
if not ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion = 4)) then
wminitmenu(button.hsubmenu);
// skincanlog:=true;
finmenu:=true;
APoint := Point(Button.bounds.left+wtr.left,Button.bounds.bottom+wtr.top);
Aflags:= TPM_LEFTALIGN or TPM_RIGHTBUTTON or TPM_NONOTIFY;
skinmanager.menuactive:=true;
activemenu:=button.hsubmenu;
InitMenuHooks;
if Button.enabled then
TrackPopupMenu(button.hsubmenu, aflags,APoint.X, APoint.Y,0,hwnd,nil );
ReleaseMenuHooks;
finmenu:=false;
Result := True;
end;
//fixed by Brian Lowe
procedure TWinSkinForm.CMDialogChar(var Message: TMessage); //TCMDialogChar
var
Button: TMenubtn;
ShiftState: TShiftState;
KeyState: TKeyboardState;
begin
GetKeyboardState(KeyState);
ShiftState := KeyboardStateToShiftState(KeyState);
Button := FindButtonFromAccel(TWMKey(Message).CharCode);
if (Button <> nil) and (ShiftState = [ssAlt]) then begin
clickbutton(button);
Message.Result := 1;
done2:=true;
end else OldWndProc(message);
end;
constructor TWinSkinForm.Create(AOwner: TComponent);
var i,l:integer;
begin
inherited create(aowner);
bstr:=' ';
SkinCanLog:=true;
poptime := 0;
charwidth := 0;
DoubleTime := GetDoubleClickTime;
// SkinCanLog:=false;
fCanvas:= TCanvas.create;
fCanvas2:= TCanvas.create;
// bg:=Tbitmap.create;
controllist:=Tlist.create;
IconBmp:=Tbitmap.create;
CaptionBuf:=Tbitmap.create;
MenuHeight := 0;
msglock:=0;
activebtn:=nil;
creating:=false;
bidileft:=false;
NewChildHwnd:=0;
fwindowactive:=true;
ActiveBtn:= nil;
skinstate:=skin_Creating;
fform:=nil;
{$IFnDEF demo}
astr:=' ';
{$else}
astr:=' Vclskin Demo';
{$ENDIF}
end;
destructor TWinSkinForm.Destroy;
begin
DeleteControls;
DeleteSysbtn;
fCanvas.free;
fCanvas2.free;
CaptionBuf.free;
if timer<>nil then timer.free;
if menu<>nil then menu.free;
CaptionFont.free;
controllist.free;
controllist:=nil;
Iconbmp.free;
skinmanager.DeleteForm2(hwnd);
skinaddlog('Skinform DESTROY '+caption);
inherited destroy;
end;
procedure TWinSkinForm.Notification(AComponent: TComponent;Operation: TOperation);
var j:integer;
sc:Tskincontrol;
begin
inherited Notification(AComponent, Operation);
{ if (skinstate<>Skin_Active) or (acomponent.tag=c_skintag) then exit;
if (Operation = opRemove) and (AComponent <> nil) then begin
skinaddlog(format('Notification Remove :%s',[acomponent.classname]));
if (AComponent is TGraphicControl) then begin
for j:= 0 to controllist.count-1 do begin
sc:= Tskincontrol(controllist.items[j]);
if sc.GControl = AComponent then begin
controllist.Delete(j);
sc.free;
break;
end;
end;
end;//Tgraphiccontrol
end else if (Operation = opInsert) and (AComponent <> nil) then begin
// skinaddlog(format('Notification Insert :%s',[acomponent.classname]));
end;}
end;
procedure TWinSkinForm.DeleteSysbtn;
var i:integer;
begin
for i:= 0 to high(SysBtn) do SysBtn[i].free;
setlength(sysbtn,0);
end;
procedure TWinSkinForm.DeleteControl(c:TSkinControl);
var i:integer;
begin
if controllist=nil then exit;
for i:= controllist.count-1 downto 0 do begin
if Controllist.items[i]=c then begin
controllist.delete(i);
break;
end;
end;
end;
procedure TWinSkinForm.DeleteSkinDeleted;
var i:integer;
c:TSkinControl;
begin
for i:= controllist.count-1 downto 0 do begin
c:=TSkinControl(Controllist.items[i]);
if c.skinstate=skin_deleted then begin
controllist.delete(i);
c.free;
end;
end;
end;
procedure TWinSkinForm.DeleteControls;
var i:integer;
c:TSkinControl;
acontrol:Tcontrol;
begin
// for i:= controllist.count-1 to 0 do begin
while controllist.count>0 do begin
c:=TSkinControl(Controllist.items[0]);
c.unsubclass;
controllist.delete(0);
c.free;
end;
controllist.clear;
end;
function TWinSkinForm.AddControlList(acontrol:TSkinControl):boolean;
var i:integer;
c:TSkinControl;
b:boolean;
begin
b:=false;
for i:= 0 to controllist.count-1 do begin
c:=TSkinControl(Controllist.items[i]);
if c=acontrol then begin
b:=true;
break;
end;
end;
if not b then controllist.add(acontrol);
result:=b;
end;
procedure TWinSkinForm.CreateCaptionFont;
var
NonClientMetrics: TNonClientMetrics;
begin
CaptionFont := TFont.Create;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -