可以通过调用 CreateWindowEx 函数并为 Windows 类参数 lpClassName 传递值 UPDOWN_CLASS 来创建上下控件。
注意 CreateUpDownControl 函数已弃用。 应改用 CreateWindowEx
函数。
本主题中特别推荐的代码示例使用上下控件来驱动进度条。
需要了解的事项
技术
先决条件
- C/C++
- Windows 用户界面编程
说明
步骤 1:添加对公共控件的引用
除了添加预处理器指令以包含公共控件头文件外,还必须配置链接器以引用最新版本的公共控件库。
#include <commctrl.h>
#pragma comment(lib, "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Lib\\ComCtl32.Lib")
#pragma comment(linker,"\"/manifestdependency:type = 'win32' \
name = 'Microsoft.Windows.Common-Controls' \
version = '6.0.0.0' \
processorArchitecture = '*' \
publicKeyToken = '6595b64144ccf1df' \
language = '*'\"")
步骤 2:转发声明
声明上下控件及其同级控件的句柄,并转发引用初始化和创建控件的函数。
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
const UINT valMin=0; // The range of values for the Up-Down control.
const UINT valMax=100;
RECT rcClient; // Client area of parent window (Dialog Box).
UINT cyVScroll; // Height of scroll bar arrow.
HWND hControl = NULL; // Handles to the controls.
HWND hwndGroupBox = NULL;
HWND hwndLabel = NULL;
HWND hwndUpDnEdtBdy = NULL;
HWND hwndUpDnCtl = NULL;
HWND hwndProgBar = NULL;
HWND CreateGroupBox(HWND); // Handles to the create controls functions.
HWND CreateLabel(HWND);
HWND CreateUpDnBuddy(HWND);
HWND CreateUpDnCtl(HWND);
HWND CreateProgBar(HWND);
为上下控件的父对话框声明对窗口处理器的正向引用。
INT_PTR CALLBACK UpDownDialogProc(HWND, UINT, WPARAM, LPARAM);
步骤 3:初始化 INITCOMMONCONTROLSEX 结构的 dwSize 成员
INITCOMMONCONTROLSEX 结构包含用于从 DLL 加载公共控件类的信息。 此结构与 InitCommonControlsEx 函数一起使用,该函数需要结构的大小才能完成工作。
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
注意
只需初始化 dwSize 成员一次,但每次创建公共控件时都必须调用 InitCommonControlsEx 函数。
步骤 4:创建父对话框以保存上下控件
可以在主窗口处理器中将其作为消息处理程序实现 (WndProc)。
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_RUN_UPDOWN:
DialogBox(g_hInst, MAKEINTRESOURCE(IDD_UPDOWN), hWnd, UpDownDialogProc);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
步骤 5:为上下控件的父窗口实现窗口处理器
创建父对话框时,将使用其子窗口(其父控件)进行初始化。 当用户单击某个上下控件的箭头时,操作系统通过向对话框发送包含通知代码 UDN_DELTAPOS 的 WM_NOTIFY 消息来通知该事件,而该对话框又包含有关伙伴窗口的新值的信息。 WM_NOTIFY 消息处理程序使用此新信息更新进度条。
INT_PTR CALLBACK UpDownDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UINT nCode;
int iPosIndicated;
LPNMUPDOWN lpnmud;
switch (message)
{
case WM_INITDIALOG:
GetClientRect(hDlg, &rcClient);
cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
hwndGroupBox = CreateGroupBox(hDlg); // Group the controls.
hwndLabel = CreateLabel(hDlg); // Create a label for the Up-Down control.
hwndUpDnEdtBdy = CreateUpDnBuddy(hDlg); // Create an buddy window (an Edit control).
hwndUpDnCtl = CreateUpDnCtl(hDlg); // Create an Up-Down control.
hwndProgBar = CreateProgBar(hDlg); // Create a Progress bar,
// to reflect the state of the Up-down control.
return (INT_PTR)TRUE;
case WM_NOTIFY:
nCode = ((LPNMHDR)lParam)->code;
switch (nCode)
{
case UDN_DELTAPOS:
lpnmud = (LPNMUPDOWN)lParam;
iPosIndicated = SendMessage(hwndProgBar, PBM_GETPOS, (WPARAM)0, (LPARAM)0);
SendMessage(hwndProgBar,
PBM_SETPOS,
(WPARAM)(iPosIndicated + lpnmud->iDelta), // iPosIndicated can have
(LPARAM)0); // any signed integer value.
break;
}
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
步骤 6:创建伙伴窗口
上下控件的伙伴窗口是一个编辑控件,而编辑控件属于标准公共控件的类。 若要使用编辑控件,请使用 ICC_STANDARD_CLASSES 初始化标志调用 InitCommonControlsEx 函数。
HWND CreateUpDnBuddy(HWND hwndParent)
{
icex.dwICC = ICC_STANDARD_CLASSES; // Set the Initialization Flag value.
InitCommonControlsEx(&icex); // Initialize the Common Controls Library to use
// Buttons, Edit Controls, Static Controls, Listboxes,
// Comboboxes, and Scroll Bars.
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_CLIENTEDGE | WS_EX_CONTEXTHELP, //Extended window styles.
WC_EDIT,
NULL,
WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER // Window styles.
| ES_NUMBER | ES_LEFT, // Edit control styles.
rcClient.left+160, rcClient.top+40,
rcClient.left+52, rcClient.top+23,
hwndParent,
NULL,
g_hInst,
NULL);
return (hControl);
}
步骤 7:创建上下控件
上下控件属于上下类。 若要使用上下控件,请使用 ICC_UPDOWN_CLASS 初始化标志调用 InitCommonControlsEx 函数。 若要使控件在用户单击控件的向上箭头时向上计数,必须设置上下控件的范围和方向。 为此,请向控件发送包含上限和下限值的 UDM_SETRANGE 消息。
HWND CreateUpDnCtl(HWND hwndParent)
{
icex.dwICC = ICC_UPDOWN_CLASS; // Set the Initialization Flag value.
InitCommonControlsEx(&icex); // Initialize the Common Controls Library.
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING,
UPDOWN_CLASS,
NULL,
WS_CHILDWINDOW | WS_VISIBLE
| UDS_AUTOBUDDY | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_HOTTRACK,
0, 0,
0, 0, // Set to zero to automatically size to fit the buddy window.
hwndParent,
NULL,
g_hInst,
NULL);
SendMessage(hControl, UDM_SETRANGE, 0, MAKELPARAM(valMax, valMin)); // Sets the controls direction
// and range.
return (hControl);
}
上下控件示例代码
这是 UpDown 代码示例的完整实现。 可以通过创建空白 Win32 项目、将此代码复制并粘贴到空 C++ 文件中,然后添加自己的头文件、RC 文件、resource.h 文件和图标文件 (*.ico) 来试验。
// UpDown.cpp : Defines the entry point for the application.
#include "UpDown.h"
#include <commctrl.h>
#pragma comment(lib, "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Lib\\ComCtl32.Lib")
#pragma comment(linker,"\"/manifestdependency:type = 'win32' \
name = 'Microsoft.Windows.Common-Controls' \
version = '6.0.0.0' \
processorArchitecture = '*' \
publicKeyToken = '6595b64144ccf1df' \
language = '*'\"")
#define MAX_LOADSTRING 100
HINSTANCE g_hInst; // Global handle to the current instance.
TCHAR g_szTitle[MAX_LOADSTRING]; // The title bar text.
TCHAR g_szWindowClass[MAX_LOADSTRING]; // The main window class name.
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
const UINT valMin=0; // The range of values for the Up-Down control.
const UINT valMax=100;
RECT rcClient; // Client area of parent window (Dialog Box).
UINT cyVScroll; // Height of scroll bar arrow.
HWND hControl = NULL; // Handles to the controls.
HWND hwndGroupBox = NULL;
HWND hwndLabel = NULL;
HWND hwndUpDnEdtBdy = NULL;
HWND hwndUpDnCtl = NULL;
HWND hwndProgBar = NULL;
HWND CreateGroupBox(HWND); // Handles to the create controls functions.
HWND CreateLabel(HWND);
HWND CreateUpDnBuddy(HWND);
HWND CreateUpDnCtl(HWND);
HWND CreateProgBar(HWND);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK UpDownDialogProc(HWND, UINT, WPARAM, LPARAM);
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
HACCEL hAccelTable;
LoadString(hInstance, IDS_APP_TITLE, g_szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_UPDOWN, g_szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_UPDOWN));
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_UpDown));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
wcex.lpszClassName = g_szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_UpDown));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
g_hInst = hInstance; // Store instance handle in our global variable.
hWnd = CreateWindow(g_szWindowClass, // Class.
g_szTitle, // Window title.
WS_OVERLAPPEDWINDOW, // Window style.
CW_USEDEFAULT, 0, // Coordinates of top left corner.
CW_USEDEFAULT, 0, // Width and height.
NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UINT wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
switch (message)
{
case WM_CREATE:
return TRUE;
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_RUN_UPDOWN:
DialogBox(g_hInst, MAKEINTRESOURCE(IDD_UPDOWN), hWnd, UpDownDialogProc);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
INT_PTR CALLBACK UpDownDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UINT nCode;
int iPosIndicated;
LPNMUPDOWN lpnmud;
switch (message)
{
case WM_INITDIALOG:
GetClientRect(hDlg, &rcClient);
cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
hwndGroupBox = CreateGroupBox(hDlg); // Group the controls.
hwndLabel = CreateLabel(hDlg); // Create a label for the Up-Down control.
hwndUpDnEdtBdy = CreateUpDnBuddy(hDlg); // Create an buddy window (an Edit control).
hwndUpDnCtl = CreateUpDnCtl(hDlg); // Create an Up-Down control.
hwndProgBar = CreateProgBar(hDlg); // Create a Progress bar,
// to reflect the state of the Up-down control.
return (INT_PTR)TRUE;
case WM_NOTIFY:
nCode = ((LPNMHDR)lParam)->code;
switch (nCode)
{
case UDN_DELTAPOS:
lpnmud = (LPNMUPDOWN)lParam;
iPosIndicated = SendMessage(hwndProgBar, PBM_GETPOS, (WPARAM)0, (LPARAM)0);
SendMessage(hwndProgBar,
PBM_SETPOS,
(WPARAM)(iPosIndicated + lpnmud->iDelta), // iPosIndicated can have
(LPARAM)0); // any signed integer value.
break;
}
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
HWND CreateUpDnBuddy(HWND hwndParent)
{
icex.dwICC = ICC_STANDARD_CLASSES; // Set the Initialization Flag value.
InitCommonControlsEx(&icex); // Initialize the Common Controls Library to use
// Buttons, Edit Controls, Static Controls, Listboxes,
// Comboboxes, and Scroll Bars.
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_CLIENTEDGE | WS_EX_CONTEXTHELP, //Extended window styles.
WC_EDIT,
NULL,
WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER // Window styles.
| ES_NUMBER | ES_LEFT, // Edit control styles.
rcClient.left+160, rcClient.top+40,
rcClient.left+52, rcClient.top+23,
hwndParent,
NULL,
g_hInst,
NULL);
return (hControl);
}
HWND CreateUpDnCtl(HWND hwndParent)
{
icex.dwICC = ICC_UPDOWN_CLASS; // Set the Initialization Flag value.
InitCommonControlsEx(&icex); // Initialize the Common Controls Library.
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING,
UPDOWN_CLASS,
NULL,
WS_CHILDWINDOW | WS_VISIBLE
| UDS_AUTOBUDDY | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_HOTTRACK,
0, 0,
0, 0, // Set to zero to automatically size to fit the buddy window.
hwndParent,
NULL,
g_hInst,
NULL);
SendMessage(hControl, UDM_SETRANGE, 0, MAKELPARAM(valMax, valMin)); // Sets the controls direction
// and range.
return (hControl);
}
HWND CreateLabel(HWND hwndParent)
{
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING,
WC_STATIC,
L"Adjust:",
WS_CHILDWINDOW | WS_VISIBLE | SS_RIGHT,
rcClient.left+100, rcClient.top+42,
rcClient.left+45, rcClient.top+23,
hwndParent,
NULL,
g_hInst,
NULL);
return (hControl);
}
HWND CreateGroupBox(HWND hwndParent)
{
hControl = CreateWindowEx(WS_EX_LEFT | WS_EX_CONTROLPARENT | WS_EX_LTRREADING,
WC_BUTTON,
L"Volume",
WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE | WS_GROUP | BS_GROUPBOX,
rcClient.left+10, rcClient.top+10,
rcClient.right-20, rcClient.bottom-2*cyVScroll-10,
hwndParent,
NULL,
g_hInst,
NULL);
return (hControl);
}
HWND CreateProgBar(HWND hwndParent)
{
icex.dwICC = ICC_PROGRESS_CLASS; // Set the Initialization Flag value.
InitCommonControlsEx(&icex); // Initialize the Common Controls Library to use the Progress Bar control.
hControl = CreateWindowEx(WS_EX_STATICEDGE,
PROGRESS_CLASS,
L"Current Volume",
WS_CHILDWINDOW | WS_VISIBLE | PBS_SMOOTH,
rcClient.left+10, rcClient.bottom - cyVScroll-10,
rcClient.right-20, cyVScroll,
hwndParent,
NULL,
g_hInst,
NULL);
// Set the range and increment of the progress bar.
SendMessage(hControl, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
SendMessage(hControl, PBM_SETSTEP, (WPARAM) 1, 0);
return (hControl);
}
相关主题