ArcMap下停靠欄的設計與實現

來源:互聯網
上載者:User

        ArcMap 9.3下的UI風格著實比較粗糙,和國內很多軟體UI相比汗顏呀,但是ArcMap在GIS編輯上的重要性是不言而喻的,最近想試著深入一下ArcMap的定製。ArcMap的可定製部分,無外乎菜單,工具列,以及停靠欄,前二者,一般使用者可能都接觸過,例子也比較多,各種語言和代碼都能找到,停靠欄在網上也能找到,VBA和C#比較多,但是C++開發的代碼沒有,原因是嵌入表單到停靠欄中不容易實現。

       在開發自訂的停靠欄之前,說說停靠欄能幹嗎用。在ArcMap中,TOC控制項就是用得最多的停靠欄,還有品質檢查控制項也是停靠欄。如果使用者互動中涉及的屬性與圖形顯示非常相關,強烈建議採用停靠欄的方式,例如在質檢過程,如果非常多的資訊需要通過圖形關係來判斷,開啟屬性工作表的方式並不是特別方便,應為屬性工作表和Map容易相互遮蓋影響互動,特別是在大資料量的情況下互動非常彆扭。

       話題涉及到如何開發,很多人在網上問到如何開發,特別是採用C++開發,事實上用C++開發很不容易,因為你需要精確的控制非模式化視窗的每個過程,從建立到銷毀都需要手工控制。

      因為9.3的後續版本下(10.0,10.1),ArcMap的風格完全改變到了,風格類似office2007,可能一定程度上會打消9.3下一部分使用者的開發需求。但是接觸了很多使用者後,我發現大部分使用者,仍然習慣9.3,而且9.3的使用者也巨大。

     開始停靠欄的開發,我們需要準備好開發環境,vc6,ArcMap9.3。如果熟悉ATL更好。

1、準備一個測試案例,我做得很簡單,就是一個Command用於啟用停靠欄

STDMETHOD(OnClick)(){HRESULT hr;IDockableWindowManagerPtr ipDockableWindowManager;                  ipDockableWindowManager=m_ipDispatch;IUIDPtr ipUID(CLSID_UID);hr=ipUID->put_Value(CComVariant("{F884D1F0-C82F-40F1-A2EB-359D51F635F7}"));IDockableWindowPtr ipDockableWindow;//執行個體化停靠欄組件hr=ipDockableWindowManager->GetDockableWindow(ipUID,&ipDockableWindow);                  VARIANT_BOOL varVisual;          hr=ipDockableWindow->IsVisible(&varVisual);         //if (varVisual==VARIANT_TRUE){   //得到當前停靠欄的大小IWindowPositionPtr ipWindowPosition;                            ipWindowPosition=ipDockableWindow;long width;long height;hr=ipDockableWindow->Show(VARIANT_TRUE);hr=ipDockableWindow->Dock(esriDockBottom);hr=ipWindowPosition->get_Width(&width);hr=ipWindowPosition->get_Height(&height);}return S_OK;}

2、擴充IDockableWindowDef

STDMETHOD(OnCreate)(IDispatch * hook){//傳遞IApplication;        HRESULT hr;        IApplicationPtr ipApplication;        ipApplication=hook;OLE_HANDLE AppOLEHandle;hr=ipApplication->get_hWnd(&AppOLEHandle);    HWND hwnd=(HWND)AppOLEHandle;        m_TableForm.Create(hwnd,(LPARAM)(hook));       // m_TableForm.Create(hwnd);        ATLTRACE("\n***建立視窗\n");return S_OK;}

3、建立自己的視窗組件

4、添加自己的屬性列表

屬性列表是放在屬性頁面中的,屬性頁面被嵌入到每個Tab control中,

        LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
         m_ipDispatch=(IDispatch * )lParam;         if(m_ipDispatch==NULL)           return 0;         USES_CONVERSION;   HRESULT hr;   //添加tab頁   //path From dll      TCHAR szFullPathName[_MAX_PATH];   GetModuleFileName((HMODULE)(_Module.m_hInst),szFullPathName,_MAX_PATH);   TCHAR drive[_MAX_DRIVE];   TCHAR dir[_MAX_DIR];   TCHAR fname[_MAX_FNAME];   TCHAR ext[_MAX_EXT];   _wsplitpath(szFullPathName, drive, dir, fname,ext);   TCHAR szPathOfMdb[_MAX_PATH];   wcscpy(szPathOfMdb,drive);   wcscat(szPathOfMdb,dir);   wcscat(szPathOfMdb,_T("diyingli.mdb"));   CComBSTR bstrPathOfmdb=szPathOfMdb;          //Open mdb   IWorkspaceFactoryPtr ipWSF(CLSID_AccessWorkspaceFactory);   IWorkspacePtr ipWorkspace;   hr=ipWSF->OpenFromFile(bstrPathOfmdb,NULL,&ipWorkspace);   if (FAILED(hr))   {       ::MessageBox(NULL,_T("沒有找到地應力資料庫"),_T("錯誤"),MB_ICONERROR);       return 1;   }            //開啟資料庫載入空間資料表格   //esriDTTable   IStringArrayPtr ipStringArray(CLSID_StrArray);   IEnumDatasetNamePtr ipEnumDatasetName;            hr=ipWorkspace->get_DatasetNames(esriDTTable,&ipEnumDatasetName);   hr=ipEnumDatasetName->Reset();   IDatasetNamePtr ipDatasetName;   while (!ipEnumDatasetName->Next(&ipDatasetName))   {   CComBSTR bstrName;           hr=ipDatasetName->get_Name(&bstrName);   hr=ipStringArray->Add(bstrName);   }   long lStrCount;   hr=ipStringArray->get_Count(&lStrCount);           HWND hwnd=GetDlgItem(IDC_TAB1);   //Get Name and table Info from gdb   for (long i=0;i<lStrCount;i++)   {      CComBSTR bstrItemName;   hr=ipStringArray->get_Element(i,&bstrItemName);   TCITEM tci;   tci.mask = TCIF_TEXT;   tci.pszText =OLE2T(bstrItemName);   tci.cchTextMax = wcslen(OLE2T(bstrItemName)) + 1;   tci.iImage = -1;   tci.lParam = 0;   TabCtrl_InsertItem(hwnd,i,&tci);               //Add table to tab control   ITablePtr ipTable;   IFeatureWorkspacePtr ipFWS;                     ipFWS=ipWorkspace;   hr=ipFWS->OpenTable(bstrItemName,&ipTable);                      //添加屬性頁面                         AddTableToTabControl(ipTable,hwnd);   }        //發送訊息TCN_SELCHANGE          // 設定Tab第一項屬性頁面為可顯示   NMHDR   nmhdr;    nmhdr.code = TCN_SELCHANGE;          nmhdr.hwndFrom = hwnd;          nmhdr.idFrom=IDC_TAB1;          ::SendMessage(hwnd,WM_NOTIFY,MAKELONG(TCN_SELCHANGE,0),(LPARAM)(&nmhdr)); 
return 1;  // Let the system set the focus
}

 

最後的效果就是下面的圖了。

 

     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.