我的項目–圖書館管理系統 [細節]

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

我的項目 圖書館管理系統(LMS)  Write by Hifan: b033205_Wangqi 王琪

-          王琪

-          同濟大學 軟件學院2003級

寫在前面->我的項目是我自己經過n天的努力,一個人完成的

       其中的代碼絕大部分是我自己寫的,也有很多是在Csdn上看別人的問題和自己問問題

或者自己看MSDN自己找到解決辦法~這也是一份比較辛苦的事情。

       有一個類的代碼大部分是看別人的就是CMyPicture顯示圖片,可以顯示多種格式的Pic

       源代碼很多有LMS[主應用程序] DLL/Picture,OtherFunc[dll]

       代碼量大概有5000~

      

細節開始 [Start]

1.       多線程 (初始化連接數據庫 有自己的Splash 顯示圖片)

// Thread in MySplash Init

       HWND hWnd=this->GetSafeHwnd();

       m_pThread=AfxBeginThread(MyAdoConnect,hWnd,THREAD_PRIORITY_NORMAL);//啓動線程THREAD_PRIORITY_HIGHEST

       m_pThread->m_bAutoDelete=FALSE;    //線程爲手動刪除

// 線程函數

UINT MyAdoConnect(LPVOID pParam)

{

       // COM初始化

       ::CoInitialize(0);

       _ConnectionPtr pConn;

       HRESULT hr;

       hr = pConn.CreateInstance(__uuidof(Connection));

      

       if(SUCCEEDED(hr))

       {

              try

              {

                     pConn->ConnectionString = "Provider=OraOLEDB.Oracle.1;Password=LMS;Persist Security Info=True;User ID=LMS;Data Source=oradb1";//設置連接字符串

                     pConn ->ConnectionTimeout = 10;                //設置連接的超時時間,可選

                     pConn ->CursorLocation    = adUseServer; //設置光標的位置,可選

                     pConn ->Open("","","",-1);

              }

              catch(_com_error& e)

              {

                     CString StrErr;

                     StrErr.Format("出錯,連接數據庫錯誤~/n錯誤:%s",e.ErrorMessage());

                     AfxMessageBox(StrErr);

                     ::PostMessage( (HWND)pParam,WM_CLOSE,0,0);

                     bpConn = false;

                     return FALSE;

              }

       }

       theApp.SetConn(pConn);

       ::PostMessage( (HWND)pParam,WM_CLOSE,0,0);

       bpConn = true;

       return TRUE;

}

2.       好玩的地方~ (讓窗口顯示的動態化~) MyLogin.Init; MySplash .Init

ShowWindow(SW_HIDE);

       CRect rect;

       this->GetClientRect(&rect);

       CPoint CenterPt;

       CenterPt.x = rect.Width()/2;

       CenterPt.y = rect.Height()/2;

      

       CRgn rgn;

       this->ShowWindow(SW_HIDE);

      

       int m = GetSystemMetrics(SM_CYSIZEFRAME);

      

       for(int i=0;i<rect.Width()/2+m;++i)

       {

              rgn.CreateRectRgn(CenterPt.x-i,CenterPt.y-i,CenterPt.x+i,CenterPt.y+i);

              SetWindowRgn( (HRGN)rgn.GetSafeHandle(),TRUE);

             

              ShowWindow(SW_SHOW);

             

              CenterWindow();

             

              rgn.DeleteObject();

       }

3.       CMyPicture用來對圖片的處理 (*.jpg,*.jif,*.bmp) 此類是放在Picture.dll裏面的

避免了Bitblt不能顯示*.jpg,*.jif的缺點 StrechBitblt的效果不好;[大部分是看別人的]

class AFX_EXT_CLASS CMyPicture

{

public:

       CMyPicture();

       virtual ~CMyPicture();

public:

       void FreePictureData();

       BOOL Load(CString sFilePathName);

       BOOL Load(UINT ResourceName, LPCSTR ResourceType);

       BOOL LoadPictureData(BYTE* pBuffer, int nSize);

       BOOL SaveAsBitmap(CString sFilePathName);

       BOOL Show(CDC* pDC, CPoint LeftTop, CPoint WidthHeight, int MagnifyX, int MagnifyY);

       BOOL Show(CDC* pDC, CRect DrawRect);

       BOOL ShowBitmapResource(CDC* pDC, const int BMPResource, CPoint LeftTop);

       BOOL UpdateSizeOnDC(CDC* pDC);

 

public:

       IPicture*        m_IPicture;

       LONG      m_Height;

       LONG      m_Weight;     

       LONG      m_Width;

};

4.       CMyStatic繼承了CStatic 來顯示圖片,處理了右鍵點擊 彈出對話框 保存圖片

// 彈出菜單

void CMyStatic::OnRButtonUp(UINT nFlags, CPoint point)

{

       {

              CMenu menu, *pMenu;

              menu.LoadMenu(IDR_MENU1);

              pMenu = menu.GetSubMenu(0);

             

              ClientToScreen(&point);

             

              pMenu->TrackPopupMenu(TPM_RIGHTBUTTON,point.x,point.y,this);

       }

       CStatic::OnRButtonUp(nFlags, point);

}

// 保存圖片

ON_COMMAND(IDC_MENU_SAVE, OnMenuSave)

void CMyStatic::OnMenuSave()

{

       CString FilePathName;

       CFileDialog Dlg(FALSE,NULL,NULL,0,

              "Jpg Files (*.jpg)|*.jpg|Gif Files (*.jif)|*.gif|Bmp Files (*.bmp)|*.bmp||",

              this);

       if(Dlg.DoModal()==IDOK)

       {

              FilePathName = Dlg.GetFileName();

       }

       if( FilePathName!="" )

              pPic->SaveAsBitmap(FilePathName);

}

5.       關於Ado的連接操作

// 主要用到以下

_ConnectionPtr       pConn;

_CommandPtr          pCmd;

_RecordsetPtr        pRst;

_variant_t             m_vTemp[10];

// pRst來遍歷

// pCmd來執行

// 可以存放圖片 顯示圖片

// 存入圖片 向數據庫中

try

{

       CFile file;

       if(file.Open(FilePathName, CFile::modeRead | CFile::typeBinary))

       {

              int nSize = file.GetLength();

              BYTE * pBuffer = new BYTE [nSize];

             

              if (file.Read(pBuffer, nSize) > 0 )

              {

                     // 下面這一段代碼是把pBuffer裏的圖片數據寫到數據庫中

                     BYTE *pBuf =       pBuffer;

                     VARIANT                     varBLOB;

 

                     SAFEARRAY            *psa;

                     SAFEARRAYBOUND       rgsabound[1];

                    

                     pRst->AddNew();

                    

                     if(pBuf)

                     {

                            rgsabound[0].lLbound      = 0;

                            rgsabound[0].cElements   = nSize;

                            psa = SafeArrayCreate(VT_UI1, 1, rgsabound);

 

                            for(LONG i = 0; i <(LONG) nSize; i++)

                                   SafeArrayPutElement(psa,&i,pBuf++);

 

                            varBLOB.vt = VT_ARRAY | VT_UI1;

                            varBLOB.parray = psa;

 

                            // 要放在它(Pic)前面~

                            pRst->Fields->GetItem("SNO")->Value = m_Sno.AllocSysString();

 

                            pRst->GetFields()->GetItem("PIC")->AppendChunk(varBLOB);

                     //       pRst->PutCollect("SNO",m_Sno.AllocSysString());

                     //       pRst->PutCollect("Pic",varBLOB);

                     }

                     pRst->Update();

                     delete [] pBuffer;

                     pRst->Close();

                     pRst=NULL;

              }

              file.Close();

       }

      

}

catch(_com_error e)

{

       bret = false;

}

// 顯示圖片 從數據庫中讀取圖片並顯示~

       str.Format("Select * from picture where sno=/'%s/'",m_Sno);

       SqlStr = str.AllocSysString();

       // First Clear.

       if(m_Pic.m_IPicture!=NULL)

              m_Pic.FreePictureData();

       hr = pRst.CreateInstance(__uuidof(Recordset));

       if(SUCCEEDED(hr))

       {

              try

              {

                     pRst->Open(SqlStr,(IDispatch*)(theApp.Conn()),

                            adOpenDynamic,adLockOptimistic,adCmdText);

                     // 只能有一條紀錄 Con_Picture_Sno_Unique

                     if(!pRst->MyHiFanEOF)

                     {

                            long nSize = pRst->GetFields()->GetItem("Pic")->ActualSize;

                            if(nSize > 0)

                            {

                                   _variant_t       varBLOB;

                                   varBLOB = pRst->GetFields()->GetItem("Pic")->GetChunk(nSize);

                                   if(varBLOB.vt == (VT_ARRAY | VT_UI1))

                                   {

                                          if(BYTE *pBuffer = new BYTE [nSize+1])                                                                             {

                                                 char *pBuf = NULL;

                                                 SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);

                                                 memcpy(pBuffer,pBuf,nSize);                                                                                       SafeArrayUnaccessData (varBLOB.parray);

                                                

                                                 m_Pic.LoadPictureData(pBuffer, nSize);

                                                 delete [] pBuffer;

                                                

                                                 CGuashi::SetPicThenShow();

                                          }

                                   }

                            }

                     }

              }

              catch(_com_error &e)

              {

                     AfxMessageBox(,e.Description());

              }

       }

// 還有很多地方用到事務~ 源程序都有介紹

bool bret = false

hr = pConn.CreateInstance(__uuidof(Connection));

if(SUCCEEDED(hr))

{

       pConn=theApp.Conn(); // 得到pConn

       pConn->BeginTrans();

       try

       {

              // 這些的語句在前面已經初始化~

              pConn->Execute(_bstr_t(SqlInertIntoStudents),0,adExecuteNoRecords);

              pConn->Execute(_bstr_t(SqlInertIntoCard),0,adExecuteNoRecords);

              bret = true;

}

catch(_com_error& e) // Get Error

{

       AfxMessageBox(e.ErrorMessage());

}

if (bret)

       pConn->CommitTrans();

else

{

       pConn->RollbackTrans();

      

       CString StrErr;

       StrErr.Format("%s出錯~!/n事務即將回滾~",OracleErrorStr);

       AfxMessageBox(StrErr);

       EndDialog(101); // 結束窗口,本窗口是模態的

       return;

}

}

6.       關於dll

這個我也不想多說了,我寫了兩個dll,一個是Picture.dll,另一個是OtherFunc.dll

Picture.dll: AFX_EXT_CLASS CMyPicture因爲這個類經常用到,所以我把它放到dll

OtherFunc.dll: 其他函數的dll

這個老師在課堂上講的我都會,所以沒有什麼可講的,其他深入的我也就沒有做~

7.       極小點

// Hide Window on Taskbar: [在任務欄上隱藏] 隱藏CMySplash

::SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,WS_EX_TOOLWINDOW);

// TopMost

1. SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); // In Init

2. void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus) // In Show Window

{

       CFrameWnd::OnShowWindow(bShow, nStatus);

       // TopMost

       SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

}

// 隨機數字的初始~ 後面就可以用rand()來得到隨機數~ [使程序更好玩]

srand( (unsigned) time(NULL) ); // Important

// 256色Toolbar

雖然我的Icon很醜,但是都是我自己畫的,而且可以是256~

// 改變CStatic背景爲透明

HBRUSH CDlgLogin::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

       HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

       // HiFan

       // For Change Static BkMode, and Text Color

       if(nCtlColor==CTLCOLOR_STATIC) //還有類似的CTLCOLOR_BTN…

       {

              pDC->SetBkMode(TRANSPARENT);

              pDC->SetTextColor(RGB(200,0,200));

              return (HBRUSH) ::GetStockObject(NULL_BRUSH);

       }

       // End of Hifan

       return hbr;

}

// 模態對話框和非模態對話框~

老師給我講了,我懂了一些~ 這些窗口被Close後並沒有完全的消失~

我所建的窗口大部分是非模態的~

 

 

// 窗口子項的使能~有必要~

CWnd * pCwnd = this->GetDlgItem(IDC_ID);

pCwnd->EnableWindow(TRUE);

// 還有我發現要使Edit中產生換行必須是”/r/n” 這個和C++中不一樣~

CString       m_Info; // /r/n; 不是/n,/n/r./r;

m_Info.Format(“/r/n/r/n/r/n”);

this->UpdateData(FALSE);

// 多頁屬性框的創建

CTabCtrl       m_Tab;

CPage1 page1;

CPage2 page2;

int CDelete::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

       if (CDialog::OnCreate(lpCreateStruct) == -1)

              return -1;

 

       m_Tab.Create(WS_VISIBLE,CRect(0,0,500,370),this,IDC_TAB1);

       m_Tab.InsertItem(0,"刪除學生");

       m_Tab.InsertItem(1,"刪除舊書");

 

       // 分頁~

       page1.Create(IDD_DIALOG9_PAGE1,this);

       page2.Create(IDD_DIALOG9_PAGE2,this);

       page1.ShowWindow(SW_SHOW);

       page2.ShowWindow(SW_HIDE);

       return 0;

}

void CDelete::OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult)

{    

       *pResult = 0;

 

       switch(m_Tab.GetCurSel())

       {

       case 0:

              page1.ShowWindow(SW_SHOW);

              page2.ShowWindow(SW_HIDE);

              break;

       case 1:

              page1.ShowWindow(SW_HIDE);

              page2.ShowWindow(SW_SHOW);

              break;

       }

}

void CDelete::OnOK()

{

       page1.DestroyWindow();

       page2.DestroyWindow();

       this->DestroyWindow();

}

//

 
發佈了26 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章