..::一步一个坚定的脚印::..

一个简单的C语言SDK风格windows窗口

上一篇 / 下一篇  2008-05-15 16:40:22 / 个人分类:MFC Windows 程序设计(第2版)-学习笔记

一个简单的C语言SDK风格windows窗口
    此程序生成一个窗口,并再窗口的左上角绘制一个椭圆来响应WM_PAINT消息。
///////////////////////////////////////////////////////////////////
#include <windows.h>

LONG WINAPI WndProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
       LPSTR lpszCmdLine,int nCmdShow)
{
 WNDCLASS wc;
 HWND hwnd;
 MSG msg;

 wc.style=0;
 wc.lpfnWndProc=(WNDPROC)WndProc;
 wc.cbClsExtra=0;
 wc.cbWndExtra=0;
 wc.hInstance=hInstance;
 wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
 wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
 wc.lpszMenuName=NULL;
 wc.lpszClassName="MyWndClass";

 RegisterClass(&wc);
 hwnd=CreateWindow(
  "MyWndClass",
  "SDK Application",
  WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  HWND_DESKTOP,
  NULL,
  hInstance,
  NULL
  );

 ShowWindow(hwnd,nCmdShow);
 UpdateWindow(hwnd);

 while(GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,
       LPARAM lParam)
{
 PAINTSTRUCT ps;
 HDC hdc;

 switch(message)
 {
 case WM_PAINT:
  hdc=BeginPaint(hwnd,&ps);
  Ellipse(hdc,0,0,200,100);
  EndPaint(hwnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return DefWindowProc(hwnd,message,wParam,lParam);
}
///////////////////////////////////////////////////////////////////
    WinMain首先调用API函数RegisterClass来注册一个窗口类。窗口类定义了窗口的重要特性,如窗口过程地址,默认背景颜色以及图标等。这些属性通过填写一个WNDCLASS结构的字段值来定义,随后将传递给RegisterClass。当应用程序生成一个窗口时,它必须指定一个窗口类,在该类能被使用之前,必须先对其进行注册。这就是为什么RegisteClass在程序的开始即被调用的原因。
    一旦WNDCLASS被注册,WinMain将调用最重要的CreateWindow函数来生成应用程序的窗口。传递给CreateWindow的第1个参数是WNDCLASS的名字,窗口将由此生成窗口。第2个参数是将在窗口的标题栏中显示的文本。第3个参数指定窗口样式。WS_OVERLAPPEDWINDOW是一个常用的样式,它生成一个顶层窗口,该窗口带有可调整大小的边框、一个标题栏、一个系统菜单及最小化、最大化和关闭窗口按钮。
    接下来的第4个参数指定了窗口的初始位置和大小。CW_USEDEFAULT用来告诉Windows使用默认值。最后4个参数依次指定:该窗口的父窗口的句柄(HWND_DESKTOP用作应用程序的主窗口的父窗口);与窗口关联的菜单的句柄;应用程序的实例句柄(一个用来让程序员区分是程序自身还是模块DLL的值);以及一个指向特定应用程序的窗口生成数据的指针。
    由于生成时没使用WS_VISIBLE,所以CreateWindow生成的窗口在屏幕上最初是不可见的。(如果使用WS_VISIBLE,则它应该在CreateWindow函数的调用中与WS_OVERLAPPEDWINDOW结合应用。)因此在WinMain中,紧随CreateWindow后面的是一对ShowWindow和UpdateWindow函数的调用,它们使窗口可见并确保WM_PAINT消息处理程序立刻被调用。
    接下来是消息循环。为了检索并调度消息,WinMain执行一个简单的反复调用GetMessage、TranslateMessage和DispatchMessage这3个API函数的while循环语句。GetMessage检查消息队列。如果某个消息是有效的,则它将从队列中被删除并复制到msg,否则,GetMessage将停留在消息队列上直到消息有效。msg是结构MSG的一个实例,其字段包含相关的消息参数,倒如消息ID和消息被放置在队列中的时间。TranslateMessage函数将一个指示字符键的键盘消息转换为更容易使用的WM_CHAR消息,DispatchMessage函数则将消息发送给窗口过程。消息循环一直执行到CreatMessage函数返回0值时结束。而此情形只有在WM_QUIT消息从消息队列中被检索到时才发生。这时WinMain结束,程序终止运行。
    由DispatchMessage函数调度的消息将生成对窗口过程WndProc的调用。上面的示例程序只是处理了两个消息类型:WM_PAINT和WM_DESTROY;所有其他消息被传递给了DefWindowProe函数进行默认处理。在switch-case块中将检查message参数传递来的消息ID,并且执行相应的消息处理程序。在绘制开始以前,WM_PAINT处理程序将调用API函数BeginPaint来获得一个设备环境句柄,当绘制完成后,API函数EndPaint将释放该句柄。在两函数之间.API函数Ellipse绘制了一个200像素宽、100像素高的椭圆。设备环境句柄是一个具有奥妙功能的东西,它允许Windows应用程序在屏幕上绘图。没有它,像Elllpse这样的函数就不能工作。
    WM_DESTROY处理程序调用PostQuitMessage API函数给消息队列发送一个WM_QUIT消息,并最终促使程序停止运行。在WM_DESTROY消息被发送给窗口之后,紧接着窗口就被撤消了。当接收到一个WM_DESTROY消息时,顶层窗口必须调用PostQuitMessage函数,否则消息循环不会停止,程序也就永远不会结束。


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-12-03  
 123456
78910111213
14151617181920
21222324252627
28293031   

我的存档

数据统计

  • 访问量: 608
  • 日志数: 8
  • 建立时间: 2008-05-06
  • 更新时间: 2008-05-26

RSS订阅

Open Toolbar