win32day10-组合框/列表框/滚动条/控件的自绘制
Posted 吴英强
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了win32day10-组合框/列表框/滚动条/控件的自绘制相关的知识,希望对你有一定的参考价值。
组合框 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 当窗口的选项发生变化的
情况下,通知父窗口.
// 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的
样式,才能发送通知消息
// 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 获取,返回当前位置
// 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_CLIPCHILDREN|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 - 控件绘制的信息
// 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,
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;
以上是关于win32day10-组合框/列表框/滚动条/控件的自绘制的主要内容,如果未能解决你的问题,请参考以下文章
Python中tkinter中控件的使用(6.Listbox列表框(添加滚动条))
在MFC中:静态文本类;按纽类;编辑框类;滚动条类;列表框类;组合框类等所对应的类名以及其功能
MFC编程入门之二十六(常用控件:滚动条控件ScrollBar)
VS2010-MFC(常用控件:滚动条控件Scroll Bar)