/*----------------------------------------
POPMENU.C -- Popup Menu Demonstration
(c) Charles Petzold, 1998
----------------------------------------*/
#include
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;//首先是一个回调函数的声明
HINSTANCE hInst ;
TCHAR szAppName[] = TEXT ("PopMenu") ;//窗口名和菜单名
int WINAPI WinMain (HINSTANCE hInstance, //应用程序当前实例的句柄
HINSTANCE hPrevInstance,//应用程序先前的实例句柄
PSTR szCmdLine, //指向应用程序命令行的字符串的指针
int iCmdShow)//指明窗口如何显示
{
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 = (HBRUSH) GetStockObject (WHITE_BRUSH) ;//窗口背景颜色的设置,此处设置为白色
wndclass.lpszMenuName = NULL ;//窗口菜单,此处为NULL
wndclass.lpszClassName = szAppName ;//窗口类名
if (!RegisterClass (&wndclass))//注册窗口,若注册失败,产生如下的信息
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hInst = hInstance ;
创建窗口,如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL
hwnd = CreateWindow (szAppName, TEXT ("Popup Menu Demonstration"),//窗口的名字
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是消息携带的参数,可以是个值,也可以是个地址
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenu ;
static int idColor [5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH,
DKGRAY_BRUSH, BLACK_BRUSH } ;//定义了背景颜色的数组
static int iSelection = IDM_BKGND_WHITE ;//背景为白色的ID标识
POINT point ;
switch (message)
{
case WM_CREATE:
hMenu = LoadMenu (hInst, szAppName) ;//LoadMenu函数从与应用程序实例相联系的可执行文件(.EXE)中加载指定的菜单资源
//第一个参数为含有被加载菜单资源的实例模块的句柄。若此参数为NULL,则从当前实例中加载菜单
//第二个参数为指向含有菜单资源名的以空结束的字符串的指针
hMenu = GetSubMenu (hMenu, 0) ;//GetSubMenu函数取得被指定菜单激活的下拉式菜单或子菜单的句柄
//第一个参数为菜单句柄
//第二个参数为激活下拉式菜单或子菜单的菜单项相对于零的位置
return 0 ;
case WM_RBUTTONUP:
point.x = LOWORD (lParam) ;
point.y = HIWORD (lParam) ;//获取鼠标的位置
ClientToScreen (hwnd, &point) ;//ClientToScreen函数的功能:该函数将指定点,或者矩形的用户坐标转换成屏幕坐标
//第一个参数为窗口句柄
//第二个参数为点的结构体
TrackPopupMenu (hMenu, TPM_RIGHTBUTTON, point.x, point.y,
0, hwnd, NULL) ;
//TrackPopupMenu函数在指定位置显示快捷菜单,并跟踪菜单项的选择。快捷菜单可出现在屏幕上的任何位置
//第一个参数为菜单句柄
//TPM_RIGHTBUTTON:若设置此标志,用户能用鼠标左、右键选择菜单项
//第三第四个参数为点的位置
//第五个参数为保留值,必须为零
//第六个参数为拥有快捷菜单的窗口的句柄
//第七个参数为NULL
return 0 ;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDM_FILE_NEW:
case IDM_FILE_OPEN:
case IDM_FILE_SAVE:
case IDM_FILE_SAVE_AS:
case IDM_EDIT_UNDO:
case IDM_EDIT_CUT:
case IDM_EDIT_COPY:
case IDM_EDIT_PASTE:
case IDM_EDIT_CLEAR:
MessageBeep (0) ;//MessageBeep函数用来播放一个波形声音
return 0 ;
case IDM_BKGND_WHITE: // Note: Logic below
case IDM_BKGND_LTGRAY: // assumes that IDM_WHITE
case IDM_BKGND_GRAY: // through IDM_BLACK are
case IDM_BKGND_DKGRAY: // consecutive numbers in
case IDM_BKGND_BLACK: // the order shown here.
CheckMenuItem (hMenu, iSelection, MF_UNCHECKED) ;
//CheckMenuItem是一个API函数,功能是复选或撤消复选指定的菜单条目
//第一个参数为含有其菜单项的标志将被提取得的菜单的句柄
//第二个参数为要修改的菜单项
//第三个参数为相当于MF_CHECKED 的反作用,取消放置于菜单项旁边的标记
iSelection = LOWORD (wParam) ;//获取当前的背景颜色信息
CheckMenuItem (hMenu, iSelection, MF_CHECKED) ;
//MF_CHECKED功能为放置选取标记于菜单项旁边(只用于下拉式菜单、子菜单或快捷菜单)
SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG)
GetStockObject
(idColor [LOWORD (wParam) - IDM_BKGND_WHITE])) ;
//SetClassLong函数功能:该函数替换额外的类存储空间中指定偏移量处的32位长整型值,或替换指定窗口所属类的WNDCLASSEX结构
//第一个参数为窗口句柄及间接给出的窗口所属的类
//第二个参数为指定将被替换的32位值。GCL_HBRBACKGROUND:替换与类有关的背景刷子的句柄
//第三个参数为指定的替换值
InvalidateRect (hwnd, NULL, TRUE) ;//重画矩形
return 0 ;
case IDM_APP_ABOUT:
MessageBox (hwnd, TEXT ("Popup Menu Demonstration Program\n")
TEXT ("(c) Charles Petzold, 1998"),
szAppName, MB_ICONINFORMATION | MB_OK) ;//显示一个对话框
return 0 ;
case IDM_APP_EXIT:
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
//SendMessage函数将指定的消息发送到一个或多个窗口
//第一个参数的意思是发送窗口的句柄
//第二个是消息
//第三第四个为附加消息,一般为0
return 0 ;
case IDM_APP_HELP:
MessageBox (hwnd, TEXT ("Help not yet implemented!"),
szAppName, MB_ICONEXCLAMATION | MB_OK) ;//显示一个对话框
return 0 ;
}
break ;
case WM_DESTROY:
PostQuitMessage (0) ;//该函数向系统表明有个线程有终止请求。通常用来响应WM_DESTROY消息
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;//该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理
}