win32 框架 - window编程

win32 框架 - window编程

    • MessageBox() API
    • PlaySound() API
    • mciSendString() API
    • 字符集
    • 基本框架
      • 主函数部分,程序的入口函数
      • 函数: MyRegisterClass()
      • 函数: InitInstance(HINSTANCE, int)
      • 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
      • 快捷消息处理程序

逻辑模块 渲染(绘制)模块

学习窗口的一些函数

api 应用程序接口

入口函数 main函数

void main()
{
    
}

int main()
{
    return 0;
}

int main(int argc,char* argv[])
{
    return 0;
}
  1. win32 的入口函数是 WinMain

  2. WinMain函数不像main函数那么自由

    windows是基于C和C++的,但是又想有自己所持有的数据类型,在C,C++的基础之上做了重定义

    • 区别C语言
    • 顾名思义
  3. H开头,在win32里面叫句柄(无类型指针)

  4. P,LP开头,在win32里面叫指针

  5. windows的数据类型基本上都是大写

#include 

int __stdcall WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPWSTR    lpCmdLine,
            int       nCmdShow)
{
    return 0;
}

//__stdcall 代表函数的参数是从右往左入栈,即从int       nCmdShow开始入栈

//参数HINSTANCE  一个无类型的指针  void*
//hInstance  实例句柄,指向实例的一个无类型指针
//hPrevInstance 父实例句柄(现在用得很少)
//lpCmdLine 命令行参数
//nCmdShow 窗口显示的方式

MessageBox() API

弹出一个对话框

//api 函数弹出一个对话框,认识API函数的参数
int MessageBox(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType);
//hWnd 窗口句柄,是一个指针,可以给空,代表这个消息的窗口的父窗口没有
//lpText 对话框里面显示的文本。
//lpCaption  对话框的的标题文本
//uType  消息盒子的风格 

PlaySound() API

#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 异步

mciSendString() API

//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;
}

函数: MyRegisterClass()

目的: 注册窗口类。
窗口注册函数

//如果想在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);//真正的调用系统的注册窗口类函数去注册上面准备好的窗口类
}

函数: InitInstance(HINSTANCE, int)

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

函数: WndProc(HWND, UINT, WPARAM, LPARAM)

目的: 处理主窗口的消息。
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;
}

你可能感兴趣的:(win32学习)