我们不能在消息框中显示图形,而且也不能在消息框中添加菜单。要添加这些对象,就需要建立自己的窗口,现在就开始。
建立窗口很简单,只需呼叫CreateWindow函数即可。建立一个窗口首先需要注册一个窗口类别,那需要一个窗口消息处理程序来处理窗口消息。处理窗口消息对每个Windows程序都带来了些负担。
代码及其详细注释如下:
/*------------------------------------------------------------ HELLOWIN.C -- Displays "Hello, Windows 98!" in client area (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;//窗口消息处理程序声明: //LRERULT为函数返回值类型,宏定义为LONG; //CALLBACK说明的是函数参数的进栈顺序(从左到右) //WndProc为函数名,可任意改 //4个函数参数为message结构体中的前4个参数, int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) //主函数,Windows程序进入点;其中,int为函数返回值类型,WINAPI说明的是函数的进栈顺序。 //第一个参数为执行实体(程序自身)句柄,唯一的标识该程序;第二个参数在32位的Windows中已失去了意义,总是NULL; //第三个参数是用于执行程序的命令列;第四个参数指出窗口最初的显示方式,最小化、最大化、还是正常显示。 { static TCHAR szAppName[] = TEXT ("HelloWin") ; //定义一个字符串数组,并赋以初值“HelloWin”,这个“HelloWin”是程序的名字 //是要进操作系统的注册表的!是告诉操作系统你这个程序的名字是什么! HWND hwnd ; //定义窗口句柄 MSG msg ; //结构体类型MSG的变量申明,该结构体中有六个成员变量,储存有关消息的信息 WNDCLASS wndclass ; //结构体类型WNDCLASS的变量申明,以下为该变量成员的初始化 wndclass.style = CS_HREDRAW | CS_VREDRAW ; //CS_HREDRAW表示水平重画,即水平拖动窗口时,会调用WM_PAINT消息重画窗口,调整窗口尺寸 //CS_VREDRAW表示垂直重画,即垂直拖动窗口时,会调用WM_PAINT消息重画窗口,调整窗口尺寸 wndclass.lpfnWndProc = WndProc ; //该字段是依据这个窗口类别来建立的所有窗口的消息处理程序的地址 wndclass.cbClsExtra = 0 ; //预留空间的附加值,此程序没用到这个域! wndclass.cbWndExtra = 0 ; //预留空间的附加值,此程序没用到这个域! wndclass.hInstance = hInstance ; //该字段为执行实体句柄,初始化为WinMain中的第一个参数 wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; //装载图标函数。当装载自己的图标时,第一个参数设为hInstance wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; //装载光标函数。也可装载自己的光标 wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ; //该字段为依据该类别建立的窗口背景颜色。此程序中设为黑色背景,可根据需要设置颜色 wndclass.lpszMenuName = NULL ; //该字段指定窗口类别菜单。该程序中没有设置菜单 wndclass.lpszClassName = szAppName ; //类别名称,该类别名称与程序名相同 if (!RegisterClass (&wndclass)) //向操作系统注册窗口类,即向操作系统申请内存 { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; //消息对话框,用于异常处理 return 0 ; } // 创建窗口函数。在CreatWindow调用返回之后,Windows内部已经建立了这个窗口,即已经分配了内存 hwnd = CreateWindow (szAppName, // window class name 应用程序在操作系统注册表中的名称 TEXT ("The Hello Program"), // window caption 应用程序标题栏名称 WS_OVERLAPPEDWINDOW, // window style 窗口样式 CW_USEDEFAULT, // initial x position 窗口显示时距屏幕左上角的x坐标 CW_USEDEFAULT, // initial y position 窗口显示时距屏幕左上角的y坐标 CW_USEDEFAULT, // initial x size 窗口宽度 CW_USEDEFAULT, // initial y size 窗口高度 NULL, // parent window handle 父窗口句柄,此程序没有 NULL, // window menu handle 菜单句柄 hInstance, // program instance handle 程序实例句柄 NULL) ; // creation parameters 创建参数指针 ShowWindow (hwnd, iCmdShow) ; //该函数在显示器上显示函数 //第一次调用窗口回调函数Wndproc,注意Wndproc函数不是ShowWindow函数来调用,而是 //ShowWindow函数向操作系统发送消息,是操作系统根据发送的消息来调用Wndproc函数! //操作系统调用Wndproc函数后并响应WM_CREATE消息! UpdateWindow (hwnd) ; //刷新窗口函数,操作系统调用WndProc函数并响应WM_PAINT消息 while (GetMessage (&msg, NULL, 0, 0)) // 这是所有WINDOWS程序的核心,消息循环处理过程!这里是接受消息和发送消息的地方! //这一呼叫传给Windows一个指标,指向名为msg的MSG结构。 //第二、第三和第四个参数设定为NULL或者0,表示程序接收它自己建立的所有窗口的所有消息。 //Windows用从消息队列中取出的下一个消息来填充消息结构的各个字段。 //GetMessage 函数从操作系统的消息队列中获得消息,一个一个的处理,来一个处理一个, //直到获得退出消息,也就是点击应用程序右上角的叉子!退出消息循环,并响应WM_QUIT消息 { TranslateMessage (&msg) ; //将msg结构传给Windows,进行一些键盘转换 DispatchMessage (&msg) ; //又把msg发送给窗口过程,由操作系统调用消息处理程序WndProc } return msg.wParam ; } //主函数结束 //窗口回调函数,此函数由操作系统调用,因此只有声明和定义! LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; //设备描述表句柄 PAINTSTRUCT ps ; //绘图结构体变量 RECT rect ; //矩形结构体变量 switch (message) //message消息类型!分别处理不同的消息! { case WM_CREATE: //此消息是一个应用程序发送的第一个消息,也是唯一的一次!在窗口显示之前该消息就已经执行了 PlaySound (TEXT ("HelloWin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播放声音文件 return 0 ; case WM_PAINT: //这个消息在Windows程序设计中是很重要的。 //当窗口显示区域的一部分显示内容或者全部变为「无效」,以致于必须「更新画面」时,将由这个消息通知程序。 hdc = BeginPaint (hwnd, &ps) ; //开始窗口绘制 GetClientRect (hwnd, &rect) ; //获得窗口客户区的尺寸 DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; //显示文本串 EndPaint (hwnd, &ps) ; //结束窗口绘制 return 0 ; case WM_DESTROY: //处理退出消息 PostQuitMessage (0) ; //在消息队列中插入一条“退出”消息 return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; //执行默认的消息处理,处理一些闲杂以及一些不可预料的消息!去掉该句可能造成死机 }
如下图:
关于此函数的详细说明,请移步:http://blog.sina.com.cn/s/blog_af169d640101nwcs.html OR http://blog.csdn.net/clearver/article/details/5209244
另外声音文件必须在您的工程目录下。。
工程文件以及源代码:http://download.csdn.net/detail/hu1020935219/6391647
执行情况如下:
未完待续.......