Windows编程基础
Windows编程基础
Unit1应用程序分类
- 控制台程序:Console
- Dos程序,本身没有窗口,通过windows Dos窗口执行
- 窗口程序
- 拥有自己的窗口,可以与用户交互
- 库程序
- 存放代码、数据的程序,执行文件可以从中取出代码执行和获取数据
- 静态库程序:扩展名LIB,在编译链接程序时,将代码放入到执行文件中
- 动态库程序:扩展名DLL,在执行文件执行时从中获取代码
应用程序对比
- 入口函数
- 控制台程序-main
- 窗口程序-winMain
- 动态库程序-DllMain
- 静态库程序-无入口函数
- 文件存在方式
- 控制台程序、窗口程序-EXE文件
- 动态库程序-DLL文件
- 静态库程序-LIB文件
Unit2开发工具和库
01编译工具
-
编译器CL.EXE,将源码编译成目标代码.obj
-
链接器LINK.EXE,将目标代码、库链接生成最终文件
-
资源编译器RC.EXE,(.rc)将资源编译,最终通过链接器存入最终文件
-
工具所在路径:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
-
注意:将上面文件夹中的
vcvars32.bat
文件拷贝到项目的所在目录下,要不然使用不了上面的工具进行操作
02库和头文件
-
Windows库
kernel32.dll
:提供了核心的API,例如进程、线程、内存管理user32.dll
:提供了窗口、消息等APIgdi32.dll
:绘图相关的API- 路径:
C:\Windows\System32
-
头文件
windows.h
:所有windows头文件的集合windef.h
:windows数据类型winbase.h
:kernel32的APIwingdi.h
:gdi32的APIwinuser.h
:user32的APIwinnt.h
:UNICODE字符集支持C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include
03相关函数
int WINAPI WinMain(
HINSTANCE hInstance,//当前程序的实例句柄
HINSTANCE hPrevInstance,//当前程序前一个实例句柄
LPSTR lpCmdLine,//命令行参数字符串
int nCmdShow//窗口的显示方式
);
int MessageBox(
HWND hWnd,//父窗口句柄
LPCTSTR lpText,//显示在信息框中的文字
LPCTSTR lpCaption,//显示在信息框中的文字
UINT uType//消息框中的按钮、图标显示类型
);//返回点击的按钮ID
04程序编译过程
- 编译环境准备:
vcvars32.bat
- 编译程序 :
CL
CL.EXE -c xxx.c
- 链接程序:
LINK
LINK.EXE xxx.obj xxx.lib
- 执行
05手动创建一个窗口程序
-
项目名为
Hello
-
用记事本新建Hello.txt文件,写入以下代码
int WinMain(HINSTANCE hIns,HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{
MessageBox(NULL, "hello world", "infomation", MB_YESNOCANCEL|MB_ICONERROR);
return 0;
}
- 修改txt文件编程c文件,
Hello.txt
变为Hello.c
- 在doc窗口下用命令进行汇编、编译、链接
- 用可能遇到命令不能用的情况,要将在终端运行
vcvars32.bat
文件
- 用可能遇到命令不能用的情况,要将在终端运行
06程序资源编译过程
- 编写资源文件:
.rc
资源脚本文件 - 编译rc文件
RC.EXE
- 将资源链接到程序中
LINK.EXE
07编译过程图解
Unit03第一个Windows窗口
01窗口创建过程
- 定义WinMain函数
- 定义窗口处理函数(自定义,处理消息)
- 注册窗口类(向操作系统写入一些数据)
- 创建窗口(内存中创建窗口)
- 显示窗口(绘制窗口的图像)
- 消息循环(获取/翻译/派发消息)
- 消息处理
02代码示例
#include <windows.h>
//窗口处理函数(自定义,处理函数)
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;
}
Unit04字符编码
01编码历史背景
- ASC(7位)
- ASCII(8位)
- DBCS(单双字节混合编码,英文字母单字节,中文双字节)
- UNICODE(双子编码)
02DBCS和UNICODE码
- DBCS字符编码
A 我 是 程 序 员
01 0203 0405 0607 0809 0A0B
但是解析时可能是
01 0203 0405 0607 0809 0A0B
0102 0304 0506 0708 090A 0B
- UNICODE编码(UTF-16)
A 我 是 程 序 员
01 0203 0405 0607 0809 0A0B
不存在解析的问题
03宽字节字符
wchar_t
每个字符占2个字节
char
每个字符占1个字节
w_char_t
实际是unsigned short
类型,定义时需增加"L"
,通知编译器按照双字节编码字符串,采用UNICODE编码- 需要使用支持
wchar_t
函数操作宽字节字符串,例如:
wchar_t* pwszText = L"Hello world";
wprintf(L"%s\n", pwszText);
#include <Windows.h>
#include <stdio.h>
void C_char(){
char* pszText = "Hello char";
printf("%s\n", pszText);
}
void W_char(){
wchar_t* pszText = L"hello wchar";
int len = wcslen(pszText);
wprintf(L"%s %d\n", pszText, len);
}
int main(){
C_char();
W_char();
getchar();
return 0;
}
04TCHAR
#ifdef UNICODE
typedef wchar_t TCHAR;
# define __TEXT(quote)L##quote
#else
typedef char TCHAR;
#define __TEXT(quote)quote
#endif
#define UNICODE
#include <Windows.h>
#include <stdio.h>
void C_char(){
char* pszText = "Hello char";
printf("%s\n", pszText);
}
void W_char(){
wchar_t* pszText = L"hello wchar";
int len = wcslen(pszText);
wprintf(L"%s %d\n", pszText, len);
}
void T_char(){
TCHAR* pszText = __TEXT("hello txt");//char* pszText = "Hello txt";/wchar_t* pszText = L"hello txt";
#ifdef UNICODE
wprintf(L"%s\n", pszText);
#else
printf("single:%s\n", pszText);
#endif
}
int main(){
C_char();
W_char();
T_char();
getchar();
return 0;
}
05打印UNICODE字符
wprintf
对UNICODE字符打印支持不完善,在Windows下使用WriteConsole
API打印UNICODE字符GetStdHandle
#define UNICODE
#include <Windows.h>
#include <stdio.h>
void C_char(){
char* pszText = "Hello char";
printf("%s\n", pszText);
}
void W_char(){
wchar_t* pszText = L"hello wchar";
int len = wcslen(pszText);
wprintf(L"%s %d\n", pszText, len);
}
void T_char(){
TCHAR* pszText = __TEXT("hello txt");//char* pszText = "Hello txt";/wchar_t* pszText = L"hello txt";
#ifdef UNICODE
wprintf(L"%s\n", pszText);
#else
printf("single:%s\n", pszText);
#endif
}
void printUnicode(){
wchar_t* pszText = L"今天在下雨";
//wprintf(L"%s\n", pszText);//打印出来的是乱码
//获取标准输出句柄
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hOut,pszText, wcslen(pszText), NULL, NULL);
}
int main(){
C_char();
W_char();
T_char();
printUnicode();
getchar();
return 0;
}