看看VCLSkin源码,它的思路是参照系统菜单的内容,自己构造一个菜单。 以下内容是WinSkinForm.pas(VCLSkin版本5.03.07.12)的CreateSysmenu2的实现:procedure TWinSkinForm.CreateSysmenu2; var i,n,j:integer; mi:TMenuItemInfo; Buffer: array[0..79] of Char; item:Tmenuitem; s:string; begin if sysmenu<>nil then begin sysmenu.free; sysmenu:=nil; end; if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion <5) then begin CreateSysmenu; exit; end; if hsysmenu = 0 then exit; n:= GetMenuItemCount(hsysmenu); sysmenu:=Tpopupmenu.create(self); sysmenu.Tag:=c_skintag; sysmenu.OwnerDraw := true; sysmenu.Images:=fsd.bmpmenu; for i:= 0 to n-1 do begin fillchar(mi,sizeof(mi),#0); mi.cbSize:= sizeof(TMENUITEMINFO); mi.fMask := MIIM_ID or MIIM_STATE or MIIM_STRING; mi.fType := 0; mi.dwTypeData := Buffer; Mi.cch := SizeOf(Buffer); GetMenuItemInfo(hsysmenu, i, TRUE, mi); s:= buffer; Item := TMenuItem.Create(sysmenu); if s='' then item.Caption:= '-' else item.Caption := s; item.Tag:= mi.wID; case mi.wID of SC_MAXIMIZE: begin item.ImageIndex :=1; item.enabled:= (windowstate<>swsmax) and (sbimax in formicons); end; SC_MINIMIZE: begin item.ImageIndex :=2; item.enabled:= (windowstate<>swsmin) and (sbimin in formicons); end; Sc_Restore : begin item.ImageIndex :=0; item.enabled:= (windowstate<>swsnormal) ; end; SC_MOVE,SC_SIZE: begin item.enabled:= (windowstate<>swsmax) ; end; SC_CLOSE : item.ImageIndex :=3; else item.ImageIndex :=-1; end; item.onclick:=dosysmenu2; if mi.fState=3 then item.Enabled:=false; if (mi.fState and MFS_CHECKED)>0 then item.Checked:=true; //item.Enabled := not ((mi.fState and $0ff) = MFS_DISABLED); item.OnDrawItem := DrawMenuItem; item.OnMeasureItem := MeasureItempop; Sysmenu.Items.Add(item); end; end;
自己重画
以下内容是WinSkinForm.pas(VCLSkin版本5.03.07.12)的CreateSysmenu2的实现:procedure TWinSkinForm.CreateSysmenu2;
var i,n,j:integer;
mi:TMenuItemInfo;
Buffer: array[0..79] of Char;
item:Tmenuitem;
s:string;
begin
if sysmenu<>nil then begin
sysmenu.free;
sysmenu:=nil;
end; if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion <5) then begin
CreateSysmenu;
exit;
end; if hsysmenu = 0 then exit; n:= GetMenuItemCount(hsysmenu);
sysmenu:=Tpopupmenu.create(self);
sysmenu.Tag:=c_skintag;
sysmenu.OwnerDraw := true;
sysmenu.Images:=fsd.bmpmenu; for i:= 0 to n-1 do begin
fillchar(mi,sizeof(mi),#0);
mi.cbSize:= sizeof(TMENUITEMINFO);
mi.fMask := MIIM_ID or MIIM_STATE or MIIM_STRING;
mi.fType := 0;
mi.dwTypeData := Buffer;
Mi.cch := SizeOf(Buffer);
GetMenuItemInfo(hsysmenu, i, TRUE, mi);
s:= buffer; Item := TMenuItem.Create(sysmenu);
if s='' then item.Caption:= '-'
else item.Caption := s;
item.Tag:= mi.wID;
case mi.wID of
SC_MAXIMIZE: begin
item.ImageIndex :=1;
item.enabled:= (windowstate<>swsmax) and (sbimax in formicons);
end;
SC_MINIMIZE: begin
item.ImageIndex :=2;
item.enabled:= (windowstate<>swsmin) and (sbimin in formicons);
end;
Sc_Restore : begin
item.ImageIndex :=0;
item.enabled:= (windowstate<>swsnormal) ;
end;
SC_MOVE,SC_SIZE: begin
item.enabled:= (windowstate<>swsmax) ;
end;
SC_CLOSE : item.ImageIndex :=3;
else item.ImageIndex :=-1;
end;
item.onclick:=dosysmenu2; if mi.fState=3 then item.Enabled:=false;
if (mi.fState and MFS_CHECKED)>0 then item.Checked:=true;
//item.Enabled := not ((mi.fState and $0ff) = MFS_DISABLED);
item.OnDrawItem := DrawMenuItem;
item.OnMeasureItem := MeasureItempop;
Sysmenu.Items.Add(item);
end;
end;