Win32编程day10 学习笔记

一 组合框 ComboBox

  1 组合框的样式
 
    1.1 简单组合框  CBS_SIMPLE
    1.2 下拉式组合框 CBS_DROPDOWN
       能输入或者从下拉列表中选择
    1.3 下拉列表式组合框 CBS_DROPDOWNLIST
       只能从下拉列表中选择
   
  2 组合框的使用
 
    2.1 组合框的创建
      窗口类名称是 COMBOBOX, 使用CreateWindow创建, 创建时要注意窗口高度(弹出的列表).
    2.2 增加选项
      CB_ADDSTRING/CB_INSERTSTRING
      CB_ADDSTRING: WPARAM为0不使用, LPARAM是添加字符串的地址
    2.3 删除选项
      CB_DELETESTRING 删除指定选项
      CB_RESETCONTENT 清空所有选项
    2.4 选择
      CB_GETCURSEL 获取被选择项
      CB_SETCURSEL 设置当前的选择项
      CB_SELECTSTRING 设置选择指定的字符串所对应的项
    2.5 查找
      CB_FINDSTRING 根据指定的字符串,找到对应项的索引
         1)大小写不敏感
         2)字符串和选项从左到右匹配.
         3)选项包含字符串即可
    2.6 获取选项或者被选择字符串
       CB_GETLBTEXT 获取选项的字符串
       WM_GETTEXT   获取被选择到窗口的字符串
      
    2.7 选项的数据
       可以将自定义数据信息,在选项中设置和获取.
       CB_SETITEMDATA 将数据保存到选项中
       CB_GETITEMDATA 从选项当中获取数据
      
    2.8 目录显示
       CB_DIR 将指定路径下的文件和路径信息显示在ComboBox当中
          wParam - 显示的类型
          lParam - 路径字符串地址
         
    2.9 通知消息
      通过WM_COMMAND消息,通知父窗口.
      CBN_SELCHANGE 当窗口的选项发生变化的情况下,通知父窗口.

View Code
// WinComboBox.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "stdio.h"
#include "resource.h"

HINSTANCE g_hInst = NULL;

void OnCreate( HWND hWnd, UINT nMsg,
              WPARAM wParam, LPARAM lParam )
{    //简单组合框的创建
    CreateWindow( "COMBOBOX", "SIMPLE",
        WS_CHILD|WS_VISIBLE|CBS_SIMPLE,
        50, 50, 120, 300, hWnd, 
        (HMENU)1001, g_hInst, NULL );
    //下拉式组合框的创建
    CreateWindow( "COMBOBOX", "DROPDOWN",
        WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWN,
        200, 50, 120, 300, hWnd,
        (HMENU)1002, g_hInst, NULL );
    //下拉列表式组合框的创建
    CreateWindow( "COMBOBOX", "DROPDOWNLIST",
        WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST,
        350, 50, 120, 100, hWnd,
        (HMENU)1003, g_hInst, NULL );
}

void OnAdd( HWND hWnd )
{    //获取COMBOBOX窗口句柄
    HWND hSimple   = GetDlgItem( hWnd, 1001 );
    HWND hDropDown = GetDlgItem( hWnd, 1002 );
    HWND hDropList = GetDlgItem( hWnd, 1003 );
    //添加多个选项
    CHAR szText[] = "ComboBox 0";
    for( int nIndex=0; nIndex<10; nIndex++ )
    {    //添加选项
        LRESULT nItem = SendMessage( hSimple, 
            CB_ADDSTRING, 0, (LPARAM)szText );
        //设置项的数据
        SendMessage( hSimple, CB_SETITEMDATA,
            nItem, 100+nIndex );

        SendMessage( hDropDown, CB_ADDSTRING, 
            0, (LPARAM)szText );
        SendMessage( hDropList, CB_ADDSTRING, 
            0, (LPARAM)szText );
        //改变选项内容
        szText[9]++;
    }
}

void OnDel( HWND hWnd )
{    //获取COMBOBOX窗口句柄
    HWND hSimple   = GetDlgItem( hWnd, 1001 );
    HWND hDropDown = GetDlgItem( hWnd, 1002 );
    HWND hDropList = GetDlgItem( hWnd, 1003 );
    //删除指定项
    SendMessage( hSimple, 
        CB_DELETESTRING, 5, 0 );
    SendMessage( hDropDown, 
        CB_DELETESTRING, 5, 0 );
    SendMessage( hDropList, 
        CB_DELETESTRING, 5, 0 );
}

void OnReset( HWND hWnd )
{    //获取COMBOBOX窗口句柄
    HWND hSimple   = GetDlgItem( hWnd, 1001 );
    HWND hDropDown = GetDlgItem( hWnd, 1002 );
    HWND hDropList = GetDlgItem( hWnd, 1003 );
    //清空所有项
    SendMessage( hSimple,   CB_RESETCONTENT, 0, 0 );
    SendMessage( hDropDown, CB_RESETCONTENT, 0, 0 );
    SendMessage( hDropList, CB_RESETCONTENT, 0, 0 );
}

void OnSelect( HWND hWnd )
{    //获取COMBOBOX窗口句柄
    HWND hSimple   = GetDlgItem( hWnd, 1001 );
    HWND hDropDown = GetDlgItem( hWnd, 1002 );
    HWND hDropList = GetDlgItem( hWnd, 1003 );
    //获取和设置选择项
    LRESULT nSel = 
        SendMessage( hSimple, CB_GETCURSEL, 0, 0 );
    //获取数据
    LRESULT nValue = SendMessage( hSimple, 
        CB_GETITEMDATA, nSel, 0 );
    CHAR szInfo[260] = { 0 };
    sprintf( szInfo, "%d", nValue );
    MessageBox( NULL, szInfo, "WinCombo", MB_OK );
    
    //设置选择项
    SendMessage( hDropDown, CB_SETCURSEL, nSel, 0 );
    CHAR szText[] = "ComboBox 5";
    SendMessage( hDropList, CB_SELECTSTRING, 
        -1, (LPARAM)szText );
}

void OnFind( HWND hWnd )
{    //获取COMBOBOX窗口句柄
    HWND hSimple   = GetDlgItem( hWnd, 1001 );
    HWND hDropDown = GetDlgItem( hWnd, 1002 );
    HWND hDropList = GetDlgItem( hWnd, 1003 );
    //查找字符串
    CHAR szText[] = "ComboBox 5";
    LRESULT nFind1 = SendMessage( hSimple, 
        CB_FINDSTRING, -1, (LPARAM)szText );
    SendMessage( hDropDown, CB_SETCURSEL,
       nFind1, 0 );
    SendMessage( hDropList, CB_SETCURSEL,
       nFind1, 0 );
}

void OnPath( HWND hWnd )
{    //获取COMBOBOX窗口句柄
    HWND hSimple   = GetDlgItem( hWnd, 1001 );
    HWND hDropDown = GetDlgItem( hWnd, 1002 );
    HWND hDropList = GetDlgItem( hWnd, 1003 );
    //显示目录
    CHAR szPath[MAX_PATH] = "C:\\*.*";
    SendMessage( hSimple, CB_DIR,
        DDL_DIRECTORY|DDL_ARCHIVE,
        (LPARAM)szPath );
    SendMessage( hDropDown, CB_DIR,
        DDL_DIRECTORY|DDL_ARCHIVE,
        (LPARAM)szPath );
    SendMessage( hDropList, CB_DIR,
        DDL_DIRECTORY|DDL_ARCHIVE,
        (LPARAM)szPath );
}

void OnCommand( HWND hWnd, UINT nMsg,
        WPARAM wParam, LPARAM lParam )
{
    int nNotifyCode = HIWORD( wParam );
    int nEventID = LOWORD( wParam );
    switch( nEventID )
    {
    case ID_ADD:
        OnAdd( hWnd );
        break;
    case ID_DEL:
        OnDel( hWnd );
        break;
    case ID_RESET:
        OnReset( hWnd );
        break;
    case ID_SEL:
        OnSelect( hWnd );
        break;
    case ID_FIND:
        OnFind( hWnd );
        break;
    case ID_PATH:
        OnPath( hWnd );
        break;
    case 1001:
        {
            HWND hSimple   = GetDlgItem( hWnd, 1001 );
            HWND hDropDown = GetDlgItem( hWnd, 1002 );
            HWND hDropList = GetDlgItem( hWnd, 1003 );
            LRESULT nSel   = 0;
            switch( nNotifyCode )
            {
            case CBN_SELCHANGE:
                nSel = SendMessage( hSimple, 
                    CB_GETCURSEL, 0, 0 );
                SendMessage( hDropDown, 
                    CB_SETCURSEL, nSel, 0 );
                SendMessage( hDropList, 
                    CB_SETCURSEL, nSel, 0 );

                //MessageBox( NULL, "CBN_SELCHANGE",
                //    "WinCombo", MB_OK );

                break;
            }
        }
        break;
    }
}

LRESULT CALLBACK WndProc( HWND   hWnd, 
                          UINT   nMsg,
                          WPARAM wParam,
                          LPARAM lParam )
{
    switch( nMsg )
    {
    case WM_CREATE:
        OnCreate( hWnd, nMsg, wParam, lParam );
        break;
    case WM_COMMAND:
        OnCommand( hWnd, nMsg, wParam, lParam );
        break;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }
    return DefWindowProc( hWnd, nMsg,
        wParam, lParam );
}

BOOL RegisterWnd( LPSTR pszClassName )
{
    WNDCLASSEX wce = { 0 };
    wce.cbSize        = sizeof( wce );
    wce.cbClsExtra    = 0;
    wce.cbWndExtra    = 0;
    wce.hbrBackground = HBRUSH(COLOR_BTNFACE+1);
    wce.hCursor       = NULL;
    wce.hIcon         = NULL;
    wce.hIconSm       = NULL;
    wce.hInstance     = g_hInst;
    wce.lpfnWndProc   = WndProc;
    wce.lpszClassName = pszClassName;
    wce.lpszMenuName  = NULL;
    wce.style         = CS_HREDRAW|CS_VREDRAW;

    ATOM nAtom = RegisterClassEx( &wce );
    if( 0 ==  nAtom )
    {
        return FALSE;
    }

    return TRUE;
}

HWND CreateWnd( LPSTR pszClassName )
{
    HMENU hMenu = LoadMenu( g_hInst,
        MAKEINTRESOURCE(IDR_MAIN) );
    HWND hWnd = CreateWindowEx( 0,
        pszClassName, "MyWnd", 
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, NULL, hMenu, g_hInst,
        NULL );
    return hWnd;
}

void DisplayWnd( HWND hWnd )
{
    ShowWindow( hWnd, SW_SHOW );
    UpdateWindow( hWnd );
}

void Message( )
{
    MSG msg = { 0 };
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    g_hInst = hInstance;
    RegisterWnd( "MYWND" );
    HWND hWnd = CreateWnd( "MYWND" );
    DisplayWnd( hWnd );
    Message( );
    return 0;
}

二 列表框 ListBox

 1 列表框的样式
   1.1 单选列表框 默认
   1.2 多选列表框 LBS_MULTIPLESEL
  
 2 列表框的使用
   2.1 列表框的创建
     窗口类名为LISTBOX, 使用CreateWindow/Ex
   2.2 增加选项
     LB_ADDSTRING
     LB_INSERTSTRING
   2.2 删除选项
     LB_DELETESTRING 删除指定选项
     LB_RESETCONTENT 清空所有选项
   2.3 选择项的获取和设置
     LB_GETCURSEL 获取被选择项
     LB_SETCURSEL 设置当前被选择项
     LB_GETSEL  获取指定项的选择状态
     LB_SETSEL  设置指定项的选择状态
     LB_GETSELCOUNT 获取被选择的数量
     LB_GETSELITEMS 获取被选择项的索引
    
    2.4 查找 LB_FINDSTRING
    2.5 获取指定项的文字
       LB_GETEXT  指定项的文字
       LB_GETTEXTLEN 指定项的文字的长度
      
    2.6 选项的数据
       LB_SETITEMDATA 将自定义数据保存到指定的选项当中
       LB_GETITEMDATA 将自定义数据从指定选项中取出
    2.7 目录信息
       LB_DIR 显示指定目录下的文件和子目录信息
    2.8 通知消息
       LBN_SELCHANGE 当ListBox中的选择项发生变化时,通知父窗口.
       注意:对于ListBox需要增加LBS_NOTIFY的样式,才能发送通知消息

View Code
// WinListBox.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

HINSTANCE g_hInst   = NULL;
HWND      g_hSingle = NULL;
HWND      g_hMulti  = NULL;
void OnCreate( HWND hWnd, UINT nMsg, 
    WPARAM wParam, LPARAM lParam )
{
    g_hSingle = CreateWindow( 
        "LISTBOX", "SINGLE", 
        WS_CHILD|WS_VISIBLE|LBS_NOTIFY,
        50, 50, 200, 400, hWnd,
        (HMENU)1001, g_hInst, NULL );
    g_hMulti = CreateWindow( 
        "LISTBOX", "MULTI", 
        WS_CHILD|WS_VISIBLE|LBS_MULTIPLESEL|LBS_NOTIFY,
        300, 50, 200, 400, hWnd,
        (HMENU)1002, g_hInst, NULL );
}

void OnAdd( )
{
    CHAR szText[] = "ListBox 0";
    for( int nIndex=0; nIndex<10; nIndex++ )
    {    //添加项
        LRESULT nItem = 
            SendMessage( g_hSingle, LB_ADDSTRING,
            0, (LPARAM)szText );
        SendMessage( g_hMulti,  LB_ADDSTRING,
            0, (LPARAM)szText );
        szText[8]++;
    }
}

void OnSelect( )
{    //设置当前选择项
    SendMessage( g_hSingle, LB_SETCURSEL, 2, 0 );
    //设置指定项的选择状态
    for( int nIndex=0; nIndex<10; nIndex++ )
    {
        SendMessage( g_hMulti, LB_SETSEL, 
            TRUE, nIndex );
    }
    //获取所有选择项的数量
    LRESULT nCount = SendMessage( g_hMulti,
        LB_GETSELCOUNT, 0, 0 );
    if( nCount == 10 )
    {
        MessageBox( NULL, "10", "10", MB_OK );
    }
    //获取选择项的索引号
    INT nSel[20] = { 0 };
    SendMessage( g_hMulti, LB_GETSELITEMS,
        20, (LPARAM)nSel );
}

void OnCommand( HWND hWnd, UINT nMsg, 
    WPARAM wParam, LPARAM lParam )
{
    int nNotifyCode = HIWORD( wParam );
    int nCtrlID = LOWORD( wParam );
    switch( nCtrlID )
    {
    case ID_ADD:
        OnAdd( );
        break;
    case ID_SELECT:
        OnSelect( );
        break;
    case 1001:
        {
            switch( nNotifyCode )
            {
            case LBN_SELCHANGE:
                MessageBox( NULL, "LBN_SELCHANGE",
                    "ListBox", MB_OK );
                break;
            }
        }
        break;
    }
}

LRESULT CALLBACK WndProc( HWND   hWnd, 
                          UINT   nMsg,
                          WPARAM wParam,
                          LPARAM lParam )
{
    switch( nMsg )
    {
    case WM_CREATE:
        OnCreate( hWnd, nMsg, wParam, lParam );
        break;
    case WM_COMMAND:
        OnCommand( hWnd, nMsg, wParam, lParam );
        break;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }
    return DefWindowProc( hWnd, nMsg,
        wParam, lParam );
}

BOOL RegisterWnd( LPSTR pszClassName )
{
    WNDCLASSEX wce = { 0 };
    wce.cbSize        = sizeof( wce );
    wce.cbClsExtra    = 0;
    wce.cbWndExtra    = 0;
    wce.hbrBackground = HBRUSH(COLOR_BTNFACE+1);
    wce.hCursor       = NULL;
    wce.hIcon         = NULL;
    wce.hIconSm       = NULL;
    wce.hInstance     = g_hInst;
    wce.lpfnWndProc   = WndProc;
    wce.lpszClassName = pszClassName;
    wce.lpszMenuName  = NULL;
    wce.style         = CS_HREDRAW|CS_VREDRAW;

    ATOM nAtom = RegisterClassEx( &wce );
    if( 0 ==  nAtom )
    {
        return FALSE;
    }

    return TRUE;
}

HWND CreateWnd( LPSTR pszClassName )
{
    HMENU hMenu = LoadMenu( g_hInst, 
        MAKEINTRESOURCE(IDR_MAIN) );
    HWND hWnd = CreateWindowEx( 0,
        pszClassName, "MyWnd", 
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, NULL, hMenu, g_hInst,
        NULL );
    return hWnd;
}

void DisplayWnd( HWND hWnd )
{
    ShowWindow( hWnd, SW_SHOW );
    UpdateWindow( hWnd );
}

void Message( )
{
    MSG msg = { 0 };
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    g_hInst = hInstance;
    RegisterWnd( "MYWND" );
    HWND hWnd = CreateWnd( "MYWND" );
    DisplayWnd( hWnd );
    Message( );
    return 0;
}

三 滚动条

   1 滚动条样式
     1.1 水平滚动条 SBS_HORZ
     1.2 垂直滚动条 SBS_VERT
    
   2 滚动条的使用
     2.1 滚动条的创建
        窗口类名称 SCROLLBAR
     2.2 消息处理  
        2.2.1 水平滚动条 WM_HSCROLL
           LOWORD(wParam) - 滚动的标示
           HIWORD(wParam) - 当前滑块的位置
           lParam - 窗口的句柄
        2.2.2 垂直滚动条 WM_VSCROLL
           LOWORD(wParam) - 滚动的标示
           HIWORD(wParam) - 当前滑块的位置
           lParam - 窗口的句柄
        2.2.3 HIWORD(wParam)只在
          SB_THUMBPOSITION/SB_THUMBTRACK时
          有效.
     2.3 滚动条的滚动范围
        SBM_SETRANGE 设置滚动条的滚动范围
           wParam - 最小值,起始值
           lParam - 最大值,终止值
        SBM_GETRANGE 获取滚动条的滚动范围
           wParam - 最小值得存放的INT的地址
           lParam - 最大值得存放的INT的地址
     2.4 滑块位置的设置和获取
        SBM_SETPOS 设置滑块位置
           wParam - 新的滑块位置
           lParam - 重新绘制窗口
        SBM_GETPOS 获取,返回当前位置

View Code
// WinScrollBar.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

HINSTANCE g_hInst = NULL;
HWND      g_hHorz = NULL;
HWND      g_hVert = NULL;
void OnCreate( HWND hWnd, WPARAM wParam,
    LPARAM lParam )
{    //创建滚动条
    g_hHorz = CreateWindow( "SCROLLBAR", "HORZ",
        WS_CHILD|WS_VISIBLE|SBS_HORZ,
        0, 300, 300, 30, hWnd,
        (HMENU)1001, g_hInst, NULL );
    g_hVert = CreateWindow( "SCROLLBAR", "VERT",
        WS_CHILD|WS_VISIBLE|SBS_VERT,
        300, 0, 30, 300, hWnd,
        (HMENU)1002, g_hInst, NULL );
    //设置滚动范围
    SendMessage( g_hHorz, SBM_SETRANGE, 0, 300 );
    SendMessage( g_hVert, SBM_SETRANGE, 0, 300 );

}
void OnHScroll( HWND hWnd, WPARAM wParam,
    LPARAM lParam )
{
    int nScrollCode = LOWORD( wParam );
    int nPos        = HIWORD( wParam ); 
    switch( nScrollCode )
    {
    case SB_LINELEFT: //左边箭头
        nPos = SendMessage( g_hHorz, SBM_GETPOS,
            0, 0 );
        nPos--;
        SendMessage( g_hHorz, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_LINERIGHT: //右边箭头
        nPos = SendMessage( g_hHorz, SBM_GETPOS,
            0, 0 );
        nPos++;
        SendMessage( g_hHorz, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_PAGELEFT: //滑块左边的空白区域
        nPos = SendMessage( g_hHorz, SBM_GETPOS,
            0, 0 );
        nPos -= 10;
        SendMessage( g_hHorz, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_PAGERIGHT://滑块右边的空白区域
        nPos = SendMessage( g_hHorz, SBM_GETPOS,
            0, 0 );
        nPos += 10;
        SendMessage( g_hHorz, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_THUMBPOSITION://拖拽滑块后
        SendMessage( g_hHorz, SBM_SETPOS,
            nPos, TRUE );
        break;
    }

    InvalidateRect( hWnd, NULL, TRUE );
}

void OnVScroll( HWND hWnd, WPARAM wParam,
    LPARAM lParam )
{
    int nScrollCode = LOWORD( wParam );
    int nPos        = HIWORD( wParam ); 
    switch( nScrollCode )
    {
    case SB_LINEUP: //上边箭头
        nPos = SendMessage( g_hVert, SBM_GETPOS,
            0, 0 );
        nPos--;
        SendMessage( g_hVert, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_LINEDOWN://下边箭头
        nPos = SendMessage( g_hVert, SBM_GETPOS,
            0, 0 );
        nPos++;
        SendMessage( g_hVert, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_PAGEUP://滑块上边的空白区域
        nPos = SendMessage( g_hVert, SBM_GETPOS,
            0, 0 );
        nPos -= 10;
        SendMessage( g_hVert, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_PAGEDOWN://滑块下边的空白区域
        nPos = SendMessage( g_hVert, SBM_GETPOS,
            0, 0 );
        nPos += 10;
        SendMessage( g_hVert, SBM_SETPOS, 
            nPos, TRUE );
        break;
    case SB_THUMBPOSITION://拖拽滑块后
        SendMessage( g_hVert, SBM_SETPOS,
            nPos, TRUE );
        break;
    }

    InvalidateRect( hWnd, NULL, TRUE );
}    

void OnPaint( HWND hWnd, WPARAM wParam,
    LPARAM lParam )
{
    PAINTSTRUCT ps = { 0 };
    HDC hDC = BeginPaint( hWnd, &ps );
    
    int nVert = SendMessage( g_hVert, 
        SBM_GETPOS, 0, 0 );
    int nHorz = SendMessage( g_hHorz, 
        SBM_GETPOS, 0, 0 );
    
    CHAR szText[] = "Hello ScroolBar";
    TextOut( hDC, 150 - nHorz, 150 - nVert, 
        szText, strlen(szText) );

    EndPaint( hWnd, &ps );
}

LRESULT CALLBACK WndProc( HWND   hWnd, 
                          UINT   nMsg,
                          WPARAM wParam,
                          LPARAM lParam )
{
    switch( nMsg )
    {
    case WM_PAINT:
        OnPaint( hWnd, wParam, lParam );
        break;
    case WM_CREATE:
        OnCreate( hWnd, wParam, lParam );
        break;
    case WM_HSCROLL:
        OnHScroll( hWnd, wParam, lParam );
        break;
    case WM_VSCROLL:
        OnVScroll( hWnd, wParam, lParam );
        break;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }
    return DefWindowProc( hWnd, nMsg,
        wParam, lParam );
}

BOOL RegisterWnd( LPSTR pszClassName )
{
    WNDCLASSEX wce = { 0 };
    wce.cbSize        = sizeof( wce );
    wce.cbClsExtra    = 0;
    wce.cbWndExtra    = 0;
    wce.hbrBackground = HBRUSH(COLOR_WINDOW);
    wce.hCursor       = NULL;
    wce.hIcon         = NULL;
    wce.hIconSm       = NULL;
    wce.hInstance     = g_hInst;
    wce.lpfnWndProc   = WndProc;
    wce.lpszClassName = pszClassName;
    wce.lpszMenuName  = NULL;
    wce.style         = CS_HREDRAW|CS_VREDRAW;

    ATOM nAtom = RegisterClassEx( &wce );
    if( 0 ==  nAtom )
    {
        return FALSE;
    }

    return TRUE;
}

HWND CreateWnd( LPSTR pszClassName )
{
    HWND hWnd = CreateWindowEx( 0,
        pszClassName, "MyWnd", 
        WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
        CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, NULL, NULL, g_hInst,
        NULL );
    return hWnd;
}

void DisplayWnd( HWND hWnd )
{
    ShowWindow( hWnd, SW_SHOW );
    UpdateWindow( hWnd );
}

void Message( )
{
    MSG msg = { 0 };
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    g_hInst = hInstance;
    RegisterWnd( "MYWND" );
    HWND hWnd = CreateWnd( "MYWND" );
    DisplayWnd( hWnd );
    Message( );
    return 0;
}

四 控件的自绘制

  1 控件具有OWNERDRAW样式
    BUTTON LISTBOX COMBOBOX
  2 WM_MEASUREITEM
    计算控件的大小   
    (UINT) wParam - 控件ID
    (LPMEASUREITEMSTRUCT)lParam-控件项的大小
  3 WM_DRAWITEM
    实现控件的绘制
    (UINT) wParam - 控件ID
    (LPDRAWITEMSTRUCT)lParam - 控件绘制的信息

View Code
// WinOwnerDraw.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

HINSTANCE g_hInst = NULL;

void OnCreate( HWND hWnd, WPARAM wParam, 
              LPARAM lParam )
{
    CreateWindow( "BUTTON", "MyButton",
        WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,  //自绘制控件需要有OWNERDRAW风格
        50, 50, 200, 50, hWnd,
        (HMENU)1001, g_hInst, NULL );
}

void OnDrawItem( HWND hWnd, WPARAM wParam, 
              LPARAM lParam )
{
    LPDRAWITEMSTRUCT pDis = 
        ( LPDRAWITEMSTRUCT )lParam;
    if( ODT_BUTTON == pDis->CtlType )
    {    //绘制按钮
        if( pDis->itemState & ODS_SELECTED )
        {
            HBRUSH hBrush = CreateSolidBrush( 
                RGB(200, 200, 255 ) );
            HBRUSH hOldBrush = (HBRUSH)
                SelectObject( pDis->hDC, hBrush );
            RoundRect( pDis->hDC, pDis->rcItem.left,
              pDis->rcItem.top, pDis->rcItem.right,
              pDis->rcItem.bottom, 15, 15 );
            SelectObject( pDis->hDC, hOldBrush );
            DeleteObject( hBrush );
        }
        else
        {
            HBRUSH hBrush = CreateSolidBrush( 
                RGB(100, 100, 255 ) );
            HBRUSH hOldBrush = (HBRUSH)
                SelectObject( pDis->hDC, hBrush );
            RoundRect( pDis->hDC, pDis->rcItem.left,
              pDis->rcItem.top, pDis->rcItem.right,
              pDis->rcItem.bottom, 15, 15 );
            SelectObject( pDis->hDC, hOldBrush );
            DeleteObject( hBrush );
        }
        //绘制按钮文字
        CHAR szName[260] = { 0 };
        GetWindowText( pDis->hwndItem, 
            szName, 260 );
        int nOldMode = SetBkMode( pDis->hDC, 
            TRANSPARENT );
        DrawText( pDis->hDC, szName, strlen(szName),
            &pDis->rcItem, 
            DT_CENTER|DT_VCENTER|DT_SINGLELINE );
        SetBkMode( pDis->hDC, nOldMode );
    }
}

void OnMeasureItem( HWND hWnd, WPARAM wParam, 
              LPARAM lParam )
{
    LPMEASUREITEMSTRUCT pMis =  
        (LPMEASUREITEMSTRUCT)lParam;
    pMis->itemHeight = 200;
}

LRESULT CALLBACK WndProc( HWND   hWnd, 
                          UINT   nMsg,
                          WPARAM wParam,
                          LPARAM lParam )
{
    switch( nMsg )
    {
    case WM_CREATE:
        OnCreate( hWnd, wParam, lParam );
        break;
    case WM_DRAWITEM:
        OnDrawItem( hWnd, wParam, lParam );
        return 0;
    case WM_MEASUREITEM:
        OnMeasureItem( hWnd, wParam, lParam );
        return 0;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }
    return DefWindowProc( hWnd, nMsg,
        wParam, lParam );
}

BOOL RegisterWnd( LPSTR pszClassName )
{
    WNDCLASSEX wce = { 0 };
    wce.cbSize        = sizeof( wce );
    wce.cbClsExtra    = 0;
    wce.cbWndExtra    = 0;
    wce.hbrBackground = HBRUSH(COLOR_WINDOW);
    wce.hCursor       = NULL;
    wce.hIcon         = NULL;
    wce.hIconSm       = NULL;
    wce.hInstance     = g_hInst;
    wce.lpfnWndProc   = WndProc;
    wce.lpszClassName = pszClassName;
    wce.lpszMenuName  = NULL;
    wce.style         = CS_HREDRAW|CS_VREDRAW;

    ATOM nAtom = RegisterClassEx( &wce );
    if( 0 ==  nAtom )
    {
        return FALSE;
    }

    return TRUE;
}

HWND CreateWnd( LPSTR pszClassName )
{
    HWND hWnd = CreateWindowEx( 0,
        pszClassName, "MyWnd", 
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, NULL, NULL, g_hInst,
        NULL );
    return hWnd;
}

void DisplayWnd( HWND hWnd )
{
    ShowWindow( hWnd, SW_SHOW );
    UpdateWindow( hWnd );
}

void Message( )
{
    MSG msg = { 0 };
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    g_hInst = hInstance;
    RegisterWnd( "MYWND" );
    HWND hWnd = CreateWnd( "MYWND" );
    DisplayWnd( hWnd );
    Message( );
    return 0;
}

 

posted @ 2012-08-16 22:11  唐小喵  阅读(3558)  评论(0编辑  收藏  举报