VC雜記

得到Combobox的狀態:向ComboBox發送CB_GETDROPPEDSTATE消息.ios

格式化字串:char buff[10] ; sprintf(buff,」1+1=%d」,1+1); Sprintf會返回格式化的字符串的長度。 程序員

C區別大小寫。 編程

窗口大部份狀況都要處理WM_PAINT,WM_PAINT處理幾乎老是從BeginPaint開始,以EndPaint結束。 windows

獲取字符串長度strlen wcslen(unicode長度); 數組

退出程序:DestroyWindow 緩存

文件拖放相關API:DragAcceptFiles,DragQueryFile以及消息WM_DROPFILES 服務器

設置定時器:SetTimer刪除定時器:KillTimer 網絡

LOWORD:返回含低16位;HIWORD:返回高16位,相似的還有LOBYTE,HIBYTE 架構

Cout,cerr與<<一塊兒完成輸出與標準錯誤檢出。Cin與>>完成輸入操做.endl表示換行。使用他們須要#include <iostream.h>。例如:cout<<」a」<<endl<<」b」<<endl. app

當子類建立時,會先調用基類的構造函數,而後再調用子類函數。在Delphi中若是不顯示使用inherited則不會調用基類的構造函數。另外C++的繼承和Delphi也不樣,C++可用Public,Protected,private指定繼承級別。

Class AA

{

AA(int i);

......

}

Class BB:AA

{

BB(int i);

......

}

//這裏會先執行父類AA的構造函數,再執行子類BB的構造函數

BB::BB(int i):AA(int i)

{

……

}

純虛函數,在最後加上=0;如virtual void aa()=0;,擁有純虛函數的類稱爲抽象類。

避免重複定義類

#inndef xxxx

#define xxxx

類包含的內容

#endif

在WM_PAINT最前面用ValidateRect(hwnd,NULL)可以使顯示區域有效且不會重繪,由於顯示區域無效纔會重繪

GetTextMetrics取得字體大小,GetSystemMetrics函式以取使用者介面上各種視覺元件大小的資訊

Stdafx:包含了一些必需的頭文件,是MFC編程的必需文件,它還會調用windows.h

AppWizard生成的典型源文件:

Project.cpp

MainFrm.capp:控制程序的主窗口

projectView.cpp

projectDoc.cpp

stdafx.cpp

project.rc:包含資源文件

resource.h:用來定義宏

m_hWnd:MFC裏窗口類的句柄

IsDlgButtonChecked判斷CheckBox是否按下

UpdateData(bSaveAndValidate)若是bSaveAndValidate=false則初始化對話框,若是bSaveAndValidate=true則從新獲取對話框的數據,默認爲True

GetCurSel:獲取ComboBox,ListBox的當前選擇項目,若是返回CB_ERR則沒有項目被選中

CWnd::SetDlgItemText:Sets the caption or text of a control owned by a window or dialog box.

CWnd::GetDlgItemText:Call this member function to retrieve the title or text associated with a control in a dialog box.

void CheckRadioButton( int nIDFirstButton, int nIDLastButton, int nIDCheckButton );

Selects (adds a check mark to) a given radio button in a group and clears (removes a check mark from) all other radio buttons in the group.

CComboBox::GetDroppedState:判斷CComboBox是否處於下拉狀態

若是要使一個static Text響應消息,必須設置一個惟一ID,並勾選屬性裏面的notify

Vector:至關於一個容器,是一個可以存聽任意類型的動態數組,可以增長和壓縮數據。

Vector<int> test;//聲明一個存放int類型的容器

Test.pushback(66);//在vector的最後放入66

Test.pushbak(88); //在vector的最後放入88

MFC程序入口點WinMain

DefWindowProc:對未被處理的消息提供默認響應。

去除一個屬性:當前屬性結合與上須要去除屬性取反後的值,如 styles & ~style1

關閉程序流程:

點擊右上角的叉叉->產生WM_CLOSE消息->在WM_CLOSE裏能夠判斷是否須要關閉,若是須要關閉則調用DestroyWindow()(做用是銷燬Windows窗體)->當窗體銷燬後產生一個WM_DESTROY消息->在WM_DESTROY裏調用PostQuitMessage(0) ->產生WM_QUIT消息(GetMessage()若是獲取到的消息是WM_QUIT就會返回0,這樣就退出消息循環)->退出消息循環,程序結束

當收到WM_DESTROY消息後,必須調用PostQuitMessage,不然消息循環不會中止,程序也永遠不會結束。PostQuitMessage會產生一個WM_QUIT消息,當應用程序收到WM_QUIT消息後就退出循環了。

DefWindowProc:缺省窗口處理過程,不須要本身處理的消息都由這個過程處理

m_前綴表明是一個類的成員變量

標準輸入輸出流(#include iostream.h):

cin>>xxxx

cout<<xxx

cerr<<xxx

在輸出時可使用endl,至關於C語言的’\n’, 表示換行

若是以一個類未提供構造函數,則C++會提供一個默認的構造函數,這個構造函數沒有參數,只負責建立對象,而不作任何的初始化工做.

只要定義了一個構造函數,C++就再也不提供默認的構造函數,若是還想要沒有參數的構造函數,則必須本身定義.

this是一個隱含的指針,它指向對象自己,表明了對象的地址.

句柄 :HWND,HICON,HCURSOR,HBRUSH等等.

Windows程序是一種基於事件驅動的程序,主要是基於消息.

在Win32程序中,WinMain函數的hPrevInstance老是NULL.

SendMessage直接將消息發到窗口,消息處理完成後才返回.

PostMessage將消息發到應用程序的消息隊列裏,並當即返回.

類成員在默認狀況下是私有的.

當以MyClass obj ;聲明一個對象時,會默認調用無參數構造函數.

在聲明一個對象時,如MyClass obj時,對象就已經建立.若是須要使用帶參數的構建函數,則在聲明對象時應該這樣 : MyClass obj(x,y)

子類聲明 :

Class fish : public animal

{

......

}

分配內存 :pName = new char[20] ;

釋放內存 :delete[] pName ;

只有返回類型不一樣是不能構成函數重載的.

在函數重載時,要注意帶有默認值參數的狀況.

子類的構造函數會先調用父類的構造函數.

子類的析構函數則相反,子類先析構,父類後析構.

當子類調用父類有不一樣參數的構造函數時,須要這樣 :

Fish(void) :animal(100,200)

{

......

}

在父類沒有和子類參數同樣的構造函數時,必須這樣處理.

C++支持多重繼承 :

Class b :public class c,public class d

{

......

}

B繼承於c和d .

初始化時按照基類表說明順序來進行的.析構函數則是按照說明順序的相反方向進行的.

子類調用父類函數(若是子類沒有調用父類的函數,則不會執行父類的虛擬函數) :

class fish:public animal

{

public:

virtual void eate(void)

{

animal::eate();

cout<<"bigfish eate"<<endl;

}

};

聲明一個純虛函數:

Virtual void eate(void) = 0;

凡是含有純虛函數的類成爲抽象類,這種類不能實例化,只是做爲基類爲派生類服務.在派生類必須所有實現基類的純虛函數,不然派生類也變成了抽象類.

當基類和子類出現兩個參數和名稱徹底同樣的函數,而且基類函數沒有使用virtual標示符,則基類的的函數將被隱藏.

當基類和子類出現兩個參數不同,但名稱徹底同樣的函數時,無論基類是否使用了virtual標示符,基類的函數都將被隱藏.

C分配類存的函數:

Malloc(),calloc(),realloc()

使用free釋放分配的內存

C++分配內存:

Int *p = new int;//單個對象

Int *q = new int[100];數組

釋放內存:

Delete p;

Delete[] q;

聲明一個引用:

int a = 5;

int &b = a;//初始化引用,表明b和a使用同一內存.

若是b = 3,則a也等於3.

引用一旦初始化後,不再能表明別的內存.

通常狀況下都不用引用,而使用指針.

每一個MFC都只有1個派生於應用程序類(CWinApp)的theApp全局變量,用來惟一標識應用程序的實例,標示了應用程序自己.

Afx前綴表明應用程序框架(Application Framework),以Afx前綴開頭的函數都是全局函數.好比AfxMessageBox。

MFC程序的全局變量都是放在Globals分支下.

在加載WinMain以前,全局對象/變量就已經初始化OK了.

Memset:填充內存爲某一ASCII值,和Delphi的FillChar相似.

MFC中後綴名爲Ex的函數都是擴展函數.

尋找WinMain:

1. APPMODUL.CPP

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

// call shared/exported WinMain

return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

2. 每一個MFC應用程序有且只有一個繼承於CWinApp的theApp對象,表明此應用程序.

3. 由於基類的構造函數會調用父類的構造函數,因此請看CwinApp的構造函數(APPCORE.CPP),

其中有一句pModuleState->m_pCurrentWinApp = this

4. 接下來再回來看第1步的_tWinMain函數中的AfxWinMain.

5. 在WINMAIN.CPP裏找到AfxWinMain的實現代碼.注意此函數定義裏的幾句代碼:

{

……

CWinThread* pThread = AfxGetThread();

CWinApp* pApp = AfxGetApp();

……

if (pApp != NULL && !pApp->InitApplication())//完成MFC內部管理工做

……

if (!pThread->InitInstance())//實際上調用的是咱們本身的應用程序對象的//InitInstance,

……

nReturnCode = pThread->Run();

}

經查看AfxGetThread實現代碼(THRDCORE.APP)可知, AfxGetThread函數最終調用了AfxGetApp()並返回,因此pThreadpApp這兩個指針是同樣的.

再來看AfxGetApp()的實現代碼:

_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()

{ return afxCurrentWinApp; }

看下afxCurrentWinApp的實現(AFXWIN.H):

#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp

從第3步以及本步的以上描述能夠得出:實際上pThreadpApp這兩個指針實際上就是this指針,this指針指向實際應用程序,也就是theApp.

6. InitInstance()函數:

再看第5步的AfxWinMain的實現,其中的pThread->InitInstance爲咱們本身程序的xxxApp(其實也能夠說是theApp)的方法.

7. 註冊類的函數AfxEndDeferRegisterClass(WINCORE.CPP).

8. MFC應用程序實際上有兩個窗口,其中一個是CMainFrame類的對象表明的應用程序框架窗口,該類有一個PreCreateWindow,它在窗口產生以前被調用.CmainFram只是僅僅調用了父類CFrameWndPreCreateWindow(WINFRM.CPP),在父類CframeWnd的PreCreateWindow函數裏又調用了AfxEndDeferRegisterClass方法註冊類(第7步).因此能夠看出, PreCreateWindow能夠再建立窗體以前能夠改變它的註冊類的各項參數,從而也改變了窗體的樣式等屬性.

9. 查看CWnd::CreateEx函數,此函數用於初始化窗口註冊類,並調用而來第8步的PreCreateWindow(因此說PreCreateWindow在建立窗體以前留給了程序員一條用於修改窗體屬性的通道),最後使用了CreateWindowEx來建立窗體.

10. 又是誰調用CreateEx呢,它就是CFrameWnd::Create(WINFRM.CPP).

11. 再往上刨刨,看看CFrameWnd::Create又是誰調用的,原來是CFrameWnd::LoadFrame.

Create -> CreateEx -> PreCreateWindow

CWnd::SetIcon:爲窗口設置一個圖標

以::開始的方法是全局函數.

定義類成員變量時,通常用m_前綴開頭.

建立一個按鈕:

m_btn1.Create("ViewBtn1",WS_CHILD | WS_VISIBLE,CRect(0,0,300,300),this,0);

GetParent()得到父窗口.

消息映射有三個地方相關:

1. 頭文件,相似於:

//{{AFX_MSG(CDrawView)

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

2. 源文件有兩處,相似於:

第一處:

BEGIN_MESSAGE_MAP(CDrawView, CView)

//{{AFX_MSG_MAP(CDrawView)

ON_WM_LBUTTONDOWN()//它是一個宏,綁定了消息和其響應方法

//}}AFX_MSG_MAP

……

END_MESSAGE_MAP()

第二處:

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

{

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

CView::OnLButtonDown(nFlags, point);

}

消息->窗口句柄和對象指針一一對應的對照表->根據消息中的句柄找到對象->把消息傳給應用程序框架類->調用WindowProc

CWnd的WindowProc會調用一個OnWndMsg函數,此函數負責對消息路由分派(一一對消息判斷,而後處理).

OnWndMsg會根據上面所述的消息映射方法,到子類的頭文件的DECLARE_MESSAGE_MAP()之上,

//{{AFX_MSG(CDrawView)和//}}AFX_MSG之間查找是否有相應的消息響應函數原型聲明,再到子類的源文件的BEGIN_MESSAGE_MAP(CDrawView, CView)和END_MESSAGE_MAP()之間查看是否有相應的消息映射宏.

若是找到了消息響應函數,就調用消息響應函數處理消息.若是子類沒有找到消息響應函數,就交給父類處理.

CclientDC:客戶區域DC,在構造或釋放時自動調用GetDC和ReleaseDC.

CwindowDC:客戶訪問整個窗口區域.包括標題欄菜單.

SetROP2:設置繪圖模式

得到一個透明背景的畫刷CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH))

建立並顯示一個插入符:

CreateSolidCaret(20,100);

ShowCaret();

SetCaretPos:設置插入符的位置

得到字體的度量信息:

BOOL GetTextMetrics(
  HDC hdc,            // handle to device context
  LPTEXTMETRIC lptm   // pointer to text metrics structure
);

使用CDC的GetTextExtent來得到字符串的寬度和高度

 

路徑層(Path bracket):

使用CDC的BeginPath和EndPath來建立及銷燬路徑層.須要配合Rectangles, Ellipse等使用, Rectangle, Ellipse等畫出了當前路徑層的範圍

當前路徑層的做用須要SelectClipPath來肯定模式.

裁剪區域(Clipping region):繪圖操做侷限於在裁剪區域.

CDC的SelectClipPath: 爲設備上下文選擇當前路徑做爲剪切區,並使用指定模式組合新區域與已存在的剪切區.

例子: pDC->BeginPath();//路徑層

CSize size = pDC->GetTextExtent(m_strText);//得到m_strText的寬度

//這裏的Rectangle標識除了路徑層的範圍

pDC->Rectangle(CRect(0,0,size.cx,size.cy));//

pDC->EndPath();

//RGN_DIFF:排除路徑層內容,也就是下面畫的線不會顯示在當前路徑層

pDC->SelectClipPath(RGN_DIFF);

//畫線,這裏就能夠看出效果了

for (int i=0;i<300;i+=10)

{

pDC->MoveTo(0,i);

pDC->LineTo(300,i);

pDC->MoveTo(i,0);

pDC->LineTo(i,300);

}

效果以下,畫的線未影響文字部分

clip_image002

Cfont:構造後還要初始化才能使用.好比用CreateFont等.

若是要使用這個字體,還必須選入設備描述符.

CeditView和CrichEditView這兩個類用來實現文字處理.

OnDraw:每單重繪時都會調用OnDraw(我的以爲應該是在WM_PAINT裏面調用的)

CCmdTarget類及其派生類能夠接受命令消息(WM_COMMAND),通告消息,但不能接收標準消息

CWnd類及其派生類能夠接收標準消息(WM_XXXX),又因Cwnd派生於CCmdTarget,因此也能夠接收命令消息,通告消息

注:

標準消息:除WM_COMMAND外,全部以WM_開頭的消息

命令消息:來自菜單,加速鍵,工具欄的消息,以WM_COMMAND的形式呈現.

通告消息:是由控件產生的消息,例如按鈕的單擊,列表框的選擇等,通告消息也是以WM_COMMAND形式呈現.

得到程序的主菜單:Cwnd的GetMenu();

得到子菜單:Cmenu的GetSubMenu;

標記菜單:

//勾選(標記)菜單,根據索引

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

//勾選(標記)菜單,根據ID號

this->GetMenu()->GetSubMenu(4)->CheckMenuItem(IDM_TEST3,MF_BYCOMMAND | MF_CHECKED);

//每一個子菜單隻能有一個缺省菜單

//設置缺省菜單,根據索引

this->GetMenu()->GetSubMenu(4)->SetDefaultItem(2,TRUE);

//設置缺省菜單,根據ID號

this->GetMenu()->GetSubMenu(4)->SetDefaultItem(IDM_TEST5,FALSE);

//設置菜單顯示圖形

int xMenu = GetSystemMetrics(SM_CXMENUCHECK);

int yMenu = GetSystemMetrics(SM_CYMENUCHECK);

CString str;

str.Format("菜單圖標的大小爲:長:%d寬%d",xMenu,yMenu);

//圖標的大小不能超過xMenu,yMenu

MessageBox(str);

CBitmap *pBitmap = new CBitmap;

pBitmap->LoadBitmap(IDB_MENU);

this->GetMenu()->GetSubMenu(4)->SetMenuItemBitmaps(3,MF_BYPOSITION,pBitmap,pBitmap);

//手動控制菜單是否可用

m_bAutoMenuEnable = FALSE;

//將"打開"設置爲不可用

this->GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);

//手動設置菜單

this->SetMenu(NULL);//這裏菜單會消息

//而後再從新設置新菜單

CMenu menu;

menu.LoadMenu(IDR_MAINFRAME);

//須要從新設置菜單的屬性

menu.GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);

this->SetMenu(&menu);

menu.Detach();//必須斷開與HMENU的聯繫,不然會出錯

若是要手動更改菜單的啓用或禁用或變灰狀態,須要在框架構建函數裏設置m_bAutoMenuEnable爲False.

UPDATE_COMMAND_UI消息用於改變菜單項的狀態,經過映射的方法可更改菜單項的狀態(只適用於子菜單).

把Toolbar工具欄的某項的ID號設置得和菜單同樣,他們就關聯到一塊兒了.

多個菜單項可使用同一個處理函數(注意消息映射).

彈出菜單:

CMenu menu;

menu.LoadMenu(IDR_MENUPOP);

CMenu *popMenu = menu.GetSubMenu(0);

ClientToScreen(&point);//窗口座標轉屏幕座標,由於TrackPopupMenu須要使用屏幕座標

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

重繪菜單: 框架類DrawMenuBar();動態編輯菜單後,須要重繪菜單反應效果.

動態添加一個菜單:

m_menu.CreatePopupMenu();

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

GetParent()->DrawMenuBar();

能夠用CWnd的虛函數OnCommand攔截菜單消息.

對於動態添加的菜單的響應能夠集中在OnCommand裏處理

GetActiveView():獲取CView

模態對話框:

打開:DoModal();

關閉:EndDialog();

例:

CDialog1 dialog ;

dialog.DoModal();

非模態對話框:

打開:Create

ShowWindow

CTestDlg *pDlg = new CTestDlg();

pDlg->Create(IDD_DIALOG1,this);

pDlg->ShowWindow(SW_SHOW);

若是在非模態對話框中實現OK按鈕,必須覆蓋OnOK成員函數,並在其中調用DestoryWindow。不能調用基類成員函數,那將會調用EndDialog,使對話框雖然存在但不可視:

void CTestDlg::OnOK()

{

DestroyWindow();//非模態調用,並註釋基類成員函數(以下)

//CDialog::OnOK();//模態調用

}

定義一個指針,分配到堆上,生命週期和整個應用程序的生命週期同樣.

CRect.IsRectNull():4個座標都爲0

CRect.IsRectEmpty():矩形大小爲0,座標爲非0

GetClientRect和GetWindowRect的區別:

GetWindowRect() 獲得的是在屏幕座標系下的RECT;(即以屏幕左上角爲原點)

GetClientRect() 獲得的是在客戶區座標系下的RECT; (即以所在窗口左上角爲原點)

先調用GetWindowRect後再調用ScreenToClient,這個時候獲得的rect和直接使用GetClientRect獲得的值是相等的。

WS_EX_TOPMOST:頂層窗口

BringWindowToTop:把一個窗口放置到Z次序的頂部.

SetForeground:設置前臺窗口(相對於同一個應用程序)

SetWindowPos:設置窗口大小,位置等

WM_INITDIALOG:Dialog及其子控件建立完成,將要顯示前產生此消息

指定的窗口數據是在緩存中保存的,所以在調用SetWindowLong以後再調用SetWindowPos函數才能使SetWindowLong函數所做的改變生效。

改變一個Button的WM_MOUSEMOVE消息的響應(假設這個Button名字爲btn1):

1. 新建一個CButton的子類,假設爲CMyButton

2. 根據須要,從新實現CMyButton的WM_MOUSEMOVE消息響應函數

3. btn1關聯一個類型爲CButton的控件變量m_btn1,

4. 如今btn1的WM_MOUSEMOVE就由CMyButton來響應了

使用PropertyPage(相似DelphiTabSheet):

1. 在資源裏添加N個IDD_PROPPAGE_XXXX(Dialog子項)

2. 爲對應的IDD_PROPPAGE_XXXX資源添加類(CPropertyPage的子類)

3. 聲明這些類的對象

4. 建立一個CPropertySheet對象.

5. CPropertySheet對象使用AddPage把第3步這些對象添加到CPropertySheet對象裏

6. 若是須要嚮導模式,則CPropertySheet對象使用SetWizardMode()方法.

7. CPropertySheet對象使用DoModal模式顯示或者Create普通顯示

8. 經過覆蓋第2步這些CPropertyPage子類的虛擬方法virtual BOOL CProp1::OnSetActive(),能夠控制顯示哪些按鈕,如只顯示」下一步」能夠在OnSetActive方法裏這樣:

((CPropertySheet *)this->GetParent())->SetWizardButtons(PSWIZB_NEXT);

關於RadioButton的分組:

將第一個RadioButton的Group勾選上,別的同組RadioButton不用勾選.爲第一個RadioButton關聯一個int類型變量,這個變量的值指示了本組哪個RadioButton本選中,-1:沒有RadioButton被選中,0:第一個RadioButton被選中,1:第二個被選中,以此類推.

下一組的第一個RadioButton的Group勾上,就做爲新的組了.

Dialog的初始化能夠放到WM_INITDIALOG消息響應函數OnInitDialog()裏

改變MFC窗口的標題

//改變窗口的標題

//需先把FWS_ADDTOTITLE去掉

cs.style &= ~FWS_ADDTOTITLE;

cs.lpszName = "窗口外觀定製";

如下爲說明的都在PreCreateWindow裏實現:

能夠用GetWindowLong,SetWindowLong修改窗口風格

能夠經過建立一個新WNDCLASS修改窗口類風格

能夠經過AfxRegisterWndClass註冊一個新窗口類來修改風格

能夠用SetClassLong改變窗口類風格,可在多處地方調用

判斷一個窗口是否可見: IsWindowVisible()

從新設置CFrameWnd對象的控件條的位置

ShowControlBar:顯示或隱藏一個ControlBar對象

View裏設置StatusBar的文本:

1.((CMainFrame *)GetParent())->m_wndStatusBar.SetWindowText(str);

2.((CMainFrame *)GetParent())->SetMessageText(str);

3.((CMainFrame *)GetParent())->GetMessageBar()->SetWindowText(str);

4.GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);

int idx = m_wndStatusBar.CommandToIndex(IDS_TIMER);//根據字符串資源得到狀態欄某項的序號

m_wndStatusBar.SetPaneInfo(idx,IDS_TIMER,SBPS_NORMAL100); //從新設置狀態欄某項的寬度

m_wndStatusBar.SetPaneText(idx,str,TRUE);//在狀態欄的某一格顯示文字

Dll導出函數方法:

1. 在頭文件裏聲明:extern "C" int __declspec(dllexport)add(int x, int y);

2. 添加一個*.def文件,文件內容以下:

LIBRARY dllTest
EXPORTS
add @ 1

Dll的靜態調用:

1.將dllTest1.lib拷貝到callDllTest2工程目錄

2.將dllTest1.dll拷貝到callDllTest2的Debug目錄

3.將dllTest1的h頭文件拷貝到工程目錄(本項目略過)

4.使用語句導入dllTest1,以下:

#pragma comment(lib,"dllTest1.lib")

extern "C" int __declspec(dllimport) add(int x,int y);

Dll的動態調用:

#include <stdio.h>
#include <windows.h>
typedef int(*lpAddFun)(int, int); //宏定義函數指針類型
int main(int argc, char *argv[])
{
HINSTANCE hDll; //DLL句柄
lpAddFun addFun; //函數指針
hDll = LoadLibrary("..\\Debug\\dllTest.dll");
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "add");
if (addFun != NULL)
{
int result = addFun(2, 3);
printf("%d", result);
}
FreeLibrary(hDll);
}
return 0;
}

Dll的入口函數:

//DLL的入口函數

BOOL APIENTRY DllMain(HANDLE hMoudle,

DWORD ul_reason_for_call,

LPVOID lpReserved)

{

switch(ul_reason_for_call){

case DLL_PROCESS_ATTACH:

printf("DLL_PROCESS_ATTACH\n");

break;

case DLL_PROCESS_DETACH:

printf("DLL_PROCESS_DETACH\n");

break;

case DLL_THREAD_ATTACH:

printf("DLL_THREAD_ATTACH\n");

break;

case DLL_THREAD_DETACH:

printf("DLL_THREAD_DETACH\n");

break;

}

return TRUE;

}

若是經過VC++編寫的DLL欲被其餘語言編寫的程序調用,應將 函數的調用方式聲明爲__stdcall方式

C/C++缺省的調用方式卻爲__cdecl

Windows編程中常見的幾種函數類型聲明宏都是與__stdcall和__cdecl有關的(節選自windef.h):

#define CALLBACK __stdcall //這就是傳說中的回調函數
#define WINAPI __stdcall //這就是傳說中的WINAPI
#define WINAPIV __cdecl
#define APIENTRY WINAPI //DllMain的入口就在這裏
#define APIPRIVATE __stdcall
#define PASCAL __stdcall

通常在Dll文件裏這樣聲明:

int __stdcall add(int x,int y){

return x + y;

}

並定義def文件,輸出函數,def文件內容以下:(經測試,若是Delphi須要調用VC寫的Dll必須用def文件導出函數)

LIBRARY dllMain

EXPORTS

add @ 1

若是要在Dll中導出變量,在def文件裏:(DATA標誌很重要)

dllGlobalVar DATA

使用dll的變量:

#include <stdio.h>
#pragma comment(lib,"dllTest.lib")
extern int _declspec(dllimport) dllGlobalVar; //用_declspec(dllimport)導入
int main(int argc, char *argv[])
{
printf("%d ", dllGlobalVar);
dllGlobalVar = 1; //這裏就能夠直接使用, 無須進行強制指針轉換
printf("%d ", dllGlobalVar);
return 0;
}

若是C++調用一個C語言編寫的.DLL時,當包括.DLL的頭文件或聲明接口函數時,應加extern "C" { }

string轉 char *:string.c_str();一樣適用於string轉LPCSTR

memset:填充緩衝

注意互斥對象在擁有Mutex時的計數。請求次數和釋放次數要相等,別的線程才能使用這個互斥對象。

當一個線程終止時,即使擁有Mutex沒有釋放,操做系統也會自動釋放線程擁有的Mutex。

在作HID的DLL時,因爲死鎖形成了不能退出線程。在線程裏調用ReadBuff回調函數,若是這時ReadBuff回調函數裏調用Close,因爲Close會等待線程結束,而線程在等待ReadBuff返回,因而形成了死鎖。

Delphi調用vc寫的dll時,須要注意調用順序,通常統一爲stdcall

CObject給子類提供了3個重要的特性:

1. 串行化支持

2. 運行時類信息支持(RTCI,和RTTI不同)

3. 診斷和調試支持

Afx函數:全局函數:

AfxGetApp:返回指向應用程序對象的指針

AfxGetMainWnd:返回指向應用程序主窗口的指針

AfxGetInstanceHandle:得到實例句柄

經常使用Afx函數見MFC Windows程序設計13頁

消息映射:

在類的最後加上DECLARE_MESSAGE_MAP(),若是在DECLARE_MESSAGE_MAP()後又定義了成員,須要從新指明訪問類型:public,protected等

而後在在.cpp文件裏BEGIN_MESSAGE_MAP(…)和裏END_MESSAGE_MAP()裏註明映射,如:

BEGIN_MESSAGE_MAP(CMaindWindows,CFrameWnd)

ON_WM_PAINT()

END_MESSAGE_MAP()

m_pMainWnd:

「用該成員變量去存儲你的線程主窗口對象。當和m_pMainWnd 相關的窗口被關閉後,MFC會自動終止你的線程。若是該線程是應用程序主線程,程序也將會被終止。若是該數據成員爲NULL,應用程序CWinApp對象的主窗口將用來決定何時去終止線程。m_pMainWnd是一個CWnd*類型的public變量(CWinApp類裏定義)。

MFC應用程序的核心就是基於CWinApp類的應用程序對象。CWinApp提供了消息循環來檢索消息並將消息調度給應用程序窗口,它還包括能夠被覆蓋的,用來自定義應用程序行爲的主要虛函數。一旦頭文件包括Afxwin.h就能夠將CWinApp以及其餘MFC類引入應用程序中。

CWinApp對象的InitInstace虛方法在程序開始運行後,窗口建立前被調用

除非InitInstace建立一個窗口,不然應用程序是不會有窗口的,這正是爲何MFC應用程序必須從CWinApp派生出一個類並覆蓋CWinApp::InitInstace的緣由。通常應用程序的初始化工做均可以放在InitInstace方法裏。若是InitInstace返回false將關閉程序

通常狀況下,在InitInstance裏調用ShowWindow時,傳遞m_nCmdShow(執行這個程序時由外部指定),而不是SW_值。

當你從CWinApp繼承應用程序類的時候,應重載InitInstance成員函數以建立應用程序的主窗口對象。

若是在InitInstance裏分配了資源,能夠在ExitInstance裏釋放這些資源,他們都是在CWinApp的虛擬函數,在CwinApp子類裏可被覆蓋.

其餘CWinApp可被覆蓋的函數有:OnIdle,Run,PreTranslateMessage.

應用程序空閒時調用OnIdle,能夠覆蓋Run來自定義消息循環,若是想在消息被調度前執行一些專門的預處理,則能夠覆蓋PreTranslateMessage.

若是MFC沒有提供某個消息的映射,能夠自定義消息映射:

ON_MESSAGE(WM_SetText,OnSetText);

……

afx_msg LRESUT OnSetText(WPARAM wPram,LPARAM lParam);

若是要調用常規API,須要在API函數前使用 :: 符號。

MessageBox(L"hello, world");

MessageBox(_T"hello, world");

L"hello, world" 這個字符串保存的是wchar的

_T"hello, world" 若是工程定義了_UNICDE則這個字符串是按wchar方式保存的,若是沒有定義則是按char方式保存的

若是想使應用程序不關心字符集,除了用_T外,還須要注意:

1. 使用TCHAR而不是char

2. 使用TCHAR*或者更佳的LPSTR和LPCSTR

3. 使用Tchar.h裏面的字符串處理函數

在AfxWinMain運行前,應用程序對象(CWinApp)必須在內存中存在。

SetWindowLong:改變窗口特徵

MoveWindow:移動窗口

DestroyWindow:退出窗口

SetWindowText:改變窗口標題欄的名稱

LoadMenu :載入一個菜單

AfxGetInstanceHandle:得到應用程序的實例

AfxRegisterWndClass (0):一個很是通常的窗口類

銷燬一個窗口:

pWnd->DestroyWindow();//刪除Windows窗口

delete pWnd;//銷燬pWnd

AfxGetApp( )->LoadCursor (xx):裝載一個光標

GetDesktopWindow:得到桌面窗口

WindowFromPoint():經過座標獲取窗口

覆蓋PreCreateWindow方法可在建立窗體前更改窗體樣式

在用到RECT的地方,能夠直接用CRect類替換

在建立窗體時,若是pParentWnd爲NULL,則此窗口的全部者就是桌面。

CWndCreate方法用於建立一個Windows窗體

CDC類封裝了Windows設備環境。

CPaintCDC派生於CDC,用於繪製屏幕,它只在WM_PAINT消息裏使用。

CPaintCDC的構造函數調用BeginPaint,析構函數調用EndPaint。

在建立了CPaintCDC對象後,OnPaint將構造一個表明矩形的CRect對象,此時能夠調用CWnd::GetClientRect以使用窗口的客戶區的座標來初始化這個矩形。

StringCbCopy

strcpy, wcscpy, _tcscpy

lstrcpy

StrCpy

StringCbCopy函數原型以下:

HRESULT StringCbCopy(

__out LPTSTR pszDest, //目標字符串緩衝區

__in size_t cbDest, //目標緩衝區大小(字節),這個值必須考慮pszSrc加上空中止符’/0’的大小;

//最大運行的字節數是STRSAFE_MAX_CCH * sizeof(TCHAR)

__in LPCTSTR pszSrc //源字符串緩衝區,必須以’/0’結尾

);

函數返回&#20540;以下(強烈建議應用SUCCEEDED和FAILED宏來測試返回&#20540;):

S_OK                 //一切OK

STRSAFE_E_INVALID_PARAMETER    //目標緩衝區中&#20540;的大小要麼是0,要麼大於最大允許&#20540;

STRSAFE_E_INSUFFICIENT_BUFFER  //目標緩衝區大小不敷,數據被截斷;

//當允許數據截斷時,這不算是錯誤

Carray:數組類

其中定義了一些專用數組類:

CByteArray,CWordArray,CUIntArray,CDWordArray,CStringArray,CObArray,CPtrArray

使用數組前,需引用afxtempl.h

CArray <CPoint,CPoint&> m_Array:傳遞參數時傳遞的是指針,推薦使用

CArray <CPoint,CPoint> m_Array:傳遞參數時傳遞的是對象.

m_Array.SetSize(10,10): SetSize函數設定數組的大小,該函數有兩個參數,第一個參數設定數組的大小;第二個參數設定數組增加時內存分配的大小,缺省值是-1,使用缺省值能夠保證內存分配得更加合理

您能夠隨時使用SetSize函數設定數組的大小,若是第一個參數值小於數組已有成員數量,多於第一個參數值的成員將被截去並釋放相應內存

在使用CArray數組前,最好先使用SetSize肯定其大小並申請存儲空間。若是不這樣作,向數組中增長元素時,須要不斷地移動和拷貝元素形成運行的低效率和內存碎塊

GetWindowsDC:能夠在窗體任一位置畫圖

CDC的子類:

CPaintDC:響應WM_PAINT消息

CClientDC:客戶區域

CWindowDC:客戶區域+非客戶區域,並不經常使用.通常藉助OnNcPaint處理程序捕獲WM_NCPAINT消息

CMetaFileDC

當使用new建立設備描述符表時,須要親自釋放,如:

CPaintDC *pDC = new CPaintDC(thils);

Delete pDC;

得到真個屏幕的設備描述表

CClientDC dc(NULL);(或者CWindowDC dc(NULL);)

背景透明:dc.SetBKMode(TRANSPARENT)

得到設備信息:

如:得到屏幕的的寬,以像素點數目計算:

CClientDC dc(this);

Int cx = dc.GetDeviceCaps(HORZRES);//寬度

Int cy = dc.GetDeviceCaps(VERTRES);//高度

Polyline:須要5個點來畫一個矩形,其中第一個點做爲矩形的起點

PolylineTo:只須要4個點,由於第一個點是使用設備描述符的當前位置(如先使用MoveTo肯定起點), PolylineTo返回最後一個點的位置

CPen:

若是要改變畫線方式,則需建立一個畫筆(CPen),並由CDC::SelectObject選入設備描述符.

建立畫筆有三種方式:

1. 直接使用構造函數

2. 使用CPen::CreatePen

3. 使用Cpen::CreatePenIndirect

畫筆的3個特性:樣式,寬度,顏色

MFC程序執行流程:

1. 全局對象(CWinApp的子類)theApp

2. CWinApp構造函數

3. theApp的構造函數

4. AfxWinMain

5. 窗體PreCreateWindow()(給了窗口建立前修改窗口的機會)

6. 應用程序InitInstance()(窗口類註冊,窗口建立,窗口顯示等工做)

7. 應用程序Run()(消息循環,處理消息)

WM_CTLCOLOR:

OnCtlColor響應WM_CTLCOLOR.

pWnd->GetDlgCtrlID():得到窗口的ID

改變對話框上按鈕的顏色:

1. 新建一個CButton的子類.

2. 覆蓋DrawItem方法

3. 在DrawItem裏修改顏色等…..

4. 創建一個和這個按鈕關聯的成員變量(類型爲新建的類)

5. 在圖形界面勾選按鈕的Style爲Owner draw

自定義背景

BOOL CBitmapDCView::OnEraseBkgnd(CDC* pDC)

{

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

CBitmap bitmap;

bitmap.LoadBitmap(IDM_BACKGROUND);//加載一幅位圖

CDC dcCompatible;

dcCompatible.CreateCompatibleDC(pDC);//建立兼容DC

dcCompatible.SelectObject(&bitmap);//將位圖選入兼容dc

CRect rect;

this->GetClientRect(&rect);

//拷貝位圖到當前dc

pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);

return TRUE;

//return CView::OnEraseBkgnd(pDC);

}

CPtrArray:

設備座標:以像素爲單位

邏輯座標:單位能夠是像素,毫米,英寸等.

OnInitialUpdate:窗口建立以後第一個被調用的函數,在第一次調用OnDraw以前調用OnInitialUpdate

SetScrollSizes:設置窗口滾動大小

指向常量的指針:

char ch [5] = 「abcd」;

//const在char的前面或後面是同樣的,因此等同於 char const * pStr = ch,通常都是把const放//在char前面.他們都表示指針指向的對象是常量

const char * pStr = ch;

*pStr = ‘w’ //error

pStr = 「xyz」 //ok

指針常量

char ch[5] = 「abcd」;

char * const pStr=ch;

//指針自己是常量,不能修改

pStr = 「xyz」; //error

//可是指針指向的內容是能夠修改的

*pStr = ‘x’; //ok

文件寫入:

FILE * file = fopen("1.txt","w");

char buffer[10];

for (int i=0;i<10;i++)

{

buffer[i] = i + 0x30;

}

fwrite(buffer,sizeof(char),10,file);

//fseek(file,0,SEEK_SET);//移動到文件的開始處

//fwrite("abcde",sizeof(char), lstrlen("abcde"),file);//這裏會覆蓋以前寫的內容

//fflush(file);//將緩衝的內容寫入磁盤文件,這樣就不用每次都使用fclose關閉文件了

fclose(file);

文件讀取:

FILE * file = fopen("1.txt","r");

char buffer[10];

fread(buffer,sizeof(char),10,file);

fclose(file);

fseek:移動文件的指針

ftell:獲取文件的當前位置

rewind:將文件指針移動到文件開始處

itoa:整形轉爲字符串

atoi:字符串轉整形

ofstream:寫文件

ifstream:讀文件

須要引用fstream.h

CreateFile,FileRead,FileWrite:API函數,可讀寫文件

MFC的Cfile:MFC的一個文件類(推薦),用於操做文件.

CFile::modeNoTruncate:在CFile構建函數的第二個參數使用CFile::modeCreate | CFile::modeNoTruncate,可不用刪除之前的文件.

初始化一個字符數組(優勢:數組大小可爲一個變量)

Char * pBuff;

pBuff = new char[100];

CDocument::SetTitle: 設置文檔的標題

也能夠經過修改IDR_MAINFRAME字符串資源的第二項來設置文檔的標題(默認爲空)

得到IDR_MAINFRAME裏的字符串:

CDocTemplate::GetDocString

Doc文檔的Serialize函數用於處理輸入輸出文件.

使一個類具備串行持久性的步驟:

1. 繼承於Cobject

2. 覆蓋Serialize成員函數(實現首先要調用基類的Serialize)

3. 在類申明的地方(頭文件)定義 DECLARE_SERIAL(CGraph)

4. 定義一個不帶參數的構造函數

5. 在類實現定義 IMPLEMENT_SERIAL(CGraph,CObject,1)

6. 而後在文檔類(doc)的Serialize函數裏保存或讀取類

在Doc文檔類裏得到視類View:

POSITION pos = GetFirstViewPosition();

if (pos != NULL)

{

CView * view = GetNextView(pos);

……

}

在View類裏獲的Doc類的指針:

直接調用view類的m_pDocument

CobArray:支持串行化,在文檔類的Serialize函數裏直接調用CobArray對象的Serialize函數,並把ar傳遞給CobArray對象的Serialize.,固然CobArray存儲的對象必須具備串行化持久性

DeleteContents:在新建或者打開文檔時會調用這個函數,用戶需覆蓋這個虛函數,從而執行清除數據工做

IP地址由4個8位點分數字表示

Port端口由一個16位數字表示,1024如下爲系統保留使用.

Socket服務器程序流程:

1

建立套接字(socket)

2

將套接字綁定到一個本地地址和端口上(bind)

3

將套接字設爲監聽模式,準備接收客戶請求(listen)

4

等待客戶請求到來.當請求到來後,接受鏈接請求,返回一個新的對應於這次鏈接的套接字(accept)

5

用返回的套接字和客戶端進行通訊(send/recv)

6

返回,等待另外一個客戶請求

7

關閉套接字

Socket客戶端程序流程

1

建立套接字(socket)

2

向服務器發出鏈接請求(connect)

3

和服務器端進行通訊(send/recv)

4

關閉套接字

UDP服務器程序流程

1

建立套接字(socket)

2

將套接字綁定到一個本地地址和端口上(bind)

3

等待接收數據(recvfrom)

4

關閉套接字

UDP客戶端程序流程

1

建立套接字(socket)

2

向服務器發送數據(sendto)

3

關閉套接字

ALT+F8:調整代碼的格式

inet_addr:將一個十進制點分格式的字符串轉換爲一個in_addr能用的u_long類型.

inet_ntoa:而此函數和inet_addr正好相反,它將一個in_addr類型轉換爲十進制點分格式的字符串.( in_addr需爲網絡字節順序)

htonl: 將一個u_long轉換爲TCP/IP網絡字節順序(大端模式,低位放高字節)

htons: 將一個u_short轉換爲TCP/IP網絡字節順序(大端模式,低位放高字節)

gets: 從stdio流中讀取字符串,直至接受到換行符或EOF時中止,並將讀取的結果存放在buffer指針所指向的字符數組中。換行符不做爲讀取串的內容,讀取的換行符被轉換爲null值,並由此來結束字符串。

和cin效果同樣

n 程序是計算機指令的集合,它以文件的形式存儲在磁盤上。

n 進程:一般被定義爲一個正在運行的程序的實例,是一個程序在其自身的地址空間中的一次執行活動。

n 進程是資源申請、調度和獨立運行的單位,所以,它使用系統中的運行資源;而程序不能申請系統資源,不能被系統調度,也不能做爲獨立運行的單位,所以,它不佔用系統的運行資源。

n 進程由兩個部分組成:

1、操做系統用來管理進程的內核對象。內核對象也是系統用來存放關於進程的統計信息的地方。

2、地址空間。它包含全部可執行模塊或DLL模塊的代碼和數據。它還包含動態內存分配的空間。如線程堆棧和堆分配空間。

n 進程是不活潑的。進程歷來不執行任何東西,它只是線程的容器。若要使進程完成某項操做,它必須擁有一個在它的環境中運行的線程,此線程負責執行包含在進程的地址空間中的代碼。

n 單個進程可能包含若干個線程,這些線程都「同時」 執行進程地址空間中的代碼。

n 每一個進程至少擁有一個線程,來執行進程的地址空間中的代碼。當建立一個進程時,操做系統會自動建立這個進程的第一個線程,稱爲主線程。此後,該線程能夠建立其餘的線程。

AfxSocketInit: 初始化socket,調用WSAStartup,並保證在程序結束前調用WSAClear. 在InitInstance裏調用這個函數.(須引用afxsock.h)

一個線程的回調函數能夠設爲類的內部函數,這個函數必須是靜態的.

當線程建立後,需立刻使用CloseHandle關閉句柄,減小線程引用計數

當CreateEvent的第二個參數爲FALSE, WaitForSingleObject執行後事件爲變爲無信號,但不會自動設置事件爲有信號,必須使用SetEvent設置事件爲有信號.

WSAAsyncSelect:將一個網絡事件和一個消息關聯.通常用於異步操做.WSASelectEvent結合WSAWaitForMultipleEvents也能夠異步操做.

若是出現了不該該編譯不過得狀況,能夠嘗試刪除DEBUG文件夾

可使用WSAAsyncSelect來異步處理SOCKET數據:

1. 使用WSAAsyncSelect,將一個網絡事件和一個自定義消息相關聯

2. 將自定義消息映射到一個函數

3. 在消息響應函數里根據事件的類型,分別處理. Wparam指定發生事件的socket, lparam低半子指定事件類型(好比FD_READ,FD_WRITE,FD_CLOSE之類的), lparam高半子指示了錯誤代碼.

gethostbyname: 根據主機名得到IP地址

gethostbyaddr:根據IP地址得到主機名

進程間通訊:

1. 剪貼板

2. 匿名管道

3. 命名管道

4. 郵槽

得到鼠標按鍵的數目:

GetSystemMetrics(SM_CMOUSEBUTTONS)

CalcWindowRect:根據客戶區域大小,計算出須要的窗口大小.必須在窗口建立以後使用.

CDC:: DeflateRect: 經過將CRect的邊向其中心移動來縮小它

CRect::PtInRect: 判斷某點是否位於RECT內

MB_SYSTEMMODAL: 若是MessageBox使用了MB_SYSTEMMODAL標誌,則對話框在全部窗口的最上面,即使切換到了其餘程序.

AfxGetApp()->LoadStandardCursor(IDC_ARROW):得到windows預約義的光標

AfxGetApp()->LoadStandardIcon(IDI_WINLOGO):得到windows預約義的圖標

AfxRegisterWndClass: 註冊一個窗口類.其中的背景顏色能夠用(HBRUSH)(COLOR_3DFACE + 1)這種方式得到windows預約義的顏色,這裏的顏色就是COLOR_3DFACE,注意要+1;

GetSysColor: 經過windows預約義顏色的序號得到RGB表示的顏色.

CreateEx: 若是要使窗口不能縮放,須要從dwStyle中移除WS_THICKFRAME

非客戶區鼠標消息:相似於客戶區鼠標消息,只是加了一個NC,如WM_NCLBUTTONDOWN,對應的處理函數爲OnNcLButtonDown, 處理函數能夠捕獲鼠標是否在標題欄,關閉按鈕,菜單欄,最大化按鈕,邊框等位置.

若是類要從CWnd派生,須要覆寫PostNcDestroy函數,並在函數實現裏刪除自身delete this.

WM_NCHITTEST: 窗口在接收到一個客戶區或非客戶區鼠標消息前,先接收到光標的屏幕座標和WM_NCHITTEST消息,基於這點,能夠在處理鼠標消息前作更多的工做.

TrackMouseEvent: 能夠捕獲鼠標的離開和必定時間靜止未動.在使用前須要引用winuser.h,並引入函數: extern "C" WINUSERAPI BOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT lpEventTrack); 在響應了WM_MOUSELEAVE和WM_MOUSEHOVER消息後必須從新調用TrackMouseEvent.

SystemParametersinfo: 得到系統參數.

SetCapture: 捕獲鼠標.捕獲鼠標後即便光標移出了窗口,仍然能夠接收鼠標消息.,通常在XbuttonDown裏SetCapture,xButtonUp裏ReleaseCapture;

dc.SetROP2(R2_NOT):一次擦除背景色,兩次還原背景色

在移動鼠標時,windows經過重畫光標的背景把光標從舊位置上清除,而後給窗口發送包含命中測試代碼的WM_SETCURSOR消息,對此消息系統的默認響應是調用::SetCursor.

改變光標的兩種方法:

1. 在註冊WNDCLASS時

2. 使用SetCursor來響應WM_SETCURSOR

SetTextAlign:設置文本對齊方式.

顯示與隱藏光標: ShowCursor(TRUE),ShowCursor(FALSE)

得到光標的位置: GetCursorPos, GetMessagePos, 他們返回的是屏幕座標,能夠用ScreenToClient轉換爲客戶區座標.

將光標固定在一個區域: ClipCursor,釋放時ClipCursor(NULL);

WM_SETFOCUS: 得到焦點

WM_KILLFOCUS: 失去焦點

wmd.SetFocus(): 設置焦點

CWnd::GetFocus(): 得到焦點

通常按鍵消息的順序:

1. WM_KEYDOWN

2. WM_CHAR

3. WM_KEYUP

ALT和F10是」系統鍵」,他們只會產生WM_SYSKEYDOWN和WM_SYSKEYUP.在ALT按着的同時,別的鍵被按下,也會產生WM_SYSKEYDOWN和WM_SYSKEYUP消息.

GetKeyState: 檢查某個鍵的狀態,若是是按下返回負值,不然返回非負值.當用來檢查Num Look,Caps Lock,Scroll Lock是否處於激活狀態能夠這樣:::GetKeyState(VK_NUMLOCK) & 0X01,返回非零值說明按鍵激活.

GetKeyState只能在鍵盤消息處理程序裏使用.若是要在別的地方得到按鍵狀態,要使用GetAsyncKeyState.

在VS2012裏,devguid.h定義了經常使用的GUID。

 

調用dll的兩種方法:

1.鏈接lib (#pragma comment(lib,"xxx.lib")),包含對應的.h頭文件(#include "xxx.H").lib文件在編譯dll文件時自動生成

2.使用LoadLibrary加載dll文件,使用GetProcAddress得到函數.使用FreeLibrary釋放由LoadLibrary加載的dll文件

 

CONTAINING_RECORD(address, type, field):根據成員的地址獲得結構的地址,如:

struct CIOCPBuffer            //per-i/o
{
    WSAOVERLAPPED ol;    
    SOCKET sClient;            //AcceptEx接受的客戶方套接字
    char *buff;                //I/O緩衝區(使用的)大小
    int nLen;
    ULONG nSequenceNumber;    //此I/O序列號
    int nOperation;            //操做類型
#define OP_ACCEPT    1
#define OP_WRITE    2
#define OP_READ        3
    CIOCPBuffer *pNext;
};

CIOCPBuffer * pBuffer = CONTAINING_RECORD(lpol,CIOCPBuffer,ol);
相關文章
相關標籤/搜索