首頁

2013年8月30日 星期五

*MSDN Library*逐步解說~移植現有原生C++ 應用程式使其與 .NET Framework 元件互通**

*MSDN Library*逐步解說~移植現有原生C++ 應用程式使其與---
--- .NET Framework 元件互通**

**在本逐步解說中,您將會用 MFC 建立預訂機票的應用程式,
然後再將其升級為以 .NET Framework 為目標,並使用 Managed Extensions 
 for C++。
MFC 應用程式會處理預訂的工作。使用者介面為 MFC 應用程式,
其引擎是由包含公司差旅規定的 Helper 函式的 DLL (原生 C++) 和處理---
---預訂機位的 COM 物件 (原生 C++) 所構成  **
*注意   若要建立本逐步解說中所描述的應用程式,您必須能夠存取已經---
---安裝 Pubs 或 Northwind 資料庫的資料庫伺服器                           *
**
*在本逐步解說中,您將會           :    
*
  • 建立 MFC 應用程式,並用 Managed Extensions for C++ 來修改。
  • 將應用程式轉換為 Managed 程式碼,並以 /clr 編譯器選項來編譯。
  • 使用 Windows Form 來取代 MFC 使用者介面。
  • 連接到 SQL Server 資料庫,以取得公司所有員工的清單。
  • 將預留機位引擎類別移植到 Managed 類別。
  • 建立新的 Managed 組件,以便與預訂用的 COM 物件互通             *
  • **在您完成本逐步解說後,架構看起來會很像下列圖表:                   
    *應用程式完成後的架構                                 : 
    ***
    *建立 MFC 應用程式
    在本章節中,您將建立具有三個專案 (MFC、ATL COM 和 MFC DLL)---
    --- 的原生 C++ MFC 應用程式,稱之為 ReservationDemo
    然後您可以在後面各章節中再對其進行修改                                    *
    **若要建立 MFC 專案**
    *
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。
      出現 [新增專案] 對話方塊。
    2. 在 [專案類型] 窗格中按一下 [Visual C++ 專案],然後再按一下 [MFC]。
    3. 在 [範本] 窗格中按一下 [MFC 應用程式]。在 [名稱] 欄位中輸入 ReservationDemo
    4. 然後按一下 [確定]。 出現 MFC 應用程式精靈。
    5. 按一下 [應用程式類型],然後選取 [對話方塊架構]。按一下 [完成]。
    6. 在 [類別檢視] 中用滑鼠右鍵按一下專案節點。在快速鍵功能表上
    7. 按一下 [加入],然後再按一下 [加入類別]。 出現 [加入類別] 對話方塊。
    8. 在 [類別] 窗格中展開 [Visual C++ 專案] 資料夾,然後再按一下 [泛用] 資料夾。
    9. 按一下 [開啟]。 出現泛用 C++ 類別精靈。
    10. 輸入 CEmployee 做為泛用 C++ 類別名稱。這是沒有基底類別的公用類別。
    11. 重複執行步驟 4 和 5,以建立泛用 C++ 類別 CReservation    
    *若要建立 ATL COM 專案 *
    *
    1. 在 [方案總管] 中用滑鼠右鍵按一下方案節點。在快速鍵功能表上按一下  [加入],
    2. 然後再按一下 [新增專案]。 出現 [加入新的專案] 對話方塊。
    3. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下  [ATL]。
    4. 在 [樣板] 窗格中,按一下 [ATL 專案]。在 [名稱] 欄位中輸入 BookingObject
    5. 然後選取 [加入至方案]。按一下 [確定]。 ATL 專案精靈就會出現。
    6. 按一下 [完成] 以接受預設值。
    7. 在 [類別檢視] 中用滑鼠右鍵按一下專案節點。在快速鍵功能表中按一下  [加入],
    8. 然後再按一下 [加入類別]。 出現 [加入類別] 對話方塊。
    9. 在 [類別] 窗格中展開 [Visual C++ 專案] 資料夾,然後再按一下   [ATL] 資料夾。
    10. 選取 [ATL 簡單物件] 並按一下 [開啟]。 出現 ATL 簡單物件精靈。
    11. 在 [簡短名稱] 欄位輸入 Booking,再按一下 [確定]。
    12. 在 [方案總管] 中連按兩下 Booking.h,將粗體字所示的程式碼加入 IBooking 
    __interface IBooking : IDispatch
    {
       [id(1), helpstring("method Reserve")] HRESULT Reserve(void);
       [id(2), helpstring("method NewBooking")] HRESULT NewBooking([in]
       BSTR fromCity, [in] BSTR toCity, [in] BYTE day, [in] BYTE month);
       [id(3), helpstring("method CheckAvailability")] HRESULT
       CheckAvailability([out,retval] BYTE* result);
    };                                                               

    8).在 Booking.h 中,將粗體字所示的程式碼加入 CBooking 宣告的結尾:
    class ATL_NO_VTABLE CBooking : public IBooking
    {
    ...
    public:
       STDMETHOD(Reserve)(void);
       STDMETHOD(NewBooking)(BSTR fromCity, BSTR toCity, BYTE day,
       BYTE month);
       STDMETHOD(CheckAvailability)(BYTE* result);
    private:
       CString from;
       CString to;
       int day;
       int month;
    }                                      

    **若要建立 MFC DLL 專案**
    1. 在 [方案總管] 中,用滑鼠右鍵按一下方案節點。在快速鍵功能表中按一下 [加入],
    2. 然後再按一下 [新增專案]。
      出現 [加入新的專案] 對話方塊。
    3. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下 [MFC]。
    4. 在 [樣板] 窗格中,按一下 [MFC DLL]。在 [名稱] 欄位中輸入 TravelPolicy
    5. 再選取 [加入至方案]。請按一下 [確定]。 會出現 MFC DLL 精靈。
    6. 按一下 [完成] 以接受預設值        .
    *將 Unmanaged 程式碼轉換為 Managed 程式碼*
    *在本章節中,您會將現有原生 C++ MFC 應用程式 ReservationDemo 轉換--
    --為 Managed 程式碼,再用 /clr 編譯器選項來編譯  .
    *若要使用 /clr 編譯器選項來編譯*
    1. 在 [方案總管] 中,用滑鼠右鍵按一下 [ReservationDemo],再按一下 [屬性]。
      [屬性頁] 對話方塊就會出現。
    2. 展開 [C/C++] 節點。
    3. 在 [命令列] 中,請於 [其他選項] 方塊中輸入 /clr
    4. 在 [程式碼產生] 中,將 [基礎 Runtime 檢查] 設為 [預設值],
    5. 並將 [啟用最少重建] 設為「否」。
    6. 在 [一般] 中選取 [偵錯資訊格式],並將它變更為 [程式資料庫 (/Zi)]。
    7. 按一下 [確定],關閉這個對話方塊。
    8. 在 [建置] 功能表上,按一下 [建置方案]。
    9. 在 [偵錯] 功能表上,按一下 [啟動但不偵錯]。
    *在本章節中,您將在預留機位引擎內建立新的 Managed 類別名為 CFlight
    CFlight 將處理航班資訊,並使用 Unmanaged CReservation 類別來處理實際的預留機位
    為了讓 Managed 類別能夠和 Unmanaged 類別互動,
    您必須為 Unmanaged 類別另外使用 Managed 包裝函式 (CReservationWrapper).  **

    **若要建立 Managed 包裝函式類別**
    1. 在 [類別檢視] 中,用滑鼠右鍵按一下 [ReservationDemo] 專案節點。
    2. 在快速鍵功能表中按一下 [加入],然後再按一下 [加入類別]。 出現加入類別精靈。
    3. 選取 [泛用 C++ 類別],並輸入 CReservationWrapper 做為類別名稱。按一下 [完成]。
    4. 在 ReservationWrapper.h 中加入下列 #include 陳述式:   
    #include "Reservation.h"               

    5).在 ReservationWrapper.h 中將下列成員加入至類別:      
    CReservation * r;
    int Reserve(void);

    6).在 ReservationWrapper.cpp 中,以下列程式碼來取代檔案的全部內容:
    #include "StdAfx.h"
    #include ".\reservationwrapper.h"
    #using <mscorlib.dll>

    using namespace System;
    using namespace System::Runtime::InteropServices;

    CReservationWrapper::CReservationWrapper(void)
    {
       System::String * strFrom = S"from";
       System::String * strTo = S"to";

       CString csFromCity ((char*)(void*)
    Marshal::StringToHGlobalAnsi(strFrom));
       CString csToCity ((char*)(void*)
    Marshal::StringToHGlobalAnsi(strTo));

       r = new CReservation(&csFromCity, &csToCity, 17,1,2,2);
    }

    CReservationWrapper::Reserve()
    {
       int res = r->Reserve();
       return res;
    }

    CReservationWrapper::~CReservationWrapper(void)
    {
       delete r;
    }

    5*若要建立 Managed 類別*
    1. 在 [類別檢視] 中,用滑鼠右鍵按一下 [ReservationDemo] 專案節點。
    2. 在快速鍵功能表中按一下 [加入],然後再按一下 [加入類別]。 出現加入類別精靈。
    3. 選取 [泛用 C++ 類別],再輸入 CFlight 做為類別名稱。按一下 [完成]。
    4. 將 Flight.h 中的類別定義修改成如下所示
    __gc class CFlight
    {
    public:
       CFlight();
       void Reserve();
    };

    5).在 Flight.cpp 中,以下列程式碼來取代檔案的全部內容:  
    #include "StdAfx.h"
    #include "Flight.h"
    #include "ReservationWrapper.h"
    #using <mscorlib.dll>

    CFlight::CFlight(void)
    {
    }

    void CFlight::Reserve()
    {
       CReservationWrapper *res = new CReservationWrapper();
       res->Reserve();
    }
    若要修改 CEmployee 以使用 CFlight
    1).在 Employee.cpp 中加入下列 #include 陳述式:    
    #include <vcclr.h>
    #include "Flight.h"

    2).在 Employee.cpp 中,修改 MakeReservation 的實作以執行---
    ---個體化 CFlight 物件為如下所示 (粗體字程式碼代表變更處)。
    請注意程式碼如何使用 gcroot 來包含 Managed 類別:
    int CEmployee::MakeReservation (CString *from, CString *to, int day1,
    int month1, int day2, int month2)
    {
       gcroot<CFlight*> flight;
       flight->Reserve();
    }

    3).在 Reservation.cpp 中,將 Reserve 實作中的 if 陳述式修改為如下所示
     (粗體字程式碼代表變更處):    
    if (b->CheckAvailability())
    {
       b->Reserve();
       return res;
    }
    else
       return res + 10;
    }

    4).在 [方案總管] 中,用滑鼠右鍵按一下 [ReservationDemo] 專案節點

    5).
    1. 在快速鍵功能表上,按一下 [建置]。
    在本章節中,您將建立一個 DLL 來為兩個新的 XML Web Service (EmployeeCodesEmployeeData) 提供員工資訊以用來擷取員工的資訊。
    第一個服務會取得員工 ID 的資訊;第二個服務則會取得員工的其他資料。
    這兩個服務都會使用 IJW 呼叫一個原生 DLL (EmployeeDLL) 以取得所需資訊。
    若要建立 EmployeeDLL 原生 C++ DLL 以提供員工資訊
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。
    2. 出現 [新增專案] 對話方塊。
    3. 在 [專案類型] 窗格中,按一下 [Visual C++ 專案],然後在 [範本] 窗格中,
    4. 按一下 [Win32 專案]。在 [名稱] 方塊中輸入 EmployeeDLL
    5. 再選取 [加入至方案]。按一下 [確定]。
    6. 修改 EmployeeDLL.cpp 檔中的程式碼   
    #include "StdAfx.h"

    extern "C" __declspec(dllexport) int EmployeeID(LPSTR name)
    {
       return (int) *name;
    }

    BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call,
    LPVOID lpReserved)
    {
       return TRUE;
    }

    4).
    1. 在 [方案總管] 中,用滑鼠右鍵按一下專案。在快速鍵功能表上,按一下 [建置]。
    若要建立 EmployeeCodes XML Web Service
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。 出現 [新增專案] 對話方塊。
    2. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下 [.NET]。
    3. 在 [樣板] 窗格中按一下 [ASP.NET Web 服務]。
    4. 在 [名稱] 欄位中輸入 EmployeeCodes,再選取 [加入至方案]。按一下 [確定]。
    5. EmployeeCodesClass.h 會出現在 [設計] 檢視中。用滑鼠右鍵按一下 [設計工具],
    6. 並在快速鍵功能表中按一下 [檢視程式碼]。
    7. EmployeeDataClass.h 會出現在 [編輯] 檢視中。
    8. 以下列程式碼來取代 EmployeeCodesClass.h 中的全部內容:  
    // EmployeeCodesClass.h

    #pragma once

    using namespace System;
    using namespace System::Web;
    using namespace System::Web::Services;

    namespace EmployeeCodes
    {
       public __gc
       class EmployeeCodesClass : public WebService
       {

       public:

          [System::Web::Services::WebMethod]
          int  EmployeeLevel(String* name);
       };
    }

    5).以下列程式碼來取代 EmployeeCodesClass.cpp 中的全部內容:   
    // EmployeeCodesClass.cpp

    #include "StdAfx.h"
    #include "EmployeeCodesClass.h"
    #include "Global.asax.h"

    using namespace System::Runtime::InteropServices;

    [DllImport("EmployeeDLL", CharSet=CharSet::Ansi)]
    extern "C" int EmployeeID(String* name);

    namespace EmployeeCodes
    {
       int  EmployeeCodesClass::EmployeeLevel(String* name)
       {
          return EmployeeID(name);
       }
    };

    若要建立 EmployeeData XML Web Service
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。 出現 [新增專案] 對話方塊。
    2. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下 [.NET]。
    3. 在 [樣板] 窗格中按一下 [ASP.NET Web 服務]。
    4. 在 [名稱] 欄位中輸入 EmployeeCodes,再選取 [加入至方案]。按一下 [確定]。
    5. EmployeeDataClass.h 會出現在 [設計] 檢視中。用滑鼠右鍵按一下 [設計工具],
    6. 並在快速鍵功能表中按一下 [檢視程式碼]。
    7. EmployeeDataClass.h 會出現在 [編輯] 檢視中。
    8. 以下列程式碼來取代 EmployeeDataClass.h 中的全部內容:      
    // EmployeeDataClass.h

    #pragma once

    using namespace System;
    using namespace System::Web;
    using namespace System::Web::Services;

    namespace EmployeeData
    {
       public __gc
       class EmployeeDataClass : public WebService
       {

       public:
          [System::Web::Services::WebMethod]
          int EmployeeLadder(String* name);
       };
    }

    5).以下列程式碼來取代 EmployeeDataClass.cpp 中的全部內容:  
    // EmployeeDataClass.cpp

    #include "StdAfx.h"
    #include "EmployeeDataClass.h"
    #include "Global.asax.h"

    using namespace System::Runtime::InteropServices;

    [DllImport("EmployeeDLL", CharSet=CharSet::Ansi)]
    extern "C" int EmployeeID(String* name);

    namespace EmployeeData
    {
       int EmployeeDataClass::EmployeeLadder(String* name)
       {
          return EmployeeID(name);
       }

    };

    6).
    在 [建置] 功能表上,按一下 [建置方案]。這樣就把 XML Web Service 部署到本機電腦上。
    若要將 XML Web Service 的參考加入 MFC 應用程式
    1. 在 [方案總管] 中,用滑鼠右鍵按一下 [ReservationDemo] 專案。
    2. 在快速鍵功能表上按一下 [加入 Web 參考]。 [加入 Web 參考] 對話方塊就會出現。
    3. 按一下 [本機電腦上的 Web 服務],再選取 EmployeeCodes 的 XML Web Service。
    4. XML Web Service 說明會出現在對話方塊的主窗格中。按一下 [加入參考]。
    5. 針對 EmployeeData 重複執行步驟 1 至 3。
    6. 修改 Employee.cpp 以便搭配 XML Web Service 使用。加入下列 #include 陳述式:         
    #define __FLTUSED__
    #include "localhost.h"
    #include "localhost1.h"
      
      6).將 CEmployee 建構函式修改為如下所示 (粗體字程式碼代表變更處):   
    CEmployee::CEmployee(CString *name)
    {
       employeeName = *name;
       reservation = NULL;

       int res;

       localhost::EmployeeCodesClass *c = new
    localhost::EmployeeCodesClass();
       res  = c->EmployeeLevel(S"app");

       localhost1::EmployeeDataClass *c1 = new
    localhost1::EmployeeDataClass();
       res  = c1->EmployeeLadder(S"paa");
    }

    7).在 [建置] 功能表上,按一下 [建置方案] .
    8).針對每一 XML Web Service 將 EmployeeDLL.dll 複製到 Inetpub 目錄。例如,
    如果您的 Inetpub 目錄位於 C: 磁碟機,則完整目錄就會是:
    C:\Inetpub\wwwroot\EmployeeCodes\bin
    C:\Inetpub\wwwroot\EmployeeData\bin

    以 Windows Form 取代使用者介面

    下一步就是使用 Windows Form 來取代 MFC 使用者介面。在本章節中,
    您將建立新的 Windows Form 應用程式,
    其中會使用到 MFC 應用程式中的預留機位引擎。
    若要建立基底表單
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。 出現 [新增專案] 對話方塊。
    2. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下 [.NET]。
    3. 在 [樣板] 窗格中按一下 [類別程式庫 (.NET)]。
    4. 在 [名稱] 欄位中輸入 ReservationApp,再選取 [加入至方案]。按一下 [確定]。
    5. 在 [ReservationApp] 專案上按一下滑鼠右鍵。在快速鍵功能表上,按一下 [加入],
    6. 再按一下 [加入項目]。 會出現 [加入項目] 對話方塊。
    7. 按一下 [Windows Form (.NET)],並將新表單命名為 ParentForm。按一下 [開啟]。
    8. 在 [檢視] 功能表上按一下 [工具箱]。
    9. 在 [工具箱] 中開啟 [Windows Form]。將按鈕從 [工具箱] 拉至表單中,
    10. 並將 Button1 的 [文字] 屬性設為 [取消]
    11. 連按兩下 [取消] 按鈕以加入事件處理常式。
    12. 將下列程式碼插入 button1_click 事件:
      Close();
      
    13. 在 [建置] 功能表上,按一下 [建置方案]。
    若要建立繼承表單
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。
    2. 出現 [新增專案] 對話方塊。
    3. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下 [.NET]。
    4. 在 [範本] 窗格中按一下 [Windows Form 應用程式 (.NET)]。
    5. 在 [名稱] 欄位中輸入 ChildForm,再選取 [加入至方案]。請按一下 [確定]。
    6. Form1 繼承父表單。開啟 Form1.h 並將下面這一行:
      public __gc class Form1 : public System::Windows::Forms::Form
      
      變更為:
      public __gc class Form1 : public ReservationApp::ParentForm
      
    7. 在 [方案總管] 中,用滑鼠右鍵按一下 [ChildForm] 專案。
    8. 在快速鍵功能表中按一下 [加入參考]。 [加入參考] 對話方塊出現。
    9. 從清單中選取 [ReservationApp],再按一下 [確定]。
    10.  [ReservationApp] 會出現在 [方案總管] 的 [參考] 清單中。
    11. 從 [工具箱] 中,將按鈕從工具箱拉到 [設計] 檢視中 ChildForm 專案的 Form1.h 內。
    12. 在 [屬性] 視窗中,將 Button1 的 [文字] 屬性設為 [確定]。
    13. 從 [工具箱] 中,拉下三個下拉式清單方塊控制項,以及代表員工名稱、
    14. 來源機場和目的地機場的三個標籤。
    15. 拉下兩個 DatePicker ActiveX 控制項:一個代表出發日期,另一個代表返回日期.
    若要將表單連接到預留機位引擎
    現在您已建立了表單的配置,所以就可以將表單連接到預留機位引擎。
    1. 將下列檔案從 ReservationDemo 目錄複製到 ChildForm 目錄:
      Employee.cpp
      Employee.h
      Flight.cpp
      Flight.h
      Reservation.cpp
      Reservation.h
      localhost.h
      localhost1.h
      
    2. 將 TravelPolicy.dll 和 BookingObject.dll 複製到 ReservationApp\Debug 目錄。
    3. 在 [方案總管] 中,用滑鼠右鍵按一下 [ChildForm] 專案。
    4. 在快速鍵功能表中按一下 [加入現有項目]。 此時會出現 [加入現有項目] 對話方塊。
    5. 選取 Employee.cpp、Employee.h、Flight.cpp、Flight.h、Reservation.cpp 和
    6.  Reservation.h。另外再從 ReservationDemo\Debug 中加入 TravelPolicy.lib。
    7. 以下列程式碼取代 ChildForm\Flight.cpp 中的程式碼:
      #include "StdAfx.h"
      #include "Flight.h"
      #include "Reservation.h"
      #using <mscorlib.dll>
      
      using namespace System;
      using namespace System::Runtime::InteropServices;
      
      CFlight::CFlight(void)
      {
      }
      
      void CFlight::Reserve()
      {
         System::String * strFrom = S"from";
         System::String * strTo = S"to";
      
         CString csFromCity ((char*)(void*) 
      Marshal::StringToHGlobalAnsi(strFrom));
         CString csToCity ((char*)(void*) 
      Marshal::StringToHGlobalAnsi(strTo));
      
         CReservation* r = new CReservation(   &csFromCity, &csToCity, 
      17,1,2,2);
         int res = r->Reserve();
      };
      
    8. 在ChildForm\Reservation.h 中加入: 
      #include <atlstr.h>
      
    9. 在 ChildForm\Form1.h 中加入下列 #include 陳述式: 
      #pragma once
      #include Employee.h
      ...
      using namespace System;
      
    10. 在 ChildForm\Form1.h 的 [設計] 檢視中,連按兩下 [確定] 按鈕以加入事件處理常式 .
    11. 將下列程式碼加入至 button2_click 事件處理常式: 
      CString name(comboBox1->Text);
      CEmployee employee(&name);
      
      CString FromCity(comboBox2->Text);
      CString ToCity(comboBox3->Text);
      
      employee.MakeReservation(&FromCity, &ToCity, 
                  dateTimePicker1->Value.Day, dateTimePicker1->Value.Month,
                  dateTimePicker1->Value.Day, dateTimePicker1->Value.Month);
      
    12. 在 [方案總管] 中,用滑鼠右鍵按一下 [ChildForm] 專案。
    13. 在快速鍵功能表上按一下 [設定為起始專案]。
    14. 以滑鼠右鍵再按一下專案,並選取 [屬性]。
      [屬性頁] 對話方塊就會出現。
    15. 選取 [偵錯],再將 [偵錯工具類型] 設為 [僅限 Managed]。按一下 [確定]。
    16. 在 [建置] 功能表上,按一下 [建置方案]。
    17. 在 Flight.cpp 中,於下列這一行上設定中斷點:
    int res = r->Reserve();
    15.從 [偵錯] 功能表中按一下 [啟動] 以執行該應用程式。
    16.按一下 [確定] 按鈕。
    程式會執行到您設定的中斷點處。
    17.當程式執行到中斷點時,請在 [偵錯] 功能表上按一下 [逐步執行],並確定應用程式能夠運作,
    然後再選取 [跳離函式] 和 [不進入函式]。在 [快速監看式] 視窗中,確認 res 的值為 -13 .
    以 Windows Form 取代使用者介面
    下一步就是使用 Windows Form 來取代 MFC 使用者介面。在本章節中,
    您將建立新的 Windows Form 應用程式,其中會使用到 MFC 應用程式中的預留機位引擎。
    若要建立基底表單
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。 出現 [新增專案] 對話方塊。
    2. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,
    3. 然後再按一下 [.NET]。在 [樣板] 窗格中按一下 [類別程式庫 (.NET)]。
    4. 在 [名稱] 欄位中輸入 ReservationApp,再選取 [加入至方案]。按一下 [確定]。
    5. 在 [ReservationApp] 專案上按一下滑鼠右鍵。在快速鍵功能表上,
    6. 按一下 [加入],再按一下 [加入項目]。 會出現 [加入項目] 對話方塊。
    7. 按一下 [Windows Form (.NET)],並將新表單命名為 ParentForm。按一下 [開啟]。
    8. 在 [檢視] 功能表上按一下 [工具箱]。
    9. 在 [工具箱] 中開啟 [Windows Form]。將按鈕從 [工具箱] 拉至表單中,
    10. 並將 Button1 的 [文字] 屬性設為 [取消]
    11. 連按兩下 [取消] 按鈕以加入事件處理常式。
    12. 將下列程式碼插入 button1_click 事件:
      Close();
      
    13. 在 [建置] 功能表上,按一下 [建置方案]。
    若要建立繼承表單
    1. 按一下 [檔案] 功能表上的 [新增],然後再按一下 [專案]。 出現 [新增專案] 對話方塊。
    2. 在 [專案類型] 窗格上,展開 [Visual C++ 專案] 資料夾,然後再按一下 [.NET]。
    3. 在 [範本] 窗格中按一下 [Windows Form 應用程式 (.NET)]。
    4. 在 [名稱] 欄位中輸入 ChildForm,再選取 [加入至方案]。請按一下 [確定]。
    5. Form1 繼承父表單。開啟 Form1.h 並將下面這一行:
      public __gc class Form1 : public System::Windows::Forms::Form
      
      變更為:
      public __gc class Form1 : public ReservationApp::ParentForm
      
    6. 在 [方案總管] 中,用滑鼠右鍵按一下 [ChildForm] 專案。
    7. 在快速鍵功能表中按一下 [加入參考]。 [加入參考] 對話方塊出現。
    8. 從清單中選取 [ReservationApp],再按一下 [確定]。
    9. [ReservationApp] 會出現在 [方案總管] 的 [參考] 清單中。
    10. 從 [工具箱] 中,將按鈕從工具箱拉到 [設計] 檢視中 ChildForm 專案的 Form1.h 內。
    11. 在 [屬性] 視窗中,將 Button1 的 [文字] 屬性設為 [確定]。
    12. 從 [工具箱] 中,拉下三個下拉式清單方塊控制項,以及代表員工名稱、
    13. 來源機場和目的地機場的三個標籤。
    拉下兩個 DatePicker ActiveX 控制項:一個代表出發日期,另一個代表返回日期。
    若要將表單連接到預留機位引擎
    現在您已建立了表單的配置,所以就可以將表單連接到預留機位引擎。
    1. 將下列檔案從 ReservationDemo 目錄複製到 ChildForm 目錄:
      Employee.cpp
      Employee.h
      Flight.cpp
      Flight.h
      Reservation.cpp
      Reservation.h
      localhost.h
      localhost1.h
      
    2. 將 TravelPolicy.dll 和 BookingObject.dll 複製到 ReservationApp\Debug 目錄。
    3. 在 [方案總管] 中,用滑鼠右鍵按一下 [ChildForm] 專案。
    4. 在快速鍵功能表中按一下 [加入現有項目]。 此時會出現 [加入現有項目] 對話方塊。
    5. 選取 Employee.cpp、Employee.h、Flight.cpp、Flight.h、Reservation.cpp
    6. 和 Reservation.h。另外再從 ReservationDemo\Debug 中加入 TravelPolicy.lib。
    7. 以下列程式碼取代 ChildForm\Flight.cpp 中的程式碼:
      #include "StdAfx.h"
      #include "Flight.h"
      #include "Reservation.h"
      #using <mscorlib.dll>
      
      using namespace System;
      using namespace System::Runtime::InteropServices;
      
      CFlight::CFlight(void)
      {
      }
      
      void CFlight::Reserve()
      {
         System::String * strFrom = S"from";
         System::String * strTo = S"to";
      
         CString csFromCity ((char*)(void*) 
      Marshal::StringToHGlobalAnsi(strFrom));
         CString csToCity ((char*)(void*) 
      Marshal::StringToHGlobalAnsi(strTo));
      
         CReservation* r = new CReservation(   &csFromCity, &csToCity, 
      17,1,2,2);
         int res = r->Reserve();
      };
      
    8. 在ChildForm\Reservation.h 中加入:
      #include <atlstr.h>
      
    9. 在 ChildForm\Form1.h 中加入下列 #include 陳述式:
      #pragma once
      #include Employee.h
      ...
      using namespace System;
      
    10. 在 ChildForm\Form1.h 的 [設計] 檢視中,連按兩下 [確定] 按鈕以加入事件處理常式。
    11. 將下列程式碼加入至 button2_click 事件處理常式:
      CString name(comboBox1->Text);
      CEmployee employee(&name);
      
      CString FromCity(comboBox2->Text);
      CString ToCity(comboBox3->Text);
      
      employee.MakeReservation(&FromCity, &ToCity, 
                  dateTimePicker1->Value.Day, dateTimePicker1->Value.Month,
                  dateTimePicker1->Value.Day, dateTimePicker1->Value.Month);
      
    12. 在 [方案總管] 中,用滑鼠右鍵按一下 [ChildForm] 專案。
    13. 在快速鍵功能表上按一下 [設定為起始專案]。
    14. 以滑鼠右鍵再按一下專案,並選取 [屬性]。 [屬性頁] 對話方塊就會出現。
    15. 選取 [偵錯],再將 [偵錯工具類型] 設為 [僅限 Managed]。按一下 [確定]。
    16. 在 [建置] 功能表上,按一下 [建置方案]。
    17. 在 Flight.cpp 中,於下列這一行上設定中斷點:
      int res = r->Reserve();
      
    18. 從 [偵錯] 功能表中按一下 [啟動] 以執行該應用程式。
    19. 按一下 [確定] 按鈕。 程式會執行到您設定的中斷點處。
    20. 當程式執行到中斷點時,請在 [偵錯] 功能表上按一下 [逐步執行],
    21. 並確定應用程式能夠運作,然後再選取 [跳離函式] 和 [不進入函式]。
    22. 在 [快速監看式] 視窗中,確認 res 的值為 -13。

    連接到 SQL Server 資料庫

    在本章節中,您將會設定應用程式以 SQL Server 資料庫的資料填滿員工的下拉式清單方塊。
    首先,您必須建立資料連接。
    若要存取資料庫的資料
    1. 在 [檢視] 功能表上按一下 [伺服器總管]。
    2. 在 [伺服器總管] 中以滑鼠右鍵按一下 [資料連接] 節點,並選取 [加入連接]。
    3. 此時會顯示 [資料連結內容] 對話方塊。
    4. 指定您擁有帳戶或存取權限的伺服器名稱。選取 [使用 Windows NT 整合安全]。
    5. 選取資料庫,例如:Pubs 或 Northwind。按一下 [確定] 以建立連接,
    6. 它會出現在 [伺服器總管] 中。
    7. 在 [伺服器總管] 中,先展開該資料庫節點,再展開 [表格] 節點,
    8. 然後再選取適合的表格 (例如作者),並將它拉到 Form1 的 [設計] 檢視中。
    9. 如此將會建立兩個物件:sqlConnection1 sqlDataAdapter1
    10. 用滑鼠右鍵按一下 [sqlDataAdapter1] 物件,再按一下 [設定資料配接器]。
    11. 出現 [設定資料配接器] 對話方塊。
    12. 按一下 [下一步]。若它不是預設的資料庫,則請先指定您的資料庫,再按一下 [下一步]。
    13. 選取 [使用SQL 陳述式],再按一下 [下一步]。
    14. 選擇 [查詢產生器],再選取您想要操作的欄位。按一下 [確定],然後再按一下 [完成]。
    15. 在 Form1 的 [設計] 檢視中,用滑鼠右鍵按一下 [sqlDataAdapter1],
    16. 並從其內容功能表中選取 [產生資料集]。 [產生資料集] 對話方塊將出現。
    17. 選擇名稱為 DataSet1 (預設值) 的新資料集,其中包含作者的表格,
    18. 並確定已選取 [將此資料集加入設計工具中]。
    若要設定表單控制項以使用產生的資料集
    1. 在 Form1 的 [設計] 檢視中,按一下員工姓名的下拉式清單方塊。
    2. 在 [屬性] 視窗中,將 DataSource 設為 dataSet11.authors
    3. 並將 DisplayMember 設定為 au_lname
    4. 連按兩下該表單以便將 Form1_Load 事件加入。將下列程式碼加入至事件:
      dataSet11->Clear( );
      sqlDataAdapter1->Fill(dataSet11);
      
    5. 在 [建置] 功能表上,按一下 [建置方案]。
      注意   若無法建置方案,請將 #include "Dataset1.h" 從 stdafx.h

      移到 ChildForm\Form1.cpp 中 #include "stdafx.h." 之後。

    將預留機位引擎移植到 Managed 類別

    在本章節中,您會將預留機位引擎移植成完全的 Managed,以展示 Managed 和 Unmanaged 程式碼
    之間的互通性。您必須把新的 Managed 類別修改為可與差旅規定 DLL 和預訂機位的 COM 物件互通。
    若要執行這項作業,則您必須依下列程式碼 (粗體字程式碼代表變更處) 所述來編輯標頭和實作檔案。
    Employee.h
    //  Employee.h
    
    #pragma once
    
    #include "reservation.h"
    
    __gc class CEmployee
    {
    protected:
       CReservation* reservation;
       System::String* employeeName;
    public:
       CEmployee(System::String* name);
       ~CEmployee(void);
    
       virtual int MakeReservation (System::String* from, 
    System::String* to, int day1, int month1, int day2, int month2);
    };
    
    Employee.cpp
    // Employee.cpp
    
    #include "StdAfx.h"
    #include <vcclr.h>
    #include "employee.h"
    #include "Flight.h"
    
    #define __FLTUSED__
    #include "localhost.h"
    #include "localhost1.h"
    
    CEmployee::CEmployee(System::String* name)
    {
       employeeName = name;
       reservation = NULL;
       int res;
    
       localhost::EmployeeCodesClass *c = new 
    localhost::EmployeeCodesClass();
       res = c->EmployeeLevel(S"app");
    
       localhost1::EmployeeDataClass *c1 = new 
    localhost1::EmployeeDataClass();
       res = c1->EmployeeLadder(S"paa");
    }
    int CEmployee::MakeReservation (System::String* from, System::String* 
    to, int day1, int month1, int day2, int month2)
    {
       CFlight* flight;
       flight->Reserve();
       return 1;
    }
    
    CEmployee::~CEmployee(void)
    {
    }
    
    --------------------------------------------------------------------------------
    Reservation.h
    // Reservation.h
    
    #pragma once
    
    __gc class CReservation
    {
    protected:
       __gc struct CityInfo {
          System::String* city;
          int departDay;
          int departMonth;
       };
       CityInfo* fromCity, * toCity;
    public:
       CReservation(System::String* from, System::String* to, int d1, int 
    m1, int d2, int m2);
       ~CReservation(void);
       virtual int Reserve ();
    protected:
       virtual int GetFlightPolicy (int level);
    };
    
    --------------------------------------------------------------------------------
    Reservation.cpp
    // Reservation.cpp
    
    #include "StdAfx.h"
    #include "reservation.h"
    
    #import "..\\bookingobject\\_bookingobject.tlb" no_namespace
    
    #using <mscorlib.dll>
    using namespace System;
    using namespace System::Runtime::InteropServices;
    
    CReservation::CReservation(System::String* from, System::String* to, 
    int d1, int m1, int d2, int m2)
    {
       fromCity = new CityInfo();
       toCity = new CityInfo();
       fromCity->city = from;
       fromCity->departDay = d1;
       fromCity->departMonth = m1;
       toCity->city = to;
       toCity->departDay = d2;
       toCity->departMonth = m2;
    }
    
    CReservation::~CReservation(void)
    {
    }
    
    int CReservation::Reserve ()
    {
       IBookingPtr b(__uuidof(CBooking));
    
       BSTR bstrFromCity = static_cast<BSTR> 
    (Marshal::StringToBSTR(fromCity->city).ToPointer());
       BSTR bstrToCity = static_cast<BSTR> (Marshal::StringToBSTR(
    toCity->city).ToPointer());
    
       b->NewBooking(bstrFromCity, bstrToCity, fromCity->departDay, 
    fromCity->departMonth);
    
       int res = GetFlightPolicy(1);
    
       if (b->CheckAvailability())
       {
          b->Reserve();
          return res;
       }
       else
          return res + 10;
    
    }
    
    __declspec( dllimport ) int GetFlightClass (int, int);
    
    int CReservation::GetFlightPolicy (int level)
    {
       return GetFlightClass(level, fromCity->departDay-toCity->departDay);
    }
    
    ------------------------------------------------------------------------------------
    Flight.cpp
    // Flight.cpp
    
    #include "StdAfx.h"
    #include ".\\flight.h"
    #include "Reservation.h"
    #using <mscorlib.dll>
    
    using namespace System;
    using namespace System::Runtime::InteropServices;
    
    CFlight::CFlight(void)
    {
    }
    
    void CFlight::Reserve()
    {
       System::String * strFrom = S"from";
       System::String * strTo = S"to";
    
       CReservation* r = new CReservation(   strFrom, strTo, 17, 1, 2, 2);
       int res = r->Reserve();
    }
    
    -------------------------------------------------------------------------------
    Form1.h
    // ChildForm\Form1.h
    // button2_click handler
    
       System::String* name(comboBox1->Text);
       CEmployee* employee = new CEmployee(name);
    
       System::String* FromCity(comboBox2->Text);
       System::String* ToCity(comboBox3->Text);
    
       employee->MakeReservation(FromCity, ToCity, 
          dateTimePicker1->Value.Day, dateTimePicker1->Value.Month,
          dateTimePicker1->Value.Day, dateTimePicker1->Value.Month);
    &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
    &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
     

    沒有留言:

    張貼留言


    if you like make fds, wellcome you here~~anytime***

    my free place for everyones who want the good software,

    come & download them~ wellcome!!