逻辑模块 渲染(绘制)模块
学习窗口的一些函数
api 应用程序接口
入口函数 main函数
void main()
{
}
int main()
{
return 0;
}
int main(int argc,char* argv[])
{
return 0;
}
win32 的入口函数是 WinMain
WinMain函数不像main函数那么自由
windows是基于C和C++的,但是又想有自己所持有的数据类型,在C,C++的基础之上做了重定义
- 区别C语言
- 顾名思义
H开头,在win32里面叫句柄(无类型指针)
P,LP开头,在win32里面叫指针
windows的数据类型基本上都是大写
#include
int __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow)
{
return 0;
}
//__stdcall 代表函数的参数是从右往左入栈,即从int nCmdShow开始入栈
//参数HINSTANCE 一个无类型的指针 void*
//hInstance 实例句柄,指向实例的一个无类型指针
//hPrevInstance 父实例句柄(现在用得很少)
//lpCmdLine 命令行参数
//nCmdShow 窗口显示的方式
弹出一个对话框
//api 函数弹出一个对话框,认识API函数的参数
int MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType);
//hWnd 窗口句柄,是一个指针,可以给空,代表这个消息的窗口的父窗口没有
//lpText 对话框里面显示的文本。
//lpCaption 对话框的的标题文本
//uType 消息盒子的风格
#include
#include
#pragma comment (lib,"winmm.lib")
//api 播放音乐的API wav格式的
BOOL PlaySound(
LPCSTR pszSound,
HMODULE hmod,
DWORD fdwSound
);
//pszSound 文件的路径名,一般用相对路径
//hmod 应用程序实例句柄
//fdwSound 播放模式
//播放模式 SND_FILENAME 制定文件名 SND_LOOP 循环 SND_ASYNC 异步
//api 播放音乐
mciSendString(
_In_ LPCWSTR lpstrCommand,
_Out_writes_opt_(uReturnLength) LPWSTR lpstrReturnString,
_In_ UINT uReturnLength,
_In_opt_ HWND hwndCallback
);
//lpstrCommand 命令字符串 通过open打开一个mp3 slias 去一两个abc的外号
//后面通过play来播放mp3
//lpstrReturnString 接受信息的缓冲区,为null表示不接受信息
//uReturnLength 接受信息的缓冲区的大小
//hwndCallback 回调函数的窗口句柄
ASCII 字符的编码
GB2312 国家标准的字符集
UTF-8 国际通用的字符集
VS中
Unicode字符集:宽字节字符集,无论是什么用的字符,固定宽度两个字符
多字节字符集:多个字节,如果是英文就是一个字节保存,如果是汉子两个字节保存
char c = 'l';
char *pc=&c; //多字节字符串
wchar_t c1='a';
wchar_t *pc1=&c1; //宽字节字符串
pc="abc"; //多字节字符串
pc1=L"abc";//宽字节字符串
//1.不管项目中使用的是什么字符集,自己可以按照上述代码自行使用多字节还是宽字节
//2.统一使用字符的通配
TCHAR c2='l';
TCHAR *pc2=&c2;
pc2 = _T("abc");
//window中只要和字符串的操作有关的函数都会有2个函数,也有一个通配的宏
窗口创建的步骤
头文件全局变量以及函数声明
#include "stdafx.h"
#include "testWin32.h" //包含自己的资源,通过此头文件,导入我们需要的资源
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
//设置警告等级的,无论删除或者留下,影响不大
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg; //消息的结构体,消息的传递
HACCEL hAccelTable; //这是一个快捷键句柄
// 初始化全局字符串
//加载字符串,表示标题栏和类名,把VS的项目名放进数组
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_TESTWIN32, szWindowClass, MAX_LOADSTRING);
//自定义函数,窗口的注册函数
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow)/*创建显示更新窗口*/)
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTWIN32));
// 主消息循环:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
目的: 注册窗口类。
窗口注册函数
//如果想在window里面去绘制一个窗口,必须先注册一个窗口类
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//WNDCLASS的扩展,如果尾部出现EX,表示此种类型的扩展
WNDCLASSEXW wcex; //结构变量
wcex.cbSize = sizeof(WNDCLASSEX); //表示自身这个结构需要多大的内存
wcex.style = CS_HREDRAW | CS_VREDRAW; //窗口类风格
//CS_HREDRAW 水平刷新 CS_VREDRAW 垂直刷新 CS_DBLCKLS 能获取鼠标双击的消息
wcex.lpfnWndProc = WndProc; //函数指针,注册窗口时指明该窗口由谁来处理用户的时间,该函数可以自定义,但是必须带4个参数
wcex.cbClsExtra = 0; //额外的类信息(暂时不用了)
wcex.cbWndExtra = 0; //额外的窗口信息(暂时不用了)
wcex.hInstance = hInstance; //窗口的句柄,窗口为哪个句柄所注册的
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTWIN32)); //窗口图标 第二个参数MAKEINTRESOURCE,把id号当作资源名来用 VS对于图标的修改支持性不强
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); //鼠标的光标样子
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //窗口的背景颜色
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_TESTWIN32); //窗口的菜单是哪个资源
wcex.lpszClassName = szWindowClass; //窗口类名
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); //小图标
return RegisterClassExW(&wcex);//真正的调用系统的注册窗口类函数去注册上面准备好的窗口类
}
CreateWindow()函数
HWND CreateWindow(LPCTSTR lpClassName, //窗口类名,要和注册时候保持一致
LPCTSTR lpWindowName, //窗口的标题名,可以修改成自己的
DWORD dwStyle, //窗口的风格
int x, //从桌面的左上角为原点CW_USEDEFAULT(使用默认)
int y, //窗口在桌面的y坐标
int nWidth, //窗口的宽度,CW_USEDEFAULT,高度会自动匹配
int nHeight, //窗口的高度,注意窗口的宽高是包含了标题栏和边框的
HWND hWndParent, //父窗口句柄
HMENU hMenu, //窗口的菜单句柄,给NULL表示用注册时的菜单,也可以用自己从新定义的菜单
HANDLE hlnstance, //窗口的实例句柄
LPVOID lpParam); //是预留信息
参数说明:
pClassName
指向一个空结束的字符串或整型数atom。如果该参数是一个整型量,它是由此前调用theGlobalAddAtom函数产生的全局量。这个小于0xC000的16位数必须是lpClassName参数字的低16位,该参数的高位必须是0。
如果lpClassName是一个[字符串,它指定了窗口的类名。这个类名可以是任何用函数RegisterClass注册的类名,或是任何预定义的控制类名。请看说明部分的列表。
LPWindowName
指向一个指定窗口名的空结束的字符串指针。
如果窗口风格指定了标题条,由lpWindowName指向的窗口标题将显示在标题条上。当使用Createwindow函数来创建控制例如按钮,选择框和静态控制时,可使用lpWindowName来指定控制文本。
dwStyle
指定创建窗口的风格。该参数可以是下列窗口风格的组合再加上说明部分的控制风格。风格意义:
值 | 说明 |
---|---|
WS_BORDER | 创建一个带边框的窗口。 |
WS_CAPTION | 创建一个有标题框的窗口(包括WS_BORDER风格)。 |
WS_CHILD | 创建一个子窗口。这个风格不能与WS_POPUP风格合用。 |
WS_CHILDWINDOW | 与WS_CHILD相同。 |
WS_CLIPCHILDREN | 当在父窗口内绘图时,排除子窗口区域。在创建父窗口时使用这个风格。 |
WS_CLIPSIBLINGS | 排除子窗口之间的相对区域,也就是,当一个特定的窗口接收到WM_PAINT消息时,WS_CLIPSIBLINGS 风格将所有层叠窗口排除在绘图之外,只重绘指定的子窗口。如果未指定WS_CLIPSIBLINGS风格,并且子窗口是层叠的,则在重绘子窗口的客户区时,就会重绘邻近的子窗口。 |
WS_DISABLED | 创建一个初始状态为禁止的子窗口。一个禁止状态的窗口不能接受来自用户的输入信息。 |
WS_DLGFRAME | 创建一个带对话框边框风格的窗口。这种风格的窗口不能带标题条。 |
WS_GROUP | 指定一组控制的第一个控制。这个控制组由第一个控制和随后定义的控制组成,自第二个控制开始每个控制,具有WS_GROUP风格,每个组的第一个控制带有WS_TABSTOP风格,从而使用户可以在组间移动。用户随后可以使用光标在组内的控制间改变键盘焦点。 |
WS_HSCROLL | 创建一个有水平滚动条的窗口。 |
WS_ICONIC | 创建一个初始状态为最小化状态的窗口。与WS_MINIMIZE风格相同。 |
WS_MAXIMIZE | 创建一个初始状态为最大化状态的窗口。 |
WS_MAXIMIZEBOX | 创建一个具有最大化按钮的窗口。该风格不能与WS_EX_CONTEXTHELP风格同时出现,同时必须指定WS_SYSMENU风格。 |
WS_OVERLAPPED | 产生一个层叠的窗口。一个层叠的窗口有一个标题条和一个边框。与WS_TILED风格相同。 |
WS_OVERLAPPEDWINDOW | 创建一个具有WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU WS_THICKFRAME,WS_MINIMIZEBOX,WS_MAXIMIZEBOX风格的层叠窗口,与WS_TILEDWINDOW风格相同。 |
WS_POPUP | 创建一个弹出式窗口。该风格不能与WS_CHILD风格同时使用。 |
WS_POPUPWINDOW | 创建一个具有WS_BORDER,WS_POPUP,WS_SYSMENU风格的窗口,WS_CAPTION和WS_POPUPWINDOW必须同时设定才能使窗口某单可见。 |
WS_SIZEBOX | 创建一个可调边框的窗口,与WS_THICKFRAME风格相同。 |
WS_SYSMENU | 创建一个在标题条上带有窗口菜单的窗口,必须同时设定WS_CAPTION风格。 |
WS_TABSTOP | 创建一个控制,这个控制在用户按下Tab键时可以获得键盘焦点。按下Tab键后使键盘焦点转移到下一具有WS_TABSTOP风格的控制。 |
WS_THICKFRAME | 创建一个具有可调边框的窗口,与WS_SIZEBOX风格相同。 |
WS_TILED | 产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与WS_OVERLAPPED风格相同。 |
WS_TILEDWINDOW | 创建一个具有WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU, WS_THICKFRAME,WS_MINIMIZEBOX,WS_MAXIMIZEBOX风格的层叠窗口。与WS_OVERLAPPEDWINDOW风格相同。 |
WS_VISIBLE | 创建一个初始状态为可见的窗口。 |
WS_VSCROLL | 创建一个有垂直滚动条的窗口。 |
X
指定窗口的初始水平位置。对一个层叠或弹出式窗口,X参数是屏幕坐标系的窗口的左上角的初始X坐标。对于子窗口,x是子窗口左上角相对父窗口客户区左上角的初始X坐标。如果该参数被设为CW_USEDEFAULT则系统为窗口选择缺省的左上角坐标并忽略Y参数。CW_USEDEFAULT只对层叠窗口有效,如果为弹出式窗口或子窗口设定,则X和y参数被设为零。
Y
指定窗口的初始垂直位置。对一个层叠或弹出式窗口,y参数是屏幕坐标系的窗口的左上角的初始y坐标。对于子窗口,y是子窗口左上角相对父窗口客户区左上角的初始y坐标。对于列表框,y是列表框客户区左上角相对父窗口客户区左上角的初始y坐标。如果层叠窗口是使用WS_VISIBLE风格位创建的并且X参数被设为CW_USEDEFAULT,则系统将忽略y参数。
nWidth
以设备单元指明窗口的宽度。对于层叠窗口,nWidth或是屏幕坐标的窗口宽度或是CW_USEDEFAULT。若nWidth是CW_USEDEFAULT,则系统为窗口选择一个缺省的高度和宽度:缺省宽度为从初始X坐标开始到屏幕的右边界,缺省高度为从初始Y坐标开始到目标区域的顶部。CW_USEDEFAULT只对层叠窗口有效;如果为弹出式窗口和子窗口设定CW_USEDEFAULT标志则nWidth和nHeight被设为零。
nHeight
以设备单元指明窗口的高度。对于层叠窗口,nHeight是屏幕坐标的窗口宽度。若nWidth被设为CW_USEDEFAULT,则系统忽略nHeight参数。
hWndParent
指向被创建窗口的父窗口或所有者窗口的句柄。若要创建一个子窗口或一个被属窗口,需提供一个有效的窗口句柄。这个参数对弹出式窗口是可选的。Windows NT 5.0;创建一个消息窗口,可以提供HWND_MESSAGE或提供一个己存在的消息窗口的句柄。
hMenu
菜单句柄,或依据窗口风格指明一个子窗口标识。对于层叠或弹出式窗口,hMenu指定窗口使用的菜单:如果使用了菜单类,则hMenu可以为NULL。对于子窗口,hMenu指定了该子窗口标识(一个整型量),一个对话框使用这个整型值将事件通知父类。应用程序确定子窗口标识,这个值对于相同父窗口的所有子窗口必须是唯一的。
hlnstance
与窗口相关联的模块实例的句柄。
lpParam
指向一个值的指针,该值传递给窗口WM_CREATE消息。该值通过在IParam参数中的CREATESTRUCT结构传递。如果应用程序调用CreateWindow创建一个MDI客户窗口,则lpParam必须指向一个CLIENTCREATESTRUCT结构。
返回值:如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。
目的: 保存实例句柄并创建主窗口
注释:
在此函数中,我们在全局变量中保存实例句柄并
创建和显示主程序窗口。
GetSystemMetrics() //得到窗口的各种尺寸
ShowCursor(false); //是否显示鼠标光标
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = FindWindow(szWindowClass,nullptr); //查找窗口函数
//如果窗口已经有了,就不再创建,返回false
if(hWnd)
{
return false;
}
//HWND 窗口句柄 创建窗口CreateWindow
hWnd = CreateWindowW(szWindowClass, //窗口类名,要和注册时候保持一致
szTitle, //窗口的标题名,可以修改成自己的
WS_OVERLAPPEDWINDOW, //窗口的风格
CW_USEDEFAULT, //从桌面的左上角为原点CW_USEDEFAULT(使用默认) 窗口在桌面的x坐标,如果x使用了CW_USEDEFAULT,那么y会自动匹配坐标
0, //窗口在桌面的y坐标
CW_USEDEFAULT, //窗口的宽度,CW_USEDEFAULT,高度会自动匹配
0, //窗口的高度,注意窗口的宽高是包含了标题栏和边框的
nullptr, //父窗口句柄
nullptr, //窗口的菜单句柄,给NULL表示用注册时的菜单,也可以用自己从新定义的菜单
hInstance, //窗口的实例句柄
nullptr); //是预留信息
//如果创建窗口失败
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow); //显示窗口
UpdateWindow(hWnd); //更新窗口
return TRUE;
}
目的: 处理主窗口的消息。
WM_COMMAND - 处理应用程序菜单
WM_PAINT - 绘制主窗口
WM_DESTROY - 发送退出消息并返回
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}