用纯C代码创建一个windows窗口

落寞 2018-7-5 401

废话不多说,直接上代码,注释写的很清楚了

#include <windows.h>
// 窗口消息处理函数的声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// 主入口点函数,就跟平时的main函数一样,程序运行后,此函数被调用
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 PSTR szCmdLine, int iCmdShow)
{
 // 一个指向字符串的指针,等下用来当做窗口类的名字
 static TCHAR szAppName[] = TEXT("HelloWin");
 // 等下存放窗口的句柄
 HWND hwnd;
 // 用来存放系统发送给窗口的消息
 MSG msg;
 // 创建一个窗口类
 WNDCLASS wndclass;
 // 设置窗口的样式
 wndclass.style = CS_HREDRAW | CS_VREDRAW;
 // 设置负责处理此窗口消息的函数
 wndclass.lpfnWndProc = WndProc;
 //窗口类额外空间字节数,写0即可
 wndclass.cbClsExtra = 0;
 // 窗口额外空间字节数,写0即可
 wndclass.cbWndExtra = 0;
 // 应用程序实体句柄
 wndclass.hInstance = hInstance;
 // 图标句柄,不用管,照抄
 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 // 光标句柄,同上,照抄
 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 // 画刷句柄,也照抄
 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 // 菜单资源名,写NULL
 wndclass.lpszMenuName = NULL;
 // 窗口类的名字
 wndclass.lpszClassName = szAppName;
 // RegisterClass是用来注册窗口类的,传给它窗口类的指针即可,如果返回FALSE代表注册失败
 if (!RegisterClass(&wndclass))
 {
  // 如果注册失败了,信息框提示
  MessageBox(NULL, TEXT("This program requires Windows NT!"),
   szAppName, MB_ICONERROR);
  return 0;
 }

 // CreateWindow用来创建窗口的,返回创建后的窗口句柄
 hwnd = CreateWindow(szAppName, // 要创建的窗口类名
  TEXT("The Hello Program"), // 窗口标题
  WS_OVERLAPPEDWINDOW, // 窗口样式
  CW_USEDEFAULT,// 窗口距离屏幕左边的距离
  CW_USEDEFAULT,// 窗口距离屏幕顶部的距离
  CW_USEDEFAULT,// 窗口宽度
  CW_USEDEFAULT,// 窗口高度
  NULL, // 父窗口句柄
  NULL, // 窗口菜单句柄
  hInstance, // 应用程序实力句柄
  NULL); // 附加参数
 // 更改窗口显示方式,创建完后默认是不可见,第一个参数是要设置的窗口句柄,第二个是显示的方式
 ShowWindow(hwnd, iCmdShow);
 // 更新窗口,如果窗口绘制区域不为空,UpdateWindow将绕过消息队列,直接发送WM_PAINT消息给消息处理函数,通知windows绘制窗口,如果为空则不发送;
 UpdateWindow(hwnd);
 // 下面负责消息循环
 // GetMessage从消息队列中取出一条消息
 // 第一个参数是MSG结构体的指针,我们前面定义了它
 // 后面三个参数是消息过滤,写NULL就可
 while (GetMessage(&msg, NULL, 0, 0))
 {
  // Translate函数是对键盘消息的转换,参数是指向MSG实力的指针;
  TranslateMessage(&msg);
  // DispatchMessage函数通知Windows给消息处理函数发送消息,参数是指向MSG结构体的指针,消息处理函数返回后,这个函数才返回,进行下一轮循环;
  DispatchMessage(&msg);
 }
 return msg.wParam;
}

// 负责处理消息的函数,是由系统调用的
// hwnd表示消息来自哪个窗口,message表示消息的值,wParam与lParam是附加参数;
// 这个附加参数,比如用户按了键盘上的一个键,windows发送一条WM_KEYDOWN消息,这时wParam中的值就是虚拟键码;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)
 {
  // 如果消息的值是代表窗口创建了
 case WM_CREATE:
  MessageBox(NULL, TEXT("hello world!"), TEXT("Message"), 64);
  return 0;
  // 当用户单机窗口右上角的关闭按钮或在系统菜单中选择关闭菜单项时,windows会发送一条WM_CLOSE消息,表示用户试图关闭窗口;
  // 这时应用程序可以调用DestroyWindow函数来销毁窗口,参数是窗口句柄;
 case WM_CLOSE:
  // 我们来谈个信息框,询问用户是否关闭窗口
  if (MessageBox(NULL, TEXT("确定要退出吗?"), TEXT("询问"), 36) == IDYES)
   // 如果按了是,我们就调用DestroyWindow
   DestroyWindow(hwnd);
  return 0;
  // 当我们调用DestroyWindow后,系统会发送一条WM_DESTROY消息,注意这时候窗口还没有被销毁;当消息处理函数处理这条消息返回后,窗口才会销毁;
 case WM_DESTROY:
  // PostQuitMessage负责停止消息循环,参数写0即可
  // 当调用这个函数后,系统会发送一条WM_QUIT消息,GetMessage取出这条消息后就返回0,循环就终止了,程序也就退出
  PostQuitMessage(0);
  return 0;
 }
 // 程序不处理的消息就调用DefWindProc,这是系统默认消息处理函数,把消息处理函数接收到的四个值按顺序传进去就行;
 return DefWindowProc(hwnd, message, wParam, lParam);
}

WNDCLASS原型如下:
struct WNDCLASS
{
    UINT        style;
    WNDPROC     lpfnWndProc;
    int         cbClsExtra;
    int         cbWndExtra;
    HINSTANCE   hInstance;
    HICON       hIcon;
    HCURSOR     hCursor;
    HBRUSH      hbrBackground;
    LPCSTR      lpszMenuName;
    LPCSTR      lpszClassName;
};

RegisterClass的函数原型是
ATOM RegisterClass(WNDCLASS *lpWndClass);

CreateWindow的函数原型是
HWND CreateWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam);

ShowWindow函数的原型是
BOOL ShowWindow(HWND hWnd,int nCmdShow);
最后窗口显示方式可以是如下几个常量之一
SW_HIDE:隐藏;
SW_MAXIMIZE:最大化;
SW_MINIMIZE:最小化;
SW_RESTORE:还原原始大小;
SW_SHOW:激活;
SW_SHOWMAXIMIZED:激活并最大化;
SW_SHOWMINIMIZED:激活并最小化;
SW_SHOWMINNOACTIVE:最小化,但不激活;
SW_SHOWNA:显示,但不激活;
SW_SHOWNOACTIVATE:还原原始大小但不激活;
SW_SHOWNORMAL:还原原始大小并激活;


最新回复 (0)
返回
发新帖

豫公网安备 41130202000228号