Windows核心编程05-窗口类的创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows核心编程05-窗口类的创建相关的知识,希望对你有一定的参考价值。

创建主窗口:

    创建主窗口这段代码经常要用到,先存起来

    

#include "stdafx.h"

HINSTANCE g_hInstance = 0; //接收应用程序实例句柄
//主窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
    switch(nMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName,WNDPROC wndproc)
{
    WNDCLASSEX wce={0};
    wce.cbSize = sizeof(wce);
    wce.cbClsExtra = 0;
    wce.cbWndExtra = 0;
    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;
    ATOM nAtom = RegisterClassEx(&wce);
    if(nAtom==0)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName)
{
    HWND hWnd = CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hInstance,NULL);
    return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd,SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    MSG nMsg={0};
    while(GetMessage(&nMsg,NULL,0,0))
    {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    g_hInstance = hInstance;
    //注册窗口
    if(!Register("Main",WndProc))
    {
        MessageBox(NULL,"注册失败","Error",MB_OK);
        return 0;
    }
    //创建窗口
    HWND hWnd = CreateMain("Main","Window");
    Display(hWnd);
    Message();
    return 0;
}

子窗口的创建

    创建时要设置父窗口句柄

    创建风格要增加WS_CHILD|WS_VISIBLE

 窗口和窗口类的附加数据缓冲区

    作用

    注册窗口时,可以设置这两个数据内存空间的大小。

    int cbClsExtra; //窗口类的附加数据buffer大小 一般4的倍数(以字节为单位)

    int cbWndExtra;//窗口的附加数据buffer大小

    可以提供窗口类和窗口存放自己的数据的空间    

将数据存入缓冲区:
DWORD SetClassLong(
    HWND hWnd, //窗口句柄     int nIndex, //字节索引号     LONG dwNewLong //new value );
读取缓冲区
DWORD GetClassLong(
    HWND hWnd,     int nIndex );//返回值接收读取的数据
窗口的附加数据缓冲区
int cbWndExtra; 一般4的倍数(以字节为单位)
LONG SetWindowLong( 
    HWND hWnd, //窗口句柄     int nIndex, //字节索引号     LONG dwNewLong //存入的数据 );

LONG GetWindowLong(
    HWND hWnd,//窗口句柄     int nIndex //字节索引号 );//返回值接收读取的数据

窗口类附加数据缓冲区与窗口附加数据缓冲区的区别
  窗口类的附加数据缓冲区 是所有基于该窗口类创建的窗口共享的buffer --相当于类里的静态成员定义的时候分配空间
  窗口附加数据缓冲区是窗口自己私有的buffer -- 相当于类的普通成员,创建的时候才分配空间
附上完整代码:读写窗口类和窗口附加函数
#include "stdafx.h"
#include "stdio.h"

HINSTANCE g_hInstance = 0; //接收应用程序实例句柄
//主窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
    switch(nMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName,WNDPROC wndproc)
{
    WNDCLASSEX wce={0};
    wce.cbSize = sizeof(wce);
    wce.cbClsExtra = 200;
    wce.cbWndExtra = 200;
    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;
    ATOM nAtom = RegisterClassEx(&wce);
    if(nAtom==0)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName)
{
    HWND hWnd = CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hInstance,NULL);
    return hWnd;
}
//创建子窗口
HWND CreateChild(LPSTR lpCLassName,LPSTR lpWndName,HWND hParent)
{
    return CreateWindowEx(0,lpCLassName,lpWndName,WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,100,100,200,200,hParent,NULL,g_hInstance,NULL);
}
//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd,SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    MSG nMsg={0};
    while(GetMessage(&nMsg,NULL,0,0))
    {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}
//读取缓冲区
void GetExtra(HWND hWnd)
{
    DWORD nClassExtra = GetClassLong(hWnd,196);//读窗口类的附加数据缓冲区
    DWORD nWndExtra = GetWindowLong(hWnd,0);//读窗口的附加数据缓冲区
    CHAR szText[256] = {0};
    sprintf(szText,"窗口类:%d,窗口:%d",nClassExtra,nWndExtra);
    MessageBox(NULL,szText,"Infor",MB_OK);
}
//存入缓冲区
void SetExtra(HWND hWnd)
{
    SetClassLong(hWnd,196,100); //写窗口类的附加数据缓冲区
    SetWindowLong(hWnd,0,100); //写窗口的附加数据缓冲区
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    g_hInstance = hInstance;
    //注册窗口
    if(!Register("Main",WndProc))
    {
        MessageBox(NULL,"注册失败","Error",MB_OK);
        return 0;
    }
    //创建窗口
    HWND hWnd = CreateMain("Main","Window");
    Register("CHILD",DefWindowProc);
    HWND hChild1 = CreateChild("CHILD","C1",hWnd);
    HWND hChild2 = CreateChild("CHILD","C2",hWnd);
    SetExtra(hChild1);
    GetExtra(hChild2);
    Display(hWnd);
    MoveWindow(hChild1,310,100,200,200,TRUE);
    MoveWindow(hChild2,510,100,200,200,TRUE);
    Message();
    return 0;
}

 


    

以上是关于Windows核心编程05-窗口类的创建的主要内容,如果未能解决你的问题,请参考以下文章

《逐梦旅程 WINDOWS游戏编程之从零开始》读书笔记1——创建窗口

Windows核心编程03-编写窗口程序的步骤

Windows核心编程

windows 编程 —— 子窗口 与 子窗口控件

七. 界面编程--Windows编程课程学习笔记

Qt 从我的主窗口创建新窗口