win32通用控件

1.标准控件
可以在win32窗口程序中添加资源脚本来给程序添加标准控件;
具体操作为:新建资源脚本    ->在.rc文件中添加控件    ->给控件绑定事件;
 
常用的标准控件:
    Static    ->组框,用来将窗口分成多个块   
    Group Box    
    Button    
    Check Box    
    Radio Button    
    Edit    
    ComboBox    
    ListBox    
 
2.通用控件
标准控件是一些常用的控件,因此每当程序编译时,会将这些控件加到exe程序中;
因此标准控件总是可用的;
 
还有一些不常用的控件,因为不常用,每次编译时加到程序中会浪费空间;
这些控件就是通用控件;
微软为了节省程序空间,将不常用的通用控件放在Comctrl32.dll中;
如果要使用通用控件,首先要引入该动态链接库:
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
常用的通用控件:
    Animation        
    ComboBoxEx         
    Date_and_Time_Picker         
    Drag_List_Box         
    Flat_Scroll_Bar         
    Header         
    HotKey         
    ImageList         
    IPAddress         
    List_View         
    Month_Calendar         
    Pager         
    Progress_Bar         
    Property_Sheets         
    Rebar         
    Status Bars         
    SysLink         
    Tab         
    Toolbar         
    ToolTip         
    Trackbar         
    TreeView         
    Up_and_Down        
 
特别说明:                
    通用控件在使用前,需要通过INITCOMMONCONTROLSEX进行初始化                
    只要在您的程序中的任意地方引用了该函数就、会使得WINDOWS的程序加载器PE Loader加载该库                
INITCOMMONCONTROLSEX icex;                
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);                
icex.dwICC = ICC_WIN95_CLASSES;                
InitCommonControlsEx(&icex);        
也就是告诉PE Loader到底要dll中的哪些通用控件;
这段代码一般放winmain刚开始的地方;
在msdn中搜索INITCOMMONCONTROLSEX结构,可以看到哪个参数对应的是哪个控件,例如:ICC_WIN95_CLASSES表示包含大多数常用通用控件;
 
3.ListView的使用
ListView是一种通用控件;用来显示多条信息;
 
往listView中添加数据:
#include <windows.h>
#include "resource.h"
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
 
//给进程窗口添加内容;就是给ListView控件添加列,本来是要遍历进程的,为了简单填假数据
void EnumProcess(HWND hListProcess){
    LV_ITEM vitem;                
                
    //初始化                
    memset(&vitem,0,sizeof(LV_ITEM));                
    vitem.mask = LVIF_TEXT;                
                
    vitem.pszText = "csrss.exe";    //
    vitem.iItem = 0;                //
    vitem.iSubItem = 0;                ////ListView_InsertItem(hListProcess, &vitem);    //一个宏和SendMessage作用一样                
    SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);    //如果用SendMessage,给第一列赋值用LVM_INSERTITEM,其它列用LVM_SETITEM,用ListView同理                
                
    vitem.pszText = TEXT("448");                
    vitem.iItem = 0;                
    vitem.iSubItem = 1;                
    ListView_SetItem(hListProcess, &vitem);                
                
    vitem.pszText = TEXT("56590000");                
    vitem.iItem = 0;                
    vitem.iSubItem = 2;                
    ListView_SetItem(hListProcess, &vitem);                
                
    vitem.pszText = TEXT("000F0000");                
    vitem.iItem = 0;                
    vitem.iSubItem = 3;                
    ListView_SetItem(hListProcess, &vitem);                
                
    vitem.pszText = TEXT("winlogon.exe");                
    vitem.iItem = 1;                
    vitem.iSubItem = 0;                
    //ListView_InsertItem(hListProcess, &vitem);                
    SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);                
                
    vitem.pszText = TEXT("456");                
    vitem.iSubItem = 1;                
    ListView_SetItem(hListProcess, &vitem);                
                
    vitem.pszText = TEXT("10000000");                
    vitem.iSubItem = 2;                
    ListView_SetItem(hListProcess, &vitem);                
                
    vitem.pszText = TEXT("000045800");                
    vitem.iSubItem = 3;                
    ListView_SetItem(hListProcess, &vitem);                
 
}
 
 
//初始化进程窗口,就是给ListView控件添加列
void initProcessView(HWND hDlg){
    LV_COLUMN lv;                                
    HWND hListProcess;                                
                                
    //初始化,局部变量堆栈中分配,不知道是什么数据所以先清零                                
    memset(&lv,0,sizeof(LV_COLUMN));                                
    //获取IDC_LIST_PROCESS句柄                                
    hListProcess = GetDlgItem(hDlg,IDC_LIST_PROCESS);                                
    //设置整行选中,窗口是windows来管理的无法直接操作,程序能做的只能发送一个消息来让windows直到该怎么做                                
    SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);                                
                                
    //第一列                                
    lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;                                
    lv.pszText = TEXT("进程");                //列标题                
    lv.cx = 150;                                //列宽
    lv.iSubItem = 0;                                
    //ListView_InsertColumn(hListProcess, 0, &lv);                                
    SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);                                
    //第二列                                
    lv.pszText = TEXT("PID");                                
    lv.cx = 90;                                
    lv.iSubItem = 1;                                
    //ListView_InsertColumn(hListProcess, 1, &lv);                                
    SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);                                
    //第三列                                
    lv.pszText = TEXT("镜像基址");                                
    lv.cx = 100;                                
    lv.iSubItem = 2;                                
    ListView_InsertColumn(hListProcess, 2, &lv);                                
    //第四列                                
    lv.pszText = TEXT("镜像大小");                                
    lv.cx = 100;                                
    lv.iSubItem = 3;                                
    ListView_InsertColumn(hListProcess, 3, &lv);                                
    
    EnumProcess(hListProcess);
}
 
//回调函数
BOOL CALLBACK DialogProc(                                    
                         HWND hwndDlg,  // handle to dialog box            
                         UINT uMsg,     // message            
                         WPARAM wParam, // first message parameter            
                         LPARAM lParam  // second message parameter            
                         )            
{    
    switch(uMsg)                                
    {    
    case WM_INITDIALOG :   
        initProcessView(hwndDlg);    //初始化列表
        return TRUE;     
                                    
    case  WM_COMMAND :                                
                                    
        switch (LOWORD (wParam))                            
        {
        case IDC_BUTTON_SHOW:                                                 
            return TRUE; 
                       
        case IDC_BUTTON_ABOUT:                                                 
            return TRUE;                        
       
        case IDC_BUTTON_OUT:                                                 
            EndDialog(hwndDlg, 0);                        
            return TRUE;                        
        }                            
        break ;                            
    }                                    
                                    
    return FALSE ;                                
}     
 
//程序入口
int CALLBACK WinMain(
                     HINSTANCE hInstance,
                     HINSTANCE hPrevHinstance,
                     LPSTR lpCmdLine,
                     int nCmdShow
        ){
    INITCOMMONCONTROLSEX icex;                
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);                
    icex.dwICC = ICC_WIN95_CLASSES;                
    InitCommonControlsEx(&icex);     
 
    //创建对话框窗口
    DialogBox(
        hInstance,
        MAKEINTRESOURCE(DLG_MAIN),
        NULL,
        DialogProc
        );    
    
    return 0;
}
结果:
 
3.WM_NOTIFY消息
该消息类型与WM_COMMAND类型相似,都是由子窗口向父窗口发送的消息。                        
WM_NOTIFY可以包含比WM_COMMAND更丰富的信息                        
Windows通用组件中有很多消息,都是通过WM_NOTIFY来描述的.                        
 
例如:
    当点击按钮时,按钮自身的回调函数会将消息转为WM_COMMAND消息给主窗口的回调函数;
    如果是想处理ListView的列的点击事件,则是通过WM_NOTIFY;
 
WM_NOTIFY消息参数如下:
    wParam:控件ID                    
    lParam:指向一个结构,并且这个结构是可以拓展的,因此比WM_COMMAND能传递更多消息                   
    typedef struct tagNMHDR {                     
        HWND hwndFrom; //发送通知消息的控件窗口句柄;    ->哪个子窗口发的消息                    
        UINT idFrom;   //发送通知消息的控件ID值;        ->子窗口的哪个控件发过来的                  
        UINT code;     //通知码,如LVM_SELCHANGED;      -> 做了那些事:点左键、点右键、值改变等等                    
    } NMHDR;
这个结构体能满足一般的要求,但能描述的信息还是有限的                        
解决方案:对每种不同用途的通知消息都定义另一种结构来表示                        
typedef struct tagNMLVCACHEHINT {            
    NMHDR   hdr;            
    int     iFrom;            
    int     iTo;            
} NMLVCACHEHINT, *PNMLVCACHEHINT;            
            
typedef struct tagLVDISPINFO {            
    NMHDR hdr;            
    LVITEM item;            
} NMLVDISPINFO, FAR *LPNMLVDISPINFO;            
            
typedef struct _NMLVFINDITEM {            
    NMHDR hdr;            
    int iStart;            
    LVFINDINFO lvfi;            
} NMLVFINDITEM, *PNMLVFINDITEM;           
这些结构有个特点:
    它们的第一个成员都是NMHDR结构;
    相当于c++中的继承,拓展了NMHDR结构; 
                    
                    
 

猜你喜欢

转载自www.cnblogs.com/ShiningArmor/p/12083803.html