标题：Z-GIS
Z-GIS简介
Z-GIS框架Z-GIS是一个企业级的通用插件式GIS应用程序框架，Z-GIS框架能够从根本上解决架构稳定性和需求多变性之间的矛盾。
Z-GIS框架不仅仅支持二次开发，还支持二次设计。Z-GIS系列软件就是在Z-GIS统一框架的基础上进行构建（设计、开发）的。
Z-GIS框架完全可以应用于任何领域、任何类型、任何规模、甚至任何开发语言的GIS产品（或项目），同时不需要对Z-GIS框架本身做任何改动。基于Z-GIS框架进行产品（线）开发，将大大减少开发的工作量。我们会提供相应的开发源码来验证、说明Z-GIS统一框架基本特性。
在Z-GIS框架安装程序中，暂时只提供Z-GIS框架在国土行业的应用范例及C#(.NET)开发范例源码，如需要其他语言的开发范例源码请联系作者！基于Z-GIS框架进行产品开发需要符合COM规范，但也并非必须完全符合COM规范。Z-GIS框架的运行环境Z-GIS框架是基于某个特定的GIS平台而构建的高级的、企业级应用框架；所以，Z-GIS框架运行环境取决特定的GIS平台。如：如果是基于ESRI公司的ArcEngine构建的Z-GIS框架，那么它的运行环境则是Windows + ArcEngine；如果是基于超图的GIS平台构建的Z-GIS框架，那么它的运行环境则是Windows + 超图的GIS环境。Z-GIS的名称由来Z-GIS框架由周健设计并加以实现。Z就是周汉语拼音的首字母。Z-GIS的设计思想Z-GIS的设计思想是封装变化部分，固化稳定部分；严格遵循开闭原则，针对接口编程；做到底层实现依赖高层抽象。
封装变化主要是指针对业务组件部分的封装，让业务组件部分可以独立演化而不影响其他部件，从而保证软件的高内聚低偶合； 固化稳定部分主要是指框架本身的稳定性，稳定的部分应该固化从而最大限度的保证软件的稳定性。
开闭原则是指对扩展开放、修改关闭；针对接口编程（即针对抽象编程），可以从很大程度上保证软件对开闭原则的遵循。
要做到底层实现依赖高层抽象，是因为底层业务逻辑的实现往往和用户的需求密切相关；用户的需求是多变的，因而底层的实现是多变的、在稳定性方面是非常脆弱的。高层抽象主要指两个方面，一是指框架，框架位于系统的最高层，其和用户的需求没有直接关系；二是指框架提供的接口，框架提供的接口除了用于实现系统必要功能以外，便主要是用于扩展，这些和用户的需求也没有直接的关系；因此，高层抽象部分应该是稳定的。所以，从总体上保证底层实现依赖高层抽象，是保证软件设计合理性的重要手段之一。
Z-GIS接口
顶级接口由Z-GIS框架直接提供的主要接口如下：
IZhoujianApplication
IZhoujianCommand 该接口继承于ICommand接口。
IZhoujianTool 该接口继承于ITool接口。
IZhoujianControl 该接口用于实现任意复杂控件在界面中显示，实现该接口必须要实现IZhoujianCommand。
IZhoujianStartForm
IZhoujianProgressBar
IZhoujianStatusBar间接接口Z-GIS是支持二次设计的，在Z-GIS二次设计时设计的接口称为间接接口：如在国土行业的应用范例中，对Z-GIS进行了二次设计。在二次设计中，设计了一个通用的（反馈）消息的组件，该组件对应的接口是IZhoujianMessageBox。类似的接口还有IZhoujianCJCommandLine、IZhoujianCJParameter、IZhoujianLayerControl、IZhoujianDatasource等等。间接接口的使用所有的间接接口都是要注册到Z-GIS框架中的，注册过程是可视化的。对于已经注册在Z-GIS系统中的间接接口的使用方法是：通过调用IZhoujianApplication接口提供的方法（函数）先获取相应的接口，再使用相应的接口提供方法（或属性）。
Z-GIS二次开发范例(C#)
创建启动画面基于Z-GIS框架进行二次开发时，可以根据产品（或项目）的需求，灵活创建个性化的启动界面。创建个性启动界面只要实现IZhoujianStartForm接口即可。范例如下：（注本功能代码为Delphi实现，其他均为C#）
unit unt_ZhoujianCJStartFormIMP;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, ActiveX, Classes, ComObj, ZhoujianCJ_TLB, StdVcl,
zhoujianUI_Tlb, forms, frm_CJForm;
type
TCJStartForm = class(TTypedComObject, IZhoujianStartForm)
protected
function Show: HResult; stdcall;
function Close: HResult; stdcall;
function SendMessage(const MessageInfo: WideString): HResult; stdcall;
function Get_Description(out Value: WideString): HResult; stdcall;
private
frm: TfrmCJForm;//定义一个窗体，作启动画面用
end;
implementation
uses ComServ;
//返回本启动画面的描述信息
function TCJStartForm.Get_Description(out Value: WideString): HResult;
begin
Value := '采集子系统启动画面(Z-GIS系列软件)'
end;
//向启动画面发送当前程序正在启动的相应信息
function TCJStartForm.SendMessage(const MessageInfo: WideString): HResult;
begin
frm.lblinfo.Caption := MessageInfo;
Application.ProcessMessages;
end;
//程序启动后，做销毁操作
function TCJStartForm.Close: HResult;
begin
frm.Free;
frm := nil;
end;
//显示启动画面
function TCJStartForm.Show: HResult;
var
L, T, H, V: Longint;
begin
frm := TfrmCJForm.Create(Application);
H := GetSystemMetrics(SM_CXSCREEN);
V := GetSystemMetrics(SM_CYSCREEN);
L := Round((H / 2)) - Round((frm.Width / 2));
T := Round((V / 2)) - Round((frm.Height / 2));
frm.Left := L;
frm.Top := T;
AnimateWindow(frm.Handle, 1000, AW_CENTER);
AnimateWindow(frm.Handle, 400, AW_CENTER + AW_HIDE);
AnimateWindow(frm.Handle, 300, AW_CENTER);
end;
initialization
TTypedComObjectFactory.Create(ComServer, TCJStartForm, Class_CJStartForm,
ciMultiInstance, tmApartment);
end.创建用户登录模块对于一般的管理信息系统而言，都会有用户登录模块（即完成用户登录，验证用户合法性的功能）。对于GIS类型的信息系统来说，用户登录模块也是必不可少的。基于Z-GIS框架进行二次开发要增加这样的一个功能，是通过Z-GIS中间件来实现的；在Z-GIS框架中只要实现一个IZhoujianMidWare接口即可完全这样的功能。具体代码如下：
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ZhoujianUI; 
using System.Windows.Forms;  
namespace UserLoginSpace
{
[Guid("3308ca48-c67e-4ed9-a283-d6b66fd66ab3")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MDataSource.Class1")]
public class UserLoginIMP : IZhoujianMidWare, IUserInfo 
{
private IZhoujianApplication mApp = null; 
private IUserInfo mUserInfo = null;
private string _UserDepartment,_UserName;
//假设IUserInfo接口只有两个元素，分别是UserName,UserDepartment，表示用户名和所属部门 
#region IUserInfo 成员
public string UserName
{
get { return _UserName; }
}
public string UserDepartment
{
get { return _UserDepartment; }
}
#endregion  
#region IZhoujianMidWare 成员
public string Name
{
get { return "User Login"; }
}
public void OnCreate(IZhoujianApplication ZApplication)
{
//首先，让用户进行认证, frmLogin是一个已经存在的窗体，作用户登录界面
mUserInfo = this as IUserInfo;
frmLogin frm = new frmLogin(mUserInfo);
if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{   //通过认证
mApp = ZApplication; 
//通过验证以后，可能会根据针对不同用户进行不同的初始化操作
//在此处添加业务代码
//最后在应用程序的状态栏上显示当前登录的用户信息
mApp.StatusBar.setValue(1,string.format("用户名：{0}      部门：   {1}",mUserInfo.UserName,mUserinfo.UserDepartmen));
}
else
{   //否则，结束应用程序 
ZApplication.Quit();
}
} 
public object get_MidWare(string UniqueName)
{   //在实际的应用中可能要根据UniqueName参数的情况不同而返回不同的值，这里只返回了用户信息
//本例中，对于其他模块还可以通过接口查询操作来获取用户信息，但Z-GIS推荐使用本方法。
return mUserInfo;
}
#endregion
} 
}创建命令创建命令只要实现IZhoujianCommand接口即可，代码如下：
//第一步：首先是引用相关的命名空间
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ZhoujianUI;
namespace CommandDEmo
{
[Guid("d21d37d1-2599-4ce4-a555-4c079071b86f")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CommandDEmo.Class_CommandDEmo")]
//借助相应的类来实现IZhoujianCommand
public class CommandDemoIMP: IZhoujianCommand
{
#region IZhoujianCommand 成员
/// <summary>
/// 设置命令按钮的图标
/// </summary>
public int Bitmap
{
get
{
return Resource1.forCommand.GetHbitmap().ToInt32();//注意一定要是Bitmap Handle
}
}
//设置命令按钮标题
public string Caption
{
get {  return "demo Command"; }
}
public string Category
{
get { return "Demo"; }
}
public bool Checked
{
get { return false; }
}
public bool Enabled
{
get { return true; }
}
public int HelpContextID
{
get { throw new NotImplementedException(); }
}
public string HelpFile
{
get { throw new NotImplementedException(); }
}
public string Message
{
get { return "【demo】创建命令按钮！"; }
}
public string Name
{
get {return "command demos"; }
}
int i = 0;
//命令被点击时，要执行相关操作的入口
public void OnClick()
{
MessageBox.Show("我被点了"+ ++i+"下！！！") ;
}
public void OnCreate(object hook)
{ //这里可以加入初始化时要做的操作
//hook 可以通过强制类型转换成IZhoujianApplication
}
public string Tooltip
{//这是命令按钮的提示信息
get { return Message; }
}
#endregion
}
}创建地图交互工具//创建命令除了要实现IZhoujianCommand接口，同时还要实现IZhoujianTool接口，IZhoujianTool定义了所有与地图交互操作的方法。代码如下：
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ZhoujianUI;
using System.Windows.Forms;
namespace ToolEDemo
{
[Guid("ca5fc134-a474-450f-89d3-f210cacce31c")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ToolEDemo.Class1")]
public class DemoToolIMP: IZhoujianCommand,IZhoujianTool
{
ContextMenuStrip mPopMenu =null;
IZhoujianApplication mApp = null;
#region IZhoujianTool 成员
public int Cursor
{
get
{
return Resource1.forCursor.Handle.ToInt32();
}
}
/// <summary>
/// 当激活其他工具时…………
/// </summary>
/// <returns></returns>
public bool Deactivate()
{
mApp.StatusBar.SetValue(1, "");
return true;
}
public bool OnContextMenu(int x, int y)
{
if (mPopMenu != null) mPopMenu.Show(x, y);
return true;
}
public void OnDblClick()
{
MessageBox.Show("在地图上双击了一次！");
}
public void OnKeyDown(int keyCode, int shift)
{
//MessageBox.Show("OnKeyDown");
}
public void OnKeyUp(int keyCode, int shift)
{
//MessageBox.Show("OnKeyUp");
}
/// <summary>
///
/// </summary>
/// <param name="button"></param>
/// <param name="shift"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public void OnMouseDown(int button, int shift, int x, int y)
{
//MessageBox.Show("OnMouseDown");
}
/// <summary>
/// 处理鼠标在地图上移动时的事件
/// </summary>
/// <param name="button"></param>
/// <param name="shift"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public void OnMouseMove(int button, int shift, int x, int y)
{  
mApp.StatusBar.SetValue(1, string.Format("正在移动鼠标，位置X={0};Y={1}【注：是屏幕坐标】",x,y));
}
public void OnMouseUp(int button, int shift, int x, int y)
{
//MessageBox.Show("OnKeyDown");
}
public void Refresh(int hdc)
{
//该方法高级操作才会用到
}
#endregion
#region IZhoujianCommand 成员
public int Bitmap
{
get
{
return Resource1.forCommand.ToBitmap().GetHbitmap().ToInt32();//注意：返回的必须是bitmap handle
}
}
public string Caption
{
get { return "Tool例"; }
}
public string Category
{
get { return "工具"; }
}
public bool Checked
{
get { return false; }
}
public bool Enabled
{
get { return true; }
}
public int HelpContextID
{
get { throw new NotImplementedException(); }
}
public string HelpFile
{
get { throw new NotImplementedException(); }
}
public string Message
{
get { return "这是一个鼠标与地图进行交互的范例！" ; }
}
public string Name
{
get { return "tool demox"; }
}
public void OnClick()
{
}
public void OnCreate(object hook)
{
mApp = hook as IZhoujianApplication;
InitializePopMenu();
}
/// <summary>
/// 初始快捷菜单
/// （如果，不熟悉通过代码进行快捷菜单的初始化，可以在窗体设计器中进行相应操作及设计  ）
/// </summary>
private void InitializePopMenu()
{
if (mPopMenu == null) mPopMenu = new ContextMenuStrip();
mPopMenu.Items.Add("第1项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第2项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第3项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第4项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第5项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第6项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第7项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第8项").Click += new EventHandler(DemoToolIMP_Click);
}
/// <summary>
/// 处理快捷菜单事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void DemoToolIMP_Click(object sender, EventArgs e)
{
MessageBox.Show((sender as ToolStripItem).Text + ",被点了！");
}
public string Tooltip
{
get { return Message; }
}
#endregion
}
}创建Combobox下拉框//在工具栏上创建下拉框除了要实现IZhoujianCommand接口，同时还要实现IZhoujianControl接口，IZhoujianControl接口只定义了一个方法，用于返回可视化Windows控件的句柄。代码如下：
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ZhoujianUI;
namespace ComboboxDemo
{
[Guid("191e0060-f725-4144-ac16-0bbae7571a36")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ComboboxDemo.Class1")]
public class ComboBoxIMP: IZhoujianCommand, IZhoujianControl
{
IZhoujianApplication mApp = null;
ComboBox mCbx = new ComboBox();
#region IZhoujianControl 成员
public int WinControlHandle
{
get { return mCbx.Handle.ToInt32(); }
}
#endregion
#region IZhoujianCommand 成员
public int Bitmap
{
get { return -1; }
}
public string Caption
{
get { return "ComboBox"; }
}
public string Category
{
get { return "控件案例"; }
}
public bool Checked
{
get {  return false; }
}
public bool Enabled
{
get { return true; }
}
public int HelpContextID
{
get { throw new NotImplementedException(); }
}
public string HelpFile
{
get { throw new NotImplementedException(); }
}
public string Message
{
get { return "这是一个在工具栏上新增ComboBox范例。"; }
}
public string Name
{
get { return "combexTest"; }
}
public void OnClick()
{
//这个方法不会被使用到
}
public void OnCreate(object hook)
{
mApp = hook as IZhoujianApplication;
initializeCombobox();
}
/// <summary>
/// 初始化Combobox
/// 并增加items  增加事件
/// </summary>
private void initializeCombobox()
{
if (mCbx == null) mCbx = new ComboBox();
mCbx.Items.Add("第一项");
mCbx.Items.Add("第二项");
mCbx.Items.Add("第三项");
mCbx.Items.Add("第四项");
mCbx.Items.Add("第五项");
mCbx.Items.Add("第六项");
mCbx.MouseEnter += new EventHandler(mCbx_MouseEnter);
mCbx.MouseLeave += new EventHandler(mCbx_MouseLeave);
mCbx.SelectedValueChanged += new EventHandler(mCbx_SelectedValueChanged);
}
/// <summary>
/// 当ComboBox选项改变的时候，将其当前值在程序标题栏上显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void mCbx_SelectedValueChanged(object sender, EventArgs e)
{
mApp.Caption = mCbx.SelectedItem.ToString();
MessageBox.Show("您选择了【"+mCbx.SelectedItem.ToString()+"】");
}
/// <summary>
/// 清除任务栏上 提示信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void mCbx_MouseLeave(object sender, EventArgs e)
{
mApp.StatusBar.SetValue(0, "");
}
/// <summary>
/// 在任务栏上显示 提示信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void mCbx_MouseEnter(object sender, EventArgs e)
{
mApp.StatusBar.SetValue(0, Tooltip);
}
public string Tooltip
{
get { return "这是一个在工具栏上新增ComboBox范例。"; }
}
#endregion
}
}创建任意复杂控件在菜单或工具栏中创建任意复杂控件的方法同创建Combobox类似，只要在IZhoujianControl的   public int WinControlHandle  中返回任意复杂控件的句柄即可。代码如下：
public int WinControlHandle
{
get {
return hComplexHandle; //hComplexHandle为任意复杂控件的句柄
}
}二次开发高级功能由于高级功能比较复杂（会涉及二次设计、多个模块间的通信及模块的依赖关系），所以代码会非常的多。如要了解二次开发高级功能，可以安装Z-GIS框架程序，其中包含少量二次开发的高级功能。