VC 操作 SQL Server 主從表

來源:互聯網
上載者:User

文章標題:VC 操作 SQL Server 主從表
原 作 者:袁懷善
原 出 處:vckbase
發 布 者:loose_went
發布類型:轉載
發布日期:2004-10-16
今日瀏覽:41
總 瀏 覽:9955
下載代碼:  Skin++ 軟體換膚套件
· 支援多種開發語言
· 介面和商務邏輯徹底分離,節約開發和維護時間
· 徹底換膚,包括標準控制項,通用對話方塊等
· 皮膚支援WinBlinds格式,有上千種皮膚免費下載
· 提供方便的設計工具,可自行設計皮膚 
 
 
 

  工作之餘,用VC作了一個小程式,是VC+SQL server模式的,程式內容比較簡單,主要設及以下內容:

視窗如何分割;
多視圖之間如何通訊;
列表視圖的操作及事件處理;
樹形控制項的操作及事件處理,利用遞迴根據資料庫動態組建目錄;
實現主從表的顯示 以下對程式細節稍作一下說明;
一、視窗如何分割

  切分視窗既適用於SDI應用程式,也適宜於MDI應用程式。它通常駐是以類 CSplitterWnd來表示,對 Windows 來說,CSplitterWnd 是一個真正的視窗,它完全佔用架構視窗的用戶端區域而視圖佔用切分視窗的窗格地區。 動態切分與靜態切分 動態切分允許使用者須任何時候對視窗進行切分,使用者既可以通過選取菜單也可以通過拖動捲軸中的切分框來進行切分。動態切分視窗使用的是一個視圖類。 靜態切分,當視窗第一次被建立時,窗格就已經被切他好了,它們不能再被改變。使用者可以移動窗格邊框,但此時不能再對視窗進行合并或再劃分。靜態切分視窗允許使用多個視圖類,並且可以建立時對這些視圖類進行配置。在靜態切分視窗中,每個窗格都有自己的捲軸。 動態切分比較簡單,不實用,下面看靜態切分。

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
CRect rect;
GetClientRect(&rect);
m_wndSplitter1.CreateStatic(this,1,2);
m_wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CClassTreeView),CSize(150,150),pContext);
m_wndSplitter2.CreateStatic(&m_wndSplitter1,
                            2,1,WS_CHILD|WS_VISIBLE,
                            m_wndSplitter1.IdFromRowCol(0,1));

m_wndSplitter2.CreateView(1,0,RUNTIME_CLASS(CDagDetialView),CSize(0,0),pContext);
m_wndSplitter2.CreateView(0,0,RUNTIME_CLASS(CDagView),CSize(0,0),pContext);
m_wndSplitter2.SetRowInfo(0,rect.Height()/2,0);

return true;

         //重載時不能調用基類的OnCreateClient()
}

以上是本程式DEMO使用的方法。關於切分詳細資料,請查閱MSDN.

二、多視圖之間的通訊

  本程式demo使用了三個視圖類,Winzard產生了一個,其餘的是我加的。關於多視圖之間的通訊主要是茯得你要訪問的視圖類的pointer,如何茯得?有兩種方法1,通過視圖類(如果有多個視圖共用一個文檔類的話)2.通過主架構茯得。由於我的程式就一個文檔類,其他視圖類是獨立的,所以就採用第二種方法了。
以下代碼是茯得CDagDetialView類指標的樣本,其餘類同。

CMainFrame* pFrame=static_cast(AfxGetMainWnd());//茯得主架構
CDagDetialView* pDagDetialView =
          static_cast(pFrame->m_wndSplitter2.GetPane(1,0));

  以上有一點,我覺得最好採用以上形式,雖說通過C的強制轉換文法也行,但最好還是使用C++的文法比較好。
  茯得視圖指標後你就可以do anything that you want to do
順便說一下,通訊細節有一些牽連到效率的地方,一定要妥善處理。上面的demo程式,沒有考慮過多。因為我覺得這比較適合大家看明白意思,如果程式模組分散開來,程式看起來是簡潔了不少,但不太方便看清程式流程。請見諒。

三、列表視圖的操作及事件處理

  說句實話,列表的屬性參數很多,標準的、擴充的風格參數一大堆,看看那些英文文檔,在其中苦苦搜尋,找一條自己需要的特性,其中的滋味別提了。還好我很有耐心:)熟練了就好了,都記住了一大半,還怕什麼。清單控制項顯示資料,要用LVS_REPORT風格,比較好看,就像DataGrid一樣。設定視窗風格需要用SetWindowLong這個API函數。這個函數是通用的。參數也一大堆。處理列表的單擊事件即是處理訊息NM_CLICK,處理選擇改變時的事件即是處理LVN_ITEMCHANGED,不同的訊息可能參數不同,需區別對待。

void CDagView::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    // TODO: Add your control notification handler code here
    CListCtrl& refListCtrl=GetListCtrl();
    if(pNMListView->uNewState&LVIS_SELECTED)
    …//選取清單項目時,事件觸發
    pResult=0;

同樣的方法處理單擊,雙擊等事件,不再嗷述。

四、樹形控制項的操作及事件處理,利用遞迴根據資料庫動態組建目錄

  樹形控制項,和清單控制項一樣,在VC資料開發中有著非常重要的地位。常用來顯示分級,分類資訊。其實,提到樹,腦海裡就出現一大堆樹,什麼二叉樹,尋找樹,哈夫曼樹等一大堆,也就想起了遍曆樹的常用演算法—遞迴。雖然採用堆棧更有效率,但使用遞迴常使程式設計簡化。
看以下程式片段:

pRS->MoveFirst();
_variant_t var;
CString strTableName,strTableCode;
HTREEITEM hChildItem;
while(!pRS->adoEOF)
{
var=pRS->GetCollect("menucode");
if(var.vt != VT_NULL)
strTableCode = (LPCSTR)_bstr_t(var);

//此即函數遞迴出口
if(!strTableCode.Find(strParent,0) &&
                                            strTableCode.GetLength()==strParent.GetLength()+2)
{
hChildItem=refTree.InsertItem(strTableName,hTreeNode,TVI_LAST);
InitTree(refTree,hChildItem,strTableCode);
}
pRS->MoveNext();

  遞迴時充分利用樹形結構的特點。然後結合遞迴思想,融合在一起,就行了。這裡就是理論和實際的結合點。不同的開發語言提供的操作介面是不同的,如Delphi、.dotnet。我呈在在.net也實現了一個類似的樹,演算法思想一樣,只是具體操作不同,因為dotnet提供的介面不同。
樹形控制項的事件處理

void CClassTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
CTreeCtrl& refTreeCtrl=GetTreeCtrl();
HTREEITEM hSelected=pNMTreeView->itemNew.hItem;
if(hSelected!=NULL)
{
m_strMenuName=refTreeCtrl.GetItemText(hSelected);
    if(AfxGetMainWnd()->IsWindowEnabled())
UpdateDagView();

}

//-----------
*pResult = 0;
}

五、實現主從表的顯示

  由於我假設不知道資料庫中有多少欄位,欄位名都是不知道的。所有都動態產生。所以首先要檢索主鍵。把主鍵檢索出來以後,然後得到列表當前選擇行的對應於主鍵列的資料。然後以這些主鍵列的值當作檢索條件檢索從表的資料(從表的主鍵一定多於主表)最後將結果顯示出來。看起來過程也挺簡單的,如果用dotnet中DataGrid做的話,太簡單了是吧,但VC操作起來,就有點麻煩了。就拿從列表取當前選擇行的主鍵列的資料的話,和dotnet一比,就知道VC麻煩在哪兒了。(不過我還是比較喜歡VC,嘿嘿)。一個DataGrid,如果我知道了列名,又茯取了當前行的行號(CurrentRowIndex)
如果你後台是直接綁定的一個DataTable,就可以直接取得這個值:

myTable.Rows[CurrnetRowIndex][“pkey1”].ToString();

當然如果你後面不是直接綁定一個DataTable,而是一個結果經過慮後的結果,那麼可能會稍煩瑣一點。這裡不對這種情況進行計討論。下面看一下VC下是怎麼處裡的,(如果有更好的方法,請通知我,先謝了)

int CDagView::GetColumnIndex(CListCtrl &ref,LPCTSTR strCol)
{
CHeaderCtrl * pHeader=ref.GetHeaderCtrl();
int nCount=pHeader->GetItemCount();
TCHAR  lpBuffer[256];
bool   fFound = false;
HDITEM hdi;
hdi.mask = HDI_TEXT;
hdi.pszText = lpBuffer;
hdi.cchTextMax = 256;
int index=-1;
for (int i=0;!fFound && (i < nCount);i++)
{
pHeader->GetItem(i, &hdi);

if (strcmp(hdi.pszText, strCol) == 0)
{
index=i;
fFound = true;
}
}
return index;
}
iSubItem=GetColumnIndex(refListCtrl);
CString strValue=refListCtrl.GetItemText(iCurrent,iSubItem);

先取得列號然後取得行號,最後取這個值......好了,就寫這麼多吧,具體細節再看代碼。

六、結束語

  其實這個程式比較簡單,在Windows 2k下調試通過!就寫到這裡吧,不足之處,見諒!有時候,再好的技術,如果缺乏有效樣本,也會變得晦澀難懂。像本文中的列表、樹形控制項參數很多,使用VC++雖然說可以發揮出他們最強勁的功能,但是有一部分參數,在MSDN中只是簡要介紹,沒有詳細的樣本說明(我猜:微軟內部肯定有更加詳細的樣本及文檔,或者說叫引擎,不對外公布)這就要靠廣大程式員的努力探索了,知識共用,大家共同進步。
 

相關文章

聯繫我們

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