二 定时器消息

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 <Windows.h>
#include <stdio.h> 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消息
       当用户点击菜单、button控件等时,系统会向窗体发送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 <Windows.h>
#include <stdio.h> 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
* 对其它控件(button等)为句柄
*/
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; /*用户点击菜单、button控件等时,系统会想窗体发送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;
}

三 系统菜单

1 运行系统提供的窗体命令。比如最大化、关闭等命令。本质上和普通菜单一样,所以我们也能够在程序中使用这个菜单
    
  2 系统菜单的使用
    2.1 获取系统菜单
       GetSystemMenu

 HMENU GetSystemMenu(
HWND hWnd, //要获取的窗体句柄
BOOL bRevert //获取时重置标示
);

bRevert: TRUE 重置 FLASE 不重置
    当Revert为TRUE时。会将菜单又一次置成默认的状态,并返回菜单句柄。假设为FALSE,菜单项不重置,获取到当前系统菜单的状态。

2.2 改动系统菜单,比如添加、删除
       2.2.1 AppednMenu
       2.2.2 InsertMenu 
         比AppednMenu添加了一个插入菜单项的位置或ID。
       2.2.3 删除菜单项

  BOOL RemoveMenu( //
HMENU hMenu, //菜单句柄
UINT uPosition,//菜单项的位置或ID
UINT uFlags );//菜单项的位置或ID的标示。

uFlags为MF_BYCOMMAND, uPosition为菜单ID
    uFlags为MF_BYPOSITION,uPosition为菜单位置

2.3 系统菜单的命令响应
       系统菜单的命令响应。是在WM_SYSCOMMAND中。

WPARAM - LOWORD(wParam)为添加的菜单的ID

     int nID = LOWORD( wParam );
switch( nID )
{
case 1001:
//...
break;
}

/* File : winMenu.cpp
* Auth : sjin
* Date : 20140706
* Mail : 413977243@qq.com
*/ #include <Windows.h>
#include <stdio.h> HINSTANCE g_hInst = NULL;
HANDLE g_hStdOut = NULL; void OnCreate( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{
/* 获取系统菜单
* HMENU GetSystemMenu(
* HWND hWnd, //要获取的窗体句柄
* BOOL bRevert //获取时重置标示
* );
* bRevert : TRUE时,菜单会重置为默认状态
* FALSE: 菜单不重置获得当前系统的菜单状态
*/
HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
/*删除菜单项
* BOOL RemoveMenu( //
* HMENU hMenu, //菜单句柄
* UINT uPosition,//菜单项的位置或ID
* UINT uFlags );//菜单项的位置或ID的标示
* uFlags为MF_BYCOMMAND, uPosition为菜单ID
* uFlags为MF_BYPOSITION,uPosition为菜单位置
*/
RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
// 添加菜单项
InsertMenu( hSysMenu, 0, MF_BYPOSITION|MF_STRING,
1001, "測试1" );
InsertMenu( hSysMenu, 1, MF_BYPOSITION|MF_STRING,
1002, "測试2" );
} void OnSysCommand( HWND hWnd, UINT nMsg,
WPARAM wParam, LPARAM lParam )
{
CHAR szText[260] = { 0 };
sprintf( szText,
"OnSysCommand: WPARAM=%08X,LPARAM=%08X\n",
wParam, lParam );
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL ); int nID = LOWORD( wParam );
switch( nID )
{
case 1001:
MessageBox( NULL, "Hello 1001", "SysMenu", MB_CANCELTRYCONTINUE );
break;
case 1002:
MessageBox( NULL, "Hello 1002", "SysMenu", MB_OK );
break;
default:
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_SYSCOMMAND:/*系统菜单命令响应*/
OnSysCommand( 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_HREDRAW|CS_VREDRAW; 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,
NULL );
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" );
HWND hWnd = CreateWnd( "MYWND" );
DisplayWnd( hWnd );
Message( );
return 0;
}

最新文章

  1. js数据类型
  2. 百度地图API示例之移动地图
  3. Handler知识点详解
  4. Matlab神经网络工具箱学习之一
  5. Android反向工程需要的几个软件
  6. Win32非递归遍历和搜索文件以及目录算法
  7. uvalive 3890 Most Distant Point from the Sea
  8. jna 使用实例,
  9. SQL脚本小笔记
  10. AJAX实例入门
  11. HDU1027 Ignatius and the Princess II 【next_permutation】【DFS】
  12. php中如何开启GD库
  13. (札记)Java应用架构设计-模块化模式与OSGi
  14. View学习(一)-DecorView,measureSpec与LayoutParams
  15. Jenkins : 邮件通知
  16. windows压缩图片
  17. A. Many Equal Substrings(水题)
  18. 【洛谷】3953:逛公园【反向最短路】【记忆化搜索(DP)统计方案】
  19. 3.4 Templates -- Displaying A List of Items(展示一个集合)
  20. 使用binlog日志还原数据详解

热门文章

  1. hdu 1598(最小生成树)
  2. ros navigation stack---move_base
  3. 第五步:Lucene创建索引
  4. Python与正则表达式[0] -&gt; re 模块的正则表达式匹配
  5. Java线程同步:synchronized锁住的是代码还是对象
  6. java多线程设计模式(3)读写锁模式
  7. JAVA实现通用日志记录
  8. NSPredicate谓词查询
  9. eclipse中jar包打断点
  10. Linux用户配置sudo权限(visudo)