day71-----C++-Win32-编码类型、窗口函数框架

编码类型
多字节编码:
目前市场主流使用的还是多字节编码字符集。
多字节编码字符集,对于不同的字符集,所使用的内存空间大小不同,英文单词使用一个字节,汉字使用2个或者三个字节表示。
这种情况下很有可能会出现解析的时候错位,导致乱码
unicode编码:
unico编码字符集,把所有的字符都使用2个字节。可以有效避免错位的问题

vs环境中的字符
在vs中有两种字符类型,单字节的char和双字节的wchar_t。
当使用wchar_t的字符串字面值的时候,需要用L在字符串前声明,告知编译器字符串使用unicode编译
wchar_t szText = L"hello";
在vs中提供了charwchar_t的兼容方法
TCHAR 这是一个条件编译的结果
#ifdef UNICODE
    typedef WCHAR TCHAR,*PTCHAR
    #define _TEXT(quote) L##quote
#else
    tyoedef char TCHAR,*PTCHAR
    #define _TEXT(quote) quote
#endif
所以,当程序有对UNICODE宏定义,那么使用TCHAR类型的时候,使用的就是UNICODE编码
反之,当程序没有定义UNICODE,那么TCHAR代表的就是char类型

窗口程序
一个完整的窗口类型,由以下几个部分组成
1、窗口程序的入口函数WinMain
2、消息处理函数
3、注册窗口类
4、创建窗口
5、显示窗口
6、消息循环
7、消息处理(也就是消息处理函数)

按照上述过程,给以给出一个最基本的窗口程序的框架
-------------------
#include <windows.h>
HINSTANCE g_hInstance;
//2、消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) {
    switch (message) {
    case WM_DESTROY:
        PostQuitMessage(0);//向系统发送WM_QUIT消息
        break;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
}
//3、注册窗口类
void Register(LPSTR lpClassName) {
    //有两种窗口类,正常版本和扩展版本,WNDCLASS/WNDCLASSEX
    //扩展版本多了两个成员变量,结构体大小和窗口类小图标
    WNDCLASSEX wec = { 0 };
    wec.cbSize = sizeof(wec);                           //结构体大小
    wec.cbClsExtra = 0;                                 //窗口类附加数据缓存区大小
    wec.cbWndExtra = 0;                                 //窗口附加数据缓存区大小
    wec.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);     //背景刷的颜色
    wec.hCursor = NULL;                                 //鼠标句柄
    wec.hIcon = NULL;                                   //窗口图标句柄
    wec.hIconSm = NULL;                                 //窗口小图标句柄
    wec.hInstance = g_hInstance;                            //当前进程句柄
    wec.lpfnWndProc = WndProc;                          //消息处理函数
    wec.lpszClassName = lpClassName;                    //窗口类名
    wec.lpszMenuName = NULL;                            //菜单
    wec.style = CS_HREDRAW | CS_VREDRAW;                //窗口类风格
    //注册窗口类
    RegisterClassEx(&wec);
}
//4、创建窗口
HWND CreateWind(LPSTR lpClassName,LPSTR lpWindowName) {
    HWND hWnd = CreateWindowEx(0,                   //窗口类扩展风格
                            lpClassName,            //窗口类名称
                            lpWindowName,           //窗口名称
                            WS_OVERLAPPEDWINDOW,    //窗口基本风格
                            100, //窗口左上角横坐标
                            100, //窗口左上角横坐标
                            700, //窗口宽度
                            500, //窗口宽度
                            NULL,//窗口的父窗口句柄
                            NULL,//窗口菜单句柄
                            g_hInstance, //当前进程句柄
                            NULL//窗口创建时附加参数
                            );
    return hWnd;
}
//5、显示窗口
void Display(HWND hWnd) {
    ShowWindow(hWnd,SW_SHOW);
    UpdateWindow(hWnd);
}
//6、消息循环
void Message(void) {
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0)) {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}
//1、窗口函数的入口函数
int CALLBACK WinMain(HINSTANCE hInstance ,HINSTANCE prevInstance,LPSTR lpCmdLine,int nComShow) {
    Register("MyClass");
    HWND hWnd = CreateWind("MyClass", "Window");
    Display(hWnd);
    Message();
    return 0;
}
-------------------
窗口类的风格:
CS_GLOBALCLASS - 应用程序全局窗口类
CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8倍数对齐
CS_BYTEALIGNWINDOW - 窗口的水平位置8倍数对齐
CS_HREDRAW - 当窗口水平变化时,窗口重新绘制
CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制 
CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备 
CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备
CS_OWNDC - 该类型的窗口,每个窗口都使用自己的绘图(DC)设备
CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是耗费内存资源
CS_DBLCLKS - 允许窗口接收鼠标双击
CS_NOCLOSE - 窗口没有关闭按钮

窗口类的注册:
自定义窗口类,必须通过注册函数将其向系统注册,系统窗口类,系统会进行注册,就不需要用户手动注册。

窗口类的分类:
窗口类可以分为应用程序的局部窗口类,全局部窗口类,系统窗口类。
通过窗口类的窗口类风格参数的选项 CS_GLOBALCLASS,可以决定这个窗口类是否声明为全局窗口类。

窗口的创建过程:
当一个窗口发起创建的时候,会根据参数中窗口类名称先到局部窗口类中寻找,如果找到了,再用当前进程句柄和窗口类匹配。成功就用这个窗口类继续创建窗口,如果失败,就到全局窗口类中寻找,如果还是失败,就到系统窗口类中寻找。在全局和系统窗口类中匹配时,不要求当前进程句柄匹配。

创建子窗口:
创建子窗口时,需要将窗口基本风格中加上WS_CHILD|WS_VISIBLE 前者表示子窗口,后者表示显示。
还要将父窗口句柄的参数填写。
代码如下:
----------
#include <windows.h>
HINSTANCE g_hInstance;
//2、消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_DESTROY:
        PostQuitMessage(0);//向系统发送WM_QUIT消息
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}
//3、注册窗口类
void Register(LPSTR lpClassName) {
    //有两种窗口类,正常版本和扩展版本,WNDCLASS/WNDCLASSEX
    //扩展版本多了两个成员变量,结构体大小和窗口类小图标
    WNDCLASSEX wec = { 0 };
    wec.cbSize = sizeof(wec);                           //结构体大小
    wec.cbClsExtra = 0;                                 //窗口类附加数据缓存区大小
    wec.cbWndExtra = 0;                                 //窗口附加数据缓存区大小
    wec.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);     //背景刷的颜色
    wec.hCursor = NULL;                                 //鼠标句柄
    wec.hIcon = NULL;                                   //窗口图标句柄
    wec.hIconSm = NULL;                                 //窗口小图标句柄
    wec.hInstance = g_hInstance;                            //当前进程句柄
    wec.lpfnWndProc = WndProc;                          //消息处理函数
    wec.lpszClassName = lpClassName;                    //窗口类名
    wec.lpszMenuName = NULL;                            //菜单
    wec.style = CS_HREDRAW | CS_VREDRAW;                //窗口类风格
                                                        //注册窗口类
    RegisterClassEx(&wec);
}
//4、创建窗口
HWND CreateWind(LPSTR lpClassName, LPSTR lpWindowName) {
    HWND hWnd = CreateWindowEx(0,                   //窗口类扩展风格
        lpClassName,            //窗口类名称
        lpWindowName,           //窗口名称
        WS_OVERLAPPEDWINDOW,    //窗口基本风格
        100, //窗口左上角横坐标
        100, //窗口左上角横坐标
        700, //窗口宽度
        500, //窗口宽度
        NULL,//窗口的父窗口句柄
        NULL,//窗口菜单句柄
        g_hInstance, //当前进程句柄
        NULL//窗口创建时附加参数
    );
    return hWnd;
}
HWND CreateChild(HWND fWnd,LPSTR lpWindowName) {
    HWND hWnd = CreateWindowEx(0,"EDIT",lpWindowName, WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,fWnd,NULL,g_hInstance,NULL);
    return hWnd;
}
//5、显示窗口
void Display(HWND hWnd) {
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
}
//6、消息循环
void Message(void) {
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0)) {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}
//1、窗口函数的入口函数
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nComShow) {
    Register("MyClass");
    HWND hWnd = CreateWind("MyClass", "Window");
    CreateChild(hWnd, "Child");
    Display(hWnd);
    Message();
    return 0;
}
----------
窗口类附加数据缓存区和窗口附加数据缓存区的使用
窗口类附件数据缓存区是可用于基于同一个窗口类创建的两个窗口之间进行通讯的。
而窗口缓存区,则可以用于一个窗口内的其他部分进行通讯,例如,通过定时器消息,每隔一段时间向窗口缓存区中写入坐标,再由重绘消息从窗口缓存区中取出作处理。
1  定义数据空间的大小
        int cbClsExtra - 一般定义为4字节倍数  200
2 存入数据
DWORD SetClassLong(
        HWND hWnd,//窗口句柄
        int nIndex,//字节索引号(从哪个字节开始存)
        LONG dwNewLong //存入数据
);返回旧数据
 3 读取数据
DWORD GetClassLong(
        HWND hWnd,  //窗口句柄
        int nIndex  //字节索引号(从哪个字节开始读)
); 返回获取值


1 定义数据空间的大小
     int cbWndExtra;
2 存入数据
LONG SetWindowLong(
        HWND hWnd,       // handle to window
        int nIndex,      // offset of value to set
        LONG dwNewLong   // new value
);
3 读取数据
LONG GetWindowLong(
        HWND hWnd,  // handle to window
        int nIndex  // offset of value to retrieve
);
一个小球再窗口内反弹
代码如下:

----------
#include <windows.h>
#include <stdio.h>
HINSTANCE g_hInstance;
HANDLE g_hOutput;
int Rec = 100;
int Der = 0x010001;
const int xStep = 2;
const int yStep = 2;
int StepCout[4][2] = {{-xStep,-yStep},{xStep,-yStep},{xStep,yStep},{-xStep,yStep}};
int NextStep[2] = {0};
int MoveTime = 1;
void OnCreate(HWND hWnd){
    SetTimer(hWnd,1,MoveTime,NULL);
}
void OnPaint(HWND hWnd){
    int x = (int)GetWindowLong(hWnd,0);
    int y = (int)GetWindowLong(hWnd,4);
    PAINTSTRUCT ps = {0}; 
    HDC hdc = BeginPaint(hWnd,&ps);
    Ellipse(hdc,x,y,x+Rec,y+Rec);
    EndPaint(hWnd,&ps);
}
void Calculate(HWND hWnd,int &x,int &y){
    if(0 == x && 0 == y){
        x += (int)HIWORD(Der);
        y += (int)LOWORD(Der);
        NextStep[0] = StepCout[2][0];
        NextStep[1] = StepCout[2][1];
    }
    else{
        int tempx = x + NextStep[0];
        int tempy = y + NextStep[1];
        RECT Cli = {0};
        GetClientRect(hWnd,&Cli);
        if(0 > tempx){//左
            if(NextStep[1] > 0){
                NextStep[0] = StepCout[2][0];
                NextStep[1] = StepCout[2][1];
            }
            else{
                NextStep[0] = StepCout[1][0];
                NextStep[1] = StepCout[1][1];
            }
        }
        else if(Cli.right < tempx + Rec){//右
            if(NextStep[1] >0){
                NextStep[0] = StepCout[3][0];
                NextStep[1] = StepCout[3][1];
            }
            else{
                NextStep[0] = StepCout[0][0];
                NextStep[1] = StepCout[0][1];
            }
        }
        if(0 > tempy){//上
            if(NextStep[0] > 0){
                NextStep[0] = StepCout[2][0];
                NextStep[1] = StepCout[2][1];
            }
            else{
                NextStep[0] = StepCout[3][0];
                NextStep[1] = StepCout[3][1];
            }
        }
        else if(Cli.bottom < tempy + Rec){//下
            if(NextStep[0] >0){
                NextStep[0] = StepCout[1][0];
                NextStep[1] = StepCout[1][1];
            }
            else{
                NextStep[0] = StepCout[0][0];
                NextStep[1] = StepCout[0][1];
            }
        }
    }
    x = x + NextStep[0];
    y = y + NextStep[1];
}
void OnTimer(HWND hWnd,WPARAM wParam){
    int x = (int)GetWindowLong(hWnd,0);
    int y = (int)GetWindowLong(hWnd,4);
    Calculate(hWnd,x,y);
    SetWindowLong(hWnd,0,x);
    SetWindowLong(hWnd,4,y);
    InvalidateRect(hWnd,NULL,TRUE);
    char szText[256] = {0};
    sprintf(szText,"Paint(%d,%d)\n",x,y);
    WriteConsole(g_hOutput,szText,sizeof(szText),NULL,NULL);
}
//消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam){
    switch(msgID){
    case WM_TIMER:
        OnTimer(hWnd,wParam);
        break;
    case WM_PAINT:
        OnPaint(hWnd);
        break;
    case WM_CREATE:
        OnCreate(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd,msgID,wParam,lParam);
}
//注册窗口类
void Register(LPSTR lpClassName,WNDPROC WndProc){
    WNDCLASSEX wce = {0};
    wce.cbSize = sizeof(wce);                           //结构体大小
    wce.cbClsExtra = 0;                                 //窗口类附加资源缓存区大小
    wce.cbWndExtra = 8;                             //窗口附加资源缓存区大小
    wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);     //背景刷子的颜色
    wce.hCursor = NULL;                                 //鼠标句柄
    wce.hIcon = NULL;                                   //窗口图标句柄
    wce.hIconSm = NULL;                                 //窗口小图标句柄
    wce.hInstance = g_hInstance;                        //当前进程句柄
    wce.lpfnWndProc = WndProc;                          //
    wce.lpszClassName = lpClassName;
    wce.lpszMenuName = NULL;
    wce.style = CS_HREDRAW|CS_VREDRAW;
    RegisterClassEx(&wce);
}
HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName){
    HWND hWnd = CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,100,100,700,500,NULL,NULL,g_hInstance,NULL);
    SetWindowLong(hWnd,0,0);
    SetWindowLong(hWnd,4,0);
    return  hWnd;
}
void display(HWND hWnd){
    ShowWindow(hWnd,SW_SHOW);
    UpdateWindow(hWnd);
}
void Message(void){
    MSG nMsg = {0};
    while(GetMessage(&nMsg,NULL,0,0)){
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}
//1入口函数
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevIn,LPSTR lpCmdLine,int nShowCmd){
    AllocConsole();
    g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    g_hInstance = hInstance;
    //注册窗口类
    Register("MyClass",WndProc);
    //创建窗口
    HWND wHnd = CreateMain("MyClass","Window");
    //显示窗口
    display(wHnd);
    //消息循环
    Message();
    return 0;
}
----------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值