Win32第一个窗口程序

完美一点

#include <windows.h>

HINSTANCE g_hInst = NULL;

//2. 定义窗口处理函数
LRESULT CALLBACK WndProc(
						HWND hWnd,
						UINT nMsg,
						WPARAM wParam,
						LPARAM lParam
						)
{
	switch(nMsg)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc(hWnd, nMsg, wParam, lParam);
}

// 3. 创建窗口类型并注册窗口类型
BOOL MyRegister(LPSTR pszClassName)
{
	WNDCLASS wc = {0};
	ATOM nAtom = 0;

	//构造注册窗口的参数
	wc.style         = CS_VREDRAW|CS_HREDRAW;
	wc.lpfnWndProc   = WndProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = g_hInst;
	wc.hIcon         = NULL;
	wc.hCursor       = NULL;
	wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = pszClassName;
	//注册窗口
	nAtom = RegisterClass( &wc );
	if( 0 == nAtom )
	{
		MessageBox( NULL, "Register Failed", "Error", MB_OK|MB_ICONWARNING );
		return FALSE;
	}
	else
	{
		MessageBox( NULL, "Register Successed", "Successed", MB_OK );
	}
	return TRUE;
}

//4. 窗口创建
HWND MyCreate(LPSTR pszClassName)
{
	HWND hWnd = NULL;

	hWnd = CreateWindow(pszClassName, "CntfWindows",
		WS_OVERLAPPEDWINDOW, 300, 300, 800, 600, NULL, NULL,
		g_hInst, NULL);


	if(hWnd == NULL)
	{
		MessageBox(NULL, "CreateWindows Failed", "Errors", MB_OK);
		return FALSE;
	}
	MessageBox(NULL, "CreateWindows Successed", "Successed", MB_OK);
	return hWnd;
}

//5. 窗口显示
void DisplayWnd( HWND hWnd)
{
	// 显示窗口
	ShowWindow(hWnd, SW_SHOW);
	// 更新窗口
	UpdateWindow(hWnd);
}

//6. 消息处理
void Message()
{
	MSG msg = {0};
	//循环处理消息和获取消息
	while(GetMessage(&msg, NULL, 0, 0))
	{
		//派发消息
		DispatchMessage(&msg);
	}
}

//1. WinMain 入口函数
int APIENTRY WinMain(HINSTANCE hInst,
					 HINSTANCE hPrevInst,
					 LPSTR pszCmdLine,
					 int nShowCmd)
{
	HWND hWnd = NULL;
	g_hInst = hInst;

	// 注册窗口类型
	MyRegister("WindowsCntf");

	// 创建窗口
	hWnd = MyCreate("WindowsCntf");

	// 显示窗口
	DisplayWnd(hWnd);

	// 消息处理
	Message();

	return 0;
}

/*
编译
cl cswin32.c /c
链接
link cswin32.obj user32.lib
执行
cswin32.exe

1. 入口函数WinMain

2.窗口处理函数
     当窗口处理消息事件时,系统调用该函数
   	LRESULT CALLBACK WindowProc(
	  HWND hwnd,      // 窗口的句柄
  	UINT uMsg,      // 消息的ID号
  	WPARAM wParam,  // 消息所对应的参数
  	LPARAM lParam   // 消息所对应的参数
		);

3.注册窗口类型
    typedef struct _WNDCLASS { 
    UINT    style;  //窗口类的风格
    WNDPROC lpfnWndProc; //窗口处理函数
    int     cbClsExtra; //窗口类附加数据大小
    int     cbWndExtra; //窗口附加数据大小
    HANDLE  hInstance; //当前应用程序的实例句柄
    HICON   hIcon; //窗口图标
    HCURSOR hCursor; //窗口的鼠标
    HBRUSH  hbrBackground; //窗口的背景画刷
    LPCTSTR lpszMenuName; //菜单
    LPCTSTR lpszClassName; //类型名称
    } WNDCLASS;

 注册函数 RegisterClass

4.创建窗口
     HWND CreateWindow(
  		LPCTSTR lpClassName,  //窗口类型名称
  		LPCTSTR lpWindowName, //窗口名称
  		DWORD dwStyle,        //窗口类型
  		int x,                //窗口的左上角X坐边
  		int y,                //窗口的左上角X坐边
  		int nWidth,           //窗口的宽度
  		int nHeight,          //窗口的高度
  		HWND hWndParent,      //父窗口句柄
  		HMENU hMenu,          //窗口菜单句柄
  	  HANDLE hInstance,     //应用程序的实例句柄
  	  LPVOID lpParam        //创建的参数,一般为NULL
		  );
5.显示窗口
     ShowWindow 显示窗口
        BOOL ShowWindow(
  			HWND hWnd,     //显示的窗口句柄
  		  int nCmdShow   //显示的方式
			  );
     UpdateWindow 刷新窗口

6.消息处理
     GetMessage 获取消息
   	 DispatchMessage 派发消息
   
7.程序退出
     窗口销毁时,退出程序。在WndProc中实现。
        WM_DESTROY: 当窗口销毁时,会调用WndProc
          传递给使用者。
        PostQuitMessage:发送一个退出消息。
		
		
    4.1 资源和资源脚本
        资源:ICON/CUSRUR/BITMAP/MENU......
        资源脚本:扩展名为rc文件
    4.2 编译资源
        rc.exe 编译资源,生成res的文件
    4.3 链接资源
        使用link将res文件链接到程序当中
        
    手动添加ico图标操作步骤
    1.新建一个rc的扩展名文件,放一个图标在当前目录下然后编辑这个文件添加
    下面一句话
    228 ICON "cs.ico"
    上面228是编号,ICON是类型,最后面那个是图标的具体位置
    2.使用rc.exe进行编译
    rc cswin32.rc
    3.编译写好的Win32程序的代码
    cl createWin32Windows.c /c
    4.链接上面的Win32程序
    link createWin32Windows.obj cswin32.RES user32.lib
    5.上面没有问题就成功了
		
 */

滴水Win32好理解

1.第一个图形界面程序

步骤1:创建Windows应用程序  选择空项目

步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件

步骤3:在新的cpp文件中添加:#include <Windows.h>

并添加入口函数:

int CALLBACK WinMain(  						CALLBACK 是一个宏
	_In_  HINSTANCE hInstance,  			#define CALLBACK    __stdcall
	_In_  HINSTANCE hPrevInstance,
	_In_  LPSTR lpCmdLine,
	_In_  int nCmdShow
	)  					                    所有的Win32 API函数都遵循该约定
{

	return 0;
}

步骤4:设计窗口类

代码:

//窗口的类名
TCHAR className[] = "My First Window";

// 创建窗口类的对象
WNDCLASS wndclass = {0};						//一定要先将所有值赋值
wndclass.hbrBackground = (HBRUSH)COLOR_MENU;	//窗口的背景色
wndclass.lpfnWndProc = WindowProc;				//窗口过程函数
wndclass.lpszClassName = className;				//窗口类的名字
wndclass.hInstance = hInstance;					//定义窗口类的应用程序的实例句柄

--------------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);
--------------------------------------------------------------------------------

typedef struct _WNDCLASS {
    UINT       style;
    WNDPROC    lpfnWndProc;
    //窗口产生消息的时候,有哪个函数去处理,(窗口消息的处理函数)
    int        cbClsExtra;
    int        cbWndExtra;
    HINSTANCE  hInstance;          //当前的窗口属于哪个应用程序
    HICON      hIcon;             //窗口上面图片的标识,就是那个小图标
    HCURSOR    hCursor;          //窗口里面出现鼠标,这个鼠标的形状是什么样的
    HBRUSH     hbrBackground;   //窗口的背景色是什么样
    LPCTSTR    lpszMenuName;    //窗口如果需要有菜单,必须告诉我菜单的名字
    LPCTSTR    lpszClassName;  //给我一个名字,必须有
} WNDCLASS, *PWNDCLASS;

步骤5:注册窗口类

RegisterClass(&wndclass);

步骤6:创建窗口

// 创建窗口
   HWND hwnd = CreateWindow(
        className,				            //类名
        TEXT("我的第一个窗口"),				//窗口标题
        WS_OVERLAPPEDWINDOW,				//窗口外观样式
        10,				                    //相对于父窗口的X坐标
        10,				                    //相对于父窗口的Y坐标
        600,				                //窗口的宽度
        300,				                //窗口的高度
        NULL,				                //父窗口句柄,为NULL
        NULL,				                //菜单句柄,为NULL
        hInstance,				            //当前应用程序的句柄
        NULL);				                //附加数据一般为NULL

    if(hwnd == NULL)					    //是否创建成功
        return 0;

步骤7:显示窗口

// 显示窗口
ShowWindow(hwnd, SW_SHOW);

步骤8:消息循环

MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

步骤9:回调函数

/*
窗口消息处理程序 窗口回调函数:

1.窗口回调函数处理过的消息,必须传回0.

2.窗口回调不处理的消息,由DefWindowProc来处理.
*/

LRESULT CALLBACK WindowProc(
							IN  HWND hwnd,
							IN  UINT uMsg,
							IN  WPARAM wParam,
							IN  LPARAM lParam
							)
{
	switch(uMsg)
	{
		//窗口消息
	case WM_CREATE:
		{
			DbgPrintf("WM_CREATE %d %d\n",wParam,lParam);
			CREATESTRUCT* createst = (CREATESTRUCT*)lParam;
			DbgPrintf("CREATESTRUCT %s\n",createst->lpszClass);

			return 0;
		}
	case WM_MOVE:
		{
			DbgPrintf("WM_MOVE %d %d\n",wParam,lParam);
			POINTS points = MAKEPOINTS(lParam);
			DbgPrintf("X Y %d %d\n",points.x,points.y);

			return 0;
		}
	case WM_SIZE:
		{
			DbgPrintf("WM_SIZE %d %d\n",wParam,lParam);
			int newWidth  = (int)(short) LOWORD(lParam);
			int newHeight  = (int)(short) HIWORD(lParam);
			DbgPrintf("WM_SIZE %d %d\n",newWidth,newHeight);

			return 0;
		}
	case WM_DESTROY:
		{
			DbgPrintf("WM_DESTROY %d %d\n",wParam,lParam);
			PostQuitMessage(0);

			return 0;
		}
		//键盘消息
	case WM_KEYUP:
		{
			DbgPrintf("WM_KEYUP %d %d\n",wParam,lParam);

			return 0;
		}
	case WM_KEYDOWN:
		{
			DbgPrintf("WM_KEYDOWN %d %d\n",wParam,lParam);

			return 0;
		}
		//鼠标消息
	case WM_LBUTTONDOWN:
		{
			DbgPrintf("WM_LBUTTONDOWN %d %d\n",wParam,lParam);
			POINTS points = MAKEPOINTS(lParam);
			DbgPrintf("WM_LBUTTONDOWN %d %d\n",points.x,points.y);

			return 0;
		}
	}
	return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

--------------------------------------------------------------------------------

课堂练习测试代码

#include "stdafx.h"

LRESULT CALLBACK WindowProc(
                            IN  HWND hwnd,
                            IN  UINT uMsg,
                            IN  WPARAM wParam,
                            IN  LPARAM lParam
                            );

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.

    /*
    第一步:创建Windows应用程序,选择空项目
    第二步:在新建项窗口中选中C++代码文件,创建一个新的cpp文件
    第三步:在新的cpp文件添加
    #include <windows.h> 然后再添加入口函数

    并添加入口函数:
    // CALLBACK 是一个宏
    // #define CALLBACK    __stdcall

    int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
    )
    // 所有的Win32 API函数都遵循该约定
    {
      return 0;
    }

    上述3个步骤,可以直接新建选择一个入口函数模板即可
    */
    //4.第四步,设计窗口类

    // 窗口的类名称
    TCHAR className[] = "My First Windows";

    // 创建窗口类的对象,创建一个自己的窗口
    //WNDCLASS wndclass;// 这里如果是左边这样写,那么编译链接成功窗口出不来
    //所以必须要把wndclass里面的每个参数都赋值,不使用也要赋值为0
    //简便的方式就是加上{0}
    WNDCLASS wndclass = {0};
    wndclass.hbrBackground = (HBRUSH)COLOR_MENU; //指定一个背景色
    wndclass.lpfnWndProc = WindowProc; //消息处理函数
    //上面表示 当前应用程序一旦有事件被触发的时候,由哪个程序去处理她,这里是WindowProc函数来处理
    wndclass.lpszClassName = className; //给当前窗口取一个名字
    wndclass.hInstance = hInstance; //当前的窗口是哪个应用程序的,也就是ImageBase的值

    //5.第五步 注册窗口类
    RegisterClass(&wndclass);

    //6.创建窗口

    HWND hwnd = CreateWindow(
        className,				            //类名
        TEXT("我的第一个窗口"),				//窗口标题
        WS_OVERLAPPEDWINDOW,				//窗口外观样式
        100,				                    //相对于父窗口的X坐标
        100,				                    //相对于父窗口的Y坐标
        600,				                //窗口的宽度
        300,				                //窗口的高度
        NULL,				                //父窗口句柄,为NULL
        NULL,				                //菜单句柄,为NULL
        hInstance,				            //当前应用程序的句柄
        NULL);				                //附加数据一般为NULL

    if(hwnd == NULL)					    //是否创建成功
        return 0;

    // 7.显示窗口
    ShowWindow(hwnd, SW_SHOW);

    // 8.消息循环
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

	return 0;
}

/*
9.回调函数

窗口消息处理程序 窗口回调函数:

  1.窗口回调函数处理过的消息,必须传回0.
  2.窗口回调不处理的消息,由DefWindowProc来处理.
*/

LRESULT CALLBACK WindowProc(
                            IN  HWND hwnd,
                            IN  UINT uMsg,
                            IN  WPARAM wParam,
                            IN  LPARAM lParam
                            )
{
    switch(uMsg)
    {
    case WM_DESTROY:
        {
            //DbgPrintf("WM_DESTROY %d %d \r\n",wParam,lParam);
            PostQuitMessage(0);

            return 0;
        }

    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}


效果展示

image

原文地址:https://www.cnblogs.com/autopwn/p/15545626.html