Visual c++中不使用對話方塊模板資源建立對話方塊應用

來源:互聯網
上載者:User

 

引言

通常情況下,利用vc為應用程式建立對話方塊需要使用對話方塊模板資源。通過vc++整合式開發環境中的對話方塊編輯器以可視化的方式建立對話方塊資源,這種方法可以應用於大多數對話方塊編程的情況下。但涉及對話方塊的程式模組必然依賴於開發項目資源,不能作為多個開發項目共用的公用程式模組。比如,筆者開發的一系列應用程式,都需要一個使用者輸入註冊資訊的功能。通常情況下,可以將公用程式模組引入不同的開發項目,而實際程式檔案只有唯一的備份。這樣便於程式的維護,避免公用模組存在多個不一致拷貝的情況。但如果在公用程式模組中存在使用者介面,則不能簡單引入不同開發項目(因為不同項目都有各自的資源,其資源定義不免存在衝突)。另外如果開發過程中需要使用大量的對話方塊,這些對話方塊內容相似,但又略有不同,用對話方塊模板資源,也顯得較為煩瑣。本文介紹了在Visualc++中不使用常規的對話方塊資源模板的情況下,動態建立對話方塊的方法。

1、基本原理

如何不使用對話方塊模板資源,建立對話方塊應用,正是本文探討的問題。如果仔細閱讀MSDN中有關CDialog的內容會發現
CDialogCreateIndriect和
CDialogInitModalIndirect兩個成員函數。正是這兩個成員函數可以利用記憶體中的對話方塊資源建立對話方塊。
CDialogCreateIndriect用於建立無強制回應對話方塊,
CDialogInitModalIndirect可以建立模式對話方塊。

這兩個成員函數都包含參數
LPCDLGTEMPLATElpDialogTemplate,它指向包含對話方塊和控制項資源的記憶體位置。該段記憶體的具體內容包括兩部分:

1.1對話方塊資源

最開始為DLGTEMPLATE結構,指出對話方塊視窗的位置、大小和風格,緊接其後的是指向菜單資源的數組(前兩個位元組為0x0000表示沒有菜單),
接下來的UniCode字串數組表示控制項對應的註冊類名(前兩個位元組為0x0000表示使用預設的預定義類),然後是UniCode字串數組表示的對話方塊標題,雙位元組的字型長度和字型名。

1.2對話方塊控制項資源

緊跟對話方塊資源之後的是一個或多個對話方塊控制項資源,每個控制項資源最開始為DLGITEMTEMPLATE結構,指出控制項視窗的位置、大小和風格,然後是控制項對應的的註冊類名,(如果前兩個位元組為0xFFFF表示使用預定義類),此時後兩個位元組指出具體類見表1,然後是控制項標題(如果前兩個位元組為0xFFFF表示將使用ICON資源),接下來的資料用於建立控制項時使用,由系統發送WM_CREATE訊息時,被lParam參數引用,可以用0x0000表示省略該部分資料。

 

表1

 

 

 

 

0x0080

Button

0x0081

Edit

0x0082

Static

0x0083

List box

0x0084

Scroll bar

0x0085

Combo box

 

 

 

 

 

 

 

表1

其中DLGTEMPLATE結構為

typedefstruct//dltt

DWORDstyle

DWORDdwExtendedStyle

WORD  cdit

shortx

shorty

shortcx

shortcy

DLGTEMPLATE

style和dwExtendedStyle為對話方塊的風格,cdit表示對話方塊包含的控制項個數,x,y,cx,cy表示視窗的大小。DLGITEMTEMPLATE結構與此類似,僅多了一項標識id。

通過上面的描述,可以知道只須自行申請記憶體空間,按要求在記憶體中定義對話方塊和控制項的資源,就可以不再依賴項目資源。實際編程中,因為在對話方塊類中定義和建立控制項比較容易,因此往往可以僅定義記憶體對話方塊資源而省略控制項資源部分,通過常規方法動態建立就可以了。

2、實現方法與步驟

下面結合一個進度顯示對話方塊執行個體介紹具體實現的步驟:

首先從CDialog中派生一個類CMemoryDialog,作為所有無模板對話方塊的基類。選擇菜單Insert->NewClass彈出New Class對話方塊,在Name項鍵入CMemoryDialog,BaseClass項選擇
CDialog,按確定按鈕。ClassWizard提示使用者首先建立對話方塊模板資源,對此不與理會,繼續建立。在建立成功的.
h檔案中找到enum IDD = _UNKNOWN_RESOURCE_ID_ ,表示未知的資源ID將這行代碼刪除。

定義成員變數:

CStringm_StrTitle//對話方塊標題

DLGTEMPLATEm_dlgTempl//記憶體對話方塊模板

定義成員函數:

intDoModalMemoryDialog//用於建立模式對話方塊

voidCreateMemoryDialog//用於建立無強制回應對話方塊

其中DoModalMemoryDialog的代碼清單如下:

intCMemoryDialogDoModalMemoryDialog

intr

       WCHAR szFontName = L″ARIAL″     //字型名

       WCHAR pszBoxCaption //標題

      int nLenTitle=m_StrTitle.GetLength+1

       pszBoxCaption = new WCHARnLenTitle

//將標題轉換為Unicode字串

      MultiByteToWideCharCP_ACP0m_StrTitle-1 pszBoxCaptionnLenTitle

      TRY   

//分配儲存資源的記憶體

intnBufferSize=
   sizeofDLGTEMPLATE+2 sizeofWORD/menu and class/ + nLenTitlesizeofWCHAR

      nBufferSize+=sizeofWORD+sizeofszFontName/fontinformation/ +

  nBufferSize=nBufferSize+2&2//adjustsize to make first control DWORD aligned

  HLOCALhLocal

      hLocal = LocalAllocLHND nBufferSize

              if hLocal == NULL

                    AfxThrowMemoryException

             BYTE pBuffer=BYTELocalLockhLocal

             if pBuffer == NULL

             

                     LocalFreehLocal

                     AfxThrowMemoryException

             

              BYTE pdest=pBuffer

              // 拷貝DLGTEMPLATE 結構

              memcpypdest &m_dlgTempl sizeofDLGTEMPLATE

              pdest+=sizeofDLGTEMPLATE

              WORDpdest=0//表示沒有菜單

              WORDpdest+1=0//使用預設類

              pdest+=2sizeofWORD

              //拷貝標題字串

              memcpypdestpszBoxCaptionnLenTitlesizeofWCHAR

              pdest+=nLenTitlesizeofWCHAR

              WORDpdest=11//字型名的長度

              pdest+=sizeofWORD

              //拷貝字型名字串

              memcpypdestszFontNamesizeofszFontName

              pdest+=sizeofszFontName

              delete pszBoxCaption

              //建立模式對話方塊

             InitModalIndirectDLGTEMPLATEpBuffer

             r=DoModal

      LocalUnlockhLocal

              LocalFreehLocal

      

       CATCHCMemoryExceptione

      

              AfxMessageBox″Memory allocation failed″

      

         END_CATCH

     return r

  CreateMemoryDialog與此類似,只需將

  InitModalIndirectDLGTEMPLATEpBuffer

  r=DoModal   

  兩行替換為

  CreateIndirectDLGTEMPLATEpBuffer

  ShowWindowSW_SHOW

  並且去掉傳回值。

  然後從CMemoryDialog再次派生新類CCustomProgressDialog。在.h檔案中加入成員CProgressCtrlm_ProCtrl,並覆蓋基類的OnInitDialog成員函數。在OnInitDialog中動態建立CProgressCtrl對象。

  這樣一個簡單的進度顯示對話方塊就建立好了,使用者可以根據需要派生更多的對話方塊類,也可隨時添加更多的控制項對象。

  3、結論

  通過上述進度顯示對話方塊的實現步驟,可以看到建立無模板資源對話方塊的實現方法。使用者可以根據需要派生更多的對話方塊類,也可隨時添加更多的控制項對象。而且這些模組都與資源無關,可以同時被多個開發項目包含,維護起來十分方便。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.