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

转载于:https://www.cnblogs.com/Tempt/p/9987732.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值