对于用MFC写程序的人来说会觉得菜单很简单 直接用 APP wizard生成就行了 消息处理也是 由MFC来完成 实际上根本不知道 菜单的原理 下面就介绍下如何在 SDK写的程序中添加菜单 我所使用的环境是 VC6.0
首先 SDK下我们需要手动加入菜单资源 点击 Project ->Add to Project -->new 新建一个 资源脚本 Resource Script 我们 Insert一个菜单资源 其他操作喝MFC一样
但是在 程序的开头要加上 #include "resource.h" 包含我们所创建的资源文件 ,然后在窗口 过程函数中做出相应的捕获 菜单的消息是 WM_COMMAND 然后我们在
根据 消息 附加参数 wParam来确定菜单的ID号 其实SDK的设计 就是这样 一个 WainMain函数喝一个窗口过程 就完成了
#include <windows.h>
#include <stdio.h>
#include "WINUSER.H"
#include "resource.h" //必须要加载 资源头文件 在SDK中women应该自己加入 菜单资源 对于菜单的消息是 WM_COMMAND
LRESULT CALLBACK WinProc( //窗口回调函数的声明
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(
HINSTANCE hInstance, // 当前实例的句柄
HINSTANCE hPrevInstance, //先前实例的一个句柄
LPSTR lpCmdLine, // 命令行
int nCmdShow // 显示状态
)
{
WNDCLASS cls;
cls.cbClsExtra =0 ;
cls.cbWndExtra=0 ;
cls.hbrBackground=(HBRUSH)::GetStockObject(GRAY_BRUSH) ;
cls.hCursor=::LoadCursor(NULL,IDC_ARROW) ;
cls.hIcon=LoadIcon(NULL,IDI_ERROR);
cls.hInstance=hInstance ;
cls.lpfnWndProc=WinProc ;
cls.lpszClassName="SDK";
cls.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
cls.style=CS_VREDRAW|CS_HREDRAW |CS_DBLCLKS|0x00020000;//|CS_NOCLOSE;
::RegisterClass(&cls) ;
HWND m_hWnd;
m_hWnd=::CreateWindow("SDK","New Win32 Application",WS_OVERLAPPEDWINDOW|WS_EX_TOOLWINDOW,100,200,600,600,NULL,NULL,hInstance,NULL) ; //创建窗口返回窗口的句柄
::ShowWindow(m_hWnd,SW_SHOWNORMAL) ; //显示窗口
::UpdateWindow(m_hWnd) ; //更新窗口
MSG msg ;
while(::GetMessage(&msg,m_hWnd,NULL,NULL)) //从消息队列检索消息
{
::TranslateMessage(&msg) ; //翻译消息
::DispatchMessage(&msg) ; //分发消息
}
return 0 ;
}
LRESULT CALLBACK WinProc(
HWND hwnd, // 窗体的句柄
UINT uMsg, // WM_开头的消息
WPARAM wParam, // 第一个附加参数
LPARAM lParam // 消息的第二个附加参数
)
{
switch(uMsg)
{
case WM_PAINT :
{
HDC hdc ;
PAINTSTRUCT ps ; //填充PAINTSTRUCT 结构体
hdc=::BeginPaint(hwnd,&ps) ; //BeginPaint() EndPaint()只有在响应WM_PAINT 消息的时候才会被调用 作用是从消息队列删除WM_PAINT 消息
//如果此处用GetDC来获取DC那么 就无法从消息队列中取出 WM_PAINT 消息 那么 windows会一直认为这是一个
//Invalid Area 无效区域 那么就会不停的重绘 导致程序卡死 。
::TextOut(hdc,10,10,"Win32_SDK",strlen("Win32_SDK")) ;
::EndPaint(hwnd,&ps); //在响应WM_PAINT 消息的时候 BeginPaint()后面必须跟上 EndPaint()
break;
}
case WM_LBUTTONDOWN:
{
HDC dc ;
dc=::GetDC(hwnd) ; //获得窗口的画布 ClientAprea
TextOut(dc,10,30,"Left Button Down!",strlen("Left Button Down!")) ;
break;
}
case WM_COMMAND : //此处是菜单消息的捕获
{
switch(wParam)
{
case IDM_OPEN :
{
::MessageBox(hwnd,"File Open","提示",MB_OK) ;
break ;
}
case IDM_NEW :
{
::MessageBox(hwnd,"File New","提示",MB_OK) ;
break ;
}
}
break;
}
case WM_CLOSE:
{ if(IDYES==::MessageBox(hwnd,"真的要退出?","提示",MB_YESNO))
::DestroyWindow(hwnd) ; //销毁窗体 销毁窗体的时候会发送一个 WM_DESTROY 消息 我们可以拦截这个消息并且调用PostQuitMessage(0)
break ; //来退出程序
}
case WM_DESTROY :
{ ::PostQuitMessage(0); //正常退出
break ;
}
case WM_RBUTTONDOWN :
{
MessageBox(hwnd,"Right Button Down","提示",MB_OK);
break ;
}
default: return DefWindowProc(hwnd,uMsg,wParam,lParam) ; //默认调用缺省的窗口过程
}
return 0 ;
}