日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

VC++笔记

發(fā)布時間:2023/12/4 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 VC++笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

匈牙利表示法

?

關(guān)于構(gòu)造函數(shù)

?

顯式調(diào)用基類的有參數(shù)的構(gòu)造函數(shù):

?

類繼承當中的三種屬性:

?

引用和指針

?

重復(fù)命名錯誤及解決

?

。。。

?

?

Windows程序運行原理PPT

?

?

?

窗口的創(chuàng)建步驟

  1. 設(shè)計一個窗口類;

typedef struct _WNDCLASS {

?? UINT??? ? style;

?? WNDPROC lpfnWndProc;

?? int???? ??? cbClsExtra;

?? int???? ??? cbWndExtra;

?? HANDLE ?? hInstance;

?? HICON?? hIcon;

?? HCURSOR ???????? hCursor;

?? HBRUSH? ???????? hbrBackground;

?? LPCTSTR ?? lpszMenuName;

?? LPCTSTR ?? lpszClassName;?

} WNDCLASS;

?

  1. 注冊窗口類;
  2. 創(chuàng)建窗口;
  3. 顯示及更新窗口。

虛函數(shù)

它是C++語言多態(tài)性的體現(xiàn)之一;

多態(tài)性是指不同類型的對象接收相同的消息時產(chǎn)生不同的行為;

多態(tài)性分為編譯時的多態(tài)性和運行時的多態(tài)性;

編譯時的多態(tài)性是通過函數(shù)的重載或運算符的重載來實現(xiàn)的;

運行時的多態(tài)性是通過虛函數(shù)來實現(xiàn)的;

這兩種多態(tài)性的方式對應(yīng)的是兩種編譯方式,靜態(tài)聯(lián)編(早期聯(lián)編)和動態(tài)聯(lián)編(晚期聯(lián)編)

虛函數(shù)特點如下:

1、? 虛函數(shù)在重新定義時參數(shù)的類型和個數(shù)必須和基類的虛函數(shù)完全匹配,這一特點與函數(shù)重載完全不同;

2、? 虛函數(shù)所具有的功能只有通過指針 才能得到,虛函數(shù)在用對象名和運算符以正常方式調(diào)用時,不能達到其功能;

3、? 虛函數(shù)必須是類的一個成員函數(shù),不能是友元函數(shù),也不能是靜態(tài)的成員函數(shù);

4、? 可以把析構(gòu)函數(shù)定義為虛函數(shù),但是不能將構(gòu)造函數(shù)定義為虛函數(shù);通常釋放基類中和其派生類中的動態(tài)申請的存儲空間時,也要把析構(gòu)函數(shù)定義為虛函數(shù),以便實現(xiàn)撤銷對象時的多態(tài)性。

純虛函數(shù)是一種特殊的虛函數(shù)。

?

文件操作

1、創(chuàng)建文件實例:fstream file;

2、聲明文件操作類型:file.open(“file.txt”,ios::out|ios::app)

3、進行相應(yīng)的文件讀寫操作:file.write(&ch,Num)

單文檔應(yīng)用程序SDI

程序框架:

1)???????? 應(yīng) 用 類:MyClass.h和MyClass.cpp,繼承類CWinApp, ,消息映射機制

2)??????? 文 檔 類:MyClassDoc.h和MyClass.cpp ,繼承類CDocument, ,消息映射機制

3)??????? 視 圖 類:MyClassView.h和MyCassView.cpp, 繼承類Cview,消息處理、文檔格式化 和文檔數(shù)據(jù)可視化處理,消息映射機制

4)??????? 主框架類:MainFrm.h和MainFrm.cpp ,繼承類CframeWnd,創(chuàng)建和控制選單、工具欄?????????????????????? 和狀態(tài)欄等界面元素,消息映射機制

5) “關(guān)于”對話框類:MyClass.cpp,繼承類Cdialog,數(shù)據(jù)映射機制

MFC三種消息的區(qū)別?

消息驅(qū)動機制的形象解釋?

接受-發(fā)送-處理

ClassWizard產(chǎn)生消息映射所完成的三個內(nèi)容安排 :

  1. 在頭文件***View.h中聲明消息處理函數(shù)

afx_msg void OnButtonDown(UNIT nFlags,Cpoint point);

DECLARE_MESSAGE_MAP();

  1. 在源文件***View.cpp的前面消息映射入口處添加相應(yīng)的宏

BEGIN_MESSAGE_MAP(C***View,CView)

ON_WM_LBUTTONDOWN()

END_MESSAGE_MAP()

  1. 在***View.cpp文件中寫入空的消息處理函數(shù)的模板,以便用戶填入代碼

添加類C***

1、? 增加兩個文件:頭文件C***.h和源文件C***.cpp,這兩個文件只是單獨的兩個文件,與主程序可能沒有關(guān)聯(lián),關(guān)聯(lián)時可以在主程序中包含該類的頭文件即可。

2、 由于對話框的代碼是以類為木塊來設(shè)計的,那么在當文檔程序中調(diào)用對話框,只需要在單文檔程序Myclass.cpp源文件上面加上包含類C***的頭文件,然后在InitInstance()函數(shù)體中的return前面添加兩行代碼:C*** dlg;dlg.DoModal();即可。

3、具體創(chuàng)建類的方法略

刪除類C***步驟

1、在ClassWizard中刪除類

2、用delete鍵“軟件”刪除類C***對應(yīng)的.h和.cpp兩個文件,取消關(guān)聯(lián)

3、關(guān)閉項目,在項目文件夾“硬件”刪除類C***對應(yīng)的.h和.cpp兩個文件以及.clw文件

改變按鈕標題方法:

1、利用按鈕本身的屬性對話框修改標題:變量m_MyBtn->SetWindowText(“歡迎”);

2、調(diào)用函數(shù):GetDlgItem(IDC_BUTTON1)->SetWindowText(“歡迎”);

?

ClassWizard創(chuàng)建變量所完成的三個內(nèi)容安排:

1、在應(yīng)用類頭文件(.h)中添加相關(guān)變量的聲明

2、在應(yīng)用類源文件(.cpp)的應(yīng)用類構(gòu)造函數(shù)中添加變量的初始化代碼

3、在應(yīng)用類源文件(.cpp)的DoDataExchange函數(shù)體內(nèi)添加DDX/DDV代碼.進行數(shù)據(jù)交換

常用控件

1、單選按鈕IDC_RADIO:

a)????? 設(shè)置默認選定按鈕:CheckRadioButton(IDC_RADIO1,IDC_RADIO4,IDC_RADIO1);

b)????? 獲得選定的單選按鈕的ID: int nID = GetCheckedRadioButton(IDC_RADIO1,IDC_RADIO4);

c)?????? 讓控件不可用(即變成灰色):GetDlgItem(ID)->EnableWindow(BOOL);

2、? 復(fù)選框IDC_CHECK:

a)???????? 如果選定了一個框,則其相應(yīng)的變量為1;

b)??????? ?

3、? 編輯框IDC_EDIT:

a)???????? 其變量的類型有很多:int、char、double…甚至可以是CString

b)??????? 變量類型是前三種的話,那么變量是什么,則編輯框內(nèi)顯示什么;

c)???????? 如果變量是Cstring類型:則顯示方法為:m_Edit.Format(“%6.2f”,m);或則m_Ave.LoadString(IDS_STRING);

d)??????? 消息:為編輯框添加EN_CHANGE消息映射

4、? 列表框IDC_LIST:

a)???????? 首先定義變量m_List,其類型是Cstring;

b)??????? 列表框顯示的是字符串,如果這個字符串代表很多數(shù)據(jù),則要將它和其他數(shù)據(jù)關(guān)聯(lián);

c)???????? 列表框的項往往用索引來確定,找到索引號,那么就可以找出項的內(nèi)容,所以要想對項進行操作,第一重要的就是找出它的索引號nIndex,然后就可以調(diào)用m_List(實際上是CString)的成員函數(shù)來獲得根據(jù)nIndex來查詢項數(shù)據(jù)、增加項、刪除項、查找項等操作;

d)??????? 找出索引號方法:int nIndex = m_List.GetCurSel(),它是整型數(shù)據(jù),列表框的第一項索引是從0開始的;

e)???????? 增加項:int nIndex = m_List.AddString(m_strName)

f)????????? 查找項,主要是為了防止重復(fù)增加項:m_List.FindString(-1,m_strName)(從頭查)

g)??????? 選擇項:m_List.SetCurSel(nIdnex);

h)??????? 根據(jù)索引號進行操作:

i,刪 除 項: m_List.DeleteString(nIdnex)

Ii,獲取數(shù)據(jù): m_List.GetText(nIndex, m_strName);

SCORE *data=(SCORE *)m_List.GetItemDataPtr(nIndex);

m_List.GetItemData (nIndex,DWORD data);

Iii,關(guān)聯(lián)數(shù)據(jù):數(shù)據(jù)比較多時候,可以預(yù)先建立一個數(shù)組或則結(jié)構(gòu)體

Int m_List.SetItemDataPtr(nIndex,new SCORE(data));(結(jié)構(gòu)體SCORE)

DOUBLE m_List.SetItemDataPtr(nIndex)

?

5、? 組合框IDC_COMBO

a)???????? 組合框是集編輯框和列表框于一體,所以既可以編輯輸入,也可以列表顯示;

b)??????? 有列表框的功能,也是根據(jù)索引號來增加項,刪除項,查找項,還可以用此索引號來關(guān)聯(lián)數(shù)據(jù)或則數(shù)據(jù)指針;

c)???????? 組合框的通知消息中最為常用的是:CBN_SELCHANGE (當組合框中的當前選擇項將要改變時發(fā)送此消息);注意這個消息是為控件本身添加的;

6、? 滾動條IDC_SCROLLBAR

a)???????? 基本操作:

設(shè)置滾動條范圍m_Scroll.SetScrollRange(0,255)

獲取滾動條范圍void GetScrollRange(lpMinpos, lpMaxpos)

設(shè)置滾動條的當前位置m_Scroll.SetScrollPos(m_RValue)

獲取滾動條的當前位置int GetScrollPos()

b)??????? 消息:

為對話框添加消息WM_HSCROLL或則WM_VSCROLL,因為滑動條(下面將提到)和滾動條都可以產(chǎn)生WM_HSCROLL或則WM_VSCROLL消息,因此當它們處在同一方向時,就需要添加代碼判斷是誰產(chǎn)生的消息;

點擊滾動條的相應(yīng)位置就產(chǎn)生相應(yīng)的消息,見下圖

?

?

SB_LINELEFT???????????????????????? SB_LINERIGHT

???????? SB_PAGELEFT???? SB_PAGERIGHT

?

?

?

?

?

7、? 滑動條IDC_SLIDER

  1. 基本操作:

設(shè)置滾動條范圍m_Slide.SetRange(0,255)

獲取滾動條范圍void GetRange(lpMinpos, lpMaxpos)

設(shè)置滾動條的當前位置m_ Slide.SetPos(int m_RValue)

獲取滾動條的當前位置int GetPos()

設(shè)置滑動條控件中的一個刻度線的位置:BOOL SetTic(int nTri)

設(shè)置刻度線的疏密程度:void SetTicFreq(int nFre)

刪除當前刻度線:void ClearTics(BOOL)

設(shè)置滑動條的開始和結(jié)束位置:void SetSelection(int nMin,int nMax)

  1. 消息:? 消息代碼都來自于WM_HSCROLL或WM_VSCROLL消息

8、? 旋轉(zhuǎn)按鈕IDC_SPIN

a)???????? 基本操作:

  1. 設(shè)置基數(shù)int SetBase( int nBase );
  2. 設(shè)置旋轉(zhuǎn)按鈕控件的當前位置和范圍int SetPos( int nPos );

void SetRange( int nLower, int nUpper );

  1. 設(shè)置和獲取旋轉(zhuǎn)按鈕控件的加速度BOOL SetAccel( int nAccel, UDACCEL* pAccel );

b)??????? 通知消息:

旋轉(zhuǎn)按鈕控件的通知消息只有一個:UDN_DELTAPOS,它是當控件的當前數(shù)值將要改變時向其父窗口發(fā)送的

9、? 標簽控件IDC_TAB

a)???????? 標簽控件的基本操作 :…

  1. ???????????????????????????????????????????????????? i.????????????? m_Tab.SetMinTabWidth(80);????????? // 設(shè)置標簽項的最小寬度
  2. ??????????????????????????????????????????????????? ii.????????????? m_Tab.SetPadding(CSize(12,3)); // 設(shè)置標簽項和圖標周圍的間隔
  3. ????????????????????????????????????????????????? iii.????????????? m_Tab.SetCurSel(0);//設(shè)置默認選定項
  4. ???????????????????????????????????????????????? iv.????????????? m_pTabDlg->Create(IDD_DIALOG3,&m_Tab);//指定IDD_DIALOG3的父窗口是m_Tab指向的窗口

b)??????? 標簽控件的通知消息:為控件映射TCN_SELCHANGE消息

c)???????? 為一個新建的Dialog創(chuàng)建一個類的時候,可以用一個指針來指向這個窗口

CTab1Dlg *m_pTab1Dlg;

d)??????? 注意創(chuàng)建的子窗口是無模式對話框m_pTab1Dlg->Create(IDD_DIALOG1,&m_Tab);

10、 消息對話框

a)???????? 最簡單的一類對話框,只是用來顯示信息的。MFC類庫中提供相應(yīng)的函數(shù)實現(xiàn)這樣的功能,只要在程序任何地方調(diào)用它們。

b)??????? 函數(shù)原型:

int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );

int MessageBox( LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK );

11、 ?

菜單

  1. 菜單操作有兩種方法:一種是ResourceView標簽操作,但是只能進行簡單的增加和刪除,還有一種是通過編程進行菜單操作
  2. 菜單的編程控制

a)???????? 基本操作:Cmenu類

l????????? 創(chuàng)建菜單:BOOL CreateMenu( );??????????? // 產(chǎn)生一個空菜單?

BOOL CreatePopupMenu( );? // 產(chǎn)生一個空的彈出式子菜單

l????????? 裝入菜單:BOOL LoadMenu( LPCTSTR lpszResourceName );

BOOL LoadMenu( UINT nIDResource );

l????????? 添加菜單項:末尾處增加與指定位置添加

BOOL ?AppendMenu( UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL );

BOOL ?AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

BOOL InsertMenu( UINT nPosition, UINT nFlags,UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

BOOL? InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

l????????? 刪除菜單項:BOOL DeleteMenu( UINT nPosition, UINT nFlags );

一定要調(diào)用CWnd::DrawMenuBar使菜單更新

l????????? 獲取菜單項:下面的三個CMenu成員函數(shù)分別獲得菜單的項數(shù)、菜單項的ID號以及彈出式子菜單的句柄。

UINT GetMenuItemCount( ) const;該函數(shù)用來獲得菜單的菜單項數(shù),調(diào)用失敗后返回-1。

UINT GetMenuItemID( int nPos ) const;該函數(shù)用來獲得由nPos指定菜單項位置(以0為基數(shù))的菜單項的標識號,若nPos是SEPARATOR,則返回-1。

CMenu* GetSubMenu( int nPos ) const; 該函數(shù)獲得指定菜單的彈出式菜單的菜單句柄

  1. 舉例說明
  • CMenu* pSysMenu = GetMenu();?????????????? // 獲得主菜單句柄
  • CMenu* pSubMenu = pSysMenu->GetSubMenu(1);// 獲得第二個子菜單的句柄
  • CString StrMenuItem("新的菜單項");
  • pSubMenu->AppendMenu(MF_SEPARATOR);? // 增加一水平分隔線
  • pSubMenu->AppendMenu(MF_STRING,ID_NEW_MENUITEM,StrMenuItem);

快捷菜單

用資源編輯器和MFC庫的CMenu::TrackPopupMenu函數(shù)創(chuàng)建這樣的菜單,CMenu::TrackPopupMenu函數(shù)原型如下:

BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL );

???????? x和y表示菜單的水平坐標和菜單的頂端的垂直坐標。pWnd表示彈出菜單的窗口。lpRect是一個RECT結(jié)構(gòu)或CRect對象指針,表示一個矩形區(qū)域,單擊這個區(qū)域時,彈出菜單不消失。當lpRect為NULL時,若擊在菜單外面,菜單立刻消失。

舉例:

在CMainFrame類加入WM_CONTEXTMENU消息處理函數(shù),代碼。

void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point)

{???????

CMenu menu;

menu.LoadMenu(IDR_MYFLOATMENU);

menu.GetSubMenu(0)

???????? ->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);

}

工具欄

工具欄和菜單相結(jié)合的方法:將工具欄按鈕的ID號設(shè)置的和相應(yīng)的菜單欄的ID號碼一樣就行了;

狀態(tài)欄

???? AppWizard創(chuàng)建的SDI或MDI應(yīng)用程序框架中,有一個靜態(tài)的indicator數(shù)組,它是在MainFrm.cpp文件中定義的,被MFC用作狀態(tài)欄的定義。

?

1.在狀態(tài)欄上顯示文本

???????? 有三種辦法可以在狀態(tài)欄窗格顯示文本信息:

???????? (1)調(diào)用CWnd::SetWindowText更新信息行窗格(或窗格0)中的文本。由于狀態(tài)欄也是一種窗口,故在使用時可直接調(diào)用。若狀態(tài)欄變量為m_wndStatusBar,則m_wndStatusBar. SetWindowText(“消息”)語句將在信息行窗格(或窗格0)內(nèi)顯示“消息”字樣。

???????? (2)手動處理狀態(tài)欄的ON_UPDATE_COMMAND_UI更新消息,并在處理函數(shù)中調(diào)用CCmdUI::SetText函數(shù)。

???????? (3)調(diào)用CStatusBar::SetPaneText函數(shù)更新任何窗格(包括信息行窗格)中的文本。此函數(shù)原型描述如下:

???????? BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE );

2.交互對象的更新:

像菜單欄、工具欄這樣的就是交互對象,可能是因為它們有相同的ID,功能一樣,當一個起作用的時候,另一個的狀態(tài)要做相應(yīng)的改變。

為能使交互對象動態(tài)更新,MFC通過ClassWizard直接映射交互對象的更新命令消息來實現(xiàn)。自動將用戶交互對象的ID號與ON_UPDATE_COMMAND_UI宏相連接并產(chǎn)生處理更新消息的相應(yīng)函數(shù),此消息處理函數(shù)只有一個參數(shù),它是指向CCmdUI對象的指針。CCmdUI 類僅用于ON_UPDATE_COMMAND_UI處理函數(shù),它的成員函數(shù)將對菜單項、工具按鈕等用戶交互對象起作用。

為什么新建的選單不能添加子選單?

SetWindowLong(hWnd,GWL_STYLE,pNewStyle)?

實例:“在列表視圖中以四種方式顯示當前文件夾中的所有文件“

  1. 要? 求:

1)???????? 用四種不同方式顯示文件:“大圖標“小圖標”“列表視圖”“報表視圖”;

2)??????? 用快捷鍵ctrl+shift+X來切換顯示方式;

3)??????? 雙擊圖標時候彈出消息對話框,對話框顯示文件類型名;

  1. 關(guān)鍵點:

1)???????? 如何獲取當前文件夾中的所有文件;

2)??????? 如何獲取各個文件的圖標以便添加到與列表控件相關(guān)聯(lián)的圖像列表中去;

3)??????? 如何設(shè)置報表顯示方式中的標題頭;

  1. 解? 決:

1)???????? 通過MFC類CfileFind來查詢文件;

2)??????? 使用API函數(shù)SHGetFileInfo來獲取文件信息,包括文件圖標;

3)??????? 使用LVCOLUMN結(jié)構(gòu)體來設(shè)置標題頭;

  1. 步? 驟:????????

1)???????? 建立列表控件風格切換函數(shù)(需要調(diào)用函數(shù)SetWindowLong(hWnd,GWL_STYLE,pNewStyle)),方便之后的函數(shù)調(diào)用;

2)??????? 將項目工作區(qū)窗口切換到ResourceView頁面,打開Accelerator節(jié)點下的IDR_MAINFRAME,為其添加一個鍵盤加速鍵Ctrl+Shift+X,其ID號為ID_VIEW_CHANGE。用ClassWizard為CEx_ListView類添加ID_VIEW_CHANGE的COMMAND消息映射函數(shù),并添加相應(yīng)代碼(這里的代碼里面就要調(diào)用相應(yīng)的風格切換函數(shù));

3)??????? 用ClassWizard為CEx_ListView類添加NM_DBLCLK消息映射函數(shù),并添加相應(yīng)代碼(可根據(jù)用戶要求來寫,本例需要彈出消息對話框,那么需要調(diào)用Messagebox());

4)??????? 添加查找文件、關(guān)聯(lián)圖標等的代碼(在CEx_ListView::OnInitialUpdate中添加代碼)

a)???????? 創(chuàng)建圖像列表,用來保存文件圖標

b)??????? 創(chuàng)建字符串數(shù)組類,用來保存文件類型,它無需跟列表控件關(guān)聯(lián),因為它主要是用來添加不重復(fù)的圖標的

c)???????? 創(chuàng)建(獲取)列表控件“句柄”,用來顯示等操作

d)??????? 關(guān)聯(lián)圖像列表和列表控件,列表控件中顯示的圖標都是從圖標列表中調(diào)取的

e)???????? 查找當前目錄下的文件,根據(jù)目錄依次查找文件并獲取文件的信息

f)????????? 獲取文件的信息(圖標,文件完整名稱(含擴展名),文件大小,文件類型,文件最后修改時間)

g)??????? 往字符串數(shù)組類中添加文件類型信息

h)??????? (如果文件類型不重復(fù)就)往圖像列表中添加文件圖標信息

i)????????? 設(shè)置報表模式顯示的表頭格式以及列寬

j)????????? 設(shè)置文件大小的顯示格式

k)??????? 設(shè)置文件最后修改時間的顯示格式

l)????????? 設(shè)置默認顯示方式為報表顯示

5)??????? 根據(jù)報表效果的顯示方式來安排程序,報表顯示方式如下,可見程序有如下幾部分:

?

總結(jié)步驟:

1)????????? 加入List Control控件

2)???????? 為該控件聲明一個對象,CListCtrl m_list;使用類向?qū)碜?/p>

3)???????? 設(shè)置CListCtrl的屬性

m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

?????????????????? m_list.SetBkColor(RGB(247,247,255));

?????????????????? m_list.SetTextColor(RGB(0,0,255));

m_list.SetTextBkColor(RGB(247,247,255));

4)???????? 設(shè)置列名

m_list.InsertColumn(0, "姓名", LVCFMT_LEFT, 80);

?????????????????? m_list.InsertColumn(1, "現(xiàn)居地", LVCFMT_LEFT, 100);

m_list.InsertColumn(2, "聯(lián)系電話", LVCFMT_LEFT, 110);

尤其要記得要將控件的類型修改為"Report"類型.

5)???????? 設(shè)置各列的內(nèi)容

m_list.InsertItem(0,"李");

????????????? m_list.SetItemText(0,1,"北京");

????????????? m_list.SetItemText(0,2,"13111111111");

???????

????????????? m_list.InsertItem(1,"張");

????????????? m_list.SetItemText(1,1,"上海");

????????????? m_list.SetItemText(1,2,"13222222222");

6)???????? 讀取數(shù)據(jù)

?????????????? m_list.GetItemText(行數(shù), 列數(shù));

7)???????? 每行前有復(fù)選框的列表

?????????????????? 初始化時使用LVS_EX_CHECKBOXES屬性

?????????????????? DWORD dwStyle;

??????????????????? dwStyle = m_list.GetStyle();

??????????????????? dwStyle |= LVS_EX_GRIDLINES |LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES ;

?????????????????? m_list.SetExtendedStyle(dwStyle);

???????? ??????????設(shè)置選中:

?????????????????? m_list.SetItemState (行數(shù),0x2000, LVIS_STATEIMAGEMASK);//設(shè)為選中狀態(tài)

??????????????????? 判斷是否選中:

?????????????????? m_list.GetItemState(行數(shù),LVIS_STATEIMAGEMASK)==0x2000//選中

切分窗口

A CSplitterWnd is usually embedded in a parent CFrameWnd or CMDIChildWnd object by taking the following steps:

  1. Embed a CSplitterWnd member variable in the parent frame.
  2. Override the parent frame’s OnCreateClient member function.
  3. Call the CreateStatic member function from within the overridden CFrameWnd::OnCreateClient.

怎樣設(shè)置透明效果

1)???????? 用SetLayedWindowAttributes實現(xiàn)整個窗口的半透明效果

BOOL?? CDlgTop::OnInitDialog()??

{

CDialog::OnInitDialog();

//以下代碼是我從別人那里抄來的,主要是使CDlgTop對話框透明

//出處為www.vckbase.com,不用細看其內(nèi)容

// 添加透明擴展樣式

SetWindowLong(this-> GetSafeHwnd(),GWL_EXSTYLE,

GetWindowLong(this-> GetSafeHwnd(),GWL_EXSTYLE)^0x80000);

// 添加庫

HINSTANCE?? hInst?? =?? LoadLibrary( "User32.DLL ");??

// 讀取函數(shù)指針

if(hInst)??

{????????????????????????

typedef?? BOOL?? (WINAPI?? *MYFUNC)(HWND,COLORREF,BYTE,DWORD);????????????????????

MYFUNC?? fun?? =?? NULL;

//取得SetLayeredWindowAttributes函數(shù)指針??????????

fun=(MYFUNC)GetProcAddress(hInst,?? "SetLayeredWindowAttributes ");

if(fun)fun(this-> GetSafeHwnd(),0,128,2);??????????

FreeLibrary(hInst);??

}

return?? TRUE;

}

// 函數(shù)原型如下:

BOOL SetLayeredWindowAttributes(

 HWND hwnd, // 窗口

 COLORREF crKey, // 顏色鍵

 BYTE bAlpha, // alpha值

 DWORD dwFlags // 透明方法

);

2)??????? 怎樣實現(xiàn)窗口的半透明漸變效果

?

3)??????? Static控件背景透明大法

常用添加dialog的OnCtlColor方法。。。修改代碼如下

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

if(nCtlColor==CTLCOLOR_STATIC)

{

?? pDC->SetBkMode(TRANSPARENT);

?? pDC->SetTextColor(RGB(255,255,255));

?? return?? (HBRUSH)::GetStockObject(NULL_BRUSH);??

}

怎樣制作電子時鐘

CWnd::OnCtlColor

This method is called by the framework when a child control is about to be drawn. Most controls send this message to their parent, usually a dialog box, to prepare the pDC for drawing the control using the correct colors.

用雙擊事件關(guān)閉窗口WM_LBUTTONDCLK

vc實現(xiàn)平滑地關(guān)閉窗口?

使窗口居中并且占整個屏幕的90%

BOOL CMainFrame::PreCreateWindow ( CREATESTRUCT& cs)

{

// center window at 90% of full screen

int xSize = ::GetSystemMetrics (SM_CXSCREEN);

int ySize = ::GetSystemMetrics (SM_CYSCREEN);

cs.cx = xSize*9/10;

cs.cy = ySize*9/10;

cs.x = (xSize-cs.cx)/2;

cs.y = (ySize-cs.cy)/2;

return CMainFrame::PreCreateWindow(cs);}

?

?

文件操作詳解

  1. 文件的創(chuàng)建
  2. 文件的讀寫
    1. 普通方法:直接使用CFile進行

// 對文件進行讀操作

???????? char sRead[2];

???????? CFile mFile(_T("user.txt"),CFile::modeRead);

???????? if(mFile.GetLength()<2)

?????????????????? return;

???????? mFile.Read(sRead,2);

???????? mFile.Close();

// 對文件進行寫操作

???????? CFile mFileW(_T("user.txt"),CFile::modeWrite|CFile::modeCreate);

???????? mFileW.Write(sRead,2);

???????? mFileW.Flush();

???????? mFileW.Close();

  1. 簡單方法:使用CArchive

首先使用CFile聲明一個對象,然后用這個對象的指針做參數(shù)聲明一個CArchive對象,我們就可以方便地存儲各種復(fù)雜的數(shù)據(jù)類型了。

???????? //對文件進行寫操作

???????? CString strTemp;

???????? CFile mfile;

???????? mfile.Open("E:\\201101-201102\\C++項目文件\\ComDlg\\user.txt",

?????????????????? CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);

???????? CArchive ar(&mfile,CArchive::store);

???????? ar<<strTemp;

???????? ar.Close();

???????? mfile.Close();

???????? // 對文件進行讀操作

???????? CFile mfilew;

???????? if (mfilew.Open("E:\\201101-201102\\C++項目文件\\ComDlg\\user.txt",CFile::modeRead)==0)

?????????????????? return;

???????? CArchive ar1(&mfilew,CArchive::load);

???????? ar1>>strTemp;

???????? ar1.Close();

???????? mfilew.Close();

  1. CArchive的<<和>>操作符用于簡單數(shù)據(jù)類型的讀寫,對于CObject派生類的存??????????????? 取要使用ReadClass()和WriteClass()還可以進行類的讀寫,如:

// 存儲CAboutDlg類

???????? ar.WriteClass(RUNTIME_CLASS(CAboutDlg));

//讀取CAboutDlg類

???????? CRuntimeClass* mRunclass = ar.ReadClass();

//使用CAboutDlg類

???????? CObject* pObject = mRunclass->CreateObject();

???????? ((CDialog* )pObject)->DoModal();

在文檔區(qū)域繪圖

  1. 畫筆

創(chuàng)建畫筆-選擇畫筆-繪制圖形-恢復(fù)畫筆

void CMyView::OnDraw( CDC* pDC )

{

?????????????????? CPen newPen( PS_SOLID, 2, RGB(0,0,0) ) );

???????? ???????? CPen*? oldPen = pDC->SelectObject(&newPen);

?????????????????? pDC->SelectObject( &newPen );

???????????????? pDC->MoveTo(...);

?????????????????? pDC->LineTo(...);

?????????????????? //pDC->SelectStockObject( BLACK_PEN );??????? // newPen被分離出來

???????? ???????? pDC->SelectObject(oldPen);????????????????????????????????? // 恢復(fù)原來畫筆

???????? ???????? newPen.Detach();????????? // 將畫筆對象與其構(gòu)造的內(nèi)容分離,以便能再次構(gòu)造畫筆

}

  1. 字體

void CMyView::OnDraw( CDC* pDC )

{

???????? CFont font;

???????? LOGFONT lf;

???????? memset(&lf, 0, sizeof(LOGFONT));?????? // zero out structure

???????? lf.lfHeight = 12;????????????????????? // request a 12-pixel-height font

???????? strcpy(lf.lfFaceName, "Arial");??????? // request a face name "Arial"

???????? VERIFY(font.CreateFontIndirect(&lf));? // create the font

???????? // Do something with the font just created...

???????? CClientDC dc(this);

???????? CFont* def_font = dc.SelectObject(&font);

???????? dc.TextOut(5, 5, "Hello", 5);

???????? dc.SelectObject(def_font);

???????? // Done with the font. Delete the font object.

???????? font.DeleteObject();

}

在文檔區(qū)顯示位圖資源

  1. 圖標

由于位圖不能直接顯示在實際設(shè)備中,因此對于GDI位圖的顯示則必須遵循下列步驟:

?????????????????? (1)? 調(diào)用CBitmap類的CreateBitmap、CreateCompatibleBitmap以及 ?????????????????????????????? ???????? CreateBitmapIndirect函數(shù)創(chuàng)建一個適當?shù)奈粓D對象。

?????????????????? (2)? ???????? 調(diào)用CDC::CreateCompatibleDC函數(shù)創(chuàng)建一個內(nèi)存設(shè)備環(huán)境,以便位圖在內(nèi)??????????? ?????????????????? 存中保存下來,并與指定設(shè)備(窗口設(shè)備)環(huán)境相兼容;

?????????????????? (3)? ???????? 調(diào)用CDC::SelectObject函數(shù)將位圖對象選入內(nèi)存設(shè)備環(huán)境中;

?????????????????? (4)? ???????? 調(diào)用CDC::BitBlt或CDC::StretchBlt函數(shù)將位圖復(fù)制到實際設(shè)備環(huán)境中。

?????????????????? (5)? ???????? 使用之后,恢復(fù)原來的內(nèi)存設(shè)備環(huán)境。

?

void CSDITextView::OnDraw(CDC* pDC)

{

???????? CSDITextDoc* pDoc = GetDocument();

???????? ASSERT_VALID(pDoc);

???????? CBitmap m_bmp;//CObject的派生類

???????? m_bmp.LoadBitmap(IDB_BITMAP1);?????????????????? // 調(diào)入位圖資源

???????? BITMAP bm;

???????? m_bmp.GetObject(sizeof(BITMAP),&bm);

???????? CDC dcMem;???????????????????????????? // 定義并創(chuàng)建一個內(nèi)存設(shè)備環(huán)境

???????? dcMem.CreateCompatibleDC(pDC);

???????? CBitmap *pOldbmp = dcMem.SelectObject(&m_bmp); // 將位圖選入內(nèi)存設(shè)備環(huán)境中

???????? pDC->StretchBlt(0,0,bm.bmWidth,bm.bmHeight,&dcMem,0,0,1024,768,SRCCOPY);

???????? // 將位圖復(fù)制到實際的設(shè)備環(huán)境中

//用BitBlt函數(shù)顯示速度比StretchBlt快? StretchBlt可以對圖像擴大或則縮小

???????? dcMem.SelectObject(pOldbmp);????????????????????????? // 恢復(fù)原來的內(nèi)存設(shè)備環(huán)境

}

  1. 光標

BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)

{

???????? // TODO: Add your message handler code here and/or call default

???????? BOOL bRes = CFrameWnd::OnSetCursor(pWnd, nHitTest, message);

???????? if (nHitTest == HTCLIENT|HTCAPTION|HTBOTTOMLEFT )

???????? {

?????????????????? HCURSOR hCursor;

?????????????????? hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);

?????????????????? SetCursor(hCursor);

?????????????????? bRes = TRUE;

???????? }

???????? return bRes;

}

在窗口畫線的幾種方法

  1. 利用SDK全局函數(shù)實現(xiàn)畫線功能

void CDrawLineView::OnLButtonDown(UINT nFlags, CPoint point)

{

???????? m_pOrign = point;

???????? CView::OnLButtonDown(nFlags, point);

}

void CDrawLineView::OnLButtonUp(UINT nFlags, CPoint point)

{

???????? HDC hDC;

???????? hDC = ::GetDC(m_hWnd);

???????? MoveToEx(hDC,m_pOrign.x,m_pOrign.y,NULL);

???????? LineTo(hDC,point.x,point.y);

???????? ::ReleaseDC(m_hWnd,hDC);

???????? CView::OnLButtonUp(nFlags, point);

}

  1. 利用MFC的CDC類實現(xiàn)畫線功能

將上面藍色部分替換成以下代碼,實現(xiàn)功能是一樣的

???????? CDC* pDC = GetDC();

???????? pDC->MoveTo(m_pOrign);

???????? pDC->LineTo(point);

???????? ReleaseDC(pDC);

  1. 利用MFC的CClientDC類來實現(xiàn)畫圖功能

??

將上面藍色部分替換成以下代碼,實現(xiàn)功能是一樣的

CClientDC dc(this);//this指向客戶區(qū)//換成GetParent()就可以在框架上面畫線了

???????? dc.MoveTo(m_pOrign);

???????? dc.LineTo(point);

  1. 利用MFC的CWindowDC()畫線

這樣可以繪圖到工具欄/菜單欄區(qū)域(非客戶區(qū))CWindowDC dc(GetParent());

  1. 在桌面窗口上面畫線CWindowDC dc(GetDesktopWindow());

線條的屬性

要利用屬性,按以下步驟:

創(chuàng)建GDI對象(如畫筆工具),用SelectObject()將畫筆工具選入設(shè)備描述表,繪制完畢恢復(fù)畫筆

顏色??

?

void CDrawLineView::OnLButtonDown(UINT nFlags, CPoint point)

{

???????? m_pOrign = point;

???????? CView::OnLButtonDown(nFlags, point);

}

void CDrawLineView::OnLButtonUp(UINT nFlags, CPoint point)

{

???????? CPen pen(PS_SOLID,4,RGB(255,0,0));//創(chuàng)建GDI對象

???????? CWindowDC dc(GetDesktopWindow());//

???????? CPen* pOldPen = dc.SelectObject(&pen);//選入設(shè)備表

???????? dc.MoveTo(m_pOrign);

???????? dc.LineTo(point);

dc.SelectObject(pOldPen);

???????? CView::OnLButtonUp(nFlags, point);

}

?

繪制透明的矩形,使它不擋住下面的圖形

void CDrawLineView::OnLButtonUp(UINT nFlags, CPoint point)

{???????

CClientDC dc(this);

???????? CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

???????? CBrush* pOleBrush = dc.SelectObject(pBrush);

???????? dc.Rectangle(CRect(m_pOrign,point));

???????? dc.SelectObject(pOleBrush);

???????? CView::OnLButtonUp(nFlags, point);

}

繪制連續(xù)的線條

m_bDraw用來判斷左鍵是否按下,按下就開始劃線,松開就結(jié)束這段線。

void CDrawLineView::OnLButtonDown(UINT nFlags, CPoint point)

{

???????? m_bDraw = TRUE;

???????? m_pOrign = point;

???????? CView::OnLButtonDown(nFlags, point);

}

void CDrawLineView::OnLButtonUp(UINT nFlags, CPoint point)

{

???????? m_bDraw = FALSE;

???????? CView::OnLButtonUp(nFlags, point);

}

void CDrawLineView::OnMouseMove(UINT nFlags, CPoint point)

{

???????? CClientDC dc(this);

???????? if(m_bDraw == TRUE)

???????? {

?????????????????? dc.MoveTo(m_pOrign);

?????????????????? dc.LineTo(point);

???????? ???????? m_pOrign = point;//修改起點

???????? }

???????? CView::OnMouseMove(nFlags, point);

}

繪制扇形? :只需將以上代碼的藍色部分去掉即可

通過畫刷填充在鼠標拖曳的矩形

void CDrawLineView::OnLButtonDown(UINT nFlags, CPoint point)

{

???????? m_pOrign = point;

???????? CView::OnLButtonDown(nFlags, point);

}

void CDrawLineView::OnLButtonUp(UINT nFlags, CPoint point)

{

???????? CBrush bru(RGB(255,1,1));

???????? CClientDC dc(this);

???????? dc.FillRect(CRect(m_pOrign,point),&bru);

???????? CView::OnLButtonUp(nFlags, point);

}

創(chuàng)建文本插入符

?

int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

???????? if (CView::OnCreate(lpCreateStruct) == -1)

?????????????????? return -1;

???????? CreateSolidCaret(20,100);//創(chuàng)建20*100大小的插入符

???????? ShowCaret();//顯示出來

???????? return 0;

}

添加字符串資源

BOOL LoadString(nID)

字符輸入

?

?

? ? ? ?

void CTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) //消息WM_CHAR

{

???????? CClientDC dc(this);

???????? TEXTMETRIC tm;

???????? dc.GetTextMetrics(&tm);

???????? if (0x0d == nChar)//回車

???????? {

?????????????????? m_strLine.Empty();

?????????????????? m_ptOrign.y += tm.tmHeight;

???????? }

???????? else if (0x08 == nChar)//退格運用視覺小技巧:刪除的文字顏色和背景顏色一樣就行了

???????? {

?????????????????? COLORREF clr = dc.SetTextColor(dc.GetBkColor());//返回文本先前的顏色

?????????????????? dc.TextOut(m_ptOrign.x,m_ptOrign.y,m_strLine);

?????????????????? m_strLine = m_strLine.Left(m_strLine.GetLength()-1);

?????????????????? dc.SetTextColor(clr);

???????? }

???????? else

???????? {

?????????????????? m_strLine += nChar;

???????? }

?

???????? CSize sz = dc.GetTextExtent(m_strLine);//使插入符也跟著移動

???????? CPoint pt;

???????? pt.x = m_ptOrign.x+sz.cx;

???????? pt.y = m_ptOrign.y;

???????? SetCaretPos(pt);//當然插入符的初始位置及大小在OnDraw中已經(jīng)設(shè)置好

?

???????? dc.TextOut(m_ptOrign.x,m_ptOrign.y,m_strLine);

?

???????? CView::OnChar(nChar, nRepCnt, nFlags);

}

?

void CTextView::OnLButtonDown(UINT nFlags, CPoint point) //消息WM_LBUTTONDOWN

{

???????? SetCaretPos(point);

???????? m_strLine.Empty();//新位置清空字符串

???????? m_ptOrign = point;//保存點

?

???????? CView::OnLButtonDown(nFlags, point);

}

字體設(shè)置

?

?

?

卡拉OK字幕變色效果

void CTextView::OnTimer(UINT nIDEvent)

{

???????? // TODO: Add your message handler code here and/or call default

???????? m_nWidth += 5;

???????? CClientDC dc(this);

???????? TEXTMETRIC tm;

???????? dc.GetTextMetrics(&tm);//獲得當前字體的字體信息

?

???????? CString str;

???????? str.LoadString(IDS_STRINGVC);

???????? dc.SetTextColor(RGB(0,255,0));

???????? dc.TextOut(0,200,str);//運行時就輸出一行字幕

?

???????? CRect rect;

???????? rect.left = 0;

???????? rect.top = 200;

???????? rect.right = m_nWidth;

???????? rect.bottom = rect.top + tm.tmHeight;//設(shè)置矩形框的大小

????????

???????? dc.SetTextColor(RGB(255,0,0));

???????? dc.DrawText(str,rect,DT_LEFT);//開始從左往右用紅色覆蓋綠色字幕

?

???????? rect.top = 150;

???????? rect.bottom = rect.top + tm.tmHeight;

???????? dc.DrawText(str,rect,DT_RIGHT);//字幕從左往右滾動顯示

?

???????? CSize sz = dc.GetTextExtent(str);//獲得字符串的寬度和長度

???????? if (m_nWidth > sz.cx)//nWidth大于字符串長度時候

???????? {

?????????????????? m_nWidth = 0;

?????????????????? dc.SetTextColor(RGB(0,255,0));

?????????????????? dc.TextOut(0,200,str);

???????? }

????????

???????? CView::OnTimer(nIDEvent);

}

圖形標記菜單

在框架類的OnCreate函數(shù)中的return 0;句之前插入一下語句:

???????? m_bitmap.LoadBitmap(IDB_BITMAP1);

???????? GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(5,MF_BYPOSITION,&m_bitmap,&m_bitmap);

注意此IDB_BITMAP1的尺寸一定要合適,可以用一下方法獲得系菜單標記圖形的大小:

???????? CString str;

???????? str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),

?????????????????? GetSystemMetrics(SM_CYMENUCHECK));

???????? MessageBox(str);

禁用菜單項

?

移除和裝載菜單

???????? SetMenu(NULL);//禁用菜單項

?

???????? CMenu menu;//裝載菜單資源

???????? menu.LoadMenu(IDR_MAINFRAME);

???????? SetMenu(&menu);

? ?

MFC菜單命令更新機制

? ? ?

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

???????? ……

?

???????? // TODO: Delete these three lines if you don't want the toolbar to

???????? //? be dockable

???????? m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

???????? EnableDocking(CBRS_ALIGN_ANY);

???????? DockControlBar(&m_wndToolBar);

?

???????? GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION|MF_CHECKED);

??????? GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_OPEN,MF_BYCOMMAND|MF_CHECKED);

???????? GetMenu()->GetSubMenu(0)->SetDefaultItem(2,TRUE);//粗體顯示默認菜單項

???????? GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_SAVE_AS,FALSE);//粗體顯示默認菜單項

???????? GetMenu()->GetSubMenu(0)->EnableMenuItem(6,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);//禁用菜單項

?

?

// ??? CString str;

// ??? str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),

// ???????????? GetSystemMetrics(SM_CYMENUCHECK));

// ??? MessageBox(str);

?

???????? m_bitmap.LoadBitmap(IDB_BITMAP1);

???????? GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(5,MF_BYPOSITION,&m_bitmap,&m_bitmap);

?

// ??? SetMenu(NULL);//禁用菜單項

//

// ??? CMenu menu;//裝載菜單資源

// ??? menu.LoadMenu(IDR_MAINFRAME);

// ??? SetMenu(&menu);

//? menu.Detach();//將菜單句柄和菜單對象分離,因為menu是個局部對象,程序不能自動析構(gòu)它

?

???????? return 0;

}

?void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)

{

???????? // TODO: Add your command update UI handler code here

???????? if (ID_EDIT_CUT == pCmdUI->m_nID)//用標識符才能夠保證菜單項和工具欄一致

???????? {

?????????????????? pCmdUI->Enable(TRUE);

???????? }

}

?

快捷菜單

?

void CMenuView::OnRButtonDown(UINT nFlags, CPoint point)

{

???????? // TODO: Add your message handler code here and/or call default

???????? CMenu menu;

???????? VERIFY(menu.LoadMenu(IDR_MENU1));

????????

???????? CMenu* pPopup = menu.GetSubMenu(0);

???????? ClientToScreen(&point);

???????? pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,

??????????????????????????? this);

???????? CView::OnRButtonDown(nFlags, point);

}

?

?

?

?

?

動態(tài)菜單操作

???? 添加

????? 插入

????? 刪除

舉例:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

????????????? ……

????????????? // TODO: Delete these three lines if you don't want the toolbar to

????????????? //? be dockable

????????????? m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

????????????? EnableDocking(CBRS_ALIGN_ANY);

????????????? DockControlBar(&m_wndToolBar);

???????? CMenu menu;

????????????? menu.CreateMenu();

????????????? GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,"Test");//添加菜單項目

????????????? GetMenu()->InsertMenu(1,MF_POPUP|MF_BYPOSITION,(UINT)menu.m_hMenu,"test1");//插入菜單項目

????????????? menu.AppendMenu(MF_STRING,IDM_HELLO,"Hello");//在剛插入的彈出式菜單下面添加菜單項111

????????????? menu.AppendMenu(MF_STRING,112,"ByeBye");//在剛插入的彈出式菜單下面添加菜單項112

????????????? menu.AppendMenu(MF_STRING,113,"MyTest");//在剛插入的彈出式菜單下面添加菜單項113

????????????? GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"Append");//在子菜單下面添加菜單項目114

????????????? GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,MF_BYCOMMAND|MF_STRING,115,"Insert");????

//在文件子菜單下面添加菜單項目115

// ??????? GetMenu()->GetSubMenu(0)->DeleteMenu(115,MF_BYCOMMAND);//刪除文件子菜單下面的115菜單項目

????????????? menu.Detach();//防止出現(xiàn)問題

????????????? return 0;

}

添加虛函數(shù)實現(xiàn)消息的截獲,了解消息路由機制

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)

{

???????? // TODO: Add your specialized code here and/or call the base class

???????? int MenuCmdID = LOWORD(wParam);//wParam的低兩位字節(jié)是消息對象的ID號

???????? CMenu4View* pView = (CMenu4View* )GetActiveView();//在框架類獲得視圖類的對象

???????? if (MenuCmdID >= IDM_PHONE1 && MenuCmdID < IDM_PHONE1+pView->m_strArray.GetSize())

???????? {

?????????????????? MessageBox("框架截獲消息");//通過此消息可以知道消息的路由過程

?????????????????? CClientDC dc(pView);

?????????????????? dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdID-IDM_PHONE1));

???????? }

???????? return CFrameWnd::OnCommand(wParam, lParam);

//????? return TRUE; 消息將不會傳送給視圖類

}

電話薄

void CMenu4View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{

???????? // TODO: Add your message handler code here and/or call default

???????? CClientDC dc(this);

???????? if (0x0d == nChar)

???????? {

?????????????????? if (0 == ++m_nIndex)

?????????????????? {

??????????????????????????? m_Menu.CreatePopupMenu();

??????????????????????????? GetParent()->GetMenu()->AppendMenu(MF_POPUP,(UINT)m_Menu.m_hMenu,"PhoneBook");

??????????????????????????? GetParent()->DrawMenuBar();

?????????????????? }

?????????????????? m_Menu.AppendMenu(MF_STRING,IDM_PHONE1+m_nIndex,m_strLine.Left(m_strLine.Find(' ')));

?????????????????? m_strArray.Add(m_strLine);

?????????????????? m_strLine.Empty();

?????????????????? Invalidate(TRUE);

???????? }

???????? else

???????? {

?????????????????? m_strLine += nChar;?????????????????

?????????????????? dc.TextOut(0,0,m_strLine);

???????? }

// ??? Invalidate();

????????

???????? CView::OnChar(nChar, nRepCnt, nFlags);

}

?

void CMenu4View::OnPhone1()

{

???????? // TODO: Add your command handler code here

???????? CClientDC dc(this);

???????? dc.TextOut(0,0,m_strArray.GetAt(0));

}

?

void CMenu4View::OnPhone2()

{

???????? // TODO: Add your command handler code here

???????? CClientDC dc(this);

???????? dc.TextOut(0,0,m_strArray.GetAt(1));

}

?

void CMenu4View::OnPhone3()

{

???????? // TODO: Add your command handler code here

???????? CClientDC dc(this);

???????? dc.TextOut(0,0,m_strArray.GetAt(2));

}

?

void CMenu4View::OnPhone4()

{

???????? // TODO: Add your command handler code here

???????? CClientDC dc(this);

???????? dc.TextOut(0,0,m_strArray.GetAt(3));

}

錯誤解決

?

此類錯誤是頭文件除了問題,導(dǎo)致某某類沒有被定義就被調(diào)用了,只要在該文件之前加上調(diào)用相應(yīng)頭文件即可。

非模式對話框的創(chuàng)建

?

動態(tài)創(chuàng)建按鈕

?

?

靜態(tài)文本默認是不發(fā)送消息的

?

每一個控件都有指向其窗口的句柄和和hWnd

GetDlgItem(nID)->hWnd

m_Edit1.hWnd

訪問控件的七種方法

?

對話空的伸縮與擴展功能

?

?

void CMyDlg::OnButton2()

{

????????????? CString str;

????????????? static CRect rectLarge;

????????????? static CRect rectSmall;

????????????? if(rectLarge.IsRectNull())

????????????? {

??????????????????????????? CRect rectSepertor;

??????????????????????????? GetWindowRect(&rectLarge);

??????????????????????????? GetDlgItem(IDC_SEPERATOR)->GetWindowRect(&rectSepertor);

?

??????????????????????????? rectSmall.left = rectLarge.left;

??????????????????????????? rectSmall.top = rectLarge.top;

??????????????????????????? rectSmall.right = rectLarge.right;

??????????????????????????? rectSmall.bottom = rectSepertor.bottom;

????????????? }

????????????? if (GetDlgItemText(IDC_BUTTON2,str),str == "收縮<<")

????????????? {

??????????????????????????? SetDlgItemText(IDC_BUTTON2,"擴展>>");??????????????????????????????????????????????????????? ????????????? SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),SWP_NOMOVE|SWP_NOZORDER);

????????????? }

????????????? else

????????????? {

??????????????????????????? SetDlgItemText(IDC_BUTTON2,"收縮<<");

??????????????????????????? SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),SWP_NOMOVE|SWP_NOZORDER);

????????????? }

}

輸入焦點的轉(zhuǎn)換(按回車鍵實現(xiàn)在編輯框之間轉(zhuǎn)換)

?

“逃跑”按鈕的實現(xiàn)

?

創(chuàng)建屬性頁

一個屬性表單有多個屬性頁組成

創(chuàng)建屬性表

屬性表不是派生于CDialog,它和對話框類相似,也可以用DOModal()來調(diào)用

?

向?qū)У膭?chuàng)建

?

?

?

修改應(yīng)用程序外觀

在程序創(chuàng)建之前修改:在CMainFrame的ProCreateWindow函數(shù)中添加代碼

?

HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);

typedef struct tagCREATESTRUCT

{LPVOID? lpCreateParams; HINSTANCE hInstance; HMENU hMenu; HWND????? hwndParent; int?? cy; int cx; int y; int x; LONG style; LPCTSTR lpszName;LPCTSTR lpszClass; DWORD???? dwExStyle; } CREATESTRUCT, *LPCREATESTRUCT;

?

lpCreateParams

Contains additional data which may be used to create the window. If the window is being created as a result of a call to the CreateWindow or CreateWindowEx function, this member contains the value of the lpParam parameter specified in the function call.

If the window being created is an MDI window, this member contains a pointer to an MDICREATESTRUCT structure.

Windows NT/2000/XP: If the window is being created from a dialog template, this member is the address of a SHORT value that specifies the size, in bytes, of the window creation data. The value is immediately followed by the creation data. For more information, see the following Remarks section.

hInstance

Handle to the module that owns the new window.

hMenu

Handle to the menu to be used by the new window.

hwndParent

Handle to the parent window, if the window is a child window. If the window is owned, this member identifies the owner window. If the window is not a child or owned window, this member is NULL.

cy

Specifies the height of the new window, in pixels.

cx

Specifies the width of the new window, in pixels.

y

Specifies the y-coordinate of the upper left corner of the new window. If the new window is a child window, coordinates are relative to the parent window. Otherwise, the coordinates are relative to the screen origin.

x

Specifies the x-coordinate of the upper left corner of the new window. If the new window is a child window, coordinates are relative to the parent window. Otherwise, the coordinates are relative to the screen origin.

style

Specifies the style for the new window.

WS_BORDER Creates a window that has a thin-line border.

WS_CAPTION Creates a window that has a title bar (includes the WS_BORDER style).

WS_CHILD Creates a child window. This style cannot be used with the WS_POPUP style.

WS_CHILDWINDOW Same as the WS_CHILD style.

WS_CLIPCHILDREN Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.

WS_CLIPSIBLINGS Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window.

WS_DISABLED Creates a window that is initially disabled. A disabled window cannot receive input from the user.

WS_DLGFRAME Creates a window that has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar.

WS_GROUP Specifies the first control of a group of controls. The group consists of this first control and all? controls defined after it, up to the next control with the WS_GROUP style. The first control in each group usually has the WS_TABSTOP style so that the user can move from group to group. The user can subsequently change the keyboard focus from one control in the group to the next control in the group by using the direction keys.

WS_HSCROLL Creates a window that has a horizontal scroll bar.

WS_ICONIC Creates a window that is initially minimized. Same as the WS_MINIMIZE style.

WS_MAXIMIZE Creates a window that is initially maximized.

WS_MAXIMIZEBOX Creates a window that has a Maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style.?

WS_MINIMIZE Creates a window that is initially minimized. Same as the WS_ICONIC style.

WS_MINIMIZEBOX Creates a window that has a Minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style.?

WS_OVERLAPPED Creates an overlapped window. An overlapped window has a title bar and a border. Same as the WS_TILED style.

WS_OVERLAPPEDWINDOW Creates an overlapped window with the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles. Same as the WS_TILEDWINDOW style.?

WS_POPUP Creates a pop-up window. This style cannot be used with the WS_CHILD style.

WS_POPUPWINDOW Creates a pop-up window with WS_BORDER, WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible.

WS_SIZEBOX Creates a window that has a sizing border. Same as the WS_THICKFRAME style.

WS_SYSMENU Creates a window that has a Close (X) button in the non-client area.

WS_TABSTOP Specifies a control that can receive the keyboard focus when the user presses the TAB key. Pressing the TAB key changes the keyboard focus to the next control with the WS_TABSTOP style.

WS_THICKFRAME Creates a window that has a sizing border. Same as the WS_SIZEBOX style.

WS_TILED Creates an overlapped window. An overlapped window has a title bar and a border. Same as the WS_OVERLAPPED style.?

WS_TILEDWINDOW Creates an overlapped window with the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles. Same as the WS_OVERLAPPEDWINDOW style.?

WS_VISIBLE Creates a window that is initially visible.

WS_VSCROLL Creates a window that has a vertical scroll bar.

lpszName

Pointer to a null-terminated string that specifies the name of the new window.

lpszClass

Pointer to a null-terminated string that specifies the class name of the new window.

dwExStyle

Specifies the extended window style for the new window.

WS_EX_ACCEPTFILES ?Specifies that a window created with this style accepts drag-drop files.

WS_EX_APPWINDOW ?Forces a top-level window onto the taskbar when the window is visible.?

WS_EX_CLIENTEDGE ?Specifies that a window has a border with a sunken edge.

WS_EX_DLGMODALFRAME Creates a window that has a double border; the window can, optionally, be created with a title bar by specifying the WS_CAPTION style in the dwStyle parameter.

WS_EX_LEFT ?Creates a window that has generic “l(fā)eft-aligned” properties. This is the default.

WS_EX_LEFTSCROLLBAR ?If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the vertical scroll bar (if present) is to the left of the client area. For other languages, the style is ignored.

WS_EX_LTRREADING ?The window text is displayed using left-to-right reading-order properties. This is the default.

WS_EX_MDICHILD ?Creates an MDI child window.

WS_EX_NOACTIVATE ?A top-level window created with this style cannot be activated. If a child window has this style, tapping it does not cause its top-level parent to be activated. A window that has this style receives stylus events, but neither it nor its child windows can get the focus. Supported in Windows CE versions 2.0 and later.

WS_EX_NOANIMATION ?A window created with this style does not show animated exploding and imploding rectangles, and does not have a button on the taskbar. Supported in Windows CE versions 2.0 and later.

WS_EX_NOPARENTNOTIFY Specifies that a child window created with this style does not send the WM_PARENTNOTIFY message to its parent window when it is created or destroyed.

WS_EX_OVERLAPPEDWINDOW Combines the WS_EX_CLIENTEDGE and WS_EX_WINDOWEDGE styles.

WS_EX_PALETTEWINDOW Combines the WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW, and WS_EX_TOPMOST styles.

WS_EX_RIGHT The window has generic “right-aligned” properties. This depends on the window class. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading-order alignment; otherwise, the style is ignored.

WS_EX_RIGHTSCROLLBAR Vertical scroll bar (if present) is to the right of the client area. This is the default.

WS_EX_RTLREADING If the shell language is Hebrew, Arabic, or another language that supports reading-order alignment, the window text is displayed using right-to-left reading-order properties. For other languages, the style is ignored.

WS_EX_STATICEDGE Creates a window with a three-dimensional border style intended to be used for items that do not accept user input.

WS_EX_TOOLWINDOW Creates a tool window; that is, a window intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE.?

WS_EX_TOPMOST Specifies that a window created with this style should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. To add or remove this style, use the SetWindowPos function.

WS_EX_TRANSPARENT Specifies that a window created with this style should not be painted until siblings beneath the window (that were created by the same thread) have been painted. The window appears transparent because the bits of underlying sibling windows have already been painted.

To achieve transparency without these restrictions, use the SetWindowRgn function.

WS_EX_WINDOWEDGE Specifies that a window has a border with a raised edge.

窗口創(chuàng)建之后修改:在OnCreate()函數(shù)當中添加SetWindowLong()代碼

???????????????????????????????????? ?? GetWindowLong(HWND hWnd,int nIndex)可以獲得當前窗口的風格

?

修改窗口光標,圖標,背景

?

? ?

?

?

?

通過SetClassLong() 重置窗口所屬窗口類的WNDCLASSEX(WNDCLASS結(jié)構(gòu)的擴展),改變光標和背景的代碼放在視圖類的OnCreate函數(shù)中,改變圖標則放在框架類的OnCreate中

SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));

SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_CROSS));

?

注冊窗口類兩種方法:

一:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

???????? if( !CFrameWnd::PreCreateWindow(cs) )

?????????????????? return FALSE;

???????? // TODO: Modify the Window class or styles here by modifying

???????? //? the CREATESTRUCT cs

???????? cs.cx = 300;//應(yīng)用程序?qū)挾?/p>

???????? cs.cy = 300;//應(yīng)用程序長度

???????? cs.style &= ~FWS_ADDTOTITLE;//修改應(yīng)用程序標題必須去掉此風格??????

???????? cs.lpszName = "Chen Sifan";

?

???????? WNDCLASS wndcls;

???????? wndcls.cbClsExtra = 0;

???????? wndcls.cbWndExtra = 0;

???????? wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);

???????? wndcls.hCursor = LoadCursor(NULL,IDC_HELP);

???????? wndcls.hIcon = LoadIcon(NULL,IDI_ERROR);

???????? wndcls.hInstance = AfxGetInstanceHandle();

???????? wndcls.lpfnWndProc = ::DefWindowProc;

???????? wndcls.lpszClassName = "sifan.org";

???????? wndcls.lpszMenuName = NULL;

???????? wndcls.style = CS_HREDRAW|CS_VREDRAW;

?

???????? RegisterClass(&wndcls);

???????? cs.lpszClass = "sifan.org";//只是改變圖標

???????? return TRUE;

}

?

BOOL CStyleView::PreCreateWindow(CREATESTRUCT& cs)

{

???????? // TODO: Modify the Window class or styles here by modifying

???????? //? the CREATESTRUCT cs

??????? cs.lpszClass = "sifan.org";//主要是改變光標和背景

???????? return CView::PreCreateWindow(cs);

}

二:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

???????? if( !CFrameWnd::PreCreateWindow(cs) )

?????????????????? return FALSE;

???????? // TODO: Modify the Window class or styles here by modifying

???????? //? the CREATESTRUCT cs

???????? cs.lpszClass = AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));

???????? return TRUE;

}

BOOL CStyleView::PreCreateWindow(CREATESTRUCT& cs)

{

???????? // TODO: Modify the Window class or styles here by modifying

???????? //? the CREATESTRUCT cs

???????? cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,LoadCursor(NULL,IDC_CROSS)

?????????????????? ,(HBRUSH)GetStockObject(BLACK_BRUSH),0);

???????? return CView::PreCreateWindow(cs);

}

?

動態(tài)改變應(yīng)用程序圖標

???????? extern CStyleApp theApp;

???????? //LoadIcon的第一個參數(shù)要是一個應(yīng)用程序句柄,第二個是把一個圖標ID轉(zhuǎn)換成一個字符串資源

???????? m_hIcon[0] =LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));

???????? m_hIcon[1] =LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));//全局變量的應(yīng)用必須先聲明

???????? m_hIcon[2] =LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));//全局函數(shù)

?

???????? SetTimer(1,1000,NULL);

void CMainFrame::OnTimer(UINT nIDEvent)

{

???????? // TODO: Add your message handler code here and/or call default

???????? static int nIndex = 0;

???????? SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcon[nIndex]);

???????? nIndex = ++nIndex%3; //很巧

???????? CFrameWnd::OnTimer(nIDEvent);

}

?

工具欄

?

?

第二個是框架類的EnableDocking,是為了讓主框架窗口可以被停靠;

? ?

代碼如下:

void CMainFrame::OnViewNewToolbar()

{

???????? // TODO: Add your command handler code here

// ??? if (m_newToolBar.IsWindowVisible())

// ??? {

// ???????????? m_newToolBar.ShowWindow(SW_HIDE);

// ??? }

// ??? else

// ??? {

// ???????????? m_newToolBar.ShowWindow(SW_SHOW);

// ??? }

// ??? RecalcLayout(TRUE);//重新調(diào)整控制條的位置,默認是真

// ??? DockControlBar(&m_newToolBar);//重新讓工具條停靠在框架窗口的邊緣

?

//用一個函數(shù)可以替換以上全部代碼,還可以讓工具欄在消失的位置顯示出來

???????? ShowControlBar(&m_newToolBar,!m_newToolBar.IsVisible(),FALSE);

}

為菜單欄添加復(fù)選標記

?

???????? pCmdUI->SetCheck(m_newToolBar.IsWindowVisible());

時間

?

?

狀態(tài)欄編程

?

進度欄編程

?

?

?

void CMainFrame::OnPaint()

{

???????? CPaintDC dc(this); // device context for painting

????????

???????? // TODO: Add your message handler code here

???????? CRect rect;

???????? m_wndStatusBar.GetItemRect(2,&rect);

???????? if (!m_progress.m_hWnd)

???????? {

???????? m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH,rect,&m_wndStatusBar,1111);

???????? }

???????? else

???????? {

?????????????????? m_progress.MoveWindow(rect);

???????? }

???????? m_progress.SetPos(50);

???????? // Do not call CFrameWnd::OnPaint() for painting messages

}

四種方法在狀態(tài)欄第一個窗口顯示鼠標的當前位置

首先確定是為視圖類添加WM_MOUSEMOVE消息

其次捕獲鼠標的坐標并且格式化

第三獲取父窗口即框架類窗口的句柄,GetParent()獲取的是CWnd指針,故要將其強制轉(zhuǎn)換為CMainFrame

void CStyleView::OnMouseMove(UINT nFlags, CPoint point)

{

???????? // TODO: Add your message handler code here and/or call default

???????? CString strMouse;

???????? strMouse.Format("X=%d,Y=%d",point.x,point.y);

???????? //調(diào)用CStatusBar的成員函數(shù)將文本放在第一個窗口

???????? ((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(strMouse);

???????? //調(diào)用CFrameWnd的成員函數(shù)將文本放在第一個窗口

???????? ((CMainFrame*)GetParent())->SetMessageText(strMouse);

???????? //通過CMainFrame ::GetMessageBar來獲取狀態(tài)欄的指針來調(diào)用SetWindowText將文本放在第一個窗口

???????? ((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(strMouse);

???????? //通過CWnd::GetDescendantWindow來獲取狀態(tài)欄的指針來調(diào)用SetWindowText將文本放在第一個窗口

???????? GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(strMouse);

???????? CView::OnMouseMove(nFlags, point);

}

?

為應(yīng)用程序添加啟動畫面

?

設(shè)置顏色對話框默認顏色

?

?

?

常見錯誤2

?

設(shè)置字體

常見錯誤3

?

示例區(qū)域

void CSetting::OnPaint()

{

???????? CPaintDC dc(this); // device context for painting

????????

???????? // TODO: Add your message handler code here

???????? CPen pen(m_nLineWidth,m_nLineStyle,m_clr);

???????? dc.SelectObject(&pen);

???????? CRect rect;

???????? GetDlgItem(IDC_SAMPLE)->GetWindowRect(&rect);//IDC_SAMPLE為組框的ID,通過她來獲得示例區(qū)域

???????? ScreenToClient(&rect);

???????? dc.MoveTo(rect.left+20,rect.top+rect.Height()/2);

???????? dc.LineTo(rect.right-20,rect.top+rect.Height()/2);

???????? UpdateData();

???????? // Do not call CDialog::OnPaint() for painting messages

}

改變對話框控件的背景及字體顏色

?

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

{

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

???????? return m_brush;// m_brush.CreateSolidBrush(RGB(0,255,0));

}

僅僅改變個別控件和字體顏色

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

{

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

????????

???????? // TODO: Change any attributes of the DC here

???????? if (pWnd->GetDlgCtrlID() == IDC_LINE_STYLE)

???????? {

?????????????????? pDC->SetTextColor(RGB(0,0,255));

?????????????????? pDC->SetBkMode(TRANSPARENT);

?????????????????? //控件上面有字,字體有陰影,此句就是將字體背景設(shè)置為透明,這樣就可以看見控件顏色了

?????????????????? return m_brush;

???????? }

???????? if (pWnd->GetDlgCtrlID() == IDC_LINE_WIDTH_EDIT)

???????? {

?????????????????? pDC->SetTextColor(RGB(0,0,255));

???????????????? pDC->SetBkMode(TRANSPARENT);

???????????????? pDC->SetBkColor(RGB(0,0,255));

?????????????????? return m_brush;

???????? }

???????? return hbr;

???????? // TODO: Return a different brush if the default is not desired

}

改變控件上面的字體

???????? if (pWnd->GetDlgCtrlID() == IDC_TEXT)

???????? {

?????????????????? pDC->SelectObject(&m_font);

?????????????????? pDC->SetTextColor(RGB(0,0,255));

???????? }

改變按鈕控件的背景和文本顏色

?

?

位圖的顯示

?

?

?

?

?

?

窗口的繪制過程:清除背景BOOL CGraphicView::OnEraseBkgnd(CDC* pDC),重繪制窗口(也會調(diào)用OnDraw函數(shù),因此也可以將代碼放到OnDraw函數(shù)中去);

只是在OnDraw當中編寫的話,每當窗口尺寸變化的時候,就會先清除窗口,因此此種方法的效果是閃爍性比較明顯。

BOOL CGraphicView::OnEraseBkgnd(CDC* pDC)

{

???????? // TODO: Add your message handler code here and/or call default

???????? CBitmap bitMap;

???????? bitMap.LoadBitmap(IDB_BITMAP1);

?

???????? BITMAP bmp;

???????? bitMap.GetBitmap(&bmp);

?

???????? CDC pCompatiableDC;

???????? pCompatiableDC.CreateCompatibleDC(pDC);//兼容DC

???????? pCompatiableDC.SelectObject(&bitMap);

?

???????? CRect rect;

???????? GetClientRect(&rect);

// ??? pDC->BitBlt(0,0,rect.Width(),rect.Height(),&pCompatiableDC,0,0,SRCCOPY);//1:1復(fù)制

???????? pDC->StretchBlt(0,0,rect.Width(),rect.Height(),&pCompatiableDC,0,0

?????????????????? ,bmp.bmWidth,bmp.bmHeight,SRCCOPY);//壓縮源圖片顯示

???????? return TRUE;//為TRUE表示不再清楚窗口背景

}

?

一、圖形的保存和重繪(huì)

?

?

?

?

?

1,為視圖類新建一個私有的CPtrArray數(shù)據(jù)類型,用來保存繪圖的三要素:起點,終點,類型

2,重繪窗口的時候會調(diào)用OnDraw函數(shù)

void CGraphicView::OnDraw(CDC* pDC)

{

???????? CGraphicDoc* pDoc = GetDocument();

???????? ASSERT_VALID(pDoc);

???????? // TODO: add draw code for native data here

???????? CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

???????? pDC->SelectObject(&pBrush);

?

???????? for (int i=0;i<m_ptrArray.GetSize();i++)

???????? {

?????????????????? switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType)

?????????????????? {

?????????????????? case 1:

??????????????????????????? pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_nEndPoint,RGB(0,0,0));

??????????????????????????? break;

?????????????????? case 2:

??????????????????????????? pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_nOriginPoint);

??????????????????????????? pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_nEndPoint);

??????????????????????????? break;

?????????????????? case 3:

?????????????????? ???????? pDC->Rectangle(CRect(

???????????????????????????????????? ((CGraph*)m_ptrArray.GetAt(i))->m_nOriginPoint,

???????????????????????????????????? ((CGraph*)m_ptrArray.GetAt(i))->m_nEndPoint));

??????????????????????????? break;

?????????????????? case 4:

??????????????????????????? pDC->Ellipse(CRect(

???????????????????????????????????? ((CGraph*)m_ptrArray.GetAt(i))->m_nOriginPoint,

???????????????????????????????????? ((CGraph*)m_ptrArray.GetAt(i))->m_nEndPoint)

???????????????????????????????????? );

??????????????????????????? break;

?????????????????? }

???????? }

}

3,在OnButtonUp函數(shù)里面加入以下代碼,將每一個圖形添加到CPtrArray當中去

???????? CGraph* pGraph =new CGraph(m_nDrawType,m_nOriginPoint,point);//new均是在堆中定義的

???????? m_ptrArray.Add(pGraph);

OnDraw和OnPaint函數(shù)

?

?

窗口滾動功能的實現(xiàn)

讓視圖基類為CScrollView,兩種方式:1,在應(yīng)用程序創(chuàng)建的第六步修改基類

2,若程序已經(jīng)創(chuàng)建了,那么只需要將應(yīng)用程序視圖類的頭文件和源文件中的

CView改成CScrollView類

錯誤4

?

圖形錯位現(xiàn)象

在OnDraw函數(shù)中添加一下代碼:

OnPrepareDC(&dc);

???????? dc.DPtoLP(&m_nOriginPoint);

???????? dc.DPtoLP(&point);

二、用元文件保存圖形

?

元文件用來保存圖形,代碼如下:

void CGraphicView::OnDraw(CDC* pDC)

{

???????? CGraphicDoc* pDoc = GetDocument();

???????? ASSERT_VALID(pDoc);

???????? // TODO: add draw code for native data here

?

???????? HMETAFILE hMetaFile;

???????? hMetaFile = m_dcMetaFile.Close();//沒想到close()函數(shù)也能夠用來獲取句柄

???????? pDC->PlayMetaFile(hMetaFile);

???????? m_dcMetaFile.Create();//在內(nèi)存中創(chuàng)建,用來播放之前繪制的圖像

???????? m_dcMetaFile.PlayMetaFile(hMetaFile);//顯示前面繪制的圖像

???????? DeleteMetaFile(hMetaFile);

}

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)

{

???????? // TODO: Add your message handler code here and/or call default

???????? CClientDC dc(this);

?

???????? CPen pen(m_nLineStyle,m_nLineWidth,m_clr);

// ??? dc.SelectObject(&pen);

??????? m_dcMetaFile.SelectObject(&pen);

????????

???????? CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

// ??? dc.SelectObject(&pBrush);

???????? m_dcMetaFile.SelectObject(&pen);

?

???????? switch (m_nDrawType)

???????? {

???????? case 1:

// ???????????? dc.SetPixel(point,m_clr);

???????? ???????? m_dcMetaFile.SetPixel(point,m_clr);

?????????????????? break;

???????? case 2:

// ???????????? dc.MoveTo(m_nOriginPoint);

?????????????????? m_dcMetaFile.MoveTo(m_nOriginPoint);

// ???????????? dc.LineTo(point);

?????????????????? m_dcMetaFile.LineTo(point);

?????????????????? break;

???????? case 3:

// ???????????? dc.Rectangle(CRect(m_nOriginPoint,point));

?????????????????? m_dcMetaFile.Rectangle(CRect(m_nOriginPoint,point));

?????????????????? break;

???????? case 4:

// ???????????? dc.Ellipse(CRect(m_nOriginPoint,point));

?????????????????? m_dcMetaFile.Ellipse(CRect(m_nOriginPoint,point));

?????????????????? break;

???????? }

????????

//? OnPrepareDC(&dc);

//? dc.DPtoLP(&m_nOriginPoint);

//? dc.DPtoLP(&point);

?

// ??? CGraph* pGraph =new CGraph(m_nDrawType,m_nOriginPoint,point);//new均是在堆中定義的

// ??? m_ptrArray.Add(pGraph);

?

???????? CScrollView::OnLButtonUp(nFlags, point);

}

將元文件保存到磁盤,用[文件]子菜單下的[打開]打開它,用[保存]保存它

?

保存

void CGraphicView::OnFileSave()

{

???????? // TODO: Add your command handler code here

???????? HMETAFILE hMetaFile;//定義一個句柄變量

???????? hMetaFile = m_dcMetaFile.Close();//獲取句柄

???????? CopyMetaFile(hMetaFile,"meta.wmf");//對元文件來說,通常用wmf格式保存它到磁盤文件WindowsMetaFile

???????? m_dcMetaFile.Create();//創(chuàng)建一個元文件,以供下一次繪圖使用

???????? DeleteMetaFile(hMetaFile);//釋放句柄

}

打開

void CGraphicView::OnFileOpen()

{

???????? // TODO: Add your command handler code here

???????? HMETAFILE hMetaFile;//定義一個句柄變量

???????? hMetaFile = GetMetaFile("meta.wmf");//獲取句柄

???????? m_dcMetaFile.PlayMetaFile(hMetaFile);

???????? DeleteMetaFile(hMetaFile);//釋放句柄

???????? Invalidate();//窗口重繪,調(diào)用OnDraw函數(shù)

}

三、兼容DC(設(shè)備描述表)保存圖形和重繪

?

?

?

void CGraphicView::OnDraw(CDC* pDC)

{

???????? CGraphicDoc* pDoc = GetDocument();

???????? ASSERT_VALID(pDoc);

???????? // TODO: add draw code for native data here

//用兼容DC保存圖像

???????? CRect rect;

???????? GetClientRect(&rect);

???????? pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatibale,0,0,SRCCOPY);

}

void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)

{

???????? // TODO: Add your message handler code here and/or call default

???????? CClientDC dc(this);

???????? CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

???????? if (!m_dcCompatibale.m_hDC)

???????? {

?????????????????? m_dcCompatibale.CreateCompatibleDC(&dc);

?????????????????? CRect rect;

?????????????????? GetClientRect(rect);

?????????????????? CBitmap bitmap;

?????????????????? bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());

?????????????????? m_dcCompatibale.SelectObject(&bitmap);

?????????????????? m_dcCompatibale.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);

?????????????????? m_dcCompatibale.SelectObject(pBrush);

???????? }

???????? switch (m_nDrawType)

???????? {

???????? case 1:

?????????????????? m_dcCompatibale.SetPixel(point,m_clr);

?????????????????? break;

???????? case 2:

?????????????????? m_dcCompatibale.MoveTo(m_nOriginPoint);

?????????????????? m_dcCompatibale.LineTo(point);

?????????????????? break;

???????? case 3:

?????????????????? m_dcCompatibale.Rectangle(CRect(m_nOriginPoint,point));

?????????????????? break;

???????? case 4:

?????????????????? m_dcCompatibale.Ellipse(CRect(m_nOriginPoint,point));

?????????????????? break;

???????? }

???????? CScrollView::OnLButtonUp(nFlags, point);

}

文件操作

寫入

void CFileView::OnFileWrite()

{

???????? // TODO: Add your command handler code here

???????? FILE* pFile = fopen("1.txt","w");

???????? CString str = "http:\\\\www.sunxin.org";

// ??? CString str1 = "weclome";

???????? fwrite(str,1,strlen(str),pFile);//將字符串寫入文件緩沖區(qū)

???????? fseek(pFile,0,SEEK_SET);//在文件開始出插入,替換Http

???????? fwrite(" ftp",1,strlen(" ftp"),pFile);

// ??? fwrite(str1,1,strlen(str1),pFile);//將字符串寫入文件緩沖區(qū)

// ??? fclose(pFile);//關(guān)閉文件,將緩沖區(qū)的內(nèi)容寫到文件當中

?????????????????????????????????????????????? //如果沒有這句話,將會導(dǎo)致內(nèi)容不能立即寫入文件中

???????? fflush(pFile);//實現(xiàn)在不關(guān)閉文件的情況下將緩沖區(qū)的內(nèi)容寫如文件,提高效率(刷新緩沖區(qū)內(nèi)容哦個)

}

讀取

void CFileView::OnFileRead()

{

???????? // TODO: Add your command handler code here

???????? FILE *pFile = fopen("1.txt","r");

???????? char ch[100];

???????? fread(ch,1,100,pFile);

???????? fclose(pFile);

???????? MessageBox(ch);

}

錯誤5

?

?

向字符串末尾添加“\0”

1 利用數(shù)組給最后一個元素賦值為‘\0’

void CFileView::OnFileWrite()

{

????????

???????? FILE* pFile = fopen("1.txt","w");

???????? char buf[22] = "http:\\\\www.sunxin.org";

???????? buf[21] = '\0';

???????? fwrite(buf,1,22,pFile);

???????? fclose(pFile);

}

2 讀的時候用memset函數(shù)先將數(shù)組初始化為全0

?

void CFileView::OnFileRead()

{

???????? // TODO: Add your command handler code here

???????? FILE *pFile = fopen("1.txt","r");

???????? char ch[100];

???????? memset(ch,0,100);?

???????? fread(ch,1,100,pFile);

???????? fclose(pFile);

???????? MessageBox(ch);

}

3 用ftell來獲取文件長度,獲取之后用rewind來將指針移動到文件開頭

void CFileView::OnFileRead()

{

???????? // TODO: Add your command handler code here

???????? FILE *pFile = fopen("1.txt","r");

???????? char* pBuf;

???????? fseek(pFile,0,SEEK_END);

???????? int len = ftell(pFile);//獲得長度

???????? pBuf = new char[len+1];

???????? rewind(pFile);//將文件指針移動到文件開頭

???????? fread(pBuf,1,len,pFile);

???????? pBuf[len] = 0;

???????? fclose(pFile);

???????? MessageBox(pBuf);

}

文本文件和二進制文件差異

?

itoa函數(shù):把一個整型數(shù)據(jù)轉(zhuǎn)換成字符形式

Win32 文件操作

void CFileView::OnFileWrite()

{

//win32 文件操作

???????? //定義一個句柄變量

???????? HANDLE hFile;

???????? hFile = CreateFile("2.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,

?????????????????? FILE_ATTRIBUTE_NORMAL,NULL);//創(chuàng)建文件

???????? DWORD dwWrites;//接收實際接受的字節(jié)數(shù)

???????? WriteFile(hFile,"win32 file operator",strlen("win32 file operator"),

?????????????????? &dwWrites,NULL);//寫入數(shù)據(jù)

???????? CloseHandle(hFile);//關(guān)閉句柄

}

void CFileView::OnFileRead()

{

//win32文件操作

???????? HANDLE hFile;//創(chuàng)建句柄對象

???????? hFile = CreateFile("2.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

???????? char ch[100];

???????? DWORD dwReads;//接受讀取的字節(jié)數(shù)

???????? ReadFile(hFile,ch,100,&dwReads,NULL);//讀取文件

???????? ch[dwReads] = 0;//設(shè)置結(jié)束標志

???????? CloseHandle(hFile);//關(guān)閉句柄

???????? MessageBox(ch);

}

往注冊表中寫入東西(win32 API函數(shù)和CWinApp函數(shù)WriteProfileString區(qū)別)

//? ::WriteProfileString("http:\\\\www.sunxin.org","admin","zhangshan");Win32 函數(shù) 寫到win.ini當中去

??????? WriteProfileString("http:www.sunxin.org","admin","zhangshan");//CWinApp函數(shù)寫到注冊表

???????? CString str;

// ??? ::GetProfileString("http:\\\\www.sunxin.org","admin","lisi",str.GetBuffer(100),100);

???????? str = GetProfileString("http:\\\\www.sunxin.org","admin");//獲取注冊表中的信息

???????? AfxMessageBox(str);

注冊表API操作

創(chuàng)建鍵

?

打開鍵

?

寫入注冊表

?

?

讀取注冊表

? ?

注冊表示例:

?

?

?

void CFileView::OnRegWrite()

{

???????? // TODO: Add your command handler code here

???????? HKEY hKey;

???????? RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);

???????? RegSetValue(hKey,NULL,REG_SZ,"zhangshan",strlen("zhangshan"));

???????? DWORD dwage = 30;

???????? //寫入一個非REG_SZ類型的數(shù)據(jù),需要調(diào)用以下函數(shù),第五個參數(shù)是數(shù)據(jù)的值,需要強制轉(zhuǎn)換

???????? RegSetValueEx(hKey,"Age",0,REG_DWORD,(const byte*)&dwage,4);

???????? RegCloseKey(hKey);

}

?

void CFileView::OnRegRead()

{

// ??? // TODO: Add your command handler code here

// ??? LONG lValue;

// ??? //第一次調(diào)用得到要讀取的字符串的長度

// ??? RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",NULL,&lValue);

// ??? char* pBuf = new char[lValue];

// ??? //第二次調(diào)用根據(jù)長度獲取數(shù)據(jù)

// ??? RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",pBuf,&lValue);

// ??? MessageBox(pBuf);

?

???????? HKEY hKey;

???????? //打開指定的注冊表項

???????? RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);

???????? DWORD dwType;

???????? DWORD dwValue;

???????? DWORD dwAge;

???????? //讀取其它類型的數(shù)據(jù)

???????? RegQueryValueEx(hKey,"Age",0,&dwType,(LPBYTE)&dwAge,&dwValue);

???????? CString str;

???????? str.Format("Age = %d",dwValue);

???????? MessageBox(str);

}

文檔與串行化

?

代碼:

void CGraphicView::OnFileRead()//對象的讀取順序和寫入順序必須一致

{

???????? // TODO: Add your command handler code here

???????? // 構(gòu)造CFile對象

???????? CFile file("ar.txt",CFile::modeRead);

???????? //構(gòu)造存檔對象

???????? CArchive ar(&file,CArchive::load);//打開操作

???????? int i;

???????? char ch;

???????? float f;

???????? CString str;

???????? CString strResult;

???????? ar>>i>>ch>>f>>str;//讀取數(shù)據(jù)

???????? strResult.Format("%d,%c,%f,%s",i,ch,f,str);//數(shù)據(jù)格式化

???????? MessageBox(strResult);

}

?

void CGraphicView::OnFileWrite()

{

???????? // TODO: Add your command handler code here

???????? // 構(gòu)造CFile對象

???????? CFile file("ar.txt",CFile::modeCreate|CFile::modeWrite);

???????? //構(gòu)造CArchive存檔對象

???????? CArchive ar(&file,CArchive::store);//保存操作

???????? int i = 4;

???????? char ch = 'a';

???????? float f =1.3f;

???????? CString str("www.sunxin.org");

???????? //保存數(shù)據(jù)

???????? ar<<i<<ch<<f<<str;

}

查看文檔模版的字符串:

?

?

文檔

? ?

?

實現(xiàn)類對串行化的支持

?

?

void CGraph::Serialize(CArchive& ar)

{

???????? if (ar.IsStoring())

???????? {

?????????????????? ar<<m_nDrawType<<m_nOriginPoint<<m_nEndPoint;

???????? }

???????? else

???????? {

?????????????????? ar>>m_nDrawType>>m_nOriginPoint>>m_nEndPoint;

???????? }

}

?

void CGraph::Draw(CDC *pDC)

{

???????? CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//穿件透明畫刷

???????? CBrush* pOldbrush = pDC->SelectObject(pBrush);

?

???????? switch(m_nDrawType)

???????? {

???????? case 1:

?????????????????? pDC->SetPixel(m_nEndPoint,RGB(0,0,0));

?????????????????? break;

???????? case 2:

?????????????????? pDC->MoveTo(m_nOriginPoint);

?????????????????? pDC->LineTo(m_nEndPoint);

?????????????????? break;

???????? case 3:

?????????????????? pDC->Rectangle(CRect(m_nOriginPoint,m_nEndPoint));

?????????????????? break;

???????? case 4:

?????????????????? pDC->Ellipse(CRect(m_nOriginPoint,m_nEndPoint));

?????????????????? break;

???????? }

???????? pDC->SelectObject(pOldbrush);

}

錯誤6

?

要求在設(shè)計可串行化的類時,在其內(nèi)部確定需要串行化的數(shù)據(jù)。

CObject本書就是串行化類,因此可以直接用CObject類來實現(xiàn)數(shù)據(jù)的設(shè)計和顯示

1、在void CGraphicDoc::Serialize(CArchive& ar)當中添加一下代碼 ????????

pView->m_obArray.Serialize(ar);//直接利用CObject類本身就是可串行化類的特點,直接用一句話實現(xiàn)串行化數(shù)據(jù)

2、在void CGraphicView::OnDraw(CDC* pDC)中添加一下代碼

???????? int nCount = m_obArray.GetSize();

???????? for (int i=0;i<nCount;i++)

???????? {

?????????????????? ((CGraph*)m_obArray.GetAt(i))->Draw(pDC);

???????? }

知識點

?

?

文檔的銷毀

?

*******RemoveAt錯誤7

void CGraphicDoc::DeleteContents()

{

???????? // TODO: Add your specialized code here and/or call the base class

???????? POSITION pos = GetFirstViewPosition();

???????? CGraphicView* pView = (CGraphicView*)GetNextView(pos);

???????? int nCount = pView->m_obArray.GetSize();

???????? for (int i=0;i<nCount;i++)//注意不要用GetSize函數(shù)作為條件,因為刪除指針數(shù)據(jù)時的內(nèi)存大小時刻在變

???????? {

?????????????????? delete pView->m_obArray.GetAt(i);//delete釋放指針指向的堆內(nèi)存,而CObArray中保存的是指針

?????????????????? // pView->m_obArray.RemoveAt(i);//刪除m_obArray當中保存的指針數(shù)據(jù)//出現(xiàn)內(nèi)存泄露

???????? }

???????? pView->m_obArray.RemoveAll();//等指針指向的堆內(nèi)存全部刪除之后再刪除全部的指針數(shù)據(jù)

???????? CDocument::DeleteContents();

}

?

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

計算機通信

條件:對方IP,通信協(xié)議,端口號;

一臺電腦會有很多個網(wǎng)絡(luò)程序在運行,要實現(xiàn)與其中一個應(yīng)用程序通信必須指定該網(wǎng)絡(luò)應(yīng)用程序的地址;那么IP相當于總機地址,端口號相當于分機地址;

?

Windows socket是網(wǎng)絡(luò)編程的一種簡單的方法

它是應(yīng)用程序和網(wǎng)絡(luò)驅(qū)動程序之間的橋梁;

應(yīng)用程序把數(shù)據(jù)傳給Socket,Socket再把數(shù)據(jù)交給驅(qū)動程序,驅(qū)動程序再把數(shù)據(jù)發(fā)送出去;

計算機從網(wǎng)絡(luò)上收到與該Socket綁定的IP地址和端口號相關(guān)的數(shù)據(jù)后,由驅(qū)動程序交給Socket,應(yīng)用程序便可從Scoket提取接收到的數(shù)據(jù)了;

ISO/OSI七層參考模型

(Open System Interconnection)

?

?

TCP/IP模型

?

協(xié)議端口(Protocol port)

端口用一個整數(shù)型標識符來表示,即端口號;

端口號與協(xié)議相關(guān);

端口號使用一個16位的數(shù)字來表示,范圍是0~65535;

1024以下的端口號留給預(yù)定義服務(wù),我們編寫網(wǎng)絡(luò)應(yīng)用程序的時候,為程序指定1024以上的端口號;

套接字(Socket)

?

套接字類型

?

網(wǎng)絡(luò)字節(jié)順序

?

客戶機/主機服務(wù)模式

?

基于TCp(面向連接)的Socket編程

?

基于UDP(面向無連接)的Socket編程

?

套接字編程需要額一些函數(shù)

WSAStart 函數(shù)? :加載套接字庫和確定Socket版本

?

Socket函數(shù)

?

Bind函數(shù)

?

Liten函數(shù)

?

Accept函數(shù)

?

Send函數(shù)

?

Recv函數(shù)

?

Connect函數(shù)

?

Rectfrom函數(shù)

?

Sendto函數(shù)

?

Htons和htonl函數(shù)

?

TCP建立工程方法

服務(wù)器程序

#include <Winsock2.h>

#include <Stdio.h>

?

void main()

{

//加載套接字庫

???????? WORD wVisionRequested;//保存WinSock庫的版本

???????? WSADATA wsaData;

???????? int err;

?

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

?

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

?

???????? if (err != 0)//如果返回值不為0 ,則直接退出

???????? {

?????????????????? return;

???????? }

?

???????? if (LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion != 1))//驗證版本號

???????? {

?????????????????? WSACleanup();

?????????????????? return;

???????? }

//創(chuàng)建套接字

???????? SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建的是流式套接字,自動選擇協(xié)議

//將套接字綁定到本機地址和端口上

???????? SOCKADDR_IN addrSrv;//定義一個SOCKADDR_IN變量,作為套接字的本地地址信息

???????? //完成對SOCKADDR_IN的賦值

???????? addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//將主機地址信息32位u_Long轉(zhuǎn)換為網(wǎng)絡(luò)地址信息

???????? addrSrv.sin_family = AF_INET;//地址家族

???????? addrSrv.sin_port = htons(6000);//端口號為6000,并將兩個字節(jié)16位的信息u_short轉(zhuǎn)換成網(wǎng)絡(luò)地址信息

?

???????? bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

//將套接字設(shè)置為監(jiān)聽模式,準備接收用戶請求

???????? listen(sockSrv,5);//第一個是套接字,第二個是等待連接隊列的最大長度

?

???????? SOCKADDR_IN add_Client;//定義一個地址及誒夠提,用來接收用戶地址信息

???????? int len = sizeof(SOCKADDR);

?

???????? while (1)

???????? {

// 等待用戶請求到來,當請求到來后,接收連接請求,返回一個新的對應(yīng)于此次連接的套接字

?????????????????? SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&add_Client,&len);//sockConn用來保存新的套接字,而先前的套接字任繼續(xù)監(jiān)聽連接請求

?????????????????? char sendBuf[100];//定義一個數(shù)組,用于保存要發(fā)送的數(shù)據(jù)

?????????????????? //ntol函數(shù)將一個in_addr的結(jié)構(gòu)類型轉(zhuǎn)換為點分十進制格式的IP地址字符串

?????????????????? sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",inet_ntoa(add_Client.sin_addr));

//發(fā)送數(shù)據(jù)??????????????

?????????????????? send(sockConn,sendBuf,100,0);

?????????????????? char recvBuf[100];

//接收數(shù)據(jù)??????????????

?????????????????? recv(sockConn,recvBuf,100,0);

// 打印數(shù)據(jù)????????????

?????????????????? printf("%s\n",recvBuf);

//關(guān)閉套接字??????????

?????????????????? closesocket(sockConn);

???????? }

}

?

客戶端程序

?

#include <Winsock2.h>

#include <Stdio.h>

?

void main()

{

//加載套接字庫

???????? WORD wVisionRequested;//保存WinSock庫的版本

???????? WSADATA wsaData;

???????? int err;

????????

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

????????

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

?

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

????????

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

????????

???????? if (err != 0)//如果返回值不為0 ,則直接退出

???????? {

?????????????????? return;

???????? }

????????

???????? if (LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion != 1))//驗證版本號

???????? {

?????????????????? WSACleanup();

?????????????????? return;

???????? }

//創(chuàng)建套接字

???????? SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建的是流式套接字,自動選擇協(xié)議

?

???????? SOCKADDR_IN addrSrv;//定義一個SOCKADDR_IN變量,作為套接字的本地地址信息

//完成對SOCKADDR_IN的賦值

???????? //設(shè)定服務(wù)器端的地址,127.0.0.1是本地回路地址,不管機器有無網(wǎng)卡都可以使用這個IP地址

???????? //往往用這個IP地址在本地機器上面測試

???????? addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//將其轉(zhuǎn)換為u_Long類型

???????? addrSrv.sin_family = AF_INET;//地址家族

???????? addrSrv.sin_port = htons(6000);//端口號為服務(wù)器等待請求信號的那個端口

//向服務(wù)器發(fā)出請求,第二個是設(shè)定連接服務(wù)器的地址信息,第三個是指定服務(wù)器端地址長度

//對于客戶端來說,它不需要綁定,可以直接連接服務(wù)器

???????? connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

//接收數(shù)據(jù)

???????? char recvBuf[100];

???????? recv(sockClient,recvBuf,100,0);

???????? printf("%s\n",recvBuf);

//發(fā)送數(shù)據(jù)

???????? //+1是為了在最后加上一個‘\0’,表示字符串結(jié)束

???????? send(sockClient,"This is Client message.",strlen("This is Client message.")+1,0);

//關(guān)閉套接字

???????? closesocket(sockClient);

???????? WSACleanup();

}

運行結(jié)果如下:

?

UDP建立工程

//UdpSrc.cpp

#include <Winsock2.h>

#include <Stdio.h>

?

void main()

{

//加載套接字庫

???????? WORD wVisionRequested;//保存WinSock庫的版本

???????? WSADATA wsaData;

???????? int err;

????????

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

????????

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

????????

???????? if (err != 0)//如果返回值不為0 ,則直接退出

???????? {

?????????????????? return;

???????? }

????????

???????? if (LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion != 1))//驗證版本號

???????? {

?????????????????? WSACleanup();

?????????????????? return;

???????? }

//創(chuàng)建套接字

???????? SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);//創(chuàng)建的是數(shù)據(jù)報式套接字,自動選擇協(xié)議

???????? //將套接字綁定到本機地址和端口上

???????? SOCKADDR_IN addrSrv;//定義一個SOCKADDR_IN變量,作為套接字的本地地址信息

???????? //完成對SOCKADDR_IN的賦值

???????? addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//將主機地址信息32位u_Long轉(zhuǎn)換為網(wǎng)絡(luò)地址信息

???????? addrSrv.sin_family = AF_INET;//地址家族

???????? addrSrv.sin_port = htons(6000);//端口號為6000,并將兩個字節(jié)16位的信息u_short轉(zhuǎn)換成網(wǎng)絡(luò)地址信息

// 綁定套接字???????

???????? bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

//等待并接收數(shù)據(jù)

???????? SOCKADDR_IN add_Client;//定義一個地址,用來接收用戶地址信息

???????? int len = sizeof(SOCKADDR);

???????? char recvBuf[100];//定義一個數(shù)組,用于保存要接收的數(shù)據(jù)

???????? recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&add_Client,&len);

???????? printf("%s\n",recvBuf);

//關(guān)閉套接字

???????? closesocket(sockSrv);

???????? WSACleanup();

}

//UdpClient.cpp

#include <Winsock2.h>

#include <Stdio.h>

?

void main()

{

//加載套接字庫

???????? WORD wVisionRequested;//保存WinSock庫的版本

???????? WSADATA wsaData;

???????? int err;

????????

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

????????

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

????????

???????? if (err != 0)//如果返回值不為0 ,則直接退出

???????? {

?????????????????? return;

???????? }

????????

???????? if (LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion != 1))//驗證版本號

???????? {

?????????????????? WSACleanup();

?????????????????? return;

???????? }

//創(chuàng)建套接字

???????? SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);//創(chuàng)建的是流式套接字,自動選擇協(xié)議

???????? SOCKADDR_IN addrSrv;//定義一個SOCKADDR_IN變量,作為套接字的本地地址信息

???????? addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

???????? addrSrv.sin_family = AF_INET;//地址家族

???????? addrSrv.sin_port = htons(6000);//端口號為6000,并將兩個字節(jié)16位的信息u_short轉(zhuǎn)換成網(wǎng)絡(luò)地址信息

//發(fā)送數(shù)據(jù)

???????? sendto(sockSrv,"This is a client message.",strlen("This is a client message.")+1

?????????????????? ,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//addrSrv為目標套接字地址

//關(guān)閉套接字

???????? closesocket(sockSrv);

???????? WSACleanup();

}

?

基于UDP的簡單聊天程序

//NetSrv.cpp

#include <Winsock2.h>

#include <Stdio.h>

?

void main()

{

???????? //加載套接字庫

???????? WORD wVisionRequested;//保存WinSock庫的版本

???????? WSADATA wsaData;

???????? int err;

????????

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

????????

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

????????

???????? if (err != 0)//如果返回值不為0 ,則直接退出

???????? {

?????????????????? return;

???????? }

????????

???????? if (LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion != 1))//驗證版本號

???????? {

?????????????????? WSACleanup();

?????????????????? return;

???????? }

????????

???????? //創(chuàng)建套接字,并且將套接字綁定到本機地址和端口上

???????? SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);

???????? SOCKADDR_IN addrSrv;

???????? addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

???????? addrSrv.sin_family = AF_INET;

???????? addrSrv.sin_port = htons(6000);

????????

???????? // 綁定套接字???????

???????? bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

????????

???????? char recvBuf[100];

???????? char sendBuf[100];

???????? char tempBuf[200];

????????

???????? SOCKADDR_IN addrClient;

???????? int len = sizeof(SOCKADDR);

????????

???????? while (1)

???????? {

?????????????????? //等待并且接收數(shù)據(jù)

?????????????????? recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);

?????????????????? if ('q' == recvBuf[0])

?????????????????? {

??????????????????????????? sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);

??????????????????????????? printf("Chat end!\n");

??????????????????????????? break;

?????????????????? }

?????????????????? sprintf(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);

?????????????????? printf("%s\n",tempBuf);

?????????????????? //發(fā)送數(shù)據(jù)

?????????????????? printf("Please input data : \n");

?????????????????? gets(sendBuf);

?????????????????? sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);

???????? }

???????? closesocket(sockSrv);

???????? WSACleanup();

}

//NetClient.cpp

#include <Winsock2.h>

#include <Stdio.h>

?

void main()

{

???????? //加載套接字庫

???????? WORD wVisionRequested;//保存WinSock庫的版本

???????? WSADATA wsaData;

???????? int err;

????????

???????? wVisionRequested = MAKEWORD(1,1);//請求版本號的WORD值

????????

???????? err = WSAStartup(wVisionRequested,&wsaData);//加載套接字庫

????????

???????? if (err != 0)//如果返回值不為0 ,則直接退出

???????? {

?????????????????? return;

???????? }

????????

???????? if (LOBYTE(wsaData.wVersion) != 1||HIBYTE(wsaData.wVersion != 1))//驗證版本號

???????? {

?????????????????? WSACleanup();

?????????????????? return;

???????? }

????????

//創(chuàng)建套接字,并且將套接字綁定到本機地址和端口上

???????? SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);

???????? SOCKADDR_IN addrSrv;

???????? addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

???????? addrSrv.sin_family = AF_INET;

???????? addrSrv.sin_port = htons(6000);

????????

???????? // 綁定套接字???????

???????? bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

????????

???????? char recvBuf[100];

???????? char sendBuf[100];

???????? char tempBuf[200];

?

???????? int len = sizeof(SOCKADDR);

????????

???????? while (1)

???????? {

//發(fā)送數(shù)據(jù)

?????????????????? printf("Please Input Data : \n");

?????????????????? gets(sendBuf);

?????????????????? sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,len);

?

//等待并且接收數(shù)據(jù)

?????????????????? recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);

?????????????????? if ('q' == recvBuf[0])

?????????????????? {

??????????????????????????? sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);

??????????????????????????? printf("Chat end!\n");

??????????????????????????? break;

?????????????????? }

?????????????????? sprintf(tempBuf,"%s say : %s",inet_ntoa(addrSrv.sin_addr),recvBuf);

?????????????????? printf("%s\n",tempBuf);

???????? }

???????? closesocket(sockSrv);

???????? WSACleanup();

}

運行結(jié)果:

?

多線程

程序、進程、線程

程序:計算機指令的集合,是一文件的形式存儲在磁盤上面的;

進程:一個正在運行的程序的實例,是一個程序在其自身地址空間的一次執(zhí)行活動;

線程:真正完成代碼的執(zhí)行;線程只有一個內(nèi)核對象和一個線程棧,占用內(nèi)存少;

所以說一個程序?qū)?yīng)多個進程;進程是線程的容器;進程是線程的執(zhí)行環(huán)境;

?

線程創(chuàng)建函數(shù)Create? Thread

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags,

LPDWORD lpThreadId);

?

舉例

舉例1:簡單

#include <WINDOWS.H>//需要訪問windows API 函數(shù),因此許加入此頭文件

#include <IOSTREAM.H>

?

DWORD WINAPI Fun1Pro(LPVOID lpParameter);

?

void main()//主線程

{

???????? HANDLE hThread1;

???????? hThread1 = CreateThread(NULL,0,Fun1Pro,NULL,0,NULL);

???????? CloseHandle(hThread1);//這里并不是終止新創(chuàng)建的線程,而是不再需要線程句柄

???????? cout<<"Main thread is running..."<<endl;

}

?

DWORD WINAPI Fun1Pro(LPVOID lpParameter)

{

???????? cout<<"Thread1 is running..."<<endl;

???????? return 0;

}

錯誤8

?

代碼

//MultiThread.cpp

#include <WINDOWS.H>//需要訪問windows API 函數(shù),因此許加入此頭文件

#include <IOSTREAM.H>

?

DWORD WINAPI Fun1Pro(LPVOID lpParameter);

int nIndex = 0;

void main()//主線程

{

???????? HANDLE hThread1;

???????? hThread1 = CreateThread(NULL,0,Fun1Pro,NULL,0,NULL);

???????? CloseHandle(hThread1);//這里并不是終止新創(chuàng)建的線程,而是不再需要線程句柄

?//?? ????? Sleep(10);???????? //讓主線程睡眠10ms,睡眠期間好讓線程1執(zhí)行

???????? while (nIndex++<1000)

???????? cout<<"Main thread is running..."<<endl;

}

?

DWORD WINAPI Fun1Pro(LPVOID lpParameter)

{

???????? while (nIndex++<1000) //驗證線程是交替運行的,運用的是時間片技術(shù)

???????? cout<<"Thread1 is running..."<<endl;

// ??? int i = 0;

// ??? while (++i)//計算計算機的運行效率

// ??? {

// ???????????? cout<<i<<".Thread1 is running..."<<endl;???????

// ??? }

???????? return 0;

}

舉例2:火車票

代碼:

#include <WINDOWS.H>//需要訪問windows API 函數(shù),因此許加入此頭文件

#include <IOSTREAM.H>

?

DWORD WINAPI Fun1Pro(LPVOID lpParameter);

DWORD WINAPI Fun2Pro(LPVOID lpParameter);

?

int nIndex = 0;

int nTickets = 100;

?

void main()//主線程

{

???????? HANDLE hThread1;

???????? HANDLE hThread2;

???????? hThread1 = CreateThread(NULL,0,Fun1Pro,NULL,0,NULL);

???????? hThread2 = CreateThread(NULL,0,Fun2Pro,NULL,0,NULL);

???????? CloseHandle(hThread1);

???????? CloseHandle(hThread2);

???????? Sleep(4000);

}

?

DWORD WINAPI Fun1Pro(LPVOID lpParameter)

{

???????? while (TRUE)

???????? {

?????????????????? if (nTickets>0)

??????????????????????????? cout<<"Thread1 sells tickets : "<<nTickets--<<endl;

?????????????????? else

??????????????????????????? break;

???????? }

???????? return 0;

}

?

DWORD WINAPI Fun2Pro(LPVOID lpParameter)

{

???????? while (TRUE)

???????? {

?????????????????? if (nTickets>0)

??????????????????????????? cout<<"Thread2 sells tickets : "<<nTickets--<<endl;

?????????????????? else

??????????????????????????? break;

???????? }

???????? return 0;

}

錯誤9

?

利用互斥對象實現(xiàn)線程同步(采用匿名互斥對象的方法)

1、? 首先定義全局互斥對象,我叫公共房間的鑰匙

2、? 創(chuàng)建互斥對象 將鑰匙放在房間門上

3、? 在子線程當中添加主動請求信號函數(shù),拿到鑰匙進入房間

4、? 在子線程當中釋放互斥對象,走出房間,將鑰匙歸位

5、? 值得注意的是,對于互斥對象:誰擁有誰釋放

1、? HANDLE hMutex;

2、? hMutex = CreateMutex(NULL,FALSE,NULL);//創(chuàng)建匿名互斥對象

3、? WaitForSingleObject(hMutex,INFINITE);

4、? ReleaseMutex(hMutex);

CreateMutex

?

ReleaseMutex

此函數(shù)在調(diào)用之前會先判斷該線程ID與當前擁有互斥對象的線程ID是否一致,一致就釋放。

?

WaitForSingleObject

? ?

保證應(yīng)用程序只有一個實例運行(采用命名互斥對象的方法)

hMutex = CreateMutex(NULL,TRUE,"tickets");

???????? if (hMutex)

???????? {

?????????????????? if (ERROR_ALREADY_EXISTS == GetLastError())

?????????????????? {

??????????????????????????? cout<<"Only one thread can run..."<<endl;

??????????????????????????? return;

?????????????????? }

???????? }

???????? WaitForSingleObject(hMutex,INFINITE);

??????? ReleaseMutex(hMutex);

???????? ReleaseMutex(hMutex);

網(wǎng)絡(luò)聊天室程序

MFC加載套接字庫AfxSocketInit()

所有與窗口有關(guān)的類都有一個數(shù)據(jù)成員m_hWnd

完全面向?qū)ο蟛捎渺o態(tài)成員函數(shù)和靜態(tài)成員變量

?

?

線程同步的另外兩種方法

事件對象

?

CreateEvent()創(chuàng)建事件對象

?

SetEvent()設(shè)置對象狀態(tài)

?

ResetEvent()重置對象

?

錯誤9

?

關(guān)鍵代碼段

?

?

1、InitiaLizeCriticalSection()創(chuàng)建關(guān)鍵代碼段

?

?

2、Enter CriticalSection()

3、Leave CriticalSection()

4、Delete CriticalSection()

互斥對象、事件對象、關(guān)鍵代碼段的比較

?

?

基于消息的異步套接字

Windows套接字在兩種模式上面執(zhí)行I/O操作:阻塞模式和非阻塞模式

阻塞模式和非阻塞模式的區(qū)別

?

Windows Sock相關(guān)函數(shù)

WSAAsyncselect()

?

?

WSAEnumProtocols()

?

WSAStartup()

?

?

WSACleanup()

?

WSASocket()

?

WSARecvFrom()

? ? ? ? ?

WSASendTo()

?

?

進程間通信

剪切板

OpenClipboard打開剪切板

EmptyClipboard清空

SetClipboradData放置數(shù)據(jù)

GlobalAlloc

?

GetClipboardData

?

匿名管道

?

CreatePipe

?

CreatProcess

?

創(chuàng)建子進程的注意事項

?

?

?

命名管道

不僅可以在本機上的實現(xiàn)兩個進程之間的通信,還可以跨網(wǎng)絡(luò)實現(xiàn)兩個進程之間的通信;

創(chuàng)建命名管道時可以指定使用權(quán)限的用戶;

命名管道是圍繞Windows文件系統(tǒng)設(shè)計的一種機制,采用“命名管道文件系統(tǒng)(NPFS)”接口;

它實際上建立了一個客戶機/服務(wù)器通信系統(tǒng);

它只能在Windows NT或Windows 2000上創(chuàng)建;

他提供了兩種基本通信模式:字節(jié)模式和消息模式;

CreateNamedPipe

?

Connect

ConnectNamedPipe()

?

CreateFile()

?

WaitNamedPipe()

?

油槽

她是基于廣播通信體系設(shè)計出來的,它采用無連接的不可靠的數(shù)據(jù)傳輸;

一對多的單項通信;可以基于此制作一個網(wǎng)絡(luò)會議通知系統(tǒng);

油槽實現(xiàn)代碼非常簡單,而采用SOCKET編程則相比之下太復(fù)雜;??????

它是一種單項通信機制,創(chuàng)建油槽的服務(wù)器進程讀取數(shù)據(jù),打開油槽的客戶機進程寫入數(shù)據(jù);

CreateMailslot()

?

四種方式比較

?

AcitiveX控件

它相當于一個服務(wù)器應(yīng)用程序,它依賴某個容器應(yīng)用程序;

?

ActiveX控件四種屬性

?

發(fā)行版本

?

總結(jié)

?

動態(tài)鏈接庫

?

動態(tài)庫和靜態(tài)庫

?

兩種加載動態(tài)鏈接庫的方式

隱式鏈接

動態(tài)加載

?

Dumpbin命令查看Dll文件

?

讓Dll導(dǎo)出函數(shù)

?

錯誤10

?

?

搜索動態(tài)鏈接庫的目錄順序

?

Depends工具? 查看動態(tài)鏈接庫和可執(zhí)行程序,主要是查看他依賴哪些動態(tài)鏈接庫

?

動態(tài)庫的創(chuàng)建并且導(dǎo)出函數(shù)

//dlll.h

_declspec(dllexport) int add(int a,int b)

{

???????? return a+b;

}

?

_declspec(dllexport) int subtract(int a,int b)

{

???????? return a-b;

}

//Dlll.h

_declspec(dllimport) int add(int a,int b);

_declspec(dllimport) int subtract(int a,int b);

#include "..\Dlll\Dlll.h"//使用動態(tài)庫

動態(tài)庫的改造,使其能夠被客戶端和自己本省都能夠使用

#ifdef DLLL_API

#else

#define DLLL_API _declspec(dllimport)

#endif

DLLL_API int add(int a,int b);

DLLL_API int subtract(int a,int b);

?

#define DLLL_API _declspec(dllexport)

#include "Dlll.h"

int add(int a,int b)

{

???????? return a+b;

}

int subtract(int a,int b)

{

???????? return a-b;

}

?

從Dll中導(dǎo)出C++類

動態(tài)庫函數(shù)名字改編問題

?

名字沒有改編

動態(tài)加載動態(tài)庫LoadLibrary()

?

void CDllTestDlg::OnBtnAdd()

{

???????? // TODO: Add your control notification handler code here

???????? HINSTANCE hInst;//定義一個實例句柄對象

???????? hInst = LoadLibrary("Dlll.dll");//動態(tài)加載動態(tài)庫

???????? typedef int (*ADDPROC)(int a,int b);//定義函數(shù)指針類型

???????? ADDPROC Add = (ADDPROC)GetProcAddress(hInst,"add");//獲取dll的函數(shù)地址

???????? if (!Add)

???????? {

?????????????????? MessageBox("獲取函數(shù)地址失敗");

?????????????????? return;

???????? }

?

???????? CString str;

???????? str.Format("5+3=%d",Add(5,3));

???????? MessageBox(str);

}

?

void CDllTestDlg::OnBtnSub()

{

???????? // TODO: Add your control notification handler code here

???????? HINSTANCE hInst;//定義一個實例句柄對象

???????? hInst = LoadLibrary("Dlll.dll");//動態(tài)加載動態(tài)庫

???????? typedef int (*ADDPROC)(int a,int b);//定義函數(shù)指針類型

???????? ADDPROC Sub = (ADDPROC)GetProcAddress(hInst,"subtract");//獲取dll的函數(shù)地址

???????? if (!Sub)

???????? {

?????????????????? MessageBox("獲取函數(shù)地址失敗");

?????????????????? return;

???????? }

?

???????? CString str;

???????? str.Format("5-3=%d",Sub(5,3));

???????? MessageBox(str);

}

?

?

/************************************************************************/

/*? 該dll文件自己是不能夠運行的,必須要有某個客戶程序加載這個dll,然后調(diào)用

SetHook函數(shù),調(diào)用SetWindowsHookEx函數(shù),安裝鉤子,這樣就可以加載全局鉤子了*/

/************************************************************************/

?

#include <WINDOWS.H>

?

/*_declspec(dllexport) void SetHook();*/

?

HHOOK g_hMouse = NULL;

//鼠標鉤子過程

LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)

{

???????? return 1;//返回非0值表示鼠標消息已經(jīng)處理了

}

//鼠標鉤子安裝

void SetHook()

{

???????? g_hMouse = SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("HOOK"),0);

???????? //第四個參數(shù)為0,表示與運行在同一桌面所有進程相關(guān)

???????? //第三個參數(shù)指定安裝鉤子過程所在的Dll模塊句柄,返回給HOOk.dll

}

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/chensifan/archive/2012/08/28/2659766.html

總結(jié)

以上是生活随笔為你收集整理的VC++笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。