• Windows基础编程SDK复习知识点


    1. CUI程序与GUI程序
        CUI程序:控制台界面
        GUI程序:图形用户界面程序
     
    2. windows编程头文件
        通常我们包含windows.h头文件,它是一个 综合型头文件。
    其次还有一些头文件,例如:tchar.h,通用字符串的定义    Commctrl.h控件API的定义
     
    3. WinMain函数
        C语言中有一个main函数,在windows编程中有一个WinMain函数,对于WinMain函数来说,他的形式永远那么固定
        int   APIENTRY   _tWinMan(    _In_            HINSTANCE    hInstance,
                                                         _In_opt_     HINSTANCE    hPrevInstance,
                                                         _In_            LPTSTR           lpCmdLine,
                                                         _In_            int                     nCmdShow
                                                     )
        其中APIENTRY指明了函数调用方式是stdcall
        WinMain是一个宏定义,自适应win32程序的版本是多字节还是UNICODE版本            (多字节编码ASC,宽字节编码unicode)
        hInstance是程序的实例句柄,它是程序加载地址
        其他参数略
     
    4. 字符编码
        ASCLL字符占1个字节
        Unicode占2个字节,使用Unicode编码可以使工程同时支持多种语言,在系统底层开发中,字符串都是以Unicode编码形式进行操作
        Tip    :当我们定义UNICODE宏时候,CreateWindowEx是宽字节版函数,没有定义UNICODE宏,CreateWindowEX是多字节版函数,这里CreateWindow是一个宏,我们切记,在windows编程中,根本就没有CreateWindowEx这个函数
        常用字符串处理函数:
       ACS版 UNICODE T版
    获取长度 strlen wcsnlen _tcslen
    字符串拷贝 strcpy_s wcscpy_s _tcscpy_s
    字符串转数字 atoi _wtoi _tstoi
    sscanf_s swscanf_s _stscanf_s
    数字转字符 sprintf_s swprintf_s _stprintf_s
     
    5.  windows数据类型
    DWORD        实际是 unsigned long
    BOOL            实际是 int 
    WCHAR        实际是 w_char
    UINT             实际是 unsigned int
    所有windows数据类型都是通过在SDK头文件中定义的,它们都是来源于标准C的数据类型
     
    6.    windows句柄和对象
        句柄:用以代表一个对象,然后使用函数操作这个对象的时候,就把句柄传进去,在作用上类似于C++this指针。
        常见的句柄类型有:HWND 窗口句柄    HMODULE模块句柄    HDC环境绘图句柄    HMENU菜单句柄    HANDLE内核对象句柄
    每一种句柄类型都是一种数据类型
     
    7.    WINDOWS错误处理
        我们根据API函数的返回值来判断函数是否成功,但是我们要进一步知道函数错误在哪里,所有在WINDOWS下每一个线程都有一块区域能够存储错误码,可以使用SetLastError(),这个API设置一个数值,每一个API函数退出之前都会调用这个函数,并且给此API设置一个错误码,我们在API调用结束之后,可以调用GetLaseError()得到错误码,再根据错误码判断是什么错误
    Tip:我们想知道某一个函数的调用结果,在函数调用完毕的地方,立即使用GetLastError函数,否则错误码可能被其他API覆盖
          
        查看错误码的方式:
    • 在VS中自带工具   “错误查找”
    • 使用FormatMessage函数,有错误码得到错误字符串
    • 在VS监视栏中输入    err,hr可以时时查看API的监控结果    (这个最为方便)
     
    8.  windows编程原理
        windows编程程序功能的实现原则是事件驱动函数,我们也可以成为消息驱动函数    事件也为消息
    而消息的产生一般代表有一个事件需要窗口程序去处理
    消息产生的条件:
            用户主动产生消息 :用户点击了窗体,按下了键盘
            windows系统本身产生的消息:系统时间的更改,系统即将被关闭
            应用程序本身产生的消息:应用程序主动给自己发送一个消息,例如调用了MoveWindow窗口函数
            其他应用程序发送过来的消息
     
        消息的流动流程:windows内部有一个消息队列,大部分消息会先进系统消息队列,每一个程序也有消息队列,操作系统能够识别出来消息队列的消息属于哪个程序,从而将消息队列中消息发送给程序的消息队列
     
    消息泵,又称消息循环
    GetMessage(LPMSG     lpMsg,                            //  消息结构体地址    (MSG)
                            HWND      hWnd,                             //  窗口句柄
                            UINT         wMsgFilterMin,               //  第一个消息
                            UINT         wMsgFilterMax               //  最后一个消息
    消息泵大概流程:GetMessage从主线程消息队列中获取一个消息将他赋值到MSG中,然后进入while循环
    TranslateAccelerator判断是不是一个按键消息,如果是按键消息,将按键消息转换成一个WM_CHAR发送给回调函数
    DispatchMessage函数把此信息发送给消息指定窗口中设定的回调函数
     
     
    回调函数模型
    LRESULT    CALLBACK     WindowProc(
            HWND        hwnd;                    //窗口句柄
            UINT           umessage;            //消息ID
            WPARAM    wParam;               //消息参数1
            LPARAM      lParam;                //消息参数2
    )
    这里需注意,返回值类型为    LRESULT    因为回调函数返回值必然是调用DefWindowProc函数来处理,所有回调函数返回值不能为0
    LRESULT本质就是  long    长整形 。
    DefWindowProc();    此函数返回值即是上面回调函数的返回值,本函数作用,它将窗口不处理的消息默认传递给系统做默认处理,此函数在  回调函数中必不可少
     
    9.    创建窗口
    1.先设计一个窗口类
    2.在注册窗口类
    3.创建窗口
    4.显示刷新窗口
    5.建立消息泵,循环接受处理消息(前提要将回调函数写好)
     
     
    10.    消息机制
     
        消息是windows操作系统发给应用程序的一个通告,他告诉应用程序某个特定的事件发生了
    系统发送给应用程序某个消息,最终处理消息的是应用程序的窗口函数,如果程序不负责处理,此消息就被系统默认处理
    (所以在窗口回调函数返回值不是0,而是我们写的    return DefWindowProc(hWnd,uMsg,wParam,lParam)         )
        消息本身是作为一个记录传递给应用程序,这个记录中包含了消息的类型,以及其他信息   (这里也很好理解,因为消息的所有信息是被MSG结构体保存,里面的不同字段代表着不同的消息类型,以及消息的附加信息)
        这里再次说明下MSG结构体里面几个重要的参数,也是我们常见的参数,例如
    • HWND  hwnd            窗口句柄,表示发给哪个窗口,通常在设计窗口类的时候已经指定了是发给哪个窗口
    • UINT    message       消息ID,表示发送的哪个消息,也就是我们通常说的消息号,根据号来告诉程序,发送了什么消息类型 比如WM_COMMAND消息号0X111
    • wParam                     通常是一个与消息相关的常量值,它的存在是取决于你是什么消息类型,也就是上一条。也可能是窗口或者控件的句柄
    • lParam                       通常是一个指向内存中数据的指针,由于WParam,lParam都是32位,他们之间都可以转换    
     
    这里我们来简单说说wParam和lParam  
        我们可以确定的是wParam和lParam是根据message的不同,他们才发生改变,他们具体代表什么,并没有固定的说法
    但是,一般来说wParam表示控件的ID,或者高16位和低16位组合起来分别表示鼠标的位置,如果发消息的时候需要附带某种结构的指针或者某种类型的句柄,习惯上用lParam.
        我们还可以用 LOWORD 和 HIWORD 来取消息的低16位和高16位    他们是两个宏
    Tip:我们常见的WM_COMMAND消息
    消息来源 wParam(高16位) wParam(低16位) IParam
    菜单 0 菜单ID 0
    快捷键 1 快捷键ID 0
    控件 控件通知码 控件ID 控件句柄
    Pis:对于按钮的响应    我们在回调函数里面,响应消息的应该是WM_COMMAND,因为他是通用控件
        这时候    WORD    wHigh  =   HIWORD(wParam)
                       WORD    wLow   =   LOWRD (wParam) 
    这里    wHigh  取到的是控件的窗口句柄
                wLow   取到的是控件ID
     
    消息标识符的值
        消息标识符的取值范围:在0x0000    到    WM_USER(0x400) 
        如果我们要自定义消息,在后面MFC中使用类向导去自定义一个消息,我们需要声明消息宏的时候,范围要大于WM_USER。通常我们可以 WM_USER+1去定义自定义消息宏
             
    消息的种类
        大致分为三种,通用窗口消息,控件消息,自定义消息
            通用窗口消息,通常以WM开头
            控件消息,控件整体上能够使用通用窗口消息,对于不同控件还有自己能够处理的消息
            自定义消息,就是我们上面所说的我们可以根据用途去规定,wParam和lParam含义
     
    队列消息和非队列消息
        从消息发送的途径来看,消息可以分为两种:队列消息和非队列消息
        队列消息,最常见的就是鼠标和键盘触发的消息    当鼠标键盘事件被触发,相应的鼠标和键盘驱动程序就会把这些事件转换成相应的消息,然后输送到系统消息队列,由Windows系统去进行处理,Windows系统就会把在系统消息队列里面取出一个消息,保存到MSG消息结构体,在将MSG结构体发送给我们的窗口,下面的事情就由我们线程消息队列去解决,Window开始自己忙自己的事
        非队列消息,会绕过系统队列和消息队列,直接将消息发送给窗口
     
    消息的发送
        我们上面说了消息队列的概念,下面我们就详细说说,消息是如果发送给我们的窗口的
    把一个消息发送到窗口有三种方式:发送,寄送,和广播
        发送消息:常见的函数有SendMessage(非队列消息),这个函数的主要作用向一个或者多个窗口发送一条消息,一直等消息被处理了才会返回
        寄送消息:常见的函数是PostMessage(队列消息)  该函数把一条消息放置创建hWnd窗口的线程的消息队列中,该函数不等消息被处理就马上将控制返回
     
    以上者两者具有代表性的函数,我们可以分析下发送消息和寄送消息,这两种方式不同:
        被发送的消息不会被立即处理,函数不会立即返回
        被寄送的消息不会被立即处理,它会被放进一个先进先出的队列中,一直等到应用程序空线的时候才会被处理,不过函数放置完消息后立即返回
     
    消息的接受
        消息接受的函数主要有三个:GetMessage,    PeekMessage,    WaitMessage
        GetMessage(LPMSG lpMsg,    HWMD hWnd,    UINT wMsgFilterMin,    UINT wMsgFilterMax)
    该函数用来获取与hWnd参数所指定的窗口相关的wMsgFilterMin和wMsgFilterMax参数所给出消息值范围内的消息,如果hWnd为NULL,则GetMessage获取属于该调用函数应用程序的任一窗口的消息,如果wMsgFilterMin和wMsgFilterMax都为0,则GetMessage可以返回所有得到的消息,函数获取消息之后,就删除消息队列中的除了WM_PAINT消息之外的其他消息,至于WM_PAINT则只有被处理后才删除
        对于上面的描述解释下:GetMessage这个函数第一个参数是消息MSG结构体的地址,里面可以得到消息的各种信息,通常我们传参&msg  ,至于第二个参数hWnd,我们通常写0,因为如果写0,这个GetMessage函数就可以获得该应用程序的任意窗口消息,这也是我们想要做到的,我们通常情况下不会希望,哪一个窗口不被发消息,不被获取消息。第三个参数和第四个参数,从参数原型就可以看出一个是min一个是max,它代表我们获取消息的范围值(通常是0-400),但是如果我们自定义消息他的默认范围就会变化,所以我们这里通常填写 0   0,它代表GetMessage获取所有的消息。
        当函数获取消息后,系统消息队列的传递任务就完成了,系统消息队列就可以把这些消息删除了。但是:WM_PAINT消息要等其被处理后才能被删除,它是重绘消息(特殊)
     
        PeekMessage(LPMSG lpMsg,    HWMD hWnd,    UINT wMsgFilterMin,    UINT wMsgFilterMax,    wRemoveMsg)
    PeekMessage与GetMessage区别在于:该函数不会等有消息进去队列才返回
     
        WaitMessage()
    当一个应用程序无事可做时候, 该函数就将控制权交给另外的应用程序,同时将该程序挂起,知道有一个新的消息放入应用程序队列中才返回
     
    11.    Window窗口
        窗口的风格有三种类型:重叠窗口,            弹出窗口,            子窗口
                                        WS_OVERLAPPED    WS_POPUP         WS_CHILD
    重叠窗口:是顶级窗口,有一个标题栏,边框,客户区,它的目的是作为一个应用程序的主窗口,它也可以有一个窗口菜单,最大化和最小化的按钮,滚动条
    弹出窗口:是顶级窗口,并且连接到桌面窗口的子窗口列表,弹出窗口多用于对话框或者MESSAGBOX,它具有WS_POPUP风格
    子窗口:    通常会有WS_CHILD风格,并且只能够被分配到父窗口的客户区域,子窗口必须要有父窗口,父窗口可以是层叠窗口,也可以是弹出窗口,也可以是其他子窗口
    也就是说,子窗口不能移出父窗口的客户区(解释上面红色语句)
     
        我们可以使用CreateWindowEx()为 窗口扩展风格
     
        窗口层次结构
    我们可以从桌面窗口出发,遍历得到所有窗口具体代码:
     
     
    #include<windows.h>
    int _tmain(int argc, _TCHAR* argv[])
    {
        //得到桌面窗口句柄
        HWND hwnd = GetDesktopWindow();
        //得到屏幕的第一个子窗口
        hwnd = GetWindow(hwnd,GW_CHILD);
        char szname[266] = { 0 };
        //循环遍历得到所有的子窗口
        while (hwnd!=NULL)
        {
            memset(szname, 0, 266);                     //每次进入循环,清空缓冲区
            GetWindowTextA(hwnd, szname, 266);          //获得窗口的窗口名
            printf("%s
    ", szname);
            hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);        //赋值给下一个窗口
        }
        return 0;
    }
     
     
    对于以上函数,解释下代码
    GetDesktopWindow()            获取桌面窗口句柄
    GetWindow()                         返回于指定窗口有特定关系的窗口句柄,这里,传入GW_CHILD 获得相对于屏幕的第一个子窗口句柄   (这里必须是有特定关系)
    memset                                 初始化缓冲区
    GetWindowTextA()                获取指定窗口句柄的标题
    GetNextWindow                    它是一个宏,他的本质还是GetWindow(),这里我们传入的参数变为GW_HWNDNEXT,这里我们指定找到他的下一个兄弟窗口,不能传                                                                GW_CHILD,因为对应了上面的红字,其他窗口直接是没有特定关系
     
    12.    控件基础
    控件是一本分windows系统内置的窗口类,他们只能是某一个窗口的子窗口,所以创建他们的风格必须都是WS_CHILD风格
    我们创建一个控件的时候,我们并没有去注册一个窗口类,因为系统以及帮我们注册好了,消息相应函数也不是我们写的,都由windows提供,即他们都有自己的窗口回调函数,(ps:当然我们也可以自己去改变这些空间本身的回调函数,setwindowlong() )
        
        控件具体分为两种
    一种是标准控件
    窗口类名 控件 英文
    "button" 按钮 Button
      复选框 CheckBox
      单选框 RadioButton
    "static" 静态文本 Static Text
      图片 Picture Control
    "combobox" 复合框 ComboBox
    "edit" 编辑 Edit
    "listbox" 列表框 ListBox
    "scrollbar" 滚动条 ScrollBar
    另一种是通用控件,通用控件较为复杂
    窗口类名 控件
    WC_LISTVIEW 列表框控件
    WC_TREEVIEW 树控件
    WC_TABCONTROL Tab控件
    HOTKEY_CLASS 热键控件
        控件的创建
    我们也是使用CreateWindow函数,只是窗口类不需要我们去注册,但是我们要指定他们的风格,WS_CHILD与WS_VISIBLE风格
     
        控件相关的消息
    分为两种
    一种是用于控制控件行为的控件控制消息
    一种是用于通知父窗口用户行为的控件通知消息
    简单的说明下这两种消息的含义:
        看起来比较绕口,我们只需要明白他们的含义就好,
        先来说说第一种控制控件行为的控件控制消息,一些控件除了会通知窗口消息之外,还有自己的专属消息,我们只需要向这些控件发送这些消息来控制他们的行为就行(比如按钮被点击按下,按钮被按下只有系统知道,我们看到了图标改变那是因为图标被重绘了),我们并不需要知道他们怎么被处理(按下按钮触发什么事件,我们并不用操心他们会触发什么事)
        第二种消息,为控件通知消息,控件通知消息是子控件来通知父窗口一些事件,常见的有子控件被点击,子控件需要重绘,对应了上面所说的去理解其中的含义。
    这里,控件通知消息分为两大类:
        WM_COMMAND:    标准控件的通知消息,标准控件的通知消息比较简单
        WM_NOTIFY:          附加通用控件通常会用此消息给父窗口发通知    (后面分析为什么要分为两大类)
     
     
    13.    Windows中资源    略
     
    14.    对话框
     
    引入对话框资源这一操作,可以使我们方便去控制窗口的各个控件位置,属性
        两个对话框创建函数的API
    一个是DiaologBox,一种是CreateDialog
    DiaologBox是生成一个模态窗口,他不需要自己写消息循环
    CreateDialog生成一个非模态对话框,他需要自己写消息循环
    他们的参数都一样,说明他们又是宏,他们背后都是在调用CreateWindow
     
        上面我们说了模态对话框和非模态对话框,这里我们来分析分析这两个概念以及区别
    • 模态对话框创建后一定要在用户关闭对话框后, 才能对父窗口进行用户操作
    • 非模态对话框创建之后,不需要等待窗口关闭,也可以对父窗口进行窗口操作
    对话框和窗口的区别
    乍一看对话框就是窗口,我们也可以说对话框是    "次一级的窗口",我们常见的对话框没有最大最小化按键,具体的视觉上区别就不一一阐述
      窗口 对话框
    函数返回值 返回LRESULT(也就是返回LONG) 返回BOOL
    消息处理 不处理WM_INITDLALOG 不处理WM_CREAT,WM_DESTORY,WM_PAINT
    不处理消息如何处理 调用DefWindowProc处理程序不处理的消息 直接返回0   (return 0)
    那么对话框主要处理的消息有:
                WM_INITDIALOG    对话框初始化时候操作
                WM_COMMAND      响应对话框上的控件一些处理操作
               
        模态对话框的显示创建
        要调用DiaologBox,在对话框处理函数中(switch语句中)处理WM_INITDIALOG和WM_COMMAND。并且模态对话框的关闭要调用EndDiaolog关闭对话框  
        消息框是模态对话框的一种特殊形式,也就是我们常见的MessageBox函数生成的消息框,我们这里只看他的参数含义
        MessageBox(拥有该消息的窗口句柄,  消息框中显示的字符串,    标题字符串,    指定消息框的内容  )
     
        非模态对话框的显示创建
        要调用CreateDialog完成创建
        不要忘记我们还要自己去写消息循环,由于非模态对话框并不禁止应用程序向其他窗口发消息,因此,在WinMain函数的消息循环中必须包含截获发往非模态对话框的消息
    具体代码如下
                while(GetMessage(&msg,NULL,0,0))
                 {
                        if (! IsDiaologMessage(hdlg,&msg))                                //如果是发往对话框的消息,取反 代表其他不属于对话框的消息,就进入循环,发给其他窗口
                            {                                                                                   //这里也就说明为什么非模态对话框,父窗口可以相应用户操作
                                    TranslateMessage(&msg);
                                    DispatchMessage(&msg);    
                            }
                 }
    关闭对话框函数
            DestroyWindow();          关闭非模态对话框,退出消息循环,结束进程,但不等于退出运行
     
    我们总结下关闭窗口或者对话框的函数
            EndDiaolog();                关闭模态对话框,调用函数中关闭对话框,关闭后会有一个返回值给父窗口
    DestroyWindow();          关闭非模态对话框,退出消息循环,结束进程,但不等于退出运行
    PostQuitMessage();       退出运行,关闭程序
     
     
    15.    控件的使用
        
    经过学习可以知道,控件的产生可以有两种方式,第一种是我们使用CreateWindow函数去创建处理    另一种就是用可视化编程创建出来
    这里要说明一点,所有控件的ID只有一个,句柄是不定的
    所以对于控件的使用,我们往往是根据ID找句柄操作他们,所以我们需要大量使用GetDigItem()函数来操作控件
        GetDigItem(父窗口句柄,控件ID)
        那么父窗口的句柄如何找到呢??
            第一种:    HWND hWnd = FindWindow(NULL, L"当前窗口的名字");
            第二种,如果知道子窗口句柄,找父窗口句柄方法    GetParent()参数为子窗口句柄
     
    控件消息
        上面我们在分析消息的时候,以及提及了控件消息的相关信息,这里我们来深入的分析下控件消息
    控件的本质也是窗口,既然是窗口那么他也有回调函数,我们在创建控件的时候并没有指定他的回调函数,那么控件的消息谁处理了呢?
        他其实是发送到了父窗口中,所以我们应该在主窗口的回调函数里面去处理控件的消息,控件消息主要分为两种类型WM_COMMAND和WM_NOTIFY,我们上面说过。控件分为两种类型,一种是标准控件,一种是通用控件,所以消息的处理也是不同的
        我们如果按下一个按钮,或者鼠标单击,那么WINDOWS将会发送一个WM_COMMAND消息给父窗口,我们这里就分析下WM_COMMAND消息参数
    消息来源 wParam(高16位) wParam(低16位) IParam
    菜单 0 菜单ID 0
    快捷键 1 快捷键ID 0
    控件 控件通知码 控件ID 控件句柄
    这里的控件通知码 如果说BN_CLICKED 区分具体是什么消息种类        我们在WM_COMMAND  中写switch语句,其中的case 后面就可写控件通知码
     
    标准控件的分类
     
    • 按钮类控件
           按钮,复选框,单选框都是窗口类为button的窗口,它的三种风格导致了三种不同的用途
            BS_PUSHBUTTON(普通按钮)
            BS_CHECKBOX(复选框)
            BS_RADIO(单选框)
         如何控制?
        Button控件,只需要响应父窗口的WM_COMMAND消息,并且通过wParam知道按得是哪一个按钮发送的消息就可以
        这里我们必须要用ID去控制按钮,因为句柄是随时可以改变的
     
    <wiz_code_mirror>
     
     
     
     
     
        case WM_COMMAND:
        {//当消息是WM_COMMAND的时候,wParam的低16位是子控件ID
            DWORD dwId = LOWORD(wParam);
            switch (dwId)
            {
            case 1000:
                MessageBox(0, TEXT("你干嘛"), TEXT("警告"), 0);
                break;
            case 1001:
                MoveWindow(hWnd, 200, 200, 600, 500, TRUE);
                break;
            case 1002:
            {
                WCHAR WindowNamebuf[100] = {};
                GetWindowText(hWnd, WindowNamebuf, 100);
                wcscat_s(WindowNamebuf, 100, L"hehe");
                SetWindowText(hWnd, WindowNamebuf);
            }
     
     
        CheckBox控件一般只需要对其控件窗口的句柄进行发消息操作就可以设置
        这里说明下,通过句柄操作确实可以,但是每次句柄都会改变,这里的句柄会是变量,但是句柄的获得是靠ID得来的,用定量去获得变量,所以这里传入句柄是可以的
    使其被选择上 SendMessage(控件窗口句柄,BM_SETCHECK,1,0);
    使其取消选择 SendMessage(控件窗口句柄,BM_SETCHECK,1,0);  再次发送点击消息即可
    获取其状态 SendMessage(控件窗口句柄,BM_SETCHECK,0,0);
        Radio Box
        它和CheckBox差不多
        这里添加一个函数,ComboBox_GetText(hWnd,szText,64);    获取选项内容
        它和CheckBox的区别就是,一个选其他全不选,所以我们就要为这些按钮分组
    分组的步骤,Ctrl+D,按顺序点你的Radio Box,在每一组的第一个按钮将属性group至为TRUE
     
    • 文本框
    编辑框除了使用SendMessage外,还需要知道一些API
    获取文本框内容 GetDlgItemText(hWnd,ID,buf);
    设置文本框内容 SetDlgItemText(hWnd,ID,buf);
    • ComboBox
    他与编辑框类似,可以使用SendMessage函数操作控件,除此之外还需要知道一些宏
    向下拉组合框添加一项 ComboBox_AddString(hwnd,szBuff);
    返回当前选择的行号 int dex = ComboBox_GetCursel(hwnd)
    删除一行 ComboBox_DeleteString(hwnd_cbb,index);
    根据文本找到第几行 int dex=ComboBox_FindString(hwnd,indexstart,szBuff);
    • Picture Control
    要将图片控件上显示一个图片资源的要素:
        首先,要有一个.bmp格式图片,并将其加载到资源当中
        其次,调用LoadBitMap函数将其加载,并得到一个控制图片的句柄,句柄类型是HBITMAP
        显示图片SendMessage(hPicCtrl,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBitMap);
     
    通用控件分类
        通用控件通知父窗口消息不再是WM_COMMAND而是WM_NOTIFY
    创建通用控件的方法依然有两种,动态创建和资源拖拽
    动态创建也就是我们用代码去实现,通常的步骤有:
        1.包含<CommCtrl.h>头文件
        2.载入ComCtrl32.lib
        3.调用InitCommonControls初始化通用控件
        4.使用CreateWindowsEX创建通用控件
     
    下面我们对应于之前所说的,来分析分析为什么通用控件给主窗口回调函数发消息需要WM_NOTIFY 而不是WM_COMMAND
    我们指定对于WM_COMMADN消息,其附加的消息是之前的表格所示 
    消息来源 wParam(高16位) wParam(低16位) IParam
    菜单 0 菜单ID 0
    快捷键 1 快捷键ID 0
    控件 控件通知码 控件ID 控件句柄
    这里我们通过wParam来区分菜单,快捷键或者控件通知码,然而我们如果选中了List控件的某一行,我们发现我们需要知道我们选中的是哪一行,这下WM_COMMAND就不能满足我们的要求,于是,WM_NOTIFY就出现了
        现在我们将所有的信息都存放到    NMHDR    结构体中,该结构体指针通过LPARAM通知到父窗口   
        typedef struct tagNMHDR 
        { 
            HWND      hwndFrom;     // 控件句柄. 
            UINT_PTR  idFrom;        // 控件 ID. 
            UINT      code;                 // NM_ code. 
         }    NMHDR; 
         但是我们需要知道ListView选中的行和列   
    typedef struct tagNMLISTVIEW 
        NMHDR   hdr;            // NMHDR. 
        int     iItem;                  // 行号. 
        int     iSubItem;           // 列号. 
        UINT    uNewState; 
        UINT    uOldState; 
        UINT    uChanged; 
        POINT   ptAction; 
        LPARAM  lParam; 
    } NMLISTVIEW, *LPNMLISTVIEW; 
    它的第一个字段就是NMHDR
    所以WM_NOTIFY消息的附加消息就如下所示
    消息类型 WPARAM LPARAM
    WM_NOTIFY 发生WM_NOTIFY消息控件的ID NMHDR指针
        通用控件的使用
    • 进度条
    常见操作:
    设置进度 SendMessage(hPosControl,PBM_SETPOS,数值,0);
    获取进度 int nPos=SendMessage(hPosControl,PBM_GETPOS,0,0);
    • 滑块
    滑块可以设置其范围,范围设置必须在WM_CREAT中写
    滑块的具体API函数    P58页
     
    • List Control
    我们要知道列表是由 行和列组成,所以我们必须要掌握如何添加行和列
    这里有两个宏,分别是添加行和列
        ListView_InsertItem(hWnd,LVITEM);                                //行
        ListView_InsertColumn(hWnd,nIndex,LPVCOLUMN);     //列
    还有一个给列表设置文本
        ListView_SetItemText(hWnd,行号,列号,文本);
    其本质都是SendMessage()
     
     
     
    16.    控件消息的截获
    控件的消息处理函数,系统以及帮我们定义好了,但是我们还是可以去修改原来的消息处理函数,这时候就要用到SetWindowLong来
                LONG SetWindowLong (
                                         HWND  hwnd,             //窗口句柄          
                                         int         index,             //索引值
                                         LONG  dwNewLong   //新值
                                      );
    我们可以根据索引值来修改不同的属性,窗口ID,消息处理函数,风格,扩展风格,对话框消息处理函数,用户数据。。。
  • 相关阅读:
    ionic 刷新页面的几种方法
    Highcharts中如何外部修改pointStart
    前端分页 思路
    快捷选时间
    获取今天,昨天,本周,上周,本月,上月时间
    angularjs 弹出框 $modal
    SQL 查找存在某内容的存储过程都有哪些
    LINQ to SQL和Entity Framework
    SQL模糊查询条件的四种匹配模式
    数据库--中文表名及字段名的优缺点
  • 原文地址:https://www.cnblogs.com/Tempt/p/9987732.html
Copyright © 2020-2023  润新知