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版UNICODET版
获取长度strlenwcsnlen_tcslen
字符串拷贝strcpy_swcscpy_s_tcscpy_s
字符串转数字atoi_wtoi_tstoi
sscanf_sswscanf_s_stscanf_s
数字转字符sprintf_sswprintf_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菜单ID0
快捷键1快捷键ID0
控件控件通知码控件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\n", 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_TABCONTROLTab控件
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菜单ID0
快捷键1快捷键ID0
控件控件通知码控件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菜单ID0
快捷键1快捷键ID0
控件控件通知码控件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消息的附加消息就如下所示

消息类型WPARAMLPARAM
WM_NOTIFY发生WM_NOTIFY消息控件的IDNMHDR指针

    通用控件的使用

  • 进度条

常见操作:

设置进度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,消息处理函数,风格,扩展风格,对话框消息处理函数,用户数据。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sinat_40572875

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值