比较复杂的对话框
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;//这是一个回调函数的声明
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
int iCurrentColor = IDC_BLACK,//刚开始默认为黑色背景
iCurrentFigure = IDC_RECT ;//刚开始默认为矩形
int WINAPI WinMain (HINSTANCE hInstance,//应用程序当前实例的句柄
HINSTANCE hPrevInstance,//应用程序先前的实例句柄
PSTR szCmdLine, //指向应用程序命令行的字符串的指针
int iCmdShow)//指明窗口如何显示
{
static TCHAR szAppName[] = TEXT ("About2") ;
MSG msg ;//消息
HWND hwnd ;//定义句柄
WNDCLASS wndclass ;//窗口类名
wndclass.style = CS_HREDRAW | CS_VREDRAW ;//窗口的显示方式,此处为水平重画和竖直重画
wndclass.lpfnWndProc = WndProc ;//窗口回调函数
wndclass.cbClsExtra = 0 ;//窗口扩展,此处为0
wndclass.cbWndExtra = 0 ;//窗口实例扩展,此处为0
wndclass.hInstance = hInstance ;//窗口的实例句柄
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(ABOUT2)) ;//窗口的显示方式,这里采用自定义资源
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;//鼠标的显示方式,此处设置为标准型
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;//窗口背景颜色的设置,此处设置为白色
wndclass.lpszMenuName = MAKEINTRESOURCE(ABOUT2) ;//窗口菜单
wndclass.lpszClassName = szAppName ;//窗口类名
if (!RegisterClass (&wndclass))//注册窗口,若注册失败,产生如下的信息
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName,
TEXT ("About Box Demo Program"),//窗口的名字
WS_OVERLAPPEDWINDOW,//窗口的创建风格
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,//以上四个参数分别为窗口的x坐标,y坐标宽度和高度
NULL, //指向被创建窗口的父窗口或所有者窗口的句柄,此处为NULL
NULL, //菜单句柄,或依据窗口风格指明一个子窗口标识,此处为NULL
hInstance, //与窗口相关联的模块实例的句柄
NULL) ;//指向一个值的指针,该值传递给窗口WM_CREATE消息
ShowWindow (hwnd, iCmdShow) ;//显示窗口,hWnd:指窗口句柄。iCmdShow:指定窗口如何显示
UpdateWindow (hwnd) ; //更新窗口,hWnd:指窗口句柄
while (GetMessage (&msg, NULL, 0, 0))//消息循环
{
TranslateMessage (&msg) ;//该函数将虚拟键消息转换为字符消息
DispatchMessage (&msg) ;//该函数分发一个消息给窗口程序
}
return msg.wParam ;//wParam是消息携带的参数,可以是个值,也可以是个地址
}
void PaintWindow (HWND hwnd, int iColor, int iFigure)
{
static COLORREF crColor[8] = { RGB ( 0, 0, 0), RGB ( 0, 0, 255),
RGB ( 0, 255, 0), RGB ( 0, 255, 255),
RGB (255, 0, 0), RGB (255, 0, 255),
RGB (255, 255, 0), RGB (255, 255, 255) } ;
//COLORREF类型用来描绘一个RGB颜色
HBRUSH hBrush ;//定义一个画刷的句柄
HDC hdc ;//定义一个句柄
RECT rect ;//用来存储矩形框的信息
hdc = GetDC (hwnd) ;//获取句柄
GetClientRect (hwnd, &rect) ;//GetClientRect函数获取窗口客户区的坐标
hBrush = CreateSolidBrush (crColor[iColor - IDC_BLACK]) ;//CreateSolidBrush函数创建一个具有指定颜色的逻辑刷子
hBrush = (HBRUSH) SelectObject (hdc, hBrush) ;
//SelectObject函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
if (iFigure == IDC_RECT)
Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
else
Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
DeleteObject (SelectObject (hdc, hBrush)) ;//释放画刷句柄
ReleaseDC (hwnd, hdc) ;//释放环境句柄
}
void PaintTheBlock (HWND hCtrl, int iColor, int iFigure)//用来绘画对话框上面的那个显示颜色和形状的控件的
{
InvalidateRect (hCtrl, NULL, TRUE) ;
UpdateWindow (hCtrl) ;
PaintWindow (hCtrl, iColor, iFigure) ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInstance ;
PAINTSTRUCT ps ;//该结构体包含了某应用程序用来绘制它所拥有的窗口客户区所需要的信息
switch (message)
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;//获取当前实例的句柄
return 0 ;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDM_APP_ABOUT:
if (DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc))
InvalidateRect (hwnd, NULL, TRUE) ;
//InvalidateRect函数向指定的窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制
//hWnd:要更新的客户区所在的窗体的句柄
//第二个参数的意思为无效区域的矩形代表,它是一个结构体指针,存放着矩形的大小。
//如果为NULL,全部的窗口客户区域将被增加到更新区域中
//第三个参数为重绘标志
return 0 ;
}
break ;
case WM_PAINT:
BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
PaintWindow (hwnd, iCurrentColor, iCurrentFigure) ;//绘制开始时的窗口
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;//该函数向系统表明有个线程有终止请求。通常用来响应WM_DESTROY消息
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;//该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理
}
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
static HWND hCtrlBlock ;
static int iColor, iFigure ;
switch (message)
{
case WM_INITDIALOG:
iColor = iCurrentColor ;
iFigure = iCurrentFigure ;
CheckRadioButton (hDlg, IDC_BLACK, IDC_WHITE, iColor) ;
//CheckRadioButton函数给一组单选按钮中的一个指定按钮加上选中标志,并且清除组中其他按钮的选中标志
//hDlg:指向包含单选按钮的对话框的句柄
//IDC_BLACK指定组中第1个单选按钮的标识符
//IDC_WHITE指定组中最后一个单选按钮的标识符
//iColor指出要选中的那个单选按钮的标识符
CheckRadioButton (hDlg, IDC_RECT, IDC_ELLIPSE, iFigure) ;
//参考上面的解释,这里是选择矩形还是椭圆形
hCtrlBlock = GetDlgItem (hDlg, IDC_PAINT) ;//返回窗口中指定参数ID的子元素的句柄
//第一个参数为控件所在对话框的句柄
//第二个参数为操作控件的ID标识
SetFocus (GetDlgItem (hDlg, iColor)) ;//SetFocus函数对指定的窗口设置键盘焦点
//参数意思为接收键盘输入的窗口指针。若该参数为NULL,则击键被忽略
return FALSE ;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
iCurrentColor = iColor ;
iCurrentFigure = iFigure ;
EndDialog (hDlg, TRUE) ;//该函数清除一个模态对话框,并使系统中止对对话框的任何处理
return TRUE ;
case IDCANCEL:
EndDialog (hDlg, FALSE) ;//该函数清除一个模态对话框,并使系统中止对对话框的任何处理
return TRUE ;
case IDC_BLACK:
case IDC_RED:
case IDC_GREEN:
case IDC_YELLOW:
case IDC_BLUE:
case IDC_MAGENTA:
case IDC_CYAN:
case IDC_WHITE:
iColor = LOWORD (wParam) ;//低位是控件ID标识
CheckRadioButton (hDlg, IDC_BLACK, IDC_WHITE, LOWORD (wParam)) ;//参考上面的解释
PaintTheBlock (hCtrlBlock, iColor, iFigure) ;
return TRUE ;
case IDC_RECT:
case IDC_ELLIPSE:
iFigure = LOWORD (wParam) ;//低位是控件ID标识
CheckRadioButton (hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD (wParam)) ;
PaintTheBlock (hCtrlBlock, iColor, iFigure) ;
return TRUE ;
}
break ;
case WM_PAINT:
//当窗口显示区域的一部分显示内容或者全部变为“无效”,以致于必须“更新画面”时,将由这个消息通知程序
PaintTheBlock (hCtrlBlock, iColor, iFigure) ;
break ;
}
return FALSE ;
}
下面是资源脚本里的
这里特别要注意ID的重要性,ID标识是程序加载资源的桥梁,所以要在心里面分外清楚,这样才不至于出错!祝大家开开心心,事事如意!