完美一点

#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);
}

效果展示

Win32-第一个窗口程序_ico

迷茫的人生,需要不断努力,才能看清远方模糊的志向!