zoukankan      html  css  js  c++  java
  • VC杂记

    获得Combobox的状态:向ComboBox发送CB_GETDROPPEDSTATE消息.

    格式化字串:char buff[10] ; sprintf(buff,”1+1=%d”,1+1); Sprintf会返回格式化的字符串的长度。

    C区别大小写。

    窗口大部份情况都要处理WM_PAINT,WM_PAINT处理几乎总是从BeginPaint开始,以EndPaint结束。

    获取字符串长度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.

    当子类创建时,会先调用基类的构造函数,然后再调用子类函数。在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语言的’ ’, 表示换行

    如果以一个类未提供构造函数,则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 ");

    break;

    case DLL_PROCESS_DETACH:

    printf("DLL_PROCESS_DETACH ");

    break;

    case DLL_THREAD_ATTACH:

    printf("DLL_THREAD_ATTACH ");

    break;

    case DLL_THREAD_DETACH:

    printf("DLL_THREAD_DETACH ");

    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);

     

     

  • 相关阅读:
    io
    文件
    诚实
    没有犯错并不代表自己就是做得好
    脑力锻炼的随缘
    电路运算
    “容错率”
    GPU简介
    名与责任
    失眠和精神的思考
  • 原文地址:https://www.cnblogs.com/cxp2009/p/3357098.html
Copyright © 2011-2022 走看看