相比上一篇的菜单插件,这个在创建和销毁时候,做了增强,同时做了2个菜单对应的窗口

unit MenuSvc;

interface

uses
windows,
classes,
SysUtils,
Graphics,
ImgList,
menus,
qstring,
QPlugins,
qplugins_params,
qplugins_base; const
MN_CLICK = ; type
// 注册的菜单项Name属性会自动加上'mi'前缀,防止控件名称与保留关键字冲突
// 这里只实现了菜单服务的部分接口,如果要实现更多的接口,请自己扩展实现
IQMenuItem = interface
['{83323919-93DE-4D40-87FB-7266AE804D6C}']
function GetCaption: PWideChar;
procedure SetCaption(const S: PWideChar);
function GetHint: PWideChar;
procedure SetHint(const S: PWideChar);
function GetParams: IQParams;
procedure SetParams(AParams: IQParams);
function SetImage(AHandle: HBITMAP): Boolean;
function GetParentMenu: IQMenuItem;
// 菜单的四个属性,标题/Hint/父菜单/参数,在接口中定义,子类来实现它
property Caption: PWideChar read GetCaption write SetCaption;
property Hint: PWideChar read GetHint write SetHint;
property ParentMenu: IQMenuItem read GetParentMenu;
property Params: IQParams read GetParams write SetParams;
end; IQMenuService = interface
['{667BD198-2F9A-445C-8A7D-B85C4B222DFC}']
// 注册, 在接口中定义,子类来实现它
function RegisterMenu(const APath: PWideChar; AOnEvent: IQNotify; ADelimitor: WideChar = '/'): IQMenuItem;
// 注销, 在接口中定义,子类来实现它
procedure UnregisterMenu(const APath: PWideChar; AOnEvent: IQNotify; ADelimitor: WideChar = '/');
end; TQMenuService = class(TQService, IQMenuService)
private
// 主菜单
FMainMenu: TMainMenu;
FQMenuItems: TList;
protected
// 注册的实现部分
function RegisterMenu(const APath: PWideChar; AOnEvent: IQNotify; ADelimitor: WideChar): IQMenuItem;
// 注销的实现部分
procedure UnregisterMenu(const APath: PWideChar; AOnEvent: IQNotify; ADelimitor: WideChar);
public
constructor Create(aMainMenu: TMainMenu);
destructor Destroy; override;
end; TQMenuItem = class(TQInterfacedObject, IQMenuItem)
private
protected
FMenuItem: TMenuItem;
FOnClick: IQNotify;
FName: string;
FParams: IQParams;
// 菜单的四个属性,标题/Hint/父菜单/参数,在接口中定义,实现部分
function GetCaption: PWideChar;
procedure SetCaption(const S: PWideChar);
function GetHint: PWideChar;
procedure SetHint(const S: PWideChar);
function SetImage(AHandle: HBITMAP): Boolean;
function GetParams: IQParams;
procedure SetParams(AParams: IQParams);
function GetParentMenu: IQMenuItem;
procedure DoClick(ASender: TObject);
public
constructor Create(AMenuItem: TMenuItem; AOnClick: IQNotify); overload;
destructor Destroy; override;
property Name: string read FName write FName;
property Params: IQParams read GetParams write SetParams;
end; implementation { TQMenuService }
const
// 菜单前缀,防止重名
MENUITEMNAME_PREFIX = 'mi'; constructor TQMenuService.Create(aMainMenu: TMainMenu);
begin
// 创建菜单服务
inherited Create(IQMenuService, 'QMenuService');
// 主菜单赋值
FMainMenu := aMainMenu;
FQMenuItems := TList.Create;
end; destructor TQMenuService.Destroy;
var
i: Integer;
aIdx: Integer;
aMenu: TMenuItem;
procedure RemoveAQMenuItem(AMenuItem: TMenuItem);
var
k: Integer;
begin
if AMenuItem.Count = then
begin
// 删除自己
// 判断是否是注册的菜单项 , 暂时用Tag 是否大于0 作为识别标志
// 但是这样就无法利用菜单项的Tag属性用于其他用途,需要优化.
if AMenuItem.Tag > then
begin
IQMenuItem(Pointer(AMenuItem.Tag)).Params._Release;
IQMenuItem(Pointer(AMenuItem.Tag))._Release;
end;
AMenuItem.Free;
end
else
begin
for k := AMenuItem.Count - downto do
begin
RemoveAQMenuItem(AMenuItem[k]);
end;
end;
end; begin
// 清理所有未注销的菜单对象
aMenu := FMainMenu.Items;
for i := aMenu.Count - downto do
begin
RemoveAQMenuItem(aMenu[i]);
end;
// 清除所有注册的菜单
// FQMenuItems { for i := FQMenuItems.Count - 1 downto 0 do
begin
TQMenuItem(FQMenuItems[i]).Free;
end;
FQMenuItems.Free; }
inherited;
end; // 注册菜单
function TQMenuService.RegisterMenu(const APath: PWideChar; AOnEvent: IQNotify; ADelimitor: WideChar): IQMenuItem;
var
p: PWideChar;
AName: QStringW;
aMenu, ANewMenu: TMenuItem;
AItem: IQMenuItem;
AChildMenu: TQMenuItem;
aIdx: Integer;
// 根据名字,找到这个菜单
function IndexOfMenuName: Integer;
var
i: Integer;
AIntf: IQMenuItem;
begin
Result := -;
for i := to aMenu.Count - do
begin
if SameText(aMenu.Items[i].Name, MENUITEMNAME_PREFIX + AName) then
begin
Result := i;
Break;
end;
end;
end; begin
// 菜单赋值到本地变量
aMenu := FMainMenu.Items;
p := PWideChar(APath);
while p^ <> # do
begin
AName := DecodeTokenW(p, [ADelimitor], #, true);
// 判断真实菜单名,长度大于0
if Length(AName) > then
begin
aIdx := IndexOfMenuName;
// 如果没有找到这个菜单,则创建
if aIdx = - then
begin
// 创建菜单
ANewMenu := TMenuItem.Create(FMainMenu);
// TQMenuItem
if p^ = # then
AChildMenu := TQMenuItem.Create(ANewMenu, AOnEvent)
else
begin
AChildMenu := TQMenuItem.Create(ANewMenu, nil);
end;
// 往菜单中插入新创建的菜单
FQMenuItems.Add(AChildMenu);
// AChildMenu.Name:= MENUITEMNAME_PREFIX + AName; //添加命名前缀'mi_',避免保留字冲突
Result := AChildMenu;
Result._AddRef;
// TMenuItem
// 设置菜单属性
ANewMenu.Name := MENUITEMNAME_PREFIX + AName;
ANewMenu.Tag := IntPtr(Pointer(AChildMenu));
ANewMenu.Caption := AName;
aMenu.Add(ANewMenu);
aMenu := ANewMenu;
end
else
begin
// 如果找到这个菜单,就释放
Result := IQMenuItem(Pointer(aMenu.Items[aIdx].Tag));
aMenu := aMenu.Items[aIdx];
end;
end;
end;
end; // 注销菜单
procedure TQMenuService.UnregisterMenu(const APath: PWideChar; AOnEvent: IQNotify; ADelimitor: WideChar);
// 找到菜单项并删除之
// 逐级查找从叶到枝
var
MenuItemIndexs: TList;
k: Integer;
p: PWideChar;
AName: QStringW;
aMenu: TMenuItem;
AQMenuItem: TQMenuItem;
aIdx: Integer;
i: Integer;
// 根据名字,找到这个菜单
function IndexOfMenuName: Integer;
var
i: Integer;
AIntf: IQMenuItem;
begin
Result := -;
for i := to aMenu.Count - do
begin
if SameText(aMenu.Items[i].Name, MENUITEMNAME_PREFIX + AName) then
begin
Result := i;
Break;
end;
end;
end; begin
aMenu := FMainMenu.Items;
{ for k := FMainMenu.Items.Count - 1 downto 0 do
begin
Debugout(FMainMenu.Items[k].Caption);
end; } MenuItemIndexs := TList.Create;
try
p := PWideChar(APath);
while p^ <> # do
begin
AName := DecodeTokenW(p, [ADelimitor], #, true);
if Length(AName) > then
begin
aIdx := IndexOfMenuName;
if aIdx = - then
begin
Break;
end
else
begin
MenuItemIndexs.Add(Pointer(aMenu.Items[aIdx]));
aMenu := aMenu.Items[aIdx];
end;
end;
end; // 开始倒序删除 MenuItemIndexs 中的菜单项
for k := MenuItemIndexs.Count - downto do
begin if TMenuItem(MenuItemIndexs[k]).Count = then
begin
if TMenuItem(MenuItemIndexs[k]).Tag > then
begin
AQMenuItem := TQMenuItem(Pointer(TMenuItem(MenuItemIndexs[k]).Tag));
// 清除内部列表中对象的引用
for i := to FQMenuItems.Count - do
begin
if FQMenuItems[i] = AQMenuItem then
begin
FQMenuItems[i] := nil;
FQMenuItems.Delete(i);
Break;
end;
end;
FreeAndNil(AQMenuItem); TMenuItem(MenuItemIndexs[k]).Free;
// MenuItemIndexs.Delete(k);
end;
end;
end;
AOnEvent := nil;
finally
MenuItemIndexs.Free;
end;
end; { TQMenuItem } constructor TQMenuItem.Create(AMenuItem: TMenuItem; AOnClick: IQNotify);
var
ATemp: Pointer;
begin
inherited Create;
FMenuItem := AMenuItem;
// 替换菜单的点击事件
FMenuItem.OnClick := DoClick;
FOnClick := AOnClick;
end; destructor TQMenuItem.Destroy;
begin
FOnClick := nil;
// FMenuItem.Free;
inherited;
end; procedure TQMenuItem.DoClick(ASender: TObject);
var
AFireNext: Boolean;
begin
AFireNext := true;
if Assigned(FOnClick) then
begin
// 在通知发生时,通知响应函数接口
FOnClick.Notify(MN_CLICK, Params, AFireNext);
end;
end; function TQMenuItem.GetCaption: PWideChar;
begin
Result := PWideChar(FMenuItem.Caption);
end; function TQMenuItem.GetHint: PWideChar;
begin
Result := PWideChar(FMenuItem.Hint);
end; function TQMenuItem.GetParams: IQParams;
begin
Result := FParams;
end; function TQMenuItem.GetParentMenu: IQMenuItem;
begin
// 父菜单存于Tag中
if Assigned(FMenuItem.Parent) then
Result := IQMenuItem(FMenuItem.Parent.Tag)
else
begin
Result := nil;
end;
end; procedure TQMenuItem.SetCaption(const S: PWideChar);
begin
FMenuItem.Caption := S;
end; procedure TQMenuItem.SetHint(const S: PWideChar);
begin
FMenuItem.Hint := S;
end; // 设置图标
function TQMenuItem.SetImage(AHandle: HBITMAP): Boolean;
var
ABitmap: TBitmap;
AIcon: TBitmap;
AImages: TCustomImageList;
begin
// 取菜单图片
AImages := (FMenuItem.Owner as TMenu).Images;
// 初始化ICON
AIcon := nil;
// 创建位图
ABitmap := TBitmap.Create;
try
// 位图赋值
ABitmap.Handle := AHandle;
// 图标尺寸如果不对,则生成临时的位图,否则ImageList会添加失败
if (ABitmap.Width <> AImages.Width) or (ABitmap.Height <> AImages.Height) then
begin
// 创建
AIcon := TBitmap.Create;
AIcon.SetSize(AImages.Width, AImages.Height);
// 是否启用透明色
AIcon.Canvas.Brush.Color := ABitmap.TransparentColor;
AIcon.Canvas.FillRect(Rect(, , AImages.Width, AImages.Height));
AIcon.Canvas.Draw((AImages.Width - ABitmap.Width) shr , (AImages.Height - ABitmap.Height) shr , ABitmap);
AIcon.Transparent := true;
// AddMasked向图像列表中加入一个图像
FMenuItem.ImageIndex := AImages.AddMasked(AIcon, ABitmap.TransparentColor);
end
else
begin
// 如果图片尺寸一样,则直接添加菜单图片
FMenuItem.ImageIndex := AImages.AddMasked(ABitmap, ABitmap.TransparentColor);
end;
finally
// 释放
FreeAndNil(AIcon);
FreeAndNil(ABitmap);
end;
Result := FMenuItem.ImageIndex <> -;
end; procedure TQMenuItem.SetParams(AParams: IQParams);
begin
FParams := AParams;
end; end.
unit Frm_Main;

interface

uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
Menus,
QPlugins,
MenuSvc; type
TMainForm = class(TForm)
MainMenu1: TMainMenu;
miFile: TMenuItem;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
MainForm: TMainForm; implementation {$R *.dfm} procedure TMainForm.FormCreate(Sender: TObject);
begin
// TQMenuService, 传入界面主菜单
RegisterServices('/Services/Menus', [TQMenuService.Create(MainMenu1)]);
end; end.
unit Frm_About;

interface

uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
ComCtrls,
ShellAPI,
QPlugins,
qplugins_base,
qplugins_params,
MenuSvc; type
TForm_About = class(TForm)
bvl1: TBevel;
btn1: TButton;
procedure FormCreate(Sender: TObject);
procedure btn1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations } procedure GetFileVersion;
public
{ Public declarations }
end; type
TFileVersionInfo = packed record
FixedInfo: TVSFixedFileInfo; { 版本信息 }
CompanyName: string; { 公司名称 }
FileDescription: string; { 说明 }
FileVersion: string; { 文件版本 }
InternalName: string; { 内部名称 }
LegalCopyright: string; { 版权 }
LegalTrademarks: string; { 合法商标 }
OriginalFilename: string; { 源文件名 }
ProductName: string; { 产品名称 }
ProductVersion: string; { 产品版本 }
Comments: string; { 备注 }
LocalPort: string;
end; implementation {$R *.dfm} procedure TForm_About.btn1Click(Sender: TObject);
begin
Close();
end; procedure TForm_About.FormCreate(Sender: TObject);
begin
Caption := '关于 ' + Application.Title;
GetFileVersion();
end; procedure TForm_About.FormShow(Sender: TObject);
begin
// 检测更新
// if FileExists(ExtractFilePath(Application.ExeName) + APPFILE_Update_exe) then
// begin
// ShellExecute(Application.Handle, PChar('open'),
// PChar(ExtractFilePath(Application.ExeName) + APPFILE_Update_exe),
// PChar('/s'), nil, SW_SHOWNORMAL);
// end;
end; procedure TForm_About.GetFileVersion;
var
FileVersionInfo: TFileVersionInfo;
begin
// if GetFileVerInfo(Application.ExeName, FileVersionInfo) then
// begin
// lblVersion.Caption := '当前版本: ' +
// IntToStr(HIWORD(FileVersionInfo.FixedInfo.dwFileVersionMS)) + '.' +
// IntToStr(LOWORD(FileVersionInfo.FixedInfo.dwFileVersionMS));
// end;
end; type
// 通知响应接口,关注某个通知时,应实现IQNotify接口,以便接收相关的通知
TShowFormAction = class(TQInterfacedObject, IQNotify)
protected
// 在通知发生时,通知响应函数接口
procedure Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean); stdcall;
end;
{ TShowFormAction } // 通知响应函数 procedure TShowFormAction.Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean);
var
F: TForm_About;
begin
// 如果存在
if Assigned(AParams) and (ParamAsString(AParams.ByName('Name')) = 'About') then
begin
// 创建自身
F := TForm_About.Create(Application);
F.ShowModal;
F.Free;
end;
end; var
AFormAction: IQNotify; // 服务注册完成时的通知回调
procedure DoMenuServiceReady2(const AService: IQService); stdcall;
begin
//
with AService as IQMenuService do
begin
AFormAction := TShowFormAction.Create;
// 注册菜单
with RegisterMenu('/Help/About', AFormAction) do
begin
// 设置菜单属性
Caption := '关于(&S)';
// F := TForm_About.Create(nil);
// SetImage(TBitmap(F.img1.Picture.Graphic).Handle);
// 参数'Name',值为'About'
Params := NewParams([]);
Params.Add('Name', ptUnicodeString).AsString := NewString('About');
// F.Free;
end;
end;
end; initialization AFormAction := nil;
// 等待指定的服务注册,DoMenuServiceReady2为服务注册完成时的通知回调
PluginsManager.WaitService(IQMenuService, DoMenuServiceReady2); // DoMenuServiceReady2;
finalization // 如果菜单存在,则注销
if Assigned(AFormAction) then
begin
with PluginsManager as IQMenuService do
begin
// 注销
UnregisterMenu('/Help/About', AFormAction);
end;
AFormAction := nil;
end; end.
unit Frm_Show;

interface

uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
QPlugins,
qplugins_base,
qplugins_params,
MenuSvc,
StdCtrls,
ExtCtrls; type
TForm_Show = class(TForm)
mmo1: TMemo;
img1: TImage;
private
{ Private declarations }
public
{ Public declarations }
end; { var
Form3: TForm_Show; } implementation {$R *.dfm} type
// 通知响应接口,关注某个通知时,应实现IQNotify接口,以便接收相关的通知
TShowFormAction = class(TQInterfacedObject, IQNotify)
protected
// 在通知发生时,通知响应函数接口
procedure Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean); stdcall;
end;
{ TShowFormAction } // 在通知发生时,通知响应函数接口
procedure TShowFormAction.Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean);
var
F: TForm_Show;
I: Integer;
begin
if Assigned(AParams) and (ParamAsString(AParams.ByName('Name')) = 'Exit') then
Application.Terminate
else
begin
// 创建窗口
F := TForm_Show.Create(Application);
// Memo输出
with F.mmo1.Lines do
begin
BeginUpdate;
try
for I := to AParams.Count - do
begin
// 窗口输出参数
Add(IntToStr(I) + ': ' + AParams[I].Name + '=' + ParamAsString(AParams[I]));
end;
finally
EndUpdate;
end;
end;
F.ShowModal;
F.Free;
end;
end; var
// 通知响应接口,关注某个通知时,应实现IQNotify接口,以便接收相关的通知
AFormAction: IQNotify; // 添加菜单相关内容
procedure DoMenuServiceReady(const AService: IQService); stdcall;
begin
// 菜单回调函数
with AService as IQMenuService do
begin
// 通知响应接口
AFormAction := TShowFormAction.Create;
// 注册菜单
with RegisterMenu('/File/ShowForm', AFormAction) do
begin
// 窗口信息
Caption := '显示窗体(&S)';
// F := TForm_Show.Create(nil);
// SetImage(TBitmap(F.img1.Picture.Graphic).Handle);
Params := NewParams([, 'Hello,world']);
// F.Free;
end;
// 注册第二个菜单
with RegisterMenu('/File/Exit', AFormAction) do
begin
Caption := '退出(&X)';
// 参数名字为Exit
Params := NewParams([]);
Params.Add('Name', ptUnicodeString).AsString := NewString('Exit');
end;
end;
end; initialization // 通知响应接口
AFormAction := nil;
// 等待指定的服务注册,DoMenuServiceReady为服务注册完成时的通知回调
PluginsManager.WaitService(IQMenuService, DoMenuServiceReady); // 在单元中放在 initialization 和 end. 之间,包含了单元退出时的代码。在程序退出时运行并且只运行一次。
finalization // 检查菜单接口是否存在,存在则释放菜单功能
if Assigned(AFormAction) then
begin
// 释放菜单功能
with PluginsManager as IQMenuService do
begin
UnregisterMenu('/File/ShowForm', AFormAction);
end;
AFormAction := nil;
end; end.

003.Delphi插件之QPlugins,菜单插件加强的更多相关文章

  1. 007.Delphi插件之QPlugins,插件的卸载和重新加载

    效果图如下,可以反复卸载和重新加载.QPlugins这个插件,还没弄明白,摸索着跟着DEMO写 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows ...

  2. 网站开发常用jQuery插件总结(十)菜单插件superfish

    网站对于菜单的依赖其实并不是很大,我们完全可以不使用菜单来设计网站,显示网站内容.但是如果网站的分类太多,“也许”使用菜单作为网站导航可以使 用户 更方便的寻找内容.superfish插件就是用于实现 ...

  3. 『练手』004 Laura.SqlForever如何扩展 导航栏 工具栏 右键菜单 插件

    004 Laura.SqlForever如何扩展 导航栏 工具栏 右键菜单 插件 导航栏 插件扩展 比如下图的    窗口 > 关闭所有文档    这个导航栏: 在 任何程序集,任何命名空间,任 ...

  4. 014.Delphi插件之QPlugins,MDI窗口

    不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应. 效果如下 主程序代码如下 unit Frm_Main; interface uses Winapi.Windows ...

  5. jQuery Wheel 环形菜单插件5种效果演示

    很酷的菜单-jQuery Wheel 环形菜单插件5种效果演示在线预览 下载地址 实例代码 <div class="container"> <!-- Top Na ...

  6. 一款效果精致的 jQuery 多层滑出菜单插件

    想要以用户友好的方式呈现多级菜单是件不容易的事情,而且还要跨浏览器兼容就更难了.Multi-Level Push Menu 这款 jQuery 插件提供了呈现这种菜单的解决方案,能够让你无限制的展示菜 ...

  7. Smint – 用于单页网站制作的 jQuery 导航菜单插件

    Smint 是一款用于实现单页风格网站的 jQuery 导航插件,包含两部分:固定在页面顶部的精美导航条和能够在你点击的时候自动滚动到对应内容的菜单按钮.Smint 使用非常简单,只有一个参数用于设置 ...

  8. 开发一个jQuery插件——多级联动菜单

    引言 开发中,有好多地方用到联动菜单,以前每次遇到联动菜单的时候都去重新写,代码重用率很低,前几天又遇到联动菜单的问题,总结了下,发现可以开发一个联动菜单的功能,以后想用的时候就方便多了.项目中每个页 ...

  9. jQuery插件——多级联动菜单

    jQuery插件——多级联动菜单 引言 开发中,有好多地方用到联动菜单,以前每次遇到联动菜单的时候都去重新写,代码重用率很低,前几天又遇到联动菜单的问题,总结了下,发现可以开发一个联动菜单的功能,以后 ...

随机推荐

  1. 2020.02.28 Linux 命令

    Cat   语法格式 cat [-AbeEnstTuv] [--help] [--version] fileName 参数说明: -n 或 --number:由 1 开始对所有输出的行数编号. -b ...

  2. LXML解析html代码和文件

    from lxml import etree text = """ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...

  3. C++代码书写规范——给新手程序员的一些建议

    代码就是程序员的面子,无论是在工作中在电脑上写程序代码还是在面试时在纸上写演示代码我们都希望写出整洁,优雅的代码.特别在工作中当我们碰到需要维护别人的代码,或者是多人参与一个项目大家一起写代码的时候, ...

  4. 线性表顺序存储_List

    #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include &q ...

  5. 2月送书福利:ASP.NET Core开发实战

    大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...

  6. spm_hrf

    a=spm_hrf(0.72); n1=MOTOR_taskdesign(1,:);cn1=conv(n1,a);plot(cn1); block design hrf

  7. 「CH6801」棋盘覆盖

    「CH6801」棋盘覆盖 传送门 考虑将棋盘黑白染色,两个都无障碍的相邻的点之间连边,边的容量都为1,然后就求一次最大匹配即可 参考代码: #include <cstring> #incl ...

  8. 从零开始编写IntelliJ IDEA插件

    写Java代码的时候,经常会涉及到重复性的操作,这个时候就会想要是有这样一个插件就好了,如果是大家都会遇到的场景,IDE或许已经提供了,再不然也有可能有人编写了相关的插件.要是这个操作是你们的编码环境 ...

  9. 5.1 Nginx的基本配置

    备注:worker_processes 1(数量建议跟系统CPU的核数相同,例如:2个CPU,每个CPU4核,建议为8),worker_connections 建议小于worker_rlimit_no ...

  10. Eclipse传递main函数参数

    在项目上右击 Run As->Run Configurations...->Arguments->在Program arguments:的文本框中输入你要传入的参数,若有几个参数则在 ...