<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    VC ++視頻教程(孫鑫)部分筆記

    VC菜單學(xué)習(xí):

    子菜單、菜單項等的概念與菜單項的定位
    菜單項的圖標(biāo)、復(fù)選、系統(tǒng)的屬性獲取
    MFC命令更新機(jī)制 CN_UPDATE_CCmdUI消息,捕獲是用ON_UPDATE_CCmdUI()函數(shù),可以用ClassWizard來;
    去除菜單及局部變量的非法性
    通過ID來與圖標(biāo)一一對應(yīng)
    右鍵彈出菜單 Project/Add to project/Components and  Controls/Visual C++,
    當(dāng)然,也可以手動增加.這里就要將客戶區(qū)坐標(biāo)換成屏幕坐標(biāo),因?yàn)槲覀兘o出的是我們以為的客戶區(qū)坐標(biāo),
    但系統(tǒng)卻把它當(dāng)作屏幕坐標(biāo)
    **********以上是關(guān)于靜態(tài)菜單 的*******************

    ***************以下是動態(tài)菜單(即用代碼添加的)***************
    在MainFrme的OnCreate()中創(chuàng)建
    建立對象,創(chuàng)建某類型的菜單,再獲取主框架的菜單,然后Append上面去或Insert上面去,注意參數(shù)的依賴
    關(guān)系;
    刪除菜單用DeleteMenu()

    Resource.h定義了資源的ID
    手動完成消息響應(yīng):在對應(yīng)頭文件中寫消息處理函數(shù)原型,在其實(shí)現(xiàn)文件中消息對應(yīng)機(jī)制
    接觸集合類和在視圖中輸出、窗口重繪
    VC ++ 開發(fā)過程中常見錯誤提示:在某個星號之前應(yīng)增加分號,而其實(shí)是說星號前面的這個動西它不認(rèn)識
    只有源文件是參與編譯的,頭文件是不參與編譯的
    如何在框架類中去截獲本由View類響應(yīng)的消息。



    對話框:

    對話框:模態(tài)對話框和非模態(tài)
    資源如何與一個類聯(lián)?難道僅僅是通過Load?
    當(dāng)用Create創(chuàng)建非模態(tài)對話框時,還要調(diào)用一個showwindow將其顯示出來,當(dāng)然局部變量不行,但
    為什么模態(tài)對話框行,因?yàn)槠鋾和T谀牵渖芷谖醋?;那么,要使非模態(tài)對話框能顯示,解決的
    辦法有:變?yōu)槌蓡T;二在堆上分配,因?yàn)樵诙焉戏峙涞淖兞?,其生命周期與應(yīng)用程序一樣;
    按鈕的消息屬于通告消息
    在對話框按件上放控件:
    “釘子圖標(biāo)”使保持顯示和不保持
    三種訪問控件的方式:
    第一種:
    表態(tài)文本框:要獲取其文本,也即獲取窗口文本
    獲取對話框上控件的指針,GetDlgItem(),這感覺就有點(diǎn)像在主框架窗口當(dāng)中,當(dāng)時要得到菜單欄一樣;
    對于于靜態(tài)文本框,它是不能接受消息并響應(yīng)的,為了使它能接受,必須改變其屬性,使其能夠Notify
    文本的形式轉(zhuǎn)換成數(shù)值形式
    第二種:
    另外一個函數(shù),GetDlgItemText()
    第三種訪問控件的方式:GetDlgItemInt()和SetDlgItemInt()
    第四種:將控件與成員變量關(guān)聯(lián) -Member Varibles,并可以看看DDX_Text函數(shù) Dialog Data Exchange
           這里更涉及到DoDataExchange()和UpdateData()
    還可以對控件變量關(guān)聯(lián)控件變量本身,其實(shí)也即控件對象。
    第六、從Windows消息的傳遞機(jī)制,我們可以考慮:只要我們知道獲取文本的消息,它是WM_TEXT
    我們可以通過發(fā)送這個SendMessage()這個Win32函數(shù),那么在VC ++中,即通過加雙冒號表示是調(diào)用Win 32
    平臺函數(shù)

    SendMessage的多種實(shí)現(xiàn) ,同時,注意怎樣去獲得句柄

    第七種:直接給對話框子控件發(fā)送消息
    獲取文本框選的一個消息,當(dāng)然,這里面還要設(shè)置其為焦點(diǎn)
    完成對話框的收縮功能,這個功能與Windows畫圖時的擴(kuò)展與收縮類似
    它用Picture來畫成一條線,并將其ID改為IDC_SEPARATOR,并設(shè)置屬性為Sunken
    既然擴(kuò)展時要還原成原來大小,那么其初始狀態(tài)要保存才好;而收縮時,要從圖像控件下面部分切除掉,那么,就
    要獲取切除那一點(diǎn)的縱坐標(biāo)。獲取窗口大小,可以用GetWindowRect()來
    完成窗口伸縮與擴(kuò)展功能,用SetWindowPos()  
    那么,剩下的問題詞是如何改變焦點(diǎn)方式及缺省按鈕的設(shè)置:
    而這不再是簡單地按一個按鈕,就響應(yīng)什么了,那么,這里,其實(shí)是通過InitDialog()函數(shù)中來改變……
    用自寫的窗口過程來代替MFC寫的窗口過程 SetWindowLong是用來改變窗口的屬性,使其控件中使其下一個焦點(diǎn)是其下面的控件
    這里又引起我的思考;強(qiáng)制類型轉(zhuǎn)換底層是怎樣的?
    怎樣去寫窗口函數(shù),可以用先要知道其類wndclass
    那么更簡單的,實(shí)現(xiàn)焦點(diǎn)依次往下傳遞是怎樣的呢?
    獲取窗口句柄:GetWindow(),GetDlgNextItem()
    焦點(diǎn)依次往下傳遞:GetFocus()->GetNextWindow()->SetFocus()
    更安全的代碼是GetNextDlgTabItem(GetFocus())->SetFocus()

     

    基于對話框的應(yīng)用程序:
    逃跑按 鈕的巧妙實(shí)現(xiàn)——
    將兩個按鈕都關(guān)聯(lián)到同一個新建的類,然后,類中可以建一個指針,來保存雙方的地址。
    ********************————————********************************
    屬性表單和菜單項的創(chuàng)建
    要想使視類具有修改編輯功能,我們可以選擇CEditView或CRichEditView類作為其基類
    一、屬性表單是由一頁頁屬性頁組成的,那么我們需一頁頁的創(chuàng)建屬性頁,而每個屬性頁就
    是一個窗口,那么,我們可以通過Insert/Dialog/IDD_……PropertyPage來創(chuàng)建一頁頁的屬性頁;
    這里面本身有VC 6.0 的bug,我們要學(xué)會如何解決:使ClassWizard找到我們新增的類
    我們先找到記錄工程類的信息的文件,我們進(jìn)入工程文件夾里,找到工程名.clw;我們可以將其刪除,
    然后重新打開工程,選擇重新建立工程的clw文件即可;
    通過菜單響應(yīng),在其中增加屬性表單頁表,來調(diào)用DoModal() 并顯示
    那么屬性表單實(shí)際上是屬性頁的父窗口
    根據(jù)MSDN來看,如果我們要得到向?qū)б晥D一步步顯示的效果,我們可以在CPropertySheet類調(diào)用DoModal()
    之前,加上調(diào)用SetWizardMode()來實(shí)現(xiàn)。那么中間又有一些BUG,我們需要改變第一頁,使其只有下一頁按
    鈕,面最后來一頁只有上一步按鈕,那么,我們根據(jù)MSDN的提示,我們知道,解決的辦法是:在CPropertyPage類
    對象中,增加OnSetActive()函數(shù),在這人函數(shù)中調(diào)用CPropertySheet類的SetWizardButtons()函數(shù)。

    那么我們再完善,要求用戶在進(jìn)行了某一項選擇之后再進(jìn)行下一步:
    這里面有一個小的注意,我們要能在ClassWizard中的屬性頁對應(yīng)的類中看到控件的ID,我們需要將控件的
    Group屬性選中,那么表示與這個控件同一類的,緊跟在其后的控件值依次增1,直到遇到下一個具有Group屬性的另
    一個,那么這里我們還有一個問題,對于屬性表單“下一步”的響應(yīng),我們是在哪里面響應(yīng)呢,我們增加虛函數(shù)
    OnWizardNext()
    ☆☆需要強(qiáng)調(diào)一下,我們是通過DoDataExchange()來與一個控件交換數(shù)據(jù)的,注意,是所有控件,只要我們想與之發(fā)生交換數(shù)據(jù)!☆☆
    那么也即調(diào)用UpdateData();
    ☆☆而我們要使下拉列表框中有初始值,我們可以增加WM_INIT()消息響應(yīng)處理函數(shù)☆☆
    增加列表框里面的字符串,用到了AddString()函數(shù)
    同樣,對于第三個屬性頁,我們也可以增加OnWizardNext()虛函數(shù),并在初始化其類之后,也對其增加AddString(),注意,
    我們的ComboBox(組合框)有sort()屬性,它能自排序,同時,我們可以設(shè)置讓其初始顯示一個默認(rèn)值,調(diào)用SetCurSel()函數(shù)

    為了使視類中輸出用戶的選擇,我們要在視類中定義相應(yīng)變量來接收用戶的選擇。
    ☆☆在這里有一個技巧,將BOOL數(shù)組變量賦初值為FALSE,用到C語言中memset()函數(shù)☆☆
    用Invalidate()來使窗口無效,從而引起完成窗口的重繪

    創(chuàng)建字體,然后將其選擇進(jìn)行設(shè)備環(huán)境,它會返回先前的字體,我們將其保存起來
    那么我們輸出時,針對具體我們的選擇,我們應(yīng)該利用我們在視圖類定義的與屬性頁對應(yīng)控件變量的變量來進(jìn)行相應(yīng)改變和輸出,
    當(dāng)然,我們要知道它輸出的位置,我們要調(diào)用GetTextMetrics()函數(shù)來


    修改程序框架及其外觀:

    要想改變MFC應(yīng)用程序的外觀,應(yīng)在其窗口創(chuàng)建之前。
    同樣,要想改變MFC應(yīng)用程序的主框架外觀,應(yīng)在主框架之前,在CMainFrame類的PreCreateWindow()函數(shù)中改變。
    那么我們在開始學(xué)習(xí)VC ++編程時,就已經(jīng)知道,PreCreateWindow()函數(shù)是一個虛函數(shù),按照VC ++機(jī)制,
    如果我們傳遞了子類的指針,,那么它先調(diào)用子類的相應(yīng)函數(shù)。而這個函數(shù)它有一個CREATESTRUCT類型的變量,而且是
    引用的,那么對其的修改,將是全局性的。
    ***********************************************************************************************************
    如果我們要在窗口創(chuàng)建之后改變窗口外觀,行不行?其實(shí),這個函數(shù)我們也已經(jīng)學(xué)了,即SetWindowLong(),同樣也別忘了猜
    測一下有沒有GetWindowLong()這個函數(shù)即其相應(yīng)功能。

    #############################################################################################################
    修改窗口的圖標(biāo)、光標(biāo)和背景,我們應(yīng)如何去修改呢?
    窗口的類型和大小,是在創(chuàng)建和顯示窗口時設(shè)定的,而要改變窗口的圖標(biāo)和光標(biāo)、背景,則是在設(shè)計窗口類時改變的,那是MFC的
    底層代碼,但是我們有其它辦法,可以對其修改:我們可以自己去設(shè)計窗口類,注冊它、顯示它
    ★★在直接用VC ++寫的應(yīng)用程序,我們獲得句柄可以由其WinMain()參數(shù)來,而在MFC中,由于應(yīng)用程序完全是由AppWizard生成
    的,那么,我們要獲得其句柄,需要用到一個全局函數(shù),可以用來獲取當(dāng)前一個應(yīng)用程序的句柄。叫做AfxGetInstanceHandle()
    ★★
    ★在LoadCursor()函數(shù)中,如果我們是要標(biāo)準(zhǔn)光標(biāo),我們需要將第一個參數(shù)設(shè)為NULL
    ★因?yàn)椴藛蔚膭?chuàng)建其實(shí)并不是在設(shè)計窗口類時完成,而是在底層完成,我們知道:在MFC中,
    ★在InitInstance()函數(shù)中,其在單文檔模板中將主菜單的資源標(biāo)識號傳給了我們的模板,
    ★那么在底層代碼下,其完成資源標(biāo)識與ID的轉(zhuǎn)換

    #############################################################################################################
    接下來我們要完成讓主框架窗口的顯示按我們設(shè)計的類來,那么,我們要做的是用cs參數(shù)來
    但是,我們要注意,對于單文檔應(yīng)用程序來說,我們看到的是View視圖類的窗口覆蓋在主框架窗口之上的,所以,如果我們要看到改變的
    效果,我們應(yīng)是在視圖類的PreCreateWindow()函數(shù)中來

    我們可見,為了修改MFC應(yīng)用程序圖標(biāo),我們幾乎重新設(shè)計了一個類,這顯然是不劃算的,那么MFC又提供了一個全局函數(shù),它是
    AfxRegisterWndClass()類名

    ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
    那么如果我們是在窗口創(chuàng)建之后,可不可以修改窗口的圖標(biāo)、光標(biāo)等呢?可以,我們可以利用一個全局的API函數(shù),SetClassLong()

    完成不斷變換的圖標(biāo):
    利用定時器和SetClassLong()即可完成:
    先準(zhǔn)備三幅圖標(biāo),放到res文件夾下
    然后定義存儲三幅圖標(biāo)的句柄數(shù)組,并在CMainFrame類中將數(shù)組元素初始化,用到了當(dāng)前應(yīng)用程序的實(shí)例句柄
    ☆獲得應(yīng)用程序當(dāng)前的實(shí)例句柄,AfxGetInstanceHandle()這個非常有用,別忘了!當(dāng)然,我們也可以
    通過CWinApp這個類本身的成員來實(shí)現(xiàn),當(dāng)然我們在源文件中要
    用到另一個源文件中定義的全局變量,我們要用extern 聲明一下;還可以利用GetApp()函數(shù)輾轉(zhuǎn)來得到當(dāng)前應(yīng)用程序的實(shí)例句柄☆+
    ★怎樣將資源的ID號轉(zhuǎn)換為資源的字符串呢,這里面就有一個宏,MAKEINTRESOURCE()★
    接下來,我們設(shè)置一個定時器,在OnCreate()函數(shù)中調(diào)用SetTimer(),然后在另外增加WM_TIMER消息,在OnTimer()函數(shù)中使用SetClassLong();
    那么,當(dāng)然,我們需要在響應(yīng)定時器的函數(shù)中,圖標(biāo)的index是在合理的變化范圍內(nèi)
    ●這里有一個技巧:要使一個值始終在一個范圍內(nèi),最好的辦法就是取模●

    ###################################################################################################################
    工具欄的編程:
    在工具欄上增加相應(yīng)圖標(biāo)——>具欄上的相應(yīng)圖標(biāo)與菜單欄上的某菜單項同樣的ID號
    在工具欄上要想增加分割符的話,我們可以左點(diǎn)擊控鈕,拖動一段距離;要刪除按鈕的話,拖動它到任意位置
    自創(chuàng)建工具欄,我們先看一下MFC的WizardApp它的是怎樣創(chuàng)建的,我們應(yīng)好好模仿
    在我們MFC中,允許一人ID號對應(yīng)多種資源
    EnableDocking()函數(shù),對于CControlBar類的,是設(shè)置其可以???,而對于主框架類的,則設(shè)置其為可以被???
    下面實(shí)現(xiàn)工具欄由復(fù)選工具箱控制顯示與隱藏:—>IsWindowVisible()來判斷一個窗口是否是可視的,然后在里面調(diào)用ShowWindow()來控制顯示或
    隱藏,但是,還需使用RecalcLayout()來調(diào)整窗口顯示。還有一個問題,當(dāng)我們拖動新工具欄,使其成為浮動窗口時,我們的點(diǎn)擊毫無意義,為此,
    還要使其???
    另一種顯示工具欄的方法是利用CFrameWnd的方法來,即ShowControlBar()

    那么為了更符合我們的使用習(xí)慣,我們可以將菜單上打?qū)矗趯?yīng)菜單上面增加UPDATE_UI_COMMAND的消息處理,在里面可以通過調(diào)用pCmdUI->SetCheck(),
    并在SetCheck()中調(diào)用IsWindowVisible()來同步我們的顯示
    #######################################################################################################################
    狀態(tài)欄的編程:
    狀態(tài)欄分為提示欄和狀態(tài)指示器:而對于MFC已經(jīng)建立的狀態(tài)欄,我們可以其全局變量數(shù)組中增加一些內(nèi)容——>
    首先,我們建立一個在字符串資源,在其中增加字符串及其ID,然后,我們可以通過函數(shù)來獲取相應(yīng)內(nèi)容,比如說,CTime來獲得當(dāng)前時間,再次,我們定義一
    中間臨時變量來存放我們想獲得的內(nèi)容,從而并顯示;利用StatusBar的函數(shù)SetPaneText()來顯示我們想要顯示的內(nèi)容,對于SetPaneText()中要獲得其索引,我們
    可以通過命令標(biāo)題來獲得其索引,即CommandToIndex()
    有時我們要改變窗格的寬度,我們可以通過CStatusBar中的方法來,這個方法是SetPaneInfo()函數(shù),而我們要獲得適當(dāng)字符串的寬度,我們要得適當(dāng)字符串的寬度,
    我們在前面已經(jīng)講過,可以用GetTextExtent(),它會返回CSize的對象,注意:CSize里面的成員變量cx才是其寬度;
    但是,為了顯示時時的最新時間,我們可以通過定時器里來做
    #########################################################################################################################
    進(jìn)度欄的編程實(shí)現(xiàn):
    類是CProgressCtrl,根據(jù)MFC的MSDN,步驟先是構(gòu)造一個CProgressCtrl對象,然后通過Create()來創(chuàng)建具體的進(jìn)度條對象;
    要想將這個進(jìn)度欄放到狀態(tài)欄里面,我們要獲取窗格的大小,我們可以用GetItemRect()來獲取,然后只是要在Create()函數(shù)中將其父窗口設(shè)置為狀態(tài)欄
    ★★★★這里面,調(diào)試時Insert BreakPoints后,再觀察,發(fā)現(xiàn)rect沒獲得想獲得的值班。那么,實(shí)際上,這與消息響應(yīng)的先后順序有關(guān)。★★★★
    ★★★★★★★★我們應(yīng)自定義消息,這樣一來,因?yàn)橄⑹欠旁谙㈥犃挟?dāng)中的,WM_CREATE消息先響應(yīng),這之后,才是我們自定義的消息,那么在★★★★★★★★
    ★★★★★★★★OnCreate()執(zhí)行之后,這樣一來,我們才可能達(dá)到我預(yù)期的目的,由于系統(tǒng)中消息都是用一個整數(shù)表示感謝的★★★★★★★★
    ★★★★★★★★是#define UM_Message WM_USER(WM_USER宏為以上允許用戶自定義的消息范圍)★★★★★★★★
    ★★★★★★★★然后作消息映射,對于消息來說,我們是用ON_MESSAGE這個宏★★★★★★★★
    ★★★★★★★★然后聲明消息處理函數(shù)afx_msg …,如果我們發(fā)送消息要順帶有參數(shù),那么參數(shù)在消息處理函數(shù)中聲明★★★★★★★★
    ★★★★★★★★然后在要發(fā)送消息的函數(shù)中調(diào)用SendMessage()函數(shù)★★★★★★★★
    在以上操作,插入斷點(diǎn),調(diào)試,仍是有問題;事實(shí)上,因?yàn)橛肧endMessage()函數(shù),那么消息馬上進(jìn)入到消息處理之后,然后再返回
    因此我們要換另一個函數(shù):PostMessage(),它是將消息放到消息隊列中,然后通過GetMessage()一條一個條取出運(yùn)行
    當(dāng)然,我們需要解決當(dāng)拖動窗口時,進(jìn)度條在狀態(tài)欄里又出現(xiàn)顯示不當(dāng)?shù)那闆r;這里,其實(shí)它在OnPaint()函數(shù)中,那么還要判斷是否這個狀態(tài)欄是第一次創(chuàng)建,若是,則
    創(chuàng)建;否則,就要移動窗口。移動窗口,有個函數(shù),叫MoveWindow();而要移動進(jìn)度條,可以用StepIt()函數(shù),放在OnTimer()函數(shù)中
    ▲▲在狀態(tài)欄中放置文本,可以調(diào)用SetWindowText()函數(shù)或直接用CFrameWnd類的SetMessageText()函數(shù)直接放在狀態(tài)欄里;也可以用CFrameWnd類的GetMessageBar()▲▲
    ▲▲函數(shù)來獲得狀態(tài)欄的指針;第四種方式,可以用CWnd類的GetDescendantWindow()函數(shù)來獲取子孫窗口,直到找到指定ID的窗口▲▲

    臨時窗口和永久窗口的概念:臨時對象是任意通過FromHandle()函數(shù)創(chuàng)建的沒有封裝過的C++對象

    ######################################################################################################################
    啟動畫面的創(chuàng)建:利用VC給我們提供的組件庫Project->Add to Project->Components and Controls…Visual C++ Components,這里面都是C++里面有用的類
    用類名::函數(shù)名,那么這個函數(shù)就是類的靜態(tài)函數(shù)



    MFC文件操作:

    在C語言中,指向文件的指針很多都是指向常量的指針和其它
    那么,先預(yù)習(xí)前提知識:指向常量的指針和指向指針的常量——>
    指向常量的指針:表示其指向的內(nèi)容是常量,不允許通過指針來修改指向的內(nèi)容.const char *pStr="iosi";或者寫為:char const * pStr="iosi";
                    那么此時若做這個操作——*pStr='W';//error    但是做pStr="wang";//OK
                    當(dāng)然,我們?nèi)钥赏ㄟ^它本身這個字符數(shù)組來修改其里面的內(nèi)容
    指針常量——>指針的值不能改變,但是指針?biāo)傅膬?nèi)容可以改變.char str[5]="isao"; char * const pStr=str;//也即形式是const放在*號的后面
                    那么,我們此時若做這個操作——*pStr='W';//OK    但是做pStr="wnag";//error
                    那么指針常量必須在定義的時候即初始化
    *****文件的操作*****
    要獲取指向文件的指針,我們通過查MSDN,可知有函數(shù)fopen()來。C語言對文件的操作采用緩沖區(qū)來進(jìn)行,所以我們?nèi)绻麤]有用fclose(pFile)來在操作完
    之后關(guān)閉文件,那么,我們只有在結(jié)束運(yùn)行之后,才能看到我們寫成功的文件
    ★★如果我們要對文件頻繁操作,那么,像上述那樣,每次打開、關(guān)閉較麻煩,我們有函數(shù)fflush()來刷新緩沖區(qū),讓緩沖區(qū)的內(nèi)容寫入到磁盤★★
    ☆☆但是,有時我們有一些特殊的應(yīng)用,比如說我們有服務(wù)器端軟件,它監(jiān)聽了很多設(shè)備,它們不斷把日志信息發(fā)送給服務(wù)器端軟件,并寫入服務(wù)器端磁盤,☆☆
    ☆☆如果我們每次去打開、關(guān)閉,那么很可能會丟失許多有用信息,那么我們此時可以使用fflush()函數(shù)來不斷刷新緩沖區(qū)進(jìn)行寫入☆☆
    ※※那么,對于我們C語言文件來說,它其實(shí)有一個文件指針,每次自動移動,指向我們要寫入的地址※※
    如果我們想移動文件指針,有許多函數(shù)可用fseek()、rewind()函數(shù)等,對文件的讀入,有時會因?yàn)檎也坏?\0"結(jié)束符而出現(xiàn)亂碼,對此,我們有多種方法解決
    第一種:是在sizeof()后加1;第二種:使用memset()函數(shù)
    ☆★有時,我們需要獲取文件的長度,用ftell()可以得到文件當(dāng)前指針的位置,那么,如果我們先用fseek()函數(shù)來使文件指針指向文件結(jié)尾處,然后我們再用★☆
    ☆★在對文件進(jìn)行操作時,我們經(jīng)常容易犯的錯誤是移動了指針,等到輸出時卻忘了要將文件指針移到我們想要開始讀出的位置★☆
    ★☆文件操作常犯的失誤:當(dāng)以文本方式去讀與以二進(jìn)制去讀時注意回車與換行的不同★☆
    比如說,如果有一個面試題,讓你將整數(shù)值,例如98341存儲到文件中,打開時,還要是98341,那么,我們要明白這是考察你對文本文件與二進(jìn)制文件的理解。
    文件的存儲底層是以二進(jìn)制的ASCII碼方式存儲,如果我們直接輸出98341,因?yàn)樗妓膫€字節(jié),且編碼是另外一種形式,等我們輸出,它就不是98341,而是按照
    ASCII碼的形式輸出為其它字符,那么,具體地解決辦法是:一、定義一個char[5],然后用char[0]=9+48;//48為0的ASCII編碼
                                                        二、采用itoa(i,ch,10);
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    接下來,我們來看C++中對文件的操作,它是幾個類,比如說ofstream,ifstream或者iostream類
    如果我們要向文件當(dāng)中寫入數(shù)據(jù),我們要用ofstream這個類,并用其方法write()來寫入數(shù)據(jù),并用其close()方法來關(guān)閉文件
    我們在讀取的時候,用ifstream這個類,當(dāng)然,使用它們我們都要包含庫頭文件#include<fstream.h>

    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    那么,下面我們來看一下,Win32中對文件的操作,我們要注意幾個函數(shù)
    CreateFile()用來創(chuàng)建或打開讀取文件等諸多對象,WriteFile()用于向這些對象寫入內(nèi)容,ReadFile()用于讀取數(shù)據(jù),CloseHandle()去關(guān)閉這個對象句柄
    同步IO:即當(dāng)我們寫入或讀取文件的時候,如果我們沒有寫入完,程序就會掛起
    異步IO:重疊IO,
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    接下來,我們來看一下MFC中提供的對文件的操作的類CFile。其打開文件的方法為根據(jù)其構(gòu)造函數(shù)來選擇CFile::modeCreate或其它屬性
    寫出有方法:write(),讀入有方法:read(),關(guān)閉有方法:Close()
    要實(shí)現(xiàn)“打開”、“保存”對話框有CFileDialog這個類,同時,要過濾掉某些文件,需要用到其數(shù)據(jù)成員m_ofn的相應(yīng)屬性,同時,在過濾字符串后面加上\0*.txt等,且最后一個
    字符串以兩個空字符結(jié)尾,對于文件過濾器lpstrfilter的設(shè)置,選兩種格式中間的分割僅用'\0'分開
    \\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
    配置文件的讀寫
    一般文件都寫到注冊表中,如果我們要寫到W.ini文件中,要用到一個函數(shù)WriteProfileString(),然后我們要得到其寫入的配置文件內(nèi)容,我們用函數(shù)GetProfileString()函數(shù)
    //那么如果我們寫入到Win.ini文件中,我們要使用Win 32 API函數(shù)::WriteProfileString() 和相應(yīng)的::GetProfileString()函數(shù),放在APP源文件的InitInstance()函數(shù)中
    //當(dāng)然,我們也可以用CWinApp的成員函數(shù)WriteProfileString()和GetProfileString()函數(shù)來
    /\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
    下面我們來看一下注冊表的編程:
    對注冊表的操作都是通過幾個函數(shù)來完成的,RegCreateKey()和RegSetValue()和最后關(guān)閉RegCloseKey()函數(shù),如果我們要讀取數(shù)據(jù),我們有一個函數(shù)RegQueryValue(),
    當(dāng)然,其中RegSetValue()函數(shù)只能設(shè)置字符串類型的值。如果我們要設(shè)置整型的值,則要用其擴(kuò)展函數(shù)叫RegSetValueEx()函數(shù),對應(yīng)打工用的函數(shù)RegOpenKey()函數(shù),
    然后再用RegQueryValueEx()函數(shù)來取出
    /\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\/\///\\\
    使用CArchive類對文件進(jìn)行操作:


    MFC文件框架內(nèi)部實(shí)現(xiàn)機(jī)制和串行化操作: 文檔與串行化
    另一種文件操作方式——>用CArchive這個類來,其"<<"和">>"這個符號用于寫出和讀入,注意,寫出的順序是怎樣的,那么讀入的順序也是一樣,其使用,具體參照MSDN來

    注意,對于我們的文件保存和文件打開選項,它對應(yīng)的CWinApp類的OnFileNew()和OnFileOpen()函數(shù),而且對于單文檔用戶程序來說,它的pDocument對象只與一個文件相關(guān)聯(lián)。

    下面我們要用CArchive類和Serialize()函數(shù)來實(shí)現(xiàn)文檔的保存和其它操作:
    要按照MSDN提示,可見CArchive類的MSDN說明文檔的下部分鏈接文檔。我們可以拷貝資源
    這里完成一個繪圖的程序:
    它增加了一個CGraph類,這個類由CObject派生出來,目的是為了串行化。那么,同時在菜單中增加了繪制幾個圖形的命令,在…View類中實(shí)現(xiàn),而在CGraph中寫了一個方法
    OnDraw(CDC *pDC),它對應(yīng)…View類中幾乎同樣的功能,而在…View類的OnLButtonUP()函數(shù)中通過CObArray類型的成員方法Add增加了一個CObject的指針。
    現(xiàn)在,我們要做的是:在…Doc類中將我們保存在CObArray集合類中的繪圖信息保存到文件中;那么,首先,我們要在…Doc類中獲得視類的指針,我們有一個方法
    GetFirstViewPosition()先獲得其位置,然后利用GetNextView()來獲得其視類指針

    MFC文件框架內(nèi)部實(shí)現(xiàn)機(jī)制和串行化操作: 文檔與串行化
    另一種文件操作方式——>用CArchive這個類來,其"<<"和">>"這個符號用于寫出和讀入,注意,寫出的順序是怎樣的,那么讀入的順序也是一樣,其使用,具體參照MSDN來

    注意,對于我們的文件保存和文件打開選項,它對應(yīng)的CWinApp類的OnFileNew()和OnFileOpen()函數(shù),而且對于單文檔用戶程序來說,它的pDocument對象只與一個文件相關(guān)聯(lián)。

    下面我們要用CArchive類和Serialize()函數(shù)來實(shí)現(xiàn)文檔的保存和其它操作:
    要按照MSDN提示,可見CArchive類的MSDN說明文檔的下部分鏈接文檔。我們可以拷貝資源
    這里完成一個繪圖的程序:
    它增加了一個CGraph類,這個類由CObject派生出來,目的是為了串行化。那么,同時在菜單中增加了繪制幾個圖形的命令,在…View類中實(shí)現(xiàn),而在CGraph中寫了一個方法
    OnDraw(CDC *pDC),它對應(yīng)…View類中幾乎同樣的功能,而在…View類的OnLButtonUP()函數(shù)中通過CObArray類型的成員方法Add增加了一個CObject的指針。
    現(xiàn)在,我們要做的是:在…Doc類中將我們保存在CObArray集合類中的繪圖信息保存到文件中;那么,首先,我們要在…Doc類中獲得視類的指針,我們有一個方法
    GetFirstViewPosition()先獲得其位置,然后利用GetNextView()來獲得其視類指針;而要在視類中獲得文檔類的指針,我們可以利用其本身有的成員函數(shù)GetDocument()方法
    ★★在我們保存可串行化的數(shù)據(jù)對象時,實(shí)際上是利用我們對象本身的Serialize()函數(shù)本身去實(shí)現(xiàn)★★



    線程同異步及套接字:

    事件內(nèi)核對象、關(guān)鍵代碼段(臨界區(qū))的講解,以及在多線程同步中的應(yīng)用。在Windows下編寫基于消息的網(wǎng)絡(luò)應(yīng)用程序,掌握阻塞與非阻塞網(wǎng)絡(luò)程序的編寫,
    理解在Windows平臺下,采用★★異步選擇機(jī)制可以提高網(wǎng)絡(luò)應(yīng)用程序的性能。★★

    事件對象:
    創(chuàng)建一個事件對象,我們要用到一個函數(shù)CreateEvent()函數(shù)
    下面我們用事件對象來創(chuàng)建線程同步應(yīng)用程序。
    創(chuàng)建事件對象,然后在內(nèi)部循環(huán)中,調(diào)用事件對象。
    注意:人工重置的事件對象,它一旦有信號后,所有等待該事件對象的線程都可運(yùn)行,而自動重置的事件對象,它只能供一個線程使用,且一旦一個線程
    等待到它時,操作系統(tǒng)內(nèi)部自動將其設(shè)為非信號狀態(tài)。人工重置的事件對象需要顯示調(diào)用Reset()函數(shù),才將事件對象設(shè)為非信號狀態(tài)。
    通過創(chuàng)建一個命名的事件對象,我們可以完成讓一個應(yīng)用程序一次只能有一個實(shí)例運(yùn)行這樣的功能。

    接下來,我們來看另一種同步方式:————》使用關(guān)鍵代碼段
    關(guān)鍵代碼段工作在用戶方式下,它是可運(yùn)行的一個小段代碼,它必須一次性獨(dú)立完整地執(zhí)行完。
    我們要想進(jìn)入關(guān)鍵代碼段,我們需要調(diào)用一個函數(shù)EnterCriticalSection()。我們的臨界區(qū)對象它是由系統(tǒng)內(nèi)部自動回復(fù)的。當(dāng)我們訪問完系統(tǒng)資源以后,它需要
    離開臨界區(qū)對象,我們又用到一個函數(shù)LeaveCriticalSection()。當(dāng)我們這個公用電話亭(臨界區(qū)對象)不需要再存在時,我們就刪除它,用到函數(shù)DeleteCriticalSection()
    函數(shù)。★★注意:刪除臨界區(qū)對象是在所有程序主線程最后退出之前,否則,在多線程程序中會出現(xiàn)內(nèi)存不能為written的BUG★★
    所以,我們在做多線程程序時,一定要避免線程間死鎖的發(fā)生。

    互斥對象和事件對象屬于內(nèi)核對象,利用內(nèi)核對象進(jìn)行線程同步,速度較慢,但利用互斥對象和事件對象這樣的內(nèi)核對象,可以在多個進(jìn)程中的各個線程間進(jìn)行同步。
    關(guān)鍵代碼段是工作在用戶方式下,同步速度較快,但在使用關(guān)鍵代碼段時,很容易進(jìn)入死鎖狀態(tài),因?yàn)樵诘却M(jìn)入關(guān)鍵代碼段時無法設(shè)定超時值。
    我們在MFC編程時,可以在類的構(gòu)造函數(shù)中調(diào)用InitializeCriticalSection()函數(shù),在其析構(gòu)函數(shù)中調(diào)用DeleteCriticalSection()函數(shù)。但是,當(dāng)有多個共有資源時,我們
    要防止發(fā)生死鎖。

    Windows套接字在兩種模式下執(zhí)行I/O操作,阻塞和非阻塞。在阻塞模式下,在I/O操作完成前,執(zhí)行操作的Winsock函數(shù)會一直等待下去,不會立即返回程序(將控制權(quán)交還給程序)。而在非阻塞模式下,Winsock函數(shù)無論如何都會立即返回。
    Windows Sockets為了支持Windows消息驅(qū)動機(jī)制,使應(yīng)用程序開發(fā)者能夠方便地處理網(wǎng)絡(luò)通信,它對網(wǎng)絡(luò)事件采用了基于消息的異步存取策略。
    Windows Sockets的異步選擇函數(shù)WSAAsyncSelect()提供了消息機(jī)制的網(wǎng)絡(luò)事件選擇,當(dāng)使用它登記的網(wǎng)絡(luò)事件發(fā)生時,Windows應(yīng)用程序相應(yīng)的窗口函數(shù)
    將收到一個消息,消息中指示了發(fā)生的網(wǎng)絡(luò)事件,以及與事件相關(guān)的一些信息。也就是說,我們可以登記多種事件,當(dāng)?shù)怯浀氖录l(fā)生時,我們可以發(fā)送消息,然后系統(tǒng)進(jìn)行處理。

     int WSAEnumProtocols( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, ILPDWORD lpdwBufferLength );
    Win32平臺支持多種不同的網(wǎng)絡(luò)協(xié)議,采用Winsock2,就可以編寫可直接使用任何一種協(xié)議的網(wǎng)絡(luò)應(yīng)用程序了。通過WSAEnumProtocols函數(shù)可以獲得系統(tǒng)中安裝的網(wǎng)絡(luò)
    協(xié)議的相關(guān)信息。lpiProtocols,一個以NULL結(jié)尾的協(xié)議標(biāo)識號數(shù)組。這個參數(shù)是可選的,如果lpiProtocols為NULL,則返回所有可用協(xié)議的信息,否則,只返回數(shù)組
    中列出的協(xié)議信息。lpProtocolBuffer,[out],一個用WSAPROTOCOL_INFO結(jié)構(gòu)體填充的緩沖區(qū)。 WSAPROTOCOL_INFO結(jié)構(gòu)體用來存放或得到一個指定協(xié)議的完整信息。
    lpdwBufferLength,[in,out],在輸入時,指定傳遞給WSAEnumProtocols()函數(shù)的lpProtocolBuffer緩沖區(qū)的長度;在輸出時,存有獲取所有請求信息需
    傳遞給WSAEnumProtocols()函數(shù)的最小緩沖區(qū)長度。這個函數(shù)不能重復(fù)調(diào)用,傳入的緩沖區(qū)必須足夠大以便能存放所有的元素。這個規(guī)定降低了該函數(shù)的
    復(fù)雜度,并且由于一個 機(jī)器上裝載的協(xié)議數(shù)目往往是很少的,所以并不會產(chǎn)生問題。

    接下來,我們采用異步套接字編寫一個網(wǎng)絡(luò)聊天室程序:
    首先,我們要加載套接字庫,但是,采用AfxSocketInit()函數(shù),我們加載的1.1版本的的套接字庫,而在我們這里,要用到WinSock2版本的的套接字,因此,我們還是調(diào)用
    WSAStartup()這個函數(shù)。我們將其放到CWinApp的Initinstance()這個函數(shù)中。同時,我們要加載庫文件#include<Winsock2.h>,和庫Ws2_32.lib這個庫。
    然后我們給應(yīng)用程序類加一個析構(gòu)函數(shù),用來調(diào)用WSACleanup()函數(shù)。然后對對話框類加一個套接字成員變量。接下來,按部就班,綁定套接字,綁定之后,就可以
    調(diào)用WSAAsyncSelect()函數(shù)了,接收數(shù)據(jù),發(fā)送數(shù)據(jù)。

    ★★在套接字庫中,對增加的函數(shù),函數(shù)名前面都是以WSA開頭★★


    什么叫重疊套接字??異步選擇機(jī)制??
    將主機(jī)名轉(zhuǎn)換成IP地址,我們可以用一個函數(shù)gethostbyname()函數(shù)。反之,則有另一個函數(shù),叫g(shù)ethostbyaddress()函數(shù)。


    多線程與聊天程序:

    多線程的編寫與對象的互斥:
    一、互斥命名對象的概念與創(chuàng)建
    多線程運(yùn)行在程序進(jìn)程的空間中,每個線程占用CPU時間片,OS以某種方式能安排時間片給不同的線程使用。
    采用多線程的好處是:線程占用的資源較少,同時,進(jìn)程與進(jìn)程之間切換花費(fèi)的時間長,代價大。

    創(chuàng)建一個線程,首先,我們要用Windows操作系統(tǒng)提供的API函數(shù),所以,我們要包含頭文件#include<windows.h>
    其次,按順序,我們先要用到函數(shù)CreateThread()這個函數(shù),完成后,我們要調(diào)用CloseHandle()來完成。注意,我們
    調(diào)用CloseHandle()并沒有終止線程,只是關(guān)閉了句柄,同時,讓這個線程的內(nèi)核引用計數(shù)遞減。顯而易見,當(dāng)我們的主線程
    退出時,從線程也就不可能再運(yùn)行了。當(dāng)然,這里肯定有BUG,為此,要使線程同步,也即要使一個線程在操作共有資源時,必須其全部過程完成之后,另一個線程
    才能操作共有資源   ★為了調(diào)試多線程的程序,我們可以在對共有資源操作時,可以調(diào)用Sleep()函數(shù),進(jìn)行調(diào)試來發(fā)現(xiàn)錯誤★

    我們要做線程的同步,要用到一個函數(shù),CreateMutex()函數(shù)。
    ★★★互斥對象(mutext)屬于內(nèi)核對象,它能確保線程擁有對單個資源的互斥訪問。
    互斥對象包含一個使用數(shù)量、一個線程ID和一個計數(shù)器。
    那么,在線程中,我們就要去請求這個互斥對象,要用到WaitForSingleObject()函數(shù),而釋放互斥對象,我們又要用到一個函數(shù)。
    這個互斥對象是誰擁有,誰去釋放。★★★
    正因?yàn)榛コ鈱ο笥芯€程相關(guān)的這個特性,我們才能用它來作為“鑰匙”,來作線程同步用。

    ★★所有與窗口有關(guān)的類,都有一個成員m_hWnd,這是一個與窗口相關(guān)的句柄★★

    下面,我們用多線程來創(chuàng)建一個網(wǎng)絡(luò)聊天室程序:
    當(dāng)然,我們肯定是基于套接字的,為此,要加載并協(xié)商套接字,我們在MFC中用到的函數(shù)是AfxSocketInit()函數(shù),而用到個函數(shù),我們要加載
    <AfxSock.h>頭文件,AfxSocketInit()函數(shù)是要放在CWinApp的InitInstance()函數(shù)中。
    當(dāng)然,注意,在調(diào)用CreateThred()函數(shù)時,線程運(yùn)行時,第三個參數(shù)需要知道已經(jīng)聲明的函數(shù)和其實(shí)現(xiàn)細(xì)節(jié),但是,在VC++編程中,要知道其實(shí)現(xiàn)細(xì)節(jié),則需要已經(jīng)創(chuàng)建了對象。解決的話,可以將作為其成員函數(shù)時,將其作為靜態(tài)成員函數(shù)。

    為什么采用多線程?  一般的,我們的接收窗口只有在有數(shù)據(jù)時才會有所響應(yīng),否則,將一直暫停,顯然,這在聊天室程序中不行,因此必須采用多線程。
    怎樣進(jìn)入新線程然后又發(fā)回到主線程?


    網(wǎng)絡(luò)編程:

    網(wǎng)絡(luò)的相關(guān)知識,網(wǎng)絡(luò)程序的編寫,Socket連接應(yīng)用程序并bind()網(wǎng)絡(luò)驅(qū)動程序:
    網(wǎng)絡(luò)及通信——>通信雙方與規(guī)則(協(xié)議),還要用端口號標(biāo)識是哪個命令終端(也即網(wǎng)絡(luò)應(yīng)用程序);
    封裝就是在數(shù)據(jù)的前面加上特定的協(xié)議頭部。
    運(yùn)輸層提供使運(yùn)行中的進(jìn)程進(jìn)行通信的能力。為了標(biāo)識通信的進(jìn)程TCP/IP提出了協(xié)議端口的概念。端口是一種抽象的軟件結(jié)構(gòu)。
    socket(套接字)是網(wǎng)絡(luò)應(yīng)用程序訪問通信協(xié)議的操作系統(tǒng)調(diào)用。存在于通信域中。在網(wǎng)絡(luò)協(xié)議中需要確定網(wǎng)絡(luò)字節(jié)的順序。
    套接字的類型:
    1、流式套接字(SOCK_STREAM),提供面向連接的、可靠的、無重復(fù)的、按順序接收的通信
    2、數(shù)據(jù)報式套接字(SOCK_DGRAM),提供無連接式服務(wù)。
    3、原始套接字(SOCK_RAW)。
    △▲客戶端/服務(wù)器模式▲△
    在TCP/IP網(wǎng)絡(luò)應(yīng)用中,通信的兩個進(jìn)程間相互作用的主要模式是客戶機(jī)/服務(wù)器模式(client/server),即客戶向服務(wù)器提出請求,服務(wù)器接收到請求后,提供相應(yīng)的服務(wù)。
    客戶機(jī)/服務(wù)器模式的建立基于以下兩點(diǎn):首先,建立網(wǎng)絡(luò)的起因是網(wǎng)絡(luò)中軟硬件資源、運(yùn)算能力和信息不均等,需要共享,從而造就擁有眾多資源的主機(jī)提供服務(wù),資源
    較少的客戶請求服務(wù)這一非對等作用。其次,網(wǎng)間進(jìn)程通信完全是異步的,相互通信的進(jìn)程間既不存在父子關(guān)系,又不共享內(nèi)存緩沖區(qū),因此需要一種機(jī)制為希望通信的
    進(jìn)程間建立聯(lián)系,為二者的數(shù)據(jù)交換提供同步,這就是基于客戶機(jī)/服務(wù)器模式的TCP/IP。
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ★★基于TCP的網(wǎng)絡(luò)應(yīng)用程序socket編程(面向連接的)★★
    ★服務(wù)器端程序:
    1、創(chuàng)建套接字(socket)。 
    2、將套接字綁定到一個本地地址和端口上(bind)。
    3、將套接字設(shè)為監(jiān)聽模式,準(zhǔn)備接收客戶請求(listen)。
    4、等待客戶請求到來;當(dāng)請求到來后,接受連接請求,返回一個新的對應(yīng)于此次連接的套接字(accept)。
    5、用返回的套接字和客戶端進(jìn)行通信(send/recv)。
    6、返回,等待另一客戶請求。
    7、關(guān)閉套接字。
    ★客戶端程序:
    1、創(chuàng)建套接字(socket)。 
    2、向服務(wù)器發(fā)出連接請求(connect)。
    3、和服務(wù)器端進(jìn)行通信(send/recv)。
    4、關(guān)閉套接字。
    ★★基于UDP的網(wǎng)絡(luò)應(yīng)用程序socket編程(面向無連接的)★★
    ★服務(wù)器端(接收端)程序:
    1、創(chuàng)建套接字(socket)。 
    2、將套接字綁定到一個本地地址和端口上(bind)。
    3、等待接收數(shù)據(jù)(recvfrom)。
    4、關(guān)閉套接字。
    ★客戶端(發(fā)送端)程序:
    1、創(chuàng)建套接字(socket)。 
    2、向服務(wù)器發(fā)送數(shù)據(jù)(sendto)。
    3、關(guān)閉套接字。

    下面我們來編寫命令終端式的面向連接的應(yīng)用程序
    要建立這類應(yīng)用程序,首先是我們要加載Socket庫,這里竟不是用預(yù)處理命令,而是用到一個平臺函數(shù)WSAStartup()函數(shù);
    然后根據(jù)上面函數(shù)的MSDN參考資料,我們完成之后,接下來要創(chuàng)建套接字,我們用到函數(shù)socket();
    創(chuàng)建套接字成功后,我們需要將其綁定到本地的端口上,要用到bind()函數(shù)。注意除了safamily這個參數(shù)以外,其它的都要轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序,為此,我們要用到htol()函數(shù)和
    htons()函數(shù)
    接下來我們應(yīng)該調(diào)用一個listen()函數(shù)來將我們的套接字設(shè)置為監(jiān)聽模式,然后做一個死循環(huán),不斷等待連接的到來,這即要調(diào)用一個函數(shù),等待客戶的連接到來,此函數(shù)即為
    accept()函數(shù)。接下來,在建立連接之后,我們可以進(jìn)行通信了,我們可以用send()函數(shù)來發(fā)送數(shù)據(jù)。與此同時,我們也可以接收一個數(shù)據(jù),用到方法recv()。接收完數(shù)據(jù)后,
    我們需要closesocket()方法去關(guān)閉socket套接字。釋放為套接字所分配的資源。
    當(dāng)然,在這個程序當(dāng)中,因?yàn)槲覀兪褂昧颂捉幼值暮瘮?shù),我們需要包含Winsock.h頭文件,同時還要鏈接一個庫文件Ws2__32.lib

    接下來我們?nèi)ゾ帉懣蛻舳顺绦?
    當(dāng)然前半部分我們與服務(wù)器端程序差不多,不過,我們不用bind()SOCKET套接字,而是直接用connect()函數(shù)去連接。
    當(dāng)我們連接之后,就可接收服務(wù)器端發(fā)送過來的數(shù)據(jù)recv(),當(dāng)然,我們也可以向服務(wù)器端發(fā)送數(shù)據(jù)send(),同樣,當(dāng)我們通信完成之后,我們也要釋放套接字closesocket(),
    最后,我們也需要終止對套接字庫的使用,我們用WSACleanup();

    下面我們來編寫命令終端式的面向無連接的應(yīng)用程序
    對于服務(wù)器端:
    同樣,順序是先加載套接字庫,然后,建立套接字socket(),并與本地地址綁定bind(),此后,這里與面向連接的不同,不再需要設(shè)置為什么監(jiān)聽模式,而是直接用recvfrom()
    函數(shù)來開始獲取信息。
    對于客戶端:
    它加載了套接字后,建立了套接字socket()后,同樣不需要綁定,而是直接可以發(fā)送各接受消息。發(fā)送消息要調(diào)用的是sendto()函數(shù)。
    這個客戶端設(shè)置的端口為服務(wù)器端設(shè)置的接收消息的端口。

    下面我們完成一個基于字符界面的聊天程序:
    對于聊天程序,我們常用基于面向無連接的的程序,采用UDP,實(shí)時性好。注意,要從鍵盤獲取輸入信息,我們有一個函數(shù)gets(),它可以從標(biāo)準(zhǔn)I/O獲得輸入

     

     鉤子程序與數(shù)據(jù)庫編程:

    Hook編程。如何安裝鉤子過程,如何編寫全局鉤子,動態(tài)連接庫里的全局變量數(shù)據(jù)共享問題分析。ADO數(shù)據(jù)庫編程。在VB中利用ADO控件和ADO對象訪問數(shù)據(jù)庫,在VC中利用ADO技術(shù)訪問數(shù)據(jù)庫。

    Hook編程:兩種鉤子——》一種是進(jìn)程內(nèi)鉤子,一種是全局鉤子。
    什么叫Hook程序,即鉤子程序?由我們的Windows消息驅(qū)動機(jī)制,我們的應(yīng)用程序由于用戶的操作,產(chǎn)生信號,OS將對應(yīng)的消息放到消息隊列,并在一定時間,將消息取出,交由我們的應(yīng)用程序按照消息對應(yīng)的過程進(jìn)行處理。那么,如果我們想在于這個過程中截取消息并作我們特殊的處理,那么,實(shí)現(xiàn)我們這個目的過程即是鉤子程序。

    安裝鉤子,我們有對應(yīng)的函數(shù),叫SetWindowsHookEx(),其具體要求做哪些準(zhǔn)備,我們可以從MSDN其函數(shù)本身說明中可知。

    那么,有可能我們涉及到要建庫,我們有一個建立動態(tài)鏈接庫的需要,而在這個庫中,我們要得到DLL庫的實(shí)例句柄的話,我們可以可以通過DLLMain()函數(shù)的參數(shù)得到,另外,我們也可用方法GetModuleHandle()。
    ★★原來,動態(tài)鏈接庫它也有一個入口,即DLLMain()函數(shù)。★★
    我們可以自建一個動態(tài)鏈接庫,然后,在其同樣的文件夾下,建一個模塊定義文件.def.注意,我們導(dǎo)出的文件有一個序號。
    動態(tài)鏈接庫不能獨(dú)立運(yùn)行,我們必須寫一個程序,然后加載這個庫。

    ★★動態(tài)鏈接庫的調(diào)試:★★
    比如說,我們要查看SetHook()(該函數(shù)是放在動態(tài)鏈接庫中),我們可以在該函數(shù)處設(shè)置斷點(diǎn)。然后我們在調(diào)試時可以選擇Debug\Step Into(F11鍵)

    ★★我們?nèi)绻朐谝粋€函數(shù)中獲得主窗口的句柄的話,我們除了可以在函數(shù)中想到用什么函數(shù)外,我們也可以將主窗口的句柄通過函數(shù)參數(shù)傳過來★★
    ★★動態(tài)鏈接庫中,對于我們的數(shù)據(jù),Windows 2000采用的是寫入式拷貝,因此,如果我們想使所有進(jìn)程都共享數(shù)據(jù),我們須在動態(tài)庫自己建一個結(jié),將數(shù)據(jù)寫在結(jié)中,用到一個#pragma data_seg("輸入名字"),并再用一個指令#pragma data_seg()作為結(jié)尾,將我們想共享的數(shù)據(jù)放在這兩個代碼的中間,注意,這個數(shù)據(jù)必須賦初值;然后將結(jié)設(shè)置為共享。我們又用到另一個#pragma comment(linker,"/section:上面輸入的名字,RWS")★★
    ★★除了用以上方式呢,我們也可以在模塊定義文件中寫上SEGMENTS ┓結(jié)名 其權(quán)限,如READ WRITE SHARED★★

    ★★我們可以用鉤子來獲取密碼等重要信息,這是它本身經(jīng)常的角色。★★

    ★★★★★★★★★★★★★★★★★★★★★★★數(shù)據(jù)庫的編程★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    不同的數(shù)據(jù)庫廠商,會在其提供數(shù)據(jù)產(chǎn)品時,也要給程序員們提供訪問其數(shù)據(jù)庫的接口,即API,那么,當(dāng)我們要編寫一個數(shù)據(jù)庫時,我們需要學(xué)習(xí)這些新的API

    微軟數(shù)據(jù)訪問技術(shù)有:
    ODBC(開放數(shù)據(jù)互連),可以訪問各種支持ODBC的關(guān)系型數(shù)據(jù)庫
    DAO(數(shù)據(jù)訪問對象)——基于Microsoft Access/Jet引擎,主要是用于VB開發(fā)面向Access數(shù)據(jù)庫的
    RDO(遠(yuǎn)程數(shù)據(jù)訪問對象)其實(shí)也是基于ODBC
    OLE DB(對象鏈接與嵌入數(shù)據(jù)庫),對ODBC進(jìn)行了擴(kuò)展,可以訪問關(guān)系型數(shù)據(jù)庫及非關(guān)系型。OLE DB程序的基本結(jié)構(gòu)是:OLE DB提供程序和用戶程序
    ADO(Activex Data Object),它建立在OLE DB之上,是OLE DB用戶程序。提供了對自動化的支持,連一些腳本語言也可以用其來訪問數(shù)據(jù)庫

    下面,我們來編寫ADO數(shù)據(jù)庫應(yīng)用程序
    ADO有三個核心對象:
    一、Connection對象:用于管理用戶程序與數(shù)據(jù)庫通信,表示了到數(shù)據(jù)庫的鏈接。
    二、Command對象:用來處理重復(fù)執(zhí)行的查詢
    三、Recordset對象:用來獲取數(shù)據(jù)庫中的數(shù)據(jù)
    注意,在編寫數(shù)據(jù)庫應(yīng)用程序時,在顯示時,一定不能忘了移動游標(biāo),否則,是一個死循環(huán)了。★★我們要記住,對數(shù)據(jù)庫的訪問,總是按行進(jìn)行的。★★
    ★VB中,若是在組件旁右擊,想添加組件,則我們可以右擊選擇組件;當(dāng)然,若是直接想在編碼中用數(shù)據(jù)庫相應(yīng)對象,則我們在Projects/下選擇的是Reference★

    ★★在VC中,我們要用到ADO去訪問數(shù)據(jù)庫,我們首先要導(dǎo)入一個庫msado15.dll,我們可以在StdAfx.h這個預(yù)編譯頭文件中導(dǎo)入,用到#import 完整路徑名 no_namespace★★
    ★★為避免命名誤會,我們可以將用rename將一個名字改為另一個名字。因?yàn)槲覀冋f過,OLE DB是基于COM組件的,因此,如果我們要用ADO訪問控件時,我們要加載COM★★

     

     

    posted on 2011-08-11 21:15 Hua Hero 閱讀(941) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計

    常用鏈接

    留言簿

    隨筆檔案

    文章檔案

    搜索

    最新評論

    主站蜘蛛池模板: 亚洲欧洲中文日韩av乱码| 亚洲日韩在线视频| 无码人妻一区二区三区免费看| 久久亚洲中文字幕精品有坂深雪 | 99久久精品国产亚洲| 女人18毛片水最多免费观看 | 曰批全过程免费视频播放网站 | 色婷婷亚洲一区二区三区| 亚洲人色婷婷成人网站在线观看| 95老司机免费福利| 黄网站色成年片大免费高清 | 中文字幕无码毛片免费看| 亚洲人成人77777网站不卡 | 久久亚洲中文无码咪咪爱| 国产日产亚洲系列| 大陆一级毛片免费视频观看i| 你是我的城池营垒免费看| 亚洲人成人网站18禁| 亚洲成A人片在线观看无码不卡| 免费黄网在线观看| 久久国产色AV免费看| 无码日韩人妻AV一区免费l | 亚洲av女电影网| 免费在线观看的黄色网址| 精品免费人成视频app | 亚洲av无码天堂一区二区三区| 18以下岁毛片在免费播放| 一级特黄a大片免费| 亚洲精品动漫免费二区| 亚洲自偷精品视频自拍| 伊人久久大香线蕉亚洲| 国产无遮挡吃胸膜奶免费看视频| 69式互添免费视频| 大地资源中文在线观看免费版 | 成年女人毛片免费播放视频m| a级在线观看免费| 一级毛片一级毛片免费毛片| 亚洲精品一卡2卡3卡四卡乱码| 久久久亚洲裙底偷窥综合| 亚洲第一AAAAA片| 国产精品亚洲一区二区三区在线|