Win32编程day06 学习笔记
一 系统菜单
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;
- }
- // SysMenu.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- #include "stdio.h"
- HINSTANCE g_hInst = NULL;
- HANDLE g_hStdOut = NULL;
- void OnCreate( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- { // 获取系统菜单
- HMENU hSysMenu =
- GetSystemMenu( hWnd, FALSE );
- // 删除菜单项
- 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_OK );
- break;
- case 1002:
- MessageBox( NULL, "Hello 1002",
- "SysMenu", MB_OK );
- 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 右键菜单
当在窗口点击鼠标右键时,弹出的菜单。
2 右键菜单的使用
2.1 创建菜单
CreatePopupMenu
2.2 菜单增加
AppendMenu
2.3 菜单的显示
- BOOL TrackPopupMenu(
- HMENU hMenu, //显示的菜单句柄
- UINT uFlags, //显示的方式
- int x, //菜单的X屏幕坐标
- int y, //菜单的Y屏幕坐标
- int nReserved, //保留,必须为0
- HWND hWnd, //处理菜单命令的窗口句柄
- CONST RECT *prcRect ); //忽略
2.4 菜单的命令处理
WM_COMMAND
2.5 使用右键菜单的位置
2.5.1 WM_RBUTTONUP 消息
在WM_RBUTTONUP中,添加菜单的创建及显示,
右键消息坐标,转换成屏幕坐标使用.
ClientToScreen.
2.5.2 WM_CONTEXTMENU 消息
用于显示右键的菜单的消息.
WPARAM – 右键抬起时对应窗口句柄
LPARAM – 右键抬起时鼠标的屏幕坐标位置
LOWORD(lParam) – X屏幕坐标
HIWORD(lParam) – Y屏幕坐标
2.5.3 WM_RBUTTONUP和WM_CONTEXTMENU对比
1) 坐标系不同, WM_RBUTTONUP客户区坐标,WM_CONTEXTMENU屏幕坐标
2) 先有WM_RBUTTONUP消息,后有WM_CONTEXTMENU消息
- // PopMenu.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- HINSTANCE g_hInst = NULL;
- void OnRButtonUp( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- { // 创建弹出式菜单
- HMENU hPopMenu = CreatePopupMenu( );
- // 增加菜单项
- AppendMenu( hPopMenu, MF_STRING, 1001, "测试1");
- AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
- AppendMenu( hPopMenu, MF_STRING, 1002, "退出");
- // 获取菜单位置
- POINT point = { 0 };
- point.x = LOWORD( lParam );
- point.y = HIWORD( lParam );
- ClientToScreen( hWnd, &point );
- // 显示菜单
- TrackPopupMenu( hPopMenu, TPM_LEFTALIGN,
- point.x, point.y, 0, hWnd, NULL );
- }
- void OnContextMenu( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- { // 创建弹出式菜单
- HMENU hPopMenu = CreatePopupMenu( );
- // 增加菜单项
- AppendMenu( hPopMenu, MF_STRING, 1001, "测试2");
- AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL );
- AppendMenu( hPopMenu, MF_STRING, 1002, "退出");
- // 坐标获取
- int nX = LOWORD( lParam );
- int nY = HIWORD( lParam );
- // 显示菜单
- TrackPopupMenu( hPopMenu, TPM_LEFTALIGN,
- nX, nY, 0, hWnd, NULL );
- // 删除菜单
- DestroyMenu( hPopMenu );
- }
- void OnCommand( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- {
- int nCmdID = LOWORD( wParam );
- switch( nCmdID )
- {
- case 1001:
- MessageBox( NULL, "Hello Popmenu",
- "PopMenu", MB_OK );
- break;
- case 1002:
- PostQuitMessage( 0 );
- break;
- }
- }
- LRESULT CALLBACK WndProc( HWND hWnd,
- UINT nMsg,
- WPARAM wParam,
- LPARAM lParam )
- {
- switch( nMsg )
- {
- case WM_RBUTTONUP:
- //OnRButtonUp( hWnd, nMsg, wParam, lParam );
- break;
- case WM_CONTEXTMENU:
- OnContextMenu( hWnd, nMsg, wParam, lParam );
- break;
- case WM_COMMAND:
- OnCommand( 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 );
- }
- }
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- g_hInst = hInstance;
- RegisterWnd( "MYWND" );
- HWND hWnd = CreateWnd( "MYWND" );
- DisplayWnd( hWnd );
- Message( );
- return 0;
- }
三 资源的使用
1 资源文件
图标、光标、字符串、菜单、加速键和对话框资源,位图资源等等。
资源脚本文件 – 扩展名为RC文件。定义了资源和相关文件等等信息。
资源编译器 – RC.exe
2 图标资源ICON
2.1 常用的几种大小: 16X16, 32X32,48X48
2.2 使用
HICON LoadIcon(
HINSTANCE hInstance, //应用程序的句柄
LPCTSTR lpIconName );//图标的ID字符串
2.3 系统提供的图标
hInstance为空, lpIconName为定义的系统图标.
2.4 自己绘制的图标
hInstance为图标所在的应用程序的实例句柄
2.5 注意点:
一个图标文件中,可以包含多种大小、颜色不同的图标,系统使用图标时,通过大小来匹配,如果未找到大小完全一致的,那么会使用大小最接近的图标格式替换。
3 光标资源
3.1 光标资源
热点 Hotspot – 可以产生鼠标点击的位置
3.2 使用
HCURSOR LoadCursor(
HINSTANCE hInstance, //应用程序实例句柄
LPCTSTR lpCursorName); //光标的ID
3.3 系统的光标
hInstance为空,lpCursorName指定为系统的光标即可获得
3.4 自绘制的光标
hInstance不能为空。
3.5 WM_SETCURSOR消息
当鼠标在窗口内就会产生。可以在程序执行的过程中修改鼠标样式。
wParam – 窗口句柄;
LOWORD(lParam) – 所在位置的标识
HIWORD(lParam) – 鼠标的消息ID
SetCursour 设置当前窗口的光标
- // WinRes.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- #include "resource.h"
- HINSTANCE g_hInst = NULL;
- BOOL OnSetCursor( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- {
- int nHitTest = LOWORD( lParam );
- if( HTCLIENT != nHitTest )
- {
- return FALSE;
- }
- //获得窗口的客户区
- RECT rcClient = { 0 };
- GetClientRect( hWnd, &rcClient );
- //获得当前光标的位置
- POINT ptPos = { 0 };
- GetCursorPos( &ptPos );
- ScreenToClient( hWnd, &ptPos );
- //根据位置加载光标
- HCURSOR hCursor = NULL;
- if( ptPos.x < rcClient.right/2 )
- {
- if( ptPos.y < rcClient.bottom/2 )
- {
- hCursor = LoadCursor( NULL, IDC_SIZEALL );
- }
- else
- {
- hCursor = LoadCursor( NULL, IDC_CROSS );
- }
- }
- else
- {
- if( ptPos.y < rcClient.bottom/2 )
- {
- hCursor = LoadCursor( NULL, IDC_WAIT );
- }
- else
- {
- hCursor = LoadCursor( NULL, IDC_UPARROW );
- }
- }
- // 设置光标
- SetCursor( hCursor );
- return TRUE;
- }
- LRESULT CALLBACK WndProc( HWND hWnd,
- UINT nMsg,
- WPARAM wParam,
- LPARAM lParam )
- {
- switch( nMsg )
- {
- case WM_SETCURSOR:
- if( TRUE == OnSetCursor( hWnd, nMsg,
- wParam, lParam ) )
- {
- return 0;
- }
- 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 =
- LoadCursor( g_hInst, MAKEINTRESOURCE(IDC_CURSOR1) );
- wce.hIcon =
- LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_MAIN) );
- 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 );
- }
- }
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- g_hInst = hInstance;
- RegisterWnd( "MYWND" );
- HWND hWnd = CreateWnd( "MYWND" );
- DisplayWnd( hWnd );
- Message( );
- return 0;
- }
4 字符串资源
4.1 包含字符串的资源
4.2 使用
int LoadString(
HINSTANCE hInstance,//程序句柄
UINT uID, //字符串资源的ID
LPTSTR lpBuffer, //存放字符串的BUFF
int nBufferMax ); //BUFF的大小
返回获取字符串的长度
5 菜单资源
5.1 添加菜单资源
5.2 加载菜单资源
HMENU LoadMenu(
HINSTANCE hInstance, //应用程序句柄
LPCTSTR lpMenuName );//菜单ID字符串
返回加载成功的菜单的句柄
5.3 命令处理
使用添加的菜单ID的宏,在WM_COMMAND消息中,处理菜单命令.
- // WinRes.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- #include "resource.h"
- HINSTANCE g_hInst = NULL;
- BOOL OnSetCursor( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- { //判断是否是位于客户区之上
- int nHitTest = LOWORD( lParam );
- if( HTCLIENT != nHitTest )
- { //不在客户区,返回FALSE,
- //让DefWindowProc处理
- return FALSE;
- }
- //获得窗口的客户区
- RECT rcClient = { 0 };
- GetClientRect( hWnd, &rcClient );
- //获得当前光标的位置
- POINT ptPos = { 0 };
- GetCursorPos( &ptPos );
- ScreenToClient( hWnd, &ptPos );
- //根据位置加载光标
- HCURSOR hCursor = NULL;
- if( ptPos.x < rcClient.right/2 )
- {
- if( ptPos.y < rcClient.bottom/2 )
- {
- hCursor = LoadCursor( NULL, IDC_SIZEALL );
- }
- else
- {
- hCursor = LoadCursor( NULL, IDC_CROSS );
- }
- }
- else
- {
- if( ptPos.y < rcClient.bottom/2 )
- {
- hCursor = LoadCursor( NULL, IDC_WAIT );
- }
- else
- {
- hCursor = LoadCursor( NULL, IDC_UPARROW );
- }
- }
- // 设置光标
- SetCursor( hCursor );
- return TRUE;
- }
- void OnCommand( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- {
- int nCmdID = LOWORD( wParam );
- switch( nCmdID )
- {
- case ID_EXIT:
- PostQuitMessage( 0 );
- break;
- case ID_ABOUT:
- break;
- }
- }
- LRESULT CALLBACK WndProc( HWND hWnd,
- UINT nMsg,
- WPARAM wParam,
- LPARAM lParam )
- {
- switch( nMsg )
- {
- case WM_COMMAND:
- OnCommand( hWnd, nMsg, wParam, lParam );
- break;
- case WM_SETCURSOR:
- if( TRUE == OnSetCursor( hWnd, nMsg,
- wParam, lParam ) )
- {
- return 0;
- }
- 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 =
- LoadCursor( g_hInst, MAKEINTRESOURCE(IDC_CURSOR1) );
- wce.hIcon =
- LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_MAIN) );
- 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 )
- {
- //加载字符串资源
- CHAR szText[260] = { 0 };
- LoadString( g_hInst, IDS_MAIN, szText, 260 );
- //加载菜单
- HMENU hMenu = LoadMenu( g_hInst,
- MAKEINTRESOURCE(IDR_MAIN) );
- //创建窗口
- HWND hWnd = CreateWindowEx( 0,
- pszClassName, szText,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, NULL, hMenu, 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 );
- }
- }
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- g_hInst = hInstance;
- RegisterWnd( "MYWND" );
- HWND hWnd = CreateWnd( "MYWND" );
- DisplayWnd( hWnd );
- Message( );
- return 0;
- }
6 加速键资源
6.1 加速键的作用
可以使用加速键执行命令. 例如Ctrl+S存盘.
6.2 加速键资源的添加
6.3 加速键的使用
6.3.1 加载
HACCEL LoadAccelerators(
HINSTANCE hInstance,//资源所在的应用程序句柄
LPCTSTR lpTableName ); //加速键表的ID字符串
加载成功返回加速键表的句柄
6.3.2 增加消息处理
- int TranslateAccelerator(
- HWND hWnd, //处理加速键的窗口句柄
- HACCEL hAccTable, //加速键表
- LPMSG lpMsg );//MSG结构的地址
6.4 关于加速键的消息
TranslateAccelerator的作用是将WM_KEYDOWN或者WM_SYSKEYDOWN消息,翻译成WM_COMMAND或者WM_SYSCOMMAND消息.
当收到KEYDOWN或者SYSKEYDOWN的消息时,会根据加速键表中按键和命令ID对应关系,找到相应的命令ID,然后调用窗口处理函数,执行WM_COMMAND或者WM_SYSCOMMAND消息.
当找到对应命令ID并执行后,TranslateAccelerator返回非零,那么就不再执行后续的处理,消息循环等候下一条消息。否则,继续让消息循环中的TansnlateMessage和DispatchMessage处理。
- // WinRes.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- #include "resource.h"
- HINSTANCE g_hInst = NULL;
- BOOL OnSetCursor( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- { //判断是否是位于客户区之上
- int nHitTest = LOWORD( lParam );
- if( HTCLIENT != nHitTest )
- { //不在客户区,返回FALSE,
- //让DefWindowProc处理
- return FALSE;
- }
- //获得窗口的客户区
- RECT rcClient = { 0 };
- GetClientRect( hWnd, &rcClient );
- //获得当前光标的位置
- POINT ptPos = { 0 };
- GetCursorPos( &ptPos );
- ScreenToClient( hWnd, &ptPos );
- //根据位置加载光标
- HCURSOR hCursor = NULL;
- if( ptPos.x < rcClient.right/2 )
- {
- if( ptPos.y < rcClient.bottom/2 )
- {
- hCursor = LoadCursor( NULL, IDC_SIZEALL );
- }
- else
- {
- hCursor = LoadCursor( NULL, IDC_CROSS );
- }
- }
- else
- {
- if( ptPos.y < rcClient.bottom/2 )
- {
- hCursor = LoadCursor( NULL, IDC_WAIT );
- }
- else
- {
- hCursor = LoadCursor( NULL, IDC_UPARROW );
- }
- }
- // 设置光标
- SetCursor( hCursor );
- return TRUE;
- }
- void OnCommand( HWND hWnd, UINT nMsg,
- WPARAM wParam, LPARAM lParam )
- {
- int nCmdID = LOWORD( wParam );
- switch( nCmdID )
- {
- case ID_EXIT:
- PostQuitMessage( 0 );
- break;
- case ID_ABOUT:
- break;
- }
- }
- LRESULT CALLBACK WndProc( HWND hWnd,
- UINT nMsg,
- WPARAM wParam,
- LPARAM lParam )
- {
- switch( nMsg )
- {
- case WM_COMMAND:
- OnCommand( hWnd, nMsg, wParam, lParam );
- break;
- case WM_SETCURSOR:
- if( TRUE == OnSetCursor( hWnd, nMsg,
- wParam, lParam ) )
- {
- return 0;
- }
- 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 =
- LoadCursor( g_hInst, MAKEINTRESOURCE(IDC_CURSOR1) );
- wce.hIcon =
- LoadIcon( g_hInst, MAKEINTRESOURCE(IDI_MAIN) );
- 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 )
- {
- //加载字符串资源
- CHAR szText[260] = { 0 };
- LoadString( g_hInst, IDS_MAIN, szText, 260 );
- //加载菜单
- HMENU hMenu = LoadMenu( g_hInst,
- MAKEINTRESOURCE(IDR_MAIN) );
- //创建窗口
- HWND hWnd = CreateWindowEx( 0,
- pszClassName, szText,
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, NULL, hMenu, g_hInst,
- NULL );
- return hWnd;
- }
- void DisplayWnd( HWND hWnd )
- {
- ShowWindow( hWnd, SW_SHOW );
- UpdateWindow( hWnd );
- }
- void Message( HWND hWnd )
- {
- //加载加速键表
- HACCEL hAccel = LoadAccelerators(
- g_hInst, MAKEINTRESOURCE(IDR_ACCEL) );
- //消息循环
- MSG msg = { 0 };
- while( GetMessage( &msg, NULL, 0, 0 ) )
- { // 增加加速键的消息处理
- if( !TranslateAccelerator( hWnd, hAccel, &msg ) )
- { //字符消息处理
- TranslateMessage( &msg );
- //消息派发
- DispatchMessage( &msg );
- }
- }
- }
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- g_hInst = hInstance;
- RegisterWnd( "MYWND" );
- HWND hWnd = CreateWnd( "MYWND" );
- DisplayWnd( hWnd );
- Message( hWnd );
- return 0;
- }
四 程序编写
1 定时器设置
实现定时器的关闭和打开
代码如下,这个是新建一个win32程序,选择简单的hello word程序。和之前的有点小不一样。
- // WinCase.cpp : Defines the entry point for the application.
- //
- #include "stdafx.h"
- #include "resource.h"
- #define MAX_LOADSTRING 100
- // Global Variables:
- HINSTANCE hInst; // current instance
- TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
- TCHAR szWindowClass[MAX_LOADSTRING];
- int g_nX = 0;
- int g_nY = 0; // The title bar text
- // Foward declarations of functions included in this code module:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- // TODO: Place code here.
- MSG msg;
- HACCEL hAccelTable;
- // Initialize global strings
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_WINCASE, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- // Perform application initialization:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WINCASE);
- // Main message loop:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return msg.wParam;
- }
- //
- // FUNCTION: MyRegisterClass()
- //
- // PURPOSE: Registers the window class.
- //
- // COMMENTS:
- //
- // This function and its usage is only necessary if you want this code
- // to be compatible with Win32 systems prior to the \'RegisterClassEx\'
- // function that was added to Windows 95. It is important to call this function
- // so that the application will get \'well formed\' small icons associated
- // with it.
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = (WNDPROC)WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WINCASE);
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = (LPCSTR)IDC_WINCASE;
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
- return RegisterClassEx(&wcex);
- }
- //
- // FUNCTION: InitInstance(HANDLE, int)
- //
- // PURPOSE: Saves instance handle and creates main window
- //
- // COMMENTS:
- //
- // In this function, we save the instance handle in a global variable and
- // create and display the main program window.
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // Store instance handle in our global variable
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return FALSE;
- }
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return TRUE;
- }
- //
- // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
- //
- // PURPOSE: Processes messages for the main window.
- //
- // WM_COMMAND - process the application menu
- // WM_PAINT - Paint the main window
- // WM_DESTROY - post a quit message and return
- //
- //
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- TCHAR szHello[MAX_LOADSTRING];
- LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
- switch (message)
- {
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // Parse the menu selections:
- switch (wmId)
- {
- case ID_BEGIN:
- SetTimer( hWnd, 1001, 1 * 1000, NULL );
- break;
- case ID_STOP:
- KillTimer( hWnd, 1001 );
- break;
- case IDM_ABOUT:
- DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
- break;
- case IDM_EXIT:
- DestroyWindow(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
- case WM_PAINT:
- {
- hdc = BeginPaint(hWnd, &ps);
- CHAR szText[] = "Hello Ball";
- TextOut( hdc, g_nX, g_nY, szText,
- strlen(szText) );
- EndPaint(hWnd, &ps);
- }
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- case WM_TIMER:
- g_nX += 5;
- g_nY += 5;
- InvalidateRect( hWnd, NULL, TRUE );
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
- // Mesage handler for about box.
- LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return TRUE;
- }
- break;
- }
- return FALSE;
- }