标签:定时器 菜单
二 定时器消息
1 定时器消息 WM_TIMER
按照定时器设置时间段,自动向窗口发送一个定时器消息WM_TIMER. 优先级比较低.
定时器精度比较低,毫秒级别.消息产生时间也精度比较低.
2 消息和函数
2.1 WM_TIMER - 消息ID
wParam: 定时器的ID
lParam: 定时器的处理函数
2.2 SetTimer - 设置一个定时器
UINT SetTimer(
HWND hWnd, //窗口的句柄,可以为NULL
UINT nIDEvent,//定时器的ID,0为不预设ID
UINT uElapse,//定时器时间间隔,毫秒级别
TIMERPROC lpTimerFunc );//定时器的处理函数,可以为NULL
返回一个创建好的定时器ID
2.3 KillTimer - 结束一个定时器
BOOL KillTimer(
HWND hWnd,//窗口句柄
UINT uIDEvent );//定时器ID
2.4 TimerProc - 定时器处理函数
VOID CALLBACK TimerProc(
HWND hwnd, //窗口句柄
UINT uMsg, //WM_TIMER消息ID
UINT idEvent,//定时器ID
DWORD dwTime );//当前系统时间
3 使用方式
3.1 创建定时器 SetTimer
3.1.1 指定窗口句柄HWND,那么 TIMERPROC 参数可以为空,那么WM_TIMER消息将会发送给指定窗口. 如果未指定, TIMERPROC不能空, 必须指定定时器处理程序.
3.1.2 如果指定定时器ID,SetTimer会按照这个ID创建定时器, 如果未指定,会返回一个创建定时器ID.
nTimerID = SetTimer( NULL, 0, 7 * 1000,TimerProc1 );
3.2 处理消息
可以根据消息传入定时器ID号,分别处理.
3.3 结束定时器
在不使用时, KillTimer结束定时器
/* File : winpaint.cpp
* Auth : sjin
* Date : 20140706
* Mail : 413977243@qq.com
*/
#include
#include
HINSTANCE g_hInst = NULL;
HANDLE g_hStdOut = NULL;
UINT g_nTimerID1 = 0;
/*定时器处理函数*/
void CALLBACK TimerProc1( HWND hWnd,
UINT nMsg,
UINT idEvent,
DWORD dwTime )
{
CHAR szText[] = "TimerProc1: Hello Timer\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
void OnCreate( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{
/*
UINT SetTimer(
HWND hWnd, //窗口的句柄,可以为NULL
UINT nIDEvent,//定时器的ID,0为不预设ID
UINT uElapse,//定时器时间间隔,毫秒级别
TIMERPROC lpTimerFunc );//定时器的处理函数,可以为NULL
return : 创建好的定时器的ID号
*/
//使用窗口处理函数,创建2个定时器
SetTimer( hWnd, 1000, 3 * 1000, NULL );
SetTimer( hWnd, 1001, 5 * 1000, NULL );
//使用窗口处理函数, 未指明定时器ID
g_nTimerID1 = SetTimer( hWnd, 0, 2* 1000, NULL );
//使用TimerProc处理函数创建定时器
//SetTimer( hWnd, 1002, 7 * 1000, TimerProc1 );
SetTimer( hWnd, 1002, 7 * 1000, NULL );
}
void OnTimer( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{
switch( wParam )
{
case 1000:
{
CHAR szText[] = "1000: Hello Timer\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
case 1001:
{
CHAR szText[] = "1001: Hello Timer\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
case 1002:/*1002 设置相应的处理函数,不会在这里调用*/
{
CHAR szText[] = "1002: Hello Timer\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
default:
{
CHAR szText[260] = {0};
sprintf( szText, "%d: Hello Timer\n",
g_nTimerID1 );
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
}
}
LRESULT CALLBACK WndProc( HWND hWnd,
UINT nMsg,
WPARAM wParam,
LPARAM lParam )
{
switch( nMsg )
{
case WM_CREATE:
OnCreate( hWnd, nMsg, wParam, lParam );
break;
case WM_TIMER:/*处理定时器事件,没有设置定时器回调函数的*/
OnTimer( hWnd, nMsg, wParam, lParam );
break;
case WM_DESTROY:
/*销毁定时器
BOOL KillTimer(
HWND hWnd,//窗口句柄
UINT uIDEvent );//定时器ID
*/
KillTimer( hWnd, 1000 );
KillTimer( hWnd, 1001 );
KillTimer( hWnd, 1002 );
KillTimer( hWnd, g_nTimerID1 );
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, nMsg,
wParam, lParam );
}
BOOL RegisterWnd( LPSTR pszClassName )
{
WNDCLASSEX wce = { 0 };
wce.cbSize = sizeof( wce );
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hbrBackground = HBRUSH(COLOR_WINDOW);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce.hInstance = g_hInst;
wce.lpfnWndProc = WndProc;
wce.lpszClassName = pszClassName;
wce.lpszMenuName = NULL;
wce.style = CS_VREDRAW|CS_HREDRAW;
ATOM nAtom = RegisterClassEx( &wce );
if( 0 == nAtom )
{
return FALSE;
}
return TRUE;
}
HWND CreateWnd( LPSTR pszClassName )
{
HWND hWnd = CreateWindowEx( 0,
pszClassName, "MyWnd",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL,
g_hInst, 0 );
return hWnd;
}
void DisplayWnd( HWND hWnd )
{
ShowWindow( hWnd, SW_SHOW );
UpdateWindow( hWnd );
}
void Message( )
{
MSG msg = {0};
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
void NewConsole()
{
/*产生控制台*/
AllocConsole();
/*获得控制台标准输出流句柄*/
g_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
CHAR szText[] = "Debug Message......:\n";
/*将szText 写到控制台*/
WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
NewConsole( );
g_hInst = hInstance;
RegisterWnd( "MYWND" );
HWND hWnd = CreateWnd( "MYWND" );
DisplayWnd( hWnd );
Message( );
return 0;
}
二 菜单
1 菜单基础
菜单 - 每个菜单会有一个HMENU句柄
菜单项 - 每个菜单项会有一个ID号,可以根据这个ID执行不同的操作
2 菜单的使用
2.1 菜单创建
2.1.1 CreateMenu - MENU 菜单
2.1.2 CreatePopupMenu - POPUPMENU 弹出式菜单
2.1.3 AppenedMenu - 增加菜单项
BOOL AppendMenu(
HMENU hMenu, //菜单句柄
UINT uFlags, //菜单项标示
UINT uIDNewItem, //菜单项的ID或者子菜单句柄
LPCTSTR lpNewItem ); //菜单项的名称
uFlags:
MF_STRING - lpNewItem是一个字符串
MF_POPUP - uIDNewItem是一个子菜单句柄
MF_SEPARATOR - 增加分隔项
MF_CHECKED/MF_UNCHECKED - 设置和取消菜单项的对勾
MF_DISABLED/MF_ENABLE - 菜单项禁止和允许状态
2.2 菜单的命令响应
2.2.1 WM_COMMAND消息
当用户点击菜单、按钮控件等时,系统会向窗口发送WM_COAMMD消息。
WPARAM:HIWORD - 通知消息标识
LOWORD - 菜单项的ID号
LPARAM:控件的句柄
2.2.2 命令处理
根据菜单项的ID号作相应处理。
2.3 菜单项的状态
2.3.1 WM_INITMENUPOPUP消息
当用户点击菜单,显示弹出菜单之前,系统会向窗口发送WM_INITMENUPOPUP消息。
WPARAM:是菜单句柄
LPARAM:LOWORD - 菜单位置
HIWORD - 是否是系统菜单
2.3.2 命令处理
根据WPARAM的菜单句柄,使用MenuAPI函数,修改菜单状态。
CheckMenuItem - 选择
EnableMenuItem - 允许和禁止
SetMenuItemInfo - 可以设置更多信息
/* File : winMenu.cpp
* Auth : sjin
* Date : 20140706
* Mail : 413977243@qq.com
*/
#include
#include
HINSTANCE g_hInst = NULL;
HANDLE g_hStdOut = NULL;
BOOL g_bCheckCut = FALSE;
void OnCreate( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{ //创建主菜单
HMENU hMainMenu = CreateMenu( );
//创建子菜单
HMENU hFileMenu = CreatePopupMenu( );
//增加菜单项 (&N) 增加快捷键ALT+N)
AppendMenu( hFileMenu, MF_STRING|MF_CHECKED, 1001, "新建(&N)");
/*增加分割线的标示*/
AppendMenu( hFileMenu, MF_SEPARATOR, 0, NULL );
AppendMenu( hFileMenu, MF_STRING, 1002, "退出(&X)");
AppendMenu( hMainMenu, MF_STRING|MF_POPUP,
(UINT)hFileMenu, "文件(&F)");
HMENU hEditMenu = CreatePopupMenu( );
AppendMenu( hEditMenu, MF_STRING, 1003, "剪切(&T)" );
/*增加分割线的标示*/
AppendMenu( hEditMenu, MF_SEPARATOR, 0, NULL );
AppendMenu( hEditMenu, MF_STRING, 1004, "拷贝(&C)" );
/*增加分割线的标示*/
AppendMenu( hEditMenu, MF_SEPARATOR, 0, NULL );
AppendMenu( hEditMenu, MF_STRING, 1005, "粘贴(&P)" );
AppendMenu( hMainMenu, MF_STRING|MF_POPUP,
(UINT)hEditMenu, "编辑(&E)");
HMENU hHelpMenu = CreatePopupMenu( );
AppendMenu( hHelpMenu, MF_STRING, 1006, "帮助(&H)" );
/*增加分割线的标示*/
AppendMenu( hHelpMenu, MF_SEPARATOR, 0, NULL );
AppendMenu( hHelpMenu, MF_STRING, 1007, "关于(&A)" );
AppendMenu( hMainMenu, MF_STRING|MF_POPUP,
(UINT)hHelpMenu, "帮助(&H)");
//给窗口设置主菜单
SetMenu( hWnd, hMainMenu );
}
void OnCommand( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{
/*wParam: HIWORD: 通知消息的标示
* LOWORD:菜单项的ID
* lParam: 控件的句柄
* 对菜单来说这个为NULL
* 对其他控件(按钮等)为句柄
*/
UINT nID = LOWORD( wParam );
CHAR szText[260] = {0};
sprintf( szText, "OnCommand: %d\n",
nID );
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
/*菜单项的处理*/
switch( nID )
{
case 1002:/*退出*/
PostQuitMessage( 0 );
break;
case 1003:
g_bCheckCut = !g_bCheckCut;
break;
}
}
void OnInitMenuPopup( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{
CHAR szText[260] = { 0 };
sprintf( szText,
"OnInitMenuPopup: WPARAM=%08X, LPARAM=%08X\n",
wParam, lParam );
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
HMENU hMenu = (HMENU)wParam;
if( TRUE == g_bCheckCut )
{
/*CheckMenuItem是一个API函数,功能是复选或撤消复选指定的菜单条目*/
CheckMenuItem( hMenu, 1003,
MF_CHECKED|MF_BYCOMMAND );
}
else
{
CheckMenuItem( hMenu, 1003,
MF_UNCHECKED|MF_BYCOMMAND );
}
}
LRESULT CALLBACK WndProc( HWND hWnd,
UINT nMsg,
WPARAM wParam,
LPARAM lParam )
{
switch( nMsg )
{
case WM_CREATE:
OnCreate( hWnd, nMsg, wParam, lParam );
break;
/*用户点击菜单、按钮控件等时,系统会想窗口发送WM_COAMMD消息*/
case WM_COMMAND:
OnCommand( hWnd, nMsg, wParam, lParam );
break;
/*用户点击菜单,显示弹出菜单之前,系统会向窗口发送WM_INITMENUPOPUP消息
*用于更新菜单项的状态
*/
case WM_INITMENUPOPUP:
OnInitMenuPopup( hWnd, nMsg, wParam, lParam );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, nMsg,
wParam, lParam );
}
BOOL RegisterWnd( LPSTR pszClassName )
{
WNDCLASSEX wce = { 0 };
wce.cbSize = sizeof( wce );
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hbrBackground = HBRUSH(COLOR_WINDOW);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce.hInstance = g_hInst;
wce.lpfnWndProc = WndProc;
wce.lpszClassName = pszClassName;
wce.lpszMenuName = NULL;
wce.style = CS_VREDRAW|CS_HREDRAW;
ATOM nAtom = RegisterClassEx( &wce );
if( 0 == nAtom )
{
return FALSE;
}
return TRUE;
}
HWND CreateWnd( LPSTR pszClassName )
{
HWND hWnd = CreateWindowEx( 0,
pszClassName, "MyWnd",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL,
g_hInst, 0 );
return hWnd;
}
void DisplayWnd( HWND hWnd )
{
ShowWindow( hWnd, SW_SHOW );
UpdateWindow( hWnd );
}
void Message( )
{
MSG msg = {0};
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
void NewConsole( )
{
AllocConsole( );
g_hStdOut =
GetStdHandle( STD_OUTPUT_HANDLE );
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
NewConsole( );
g_hInst = hInstance;
RegisterWnd( "MYWND_MENU" );
HWND hWnd = CreateWnd( "MYWND_MENU" );
DisplayWnd( hWnd );
Message( );
return 0;
}
走进windows编程的世界-----消息处理函数(3),搜素材,soscw.com
走进windows编程的世界-----消息处理函数(3)
标签:定时器 菜单
原文地址:http://blog.csdn.net/sjin_1314/article/details/37518361