Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码

01 Windows应用程序分类

1.应用程序分类

  • 控制台程序Console
    DOS程序,本身没有窗口,通过Windows DOS窗口执行(借的的操作系统的窗口)
  • 窗口程序
    拥有自己的窗口,可以与用户交互
  • 程序库
    存放代码,数据的程序,执行文件可以从中取出代码执行和获取数据

    静态库程序:扩展名LIB,在编译链接程序时,将代码放入到执行文件中
    动态库程序:扩展名DLL,在执行文件执行时从中获取代码。

2.控制台程序Console创建

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第1张图片
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第2张图片
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第3张图片
此处的Debug放的所有项目最终文件
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第4张图片
此处Debug放的是中间文件’
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第5张图片

3.窗口程序创建

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第6张图片
更改字符集
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第7张图片
生成结构:
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第8张图片

4.静态库程序创建

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第9张图片
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第10张图片
早在VS2017开始,stdafx.h改名为pch.h
之前的版本:
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第11张图片

5.动态库程序创建

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第12张图片
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第13张图片

6.应用程序对比

  • 入口函数
    控制台程序 -main
    窗口程序 -WinMain
    动态库程序 -DLLMain
    静态库程序 -无入口函数
  • 文件存在方式
    控制台程序,窗口程序 -EXE文件
    动态库程序 -DLL文件
    静态库程序 -LIB文件

02 开发工具和库

1.编译工具

  • 编译器CL.EXE,将源代码编译成目标代码.obj
  • 链接器LINK.EXE,将目标代码,库链接生成最终文件
  • 资源编译器RC.EXE(.rc),将资源编译,最终通过链接器存入最终文件
    工具存放路径:(存在此版本的VS)在这里插入图片描述

2.库和头文件

  • Windows库
    kernel32.dll -提供了核心的API,例如进程,线程,内存管理等
    user32.dll -提供了窗口,消息等API
    gdi32.dll -绘图相关的API
    存放路径:C:\Windows\System32

  • 头文件
    windows.h -所有windows头文件的集合
    windef.h -windows数据类型
    winbase.h -kernel32的API
    wingdi.h -gdi32的API
    winuser.h -user32的API
    winnt.h -UNICODE字符集支持

    存放路径:C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um
    windows.h包含下面所有:
    Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第14张图片

    3.相关函数

  • int WINAPI WinMain(
    //句柄是用来找到内存的东西,但不是指针
    HINSTANCE hInstance, //当前程序的实例句柄, 找到当前进程的内存
    HINSTANCE hPrevInstance, //当前程序前一个实例句柄
    LPSTR lpCmdLIne, //命令行参数字符串
    int nCmdShow //窗口的显示方式
    );

  • int MessageBox(
    HWND hWnd,//父窗口句柄,没有,为null
    LPCTSTR lpText, //显示在消息框中的文字
    LPCTSTR lpCaption, //显示在标题栏中的文字
    UINT uType //消息框中的按钮,图标显示类型
    );//返回点击的按钮ID

4.以命令行形式写代码过程

创建文档
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第15张图片
代码:

#include

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLIne, int nCmdShow)
{
     int nRet = MessageBox(NULL,"hello world","Information",MB_YESNOCANCEL|MB_ICONERROR);
     if(nRet == IDYES){
     }else if (nRet == IDNO){
     }else{
    
    }
     return 0;
}

将名称改为.c
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第16张图片
以命令行形式执行
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第17张图片
测试CL.EXE是否当前目录可以

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第18张图片
以上情况不可用,运行vcvars32.bat,此时命令CL.EXE可用
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第19张图片
编译,生成.obj
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第20张图片
链接,生成.exe
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第21张图片
点击.exe
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第22张图片

5.程序编译过程

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第23张图片

  • 编写资源的文件 -.rc资源脚本文件
  • 编译rc文件 -RC.EXE
  • 将资源链接到程序中 -LINK.EXE

给上述过程加上图标:
创建hello.rc和将图标加入
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第24张图片
写脚本语言
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第25张图片
编译
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第26张图片
链接,图标也改成small.ico的
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第27张图片

6.程序编译过程

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第28张图片

03 第一个Windows程序

1.窗口创建过程

  • 定义WinMain函数
  • 定义窗口处理函数(自定义,处理消息)
  • 注册窗口类(向操作系统写入一些数据)
  • 创建窗口(内存中创建窗口)
  • 显示窗口(绘制窗口的图形)
  • 消息循环(获取/翻译/派发消息)
  • 消息处理(同第二个)

WinBase.cpp:

#include

LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
	return DefWindowProc(hWnd, msgID, wParam, lParam);
}

//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow)
{
	//注册窗口类
	WNDCLASS wc = { 0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hInstance = hIns;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = "Main";
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wc);//将以上所有赋值全部写入操作系统。
	//在内存创建窗口
	HWND hWnd = CreateWindow("Main", "window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);
	//显示窗口
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);
	//消息循环
	MSG nMsg = { 0 };
	while (GetMessage(&nMsg, NULL, 0, 0))
	{
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理
	}
	return 0;
}

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第29张图片

04 字符编码

1.编码历史背景

  • ASC 7位 128个
  • ASCII 8位 256位
  • DBCS
  • UNICODE

2.DBCS和UNICODE码

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第30张图片

3.宽字节字符

  • wchar_t 每个字符占2个字节
    char 每个字符占1个字节
    wchar_t实际是unsigned short 类型,定义时,需要增加"L",通知编译器按照双字节编译字符串,采用UNICODE编码。
  • 需要使用支持wchar_t函数操作宽字节字符串。例如:
    wchar_t * pwszText = L"Hello wchar";
    wprintf(L"%s\n",pwszText);

WinChar.cpp:

#include
#include

void C_char()
{
	char s[] = "hello char";
	char* pszText =s;
	printf("%s\n", pszText);//strlen
}

void W_char()
{
	wchar_t s1[] = L"hello wchar";
	wchar_t* pszText = s1;
	int len = wcslen(pszText);
	wprintf(L"%s %d\n", pszText,len);//strlen
}

int main()
{
	C_char();
	W_char();
	getchar();
	return 0;
}

在这里插入图片描述

4.TCHAR

TCHAR兼容wchar_t和char

#ifdef UNICODE
typedef wchar_t TCHAR;
    #define _TEXT(quote) L##quote
#else
 typedef char TCHAR;
    #define _TEXT(quote)  quote
#endif

此时项目是多字节项目

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第31张图片
不使用UNICODE编码

#include
#include

void T_char()
{
	const TCHAR* pszText = __TEXT("hello world");
#ifdef UNICODE
	wprintf(L"%s\n", pszText);
#else
	printf("单:%s\n", pszText);
#endif
}
int main()
{

	T_char();
	getchar();
	return 0;
}

输出:
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第32张图片
将项目改成UNICODE编码,需要在#include上添加

#define UNICODE
#include
#include

void T_char()
{
	const TCHAR* pszText = __TEXT("hello world");
#ifdef UNICODE
	wprintf(L"%s\n", pszText);
#else
	printf("单:%s\n", pszText);
#endif
}
int main()
{

	T_char();
	getchar();
	return 0;
}

输出:
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第33张图片

通过更改字符集改编码格式,和上述一样的效果
Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第34张图片

//#define UNICODE
#include
#include

void T_char()
{
	const TCHAR* pszText = __TEXT("hello world");
#ifdef UNICODE
	wprintf(L"%s\n", pszText);
#else
	printf("单:%s\n", pszText);
#endif
}
int main()
{

	T_char();
	getchar();
	return 0;
}

Windows编程01_应用程序分类,开发工具和库,第一个Windows程序,字符编码_第35张图片

5.打印UNICODE字符集

UNICODE字符打印
wprintf对UNICODE字符打印支持不完善
在Windows下使用WriteConsole API打印UNICODE字符GetStdHandle

void PrintUnicode()
{
	wchar_t s1[] = L"为大家都大是大非方法大是大非水电费";
	wchar_t* pszText = s1;
	//wprintf(L"%s\n", pszText);//乱码
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	WriteConsole(hOut, pszText, wcslen(pszText), NULL, NULL);
}
int main()
{

	PrintUnicode();
	getchar();
	return 0;
}

在这里插入图片描述

6.为什么推荐使用多字节字符集:

系统调用函数的参数类型
LPSTR === char* LPCSTR === const char*
LPWSTR === wchar_t* LPCWSTR === const wchar_t*
LPTSTR === TCHAR* LPCTSTR === const TCHAR*

大量系统的变量是最后一个,使用多字节字符集,字符串可以不必添加大写L

你可能感兴趣的:(#,windows,windows)