您的位置:首页 > 其它

Windows学习心得【非模态对话框】

2014-05-02 15:59 281 查看
#include <windows.h>

LRESULT CALLBACK WndProc     (HWND, UINT, WPARAM, LPARAM) ;//回调函数的声明
BOOL    CALLBACK ColorScrDlg (HWND, UINT, WPARAM, LPARAM) ;

HWND hDlgModeless ;//全局变量,这是非模态对话框的句柄

int WINAPI WinMain (HINSTANCE hInstance, //应用程序当前实例的句柄
HINSTANCE hPrevInstance,//应用程序先前的实例句柄
PSTR szCmdLine,//指向应用程序命令行的字符串的指针
int iCmdShow)//指明窗口如何显示
{
static TCHAR szAppName[] = TEXT ("Colors2") ;
HWND         hwnd ;//消息
MSG          msg ;//定义句柄
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 (NULL, IDI_APPLICATION) ;//窗口的显示方式,这里采用应用程序类
wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;//鼠标的显示方式,此处设置为标准型
wndclass.hbrBackground = CreateSolidBrush (0) ;//窗口背景为白色
wndclass.lpszMenuName  = NULL ;//窗口菜单,此处为NULL
wndclass.lpszClassName = szAppName ;//窗口类名

if (!RegisterClass (&wndclass))//注册窗口,若注册失败,产生如下的信息
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}

//创建窗口,如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL
hwnd = CreateWindow (szAppName,
TEXT ("Color Scroll"),//窗口的名字
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,//窗口的创建风格
//其中WS_CLIPCHILDREN的意思就是当重绘主窗口时,其子窗口所在的区域不进行重绘
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:指窗口句柄

hDlgModeless = CreateDialog (hInstance, TEXT ("ColorScrDlg"),
hwnd, ColorScrDlg) ;
//CreateDialog创建非模态对话框,如果函数调用成功,则返回值为指向对话框的句柄;如果函数调用失败,则返回值为NULL
//第一个参数为当前应用程序实例句柄
//第一个参数为标识对话框模板资源,有两种使用方式:一种是把对话框模板的ID强制转为LPCTSTR,一种可以使用MAKEINTRESOURCE宏得到标识ID
//第三个参数为 父窗口的句柄
//第四个参数为 对话框消息处理函数

while (GetMessage (&msg, NULL, 0, 0))//消息循环
{
//由于非模态消息是放在当前程序消息队列中的,所以下面的if语句就是用来判断消息是否应该传送到非模态对话框里面
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
TranslateMessage (&msg) ;//该函数将虚拟键消息转换为字符消息
DispatchMessage  (&msg) ;//该函数分发一个消息给窗口程序
}
}
return msg.wParam ;//wParam是消息携带的参数,可以是个值,也可以是个地址
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY :
DeleteObject ((HGDIOBJ) SetClassLong (hwnd, GCL_HBRBACKGROUND,
(LONG) GetStockObject (WHITE_BRUSH))) ;
//DeleteObject函数删除一个与该对象有关的系统资源,
//参数为相应句柄

PostQuitMessage (0) ;//该函数向系统表明有个线程有终止请求。通常用来响应WM_DESTROY消息
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;//该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理
}

BOOL CALLBACK ColorScrDlg (HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
static int iColor[3] ;
HWND       hwndParent, hCtrl ;
int        iCtrlID, iIndex ;

switch (message)
{
case WM_INITDIALOG :
for (iCtrlID = 10 ; iCtrlID < 13 ; iCtrlID++)
{
hCtrl = GetDlgItem (hDlg, iCtrlID) ;//返回窗口中指定参数ID的子元素的句柄,hDlg是对话框窗口的句柄
SetScrollRange (hCtrl, SB_CTL, 0, 255, FALSE) ;//SetScrollRange函数设置所指定滚动条范围的最小值和最大值
//第一个参数为该滚动条的句柄
//第二个参数为滚动条类型
//第三四个参数分别为最大值和最小值
//第五个参数为重绘标志
SetScrollPos   (hCtrl, SB_CTL, 0, FALSE) ;//该函数设置所指定滚动条中的滚动按钮的位置
}
return TRUE ;

case WM_VSCROLL :
hCtrl   = (HWND) lParam ;//获取句柄
iCtrlID = GetWindowLong (hCtrl, GWL_ID) ;//GetWindowLong函数获得有关指定窗口的信息
//第一个参数为句柄
//第二个参数为获得窗口标识,具体参数请参考MSDN
iIndex  = iCtrlID - 10 ;
hwndParent = GetParent (hDlg) ;//获取父窗口的句柄

switch (LOWORD (wParam))
{
case SB_PAGEDOWN ://向下滚动一页
iColor[iIndex] += 15 ;// fall through
case SB_LINEDOWN ://向下滚动一行
iColor[iIndex] = min (255, iColor[iIndex] + 1) ;
break ;
case SB_PAGEUP ://向上滚动一页
iColor[iIndex] -= 15 ;        // fall through
case SB_LINEUP ://向上滚动一行
iColor[iIndex] = max (0, iColor[iIndex] - 1) ;
break ;
case SB_TOP ://滚动到顶端
iColor[iIndex] = 0 ;
break ;
case SB_BOTTOM ://滚动到底部
iColor[iIndex] = 255 ;
break ;
case SB_THUMBPOSITION ://用户有拖动滚动框 (滑块),并释放鼠标按钮
case SB_THUMBTRACK ://用户正在拖动滚动框
iColor[iIndex] = HIWORD (wParam) ;
break ;
default :
return FALSE ;
}
SetScrollPos  (hCtrl, SB_CTL,      iColor[iIndex], TRUE) ;//该函数设置所指定滚动条中的滚动按钮的位置
SetDlgItemInt (hDlg,  iCtrlID + 3, iColor[iIndex], FALSE) ;//该函数将第三个参数的值的值设为对话框控件的文本
//第一个参数为非模态控件的ID
//第二个参数为该静态文本区域的ID
//第三个参数指向要设置的值
//第四个参数的意思是要设置的值否为一个有符号的值

DeleteObject ((HGDIOBJ) SetClassLong (hwndParent, GCL_HBRBACKGROUND,
(LONG) CreateSolidBrush (
RGB (iColor[0], iColor[1], iColor[2])))) ;//释放滚动条资源

InvalidateRect (hwndParent, NULL, TRUE) ;//重绘窗口
return TRUE ;
}
return FALSE ;
}

这段代码有要注意的地方,那就是消息循环和以往不同,要用到if语句来判断该消息是该传送到对话框还是父窗口。

while (GetMessage (&msg, NULL, 0, 0))//消息循环
{
//由于非模态消息是放在当前程序消息队列中的,所以下面的if语句就是用来判断消息是否应该传送到非模态对话框里面
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
TranslateMessage (&msg) ;//该函数将虚拟键消息转换为字符消息
DispatchMessage  (&msg) ;//该函数分发一个消息给窗口程序
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: