- GUI
- Windows API tutorial
- Introduction to Windows API
- Windows API main functions
- System functions in Windows API
- Strings in Windows API
- Date & time in Windows API
- A window in Windows API
- First steps in UI
- Windows API menus
- Windows API dialogs
- Windows API controls I
- Windows API controls II
- Windows API controls III
- Advanced controls in Windows API
- Custom controls in Windows API
- The GDI in Windows API
- PyQt4 tutorial
- PyQt5 tutorial
- Qt4 tutorial
- Introduction to Qt4 toolkit
- Qt4 utility classes
- Strings in Qt4
- Date and time in Qt4
- Working with files and directories in Qt4
- First programs in Qt4
- Menus and toolbars in Qt4
- Layout management in Qt4
- Events and signals in Qt4
- Qt4 Widgets
- Qt4 Widgets II
- Painting in Qt4
- Custom widget in Qt4
- The Breakout game in Qt4
- Qt5 tutorial
- Introduction to Qt5 toolkit
- Strings in Qt5
- Date and time in Qt5
- Containers in Qt5
- Working with files and directories in Qt5
- First programs in Qt5
- Menus and toolbars in Qt5
- Layout management in Qt5
- Events and signals in Qt5
- Qt5 Widgets
- Qt5 Widgets II
- Painting in Qt5
- Custom widget in Qt5
- Snake in Qt5
- The Breakout game in Qt5
- PySide tutorial
- Tkinter tutorial
- Tcl/Tk tutorial
- Qt Quick tutorial
- Java Swing tutorial
- JavaFX tutorial
- Java SWT tutorial
- wxWidgets tutorial
- Introduction to wxWidgets
- wxWidgets helper classes
- First programs in wxWidgets
- Menus and toolbars in wxWidgets
- Layout management in wxWidgets
- Events in wxWidgets
- Dialogs in wxWidgets
- wxWidgets widgets
- wxWidgets widgets II
- Drag and Drop in wxWidgets
- Device Contexts in wxWidgets
- Custom widgets in wxWidgets
- The Tetris game in wxWidgets
- wxPython tutorial
- Introduction to wxPython
- First Steps
- Menus and toolbars
- Layout management in wxPython
- Events in wxPython
- wxPython dialogs
- Widgets
- Advanced widgets in wxPython
- Drag and drop in wxPython
- Internationalisation
- Application skeletons in wxPython
- The GDI
- Mapping modes
- Creating custom widgets
- Tips and Tricks
- wxPython Gripts
- The Tetris game in wxPython
- C# Winforms Mono tutorial
- Java Gnome tutorial
- Introduction to Java Gnome
- First steps in Java Gnome
- Layout management in Java Gnome
- Layout management II in Java Gnome
- Menus in Java Gnome
- Toolbars in Java Gnome
- Events in Java Gnome
- Widgets in Java Gnome
- Widgets II in Java Gnome
- Advanced widgets in Java Gnome
- Dialogs in Java Gnome
- Pango in Java Gnome
- Drawing with Cairo in Java Gnome
- Drawing with Cairo II
- Nibbles in Java Gnome
- QtJambi tutorial
- GTK+ tutorial
- Ruby GTK tutorial
- GTK# tutorial
- Visual Basic GTK# tutorial
- PyGTK tutorial
- Introduction to PyGTK
- First steps in PyGTK
- Layout management in PyGTK
- Menus in PyGTK
- Toolbars in PyGTK
- Signals & events in PyGTK
- Widgets in PyGTK
- Widgets II in PyGTK
- Advanced widgets in PyGTK
- Dialogs in PyGTK
- Pango
- Pango II
- Drawing with Cairo in PyGTK
- Drawing with Cairo II
- Snake game in PyGTK
- Custom widget in PyGTK
- PHP GTK tutorial
- C# Qyoto tutorial
- Ruby Qt tutorial
- Visual Basic Qyoto tutorial
- Mono IronPython Winforms tutorial
- Introduction
- First steps in IronPython Mono Winforms
- Layout management
- Menus and toolbars
- Basic Controls in Mono Winforms
- Basic Controls II in Mono Winforms
- Advanced Controls in Mono Winforms
- Dialogs
- Drag & drop in Mono Winforms
- Painting
- Painting II in IronPython Mono Winforms
- Snake in IronPython Mono Winforms
- The Tetris game in IronPython Mono Winforms
- FreeBASIC GTK tutorial
- Jython Swing tutorial
- JRuby Swing tutorial
- Visual Basic Winforms tutorial
- JavaScript GTK tutorial
- Ruby HTTPClient tutorial
- Ruby Faraday tutorial
- Ruby Net::HTTP tutorial
- Java 2D games tutorial
- Java 2D tutorial
- Cairo graphics tutorial
- PyCairo tutorial
- HTML5 canvas tutorial
- Python tutorial
- Python language
- Interactive Python
- Python lexical structure
- Python data types
- Strings in Python
- Python lists
- Python dictionaries
- Python operators
- Keywords in Python
- Functions in Python
- Files in Python
- Object-oriented programming in Python
- Modules
- Packages in Python
- Exceptions in Python
- Iterators and Generators
- Introspection in Python
- Ruby tutorial
- PHP tutorial
- Visual Basic tutorial
- Visual Basic
- Visual Basic lexical structure
- Basics
- Visual Basic data types
- Strings in Visual Basic
- Operators
- Flow control
- Visual Basic arrays
- Procedures & functions in Visual Basic
- Organizing code in Visual Basic
- Object-oriented programming
- Object-oriented programming II in Visual Basic
- Collections in Visual Basic
- Input & output
- Tcl tutorial
- C# tutorial
- Java tutorial
- AWK tutorial
- Jetty tutorial
- Tomcat Derby tutorial
- Jtwig tutorial
- Android tutorial
- Introduction to Android development
- First Android application
- Android Button widgets
- Android Intents
- Layout management in Android
- Android Spinner widget
- SeekBar widget
- Android ProgressBar widget
- Android ListView widget
- Android Pickers
- Android menus
- Dialogs
- Drawing in Android
- Java EE 5 tutorials
- Introduction
- Installing Java
- Installing NetBeans 6
- Java Application Servers
- Resin CGIServlet
- JavaServer Pages, (JSPs)
- Implicit objects in JSPs
- Shopping cart
- JSP & MySQL Database
- Java Servlets
- Sending email in a Servlet
- Creating a captcha in a Servlet
- DataSource & DriverManager
- Java Beans
- Custom JSP tags
- Object relational mapping with iBATIS
- Jsoup tutorial
- MySQL tutorial
- MySQL quick tutorial
- MySQL storage engines
- MySQL data types
- Creating, altering and dropping tables in MySQL
- MySQL expressions
- Inserting, updating, and deleting data in MySQL
- The SELECT statement in MySQL
- MySQL subqueries
- MySQL constraints
- Exporting and importing data in MySQL
- Joining tables in MySQL
- MySQL functions
- Views in MySQL
- Transactions in MySQL
- MySQL stored routines
- MySQL Python tutorial
- MySQL Perl tutorial
- MySQL C API programming tutorial
- MySQL Visual Basic tutorial
- MySQL PHP tutorial
- MySQL Java tutorial
- MySQL Ruby tutorial
- MySQL C# tutorial
- SQLite tutorial
- SQLite C tutorial
- SQLite PHP tutorial
- SQLite Python tutorial
- SQLite Perl tutorial
- SQLite Ruby tutorial
- SQLite C# tutorial
- SQLite Visual Basic tutorial
- PostgreSQL C tutorial
- PostgreSQL Python tutorial
- PostgreSQL Ruby tutorial
- PostgreSQL PHP tutorial
- PostgreSQL Java tutorial
- Apache Derby tutorial
- SQLAlchemy tutorial
- MongoDB PHP tutorial
- MongoDB Java tutorial
- MongoDB JavaScript tutorial
- MongoDB Ruby tutorial
- Spring JdbcTemplate tutorial
- JDBI tutorial
Windows API controls III
In this chapter, we will finish talking about Windows API controls. We will mention radio buttons, radio box, combo box, and a progress bar.
Radio buttons and GroupBox
Here we introduce two controls. A group box is a rectangle that surrounds a set of controls. These are often radio buttons. A group box has a label that describes the control. The purpose of this control is to group controls that are somehow related. A radio button is a special kind of button that can be selected by the user, but not cleared. It allows the user to select a single exclusive choice from a group of options.
radio_buttons.c
#include <windows.h> #define ID_BLUE 1 #define ID_YELLOW 2 #define ID_ORANGE 3 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE g_hinst; COLORREF g_color; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, int nCmdShow) { HWND hwnd; MSG msg ; WNDCLASSW wc = {0}; wc.lpszClassName = L"GroupBox"; wc.hInstance = hInstance; wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.lpfnWndProc = WndProc; wc.hCursor = LoadCursor(0, IDC_ARROW); g_hinst = hInstance; RegisterClassW(&wc); hwnd = CreateWindowW(wc.lpszClassName, L"GroupBox", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 300, 170, 0, 0, hInstance, 0); while (GetMessage(&msg, NULL, 0, 0)) { DispatchMessage(&msg); } return (int) msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HBRUSH hBrush, holdBrush; HPEN hPen, holdPen; switch(msg) { case WM_CREATE: CreateWindowW(L"Button", L"Choose colour", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 10, 10, 120, 110, hwnd, (HMENU) 0, g_hinst, NULL); CreateWindowW(L"Button", L"Blue", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 20, 30, 100, 30, hwnd, (HMENU) ID_BLUE , g_hinst, NULL); CreateWindowW(L"Button", L"Yellow", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 20, 55, 100, 30, hwnd, (HMENU) ID_YELLOW , g_hinst, NULL); CreateWindowW(L"Button", L"Orange", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 20, 80, 100, 30, hwnd, (HMENU) ID_ORANGE , g_hinst, NULL); break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case ID_BLUE: g_color = RGB(0, 76, 255); break; case ID_YELLOW: g_color = RGB(255, 255, 0); break; case ID_ORANGE: g_color = RGB(255, 123, 0); break; } InvalidateRect(hwnd, NULL, TRUE); } break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); hBrush = CreateSolidBrush(g_color); hPen = CreatePen(PS_NULL, 1, RGB(0, 0, 0)); holdPen = SelectObject(hdc, hPen); holdBrush = (HBRUSH) SelectObject(hdc, hBrush); Rectangle(hdc, 160, 20, 260, 120); SelectObject(hdc, holdBrush); SelectObject(hdc, holdPen); DeleteObject(hPen); DeleteObject(hBrush); EndPaint(hwnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProcW(hwnd, msg, wParam, lParam); }
In our example, we have a group box with three radio buttons. By clicking on the radio button, we select a background colour for the rectangle on the right.
CreateWindowW(L"Button", L"Choose colour", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 10, 10, 120, 110, hwnd, (HMENU) 0, g_hinst, NULL);
A group box is a special kind of a button created with the BS_GROUPBOX
style.
CreateWindowW(L"Button", L"Blue", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 20, 30, 100, 30, hwnd, (HMENU) ID_BLUE , g_hinst, NULL);
A radio button is also a special kind of a button with BS_AUTORADIOBUTTON
style.
case ID_BLUE: g_color = RGB(0, 76, 255); break;
If we click on the radio button, a global variable is filled with selected colour. This variable is used to create a brush that fills the rectangle.
InvalidateRect(hwnd, NULL, TRUE);
We invalidate the rectangle (in this case whole window), which will cause the client area to be redrawn. This will launch a WM_PAINT
message. During the WM_PAINT
message, we draw the rectangle. Drawing is explained in GDI chapter in more detail.

Combo box
A combo box is a combination of an edit box or static text and a list. A combo box is used when we need to select an item from a list of available options.
combobox.c
#include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE g_hinst; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, int nCmdShow) { HWND hwnd; MSG msg ; WNDCLASSW wc = {0}; wc.lpszClassName = L"Application"; wc.hInstance = hInstance ; wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.lpfnWndProc = WndProc ; wc.hCursor = LoadCursor(0,IDC_ARROW); g_hinst = hInstance; RegisterClassW(&wc); hwnd = CreateWindowW(wc.lpszClassName, L"Combo box", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 270, 170, 0, 0, hInstance, 0); while (GetMessage(&msg, NULL, 0, 0)) { DispatchMessage(&msg); } return (int) msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HWND hwndCombo, hwndStatic; const wchar_t *items[] = { L"FreeBSD", L"OpenBSD", L"NetBSD", L"Solaris", L"Arch" }; switch(msg) { case WM_CREATE: hwndCombo = CreateWindowW(L"Combobox", NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 10, 10, 120, 110, hwnd, NULL, g_hinst, NULL); CreateWindowW(L"Button", L"Drop down", WS_CHILD | WS_VISIBLE, 150, 10, 90, 25, hwnd, (HMENU) 1, g_hinst, NULL); hwndStatic = CreateWindowW(L"Static", L"", WS_CHILD | WS_VISIBLE, 150, 80, 90, 25, hwnd, NULL, g_hinst, NULL); for (int i = 0; i < 4; i++ ) { SendMessageW(hwndCombo, CB_ADDSTRING, 0, (LPARAM) items[i]); } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { SendMessage(hwndCombo, CB_SHOWDROPDOWN, (WPARAM) TRUE, 0); } if (HIWORD(wParam) == CBN_SELCHANGE) { LRESULT sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0); SetWindowTextW(hwndStatic, items[sel]); } break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProcW(hwnd, msg, wParam, lParam); }
In our example, we put three controls on the window: a combo box, a button, and a static text. The static text displays the currently selected item from the combo box. It is used to demonstrate the CBN_SELCHANGE
combo box message. The button programatically opens the combo box.
hwndCombo = CreateWindowW(L"Combobox", NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 10, 10, 120, 110, hwnd, NULL, g_hinst, NULL);
To create a combo box, we use the L"Combobox"
window class. The CBS_DROPDOWN
flag creates a drop-down list.
for (int i = 0; i < 4; i++ ) { SendMessageW(hwndCombo, CB_ADDSTRING, 0, (LPARAM) items[i]); }
We fill the combo box with items. To add a string to the combo box, we send a CB_ADDSTRING
message.
if (HIWORD(wParam) == BN_CLICKED) { SendMessage(hwndCombo, CB_SHOWDROPDOWN, (WPARAM) TRUE, 0); }
Clicking on the button causes a CB_SHOWDROPDOWN
message to be send, which programmatically invokes a drop down of the combo box.
If we select an item from the combo box, the window procedure receives the WM_COMMAND
message with the notification message CBN_SELCHANGE
in the high-order word of the wParam
parameter.
if (HIWORD(wParam) == CBN_SELCHANGE) { LRESULT sel = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0); SetWindowTextW(hwndStatic, items[sel]); }
We figure out the currently selected item. We send a CB_GETCURSEL
message to the combo box. The function returns the index of the currently selected item. We set the static text to the currently selected string.

Progress bar
A progress bar is a control that is used when we process lengthy tasks. It is animated so that the user knows that our task is progressing.
progressbar.c
#include <windows.h> #include <commctrl.h> #define ID_BUTTON 1 #define ID_TIMER 2 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void CreateControls(HWND); HWND hwndPrgBar; HWND hbtn; int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, int nCmdShow) { HWND hwnd; MSG msg ; WNDCLASSW wc = {0}; wc.lpszClassName = L"Application"; wc.hInstance = hInstance; wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.lpfnWndProc = WndProc; wc.hCursor = LoadCursor(0, IDC_ARROW); RegisterClassW(&wc); hwnd = CreateWindowW(wc.lpszClassName, L"Progress bar", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 260, 170, 0, 0, hInstance, 0); while (GetMessage(&msg, NULL, 0, 0)) { DispatchMessage(&msg); } return (int) msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int i = 0; switch(msg) { case WM_CREATE: CreateControls(hwnd); break; case WM_TIMER: SendMessage(hwndPrgBar, PBM_STEPIT, 0, 0); i++; if (i == 150) { KillTimer(hwnd, ID_TIMER); SendMessageW(hbtn, WM_SETTEXT, (WPARAM) NULL, (LPARAM) L"Start"); i = 0; } break; case WM_COMMAND: if (i == 0) { i = 1; SendMessage(hwndPrgBar, PBM_SETPOS, 0, 0); SetTimer(hwnd, ID_TIMER, 5, NULL); SendMessageW(hbtn, WM_SETTEXT, (WPARAM) NULL, (LPARAM) L"In progress"); } break; case WM_DESTROY: KillTimer(hwnd, ID_TIMER); PostQuitMessage(0); break; } return DefWindowProcW(hwnd, msg, wParam, lParam); } void CreateControls(HWND hwnd) { INITCOMMONCONTROLSEX icex; icex.dwSize = sizeof(INITCOMMONCONTROLSEX); icex.dwICC = ICC_PROGRESS_CLASS; InitCommonControlsEx(&icex); hwndPrgBar = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 30, 20, 190, 25, hwnd, NULL, NULL, NULL); hbtn = CreateWindowW(L"Button", L"Start", WS_CHILD | WS_VISIBLE, 85, 90, 85, 25, hwnd, (HMENU) 1, NULL, NULL); SendMessage(hwndPrgBar, PBM_SETRANGE, 0, MAKELPARAM(0, 150)); SendMessage(hwndPrgBar, PBM_SETSTEP, 1, 0); }
In our example, we have a progress bar and a button. The button starts a timer which updates the progress bar.
hwndPrgBar = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 30, 20, 190, 25, hwnd, NULL, NULL, NULL);
We create a progress bar control with PROGRESS_CLASS
class name and PBS_SMOOTH
style.
SendMessage(hwndPrgBar, PBM_SETRANGE, 0, MAKELPARAM(0, 150)); SendMessage(hwndPrgBar, PBM_SETSTEP, 1, 0);
We set the range of the progress bar and its step.
i = 1; SendMessage(hwndPrgBar, PBM_SETPOS, 0, 0); SetTimer(hwnd, ID_TIMER, 5, NULL);
When we press the Start button, we set the i
value to 1, set the initial position of the progress bar, and start the timer. The timer will periodically send a WM_TIMER
message to the window procedure, until it is killed.
SendMessageW(hbtn, WM_SETTEXT, (WPARAM) NULL, (LPARAM) L"In progress");
When the timer is in progress, we change the label of the button.
case WM_TIMER: SendMessage(hwndPrgBar, PBM_STEPIT, 0, 0); i++; if (i == 150) { KillTimer(hwnd, ID_TIMER); SendMessageW(hbtn, WM_SETTEXT, (WPARAM) NULL, (LPARAM) L"Start"); i = 0; } break;
When we receive the WM_TIMER
message, we update the progress bar by one step sending the PBM_STEPIT
message. The timer is killed when the i
variable reaches the upper limit of the progress bar.

In this part of the Windows API tutorial, we have finished covering Windows controls.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论