Windows第一次实验(2)

来源:互联网 发布:软件盒子 编辑:程序博客网 时间:2024/06/15 15:14

一个简单的窗口程序:

#include <windows.h>

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window ProcedureLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{ switch(msg)

{ case WM_CLOSE: DestroyWindow(hwnd);

break;

        case WM_DESTROY: PostQuitMessage(0);

        break; default: return DefWindowProc(hwnd, msg, wParam, lParam); }

return 0;}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{ WNDCLASSEX wc; HWND hwnd; MSG Msg;

//Step 1: Registering the Window Class

    wc.cbSize = sizeof(WNDCLASSEX);

    wc.style = 0;

    wc.lpfnWndProc = WndProc;

    wc.cbClsExtra = 0;

    wc.cbWndExtra = 0;

    wc.hInstance = hInstance;

    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

    wc.lpszMenuName = NULL;

    wc.lpszClassName = g_szClassName;

    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))

    { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

// Step 2: Creating the Window

    hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window",

        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);

if(hwnd == NULL)

    { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

ShowWindow(hwnd, nCmdShow);

UpdateWindow(hwnd);

// Step 3: The Message Loop

    while(GetMessage(&Msg, NULL, 0, 0) > 0)

    { TranslateMessage(&Msg); DispatchMessage(&Msg); }

return Msg.wParam;

}

运行结果如下:

第一步:注册窗口类

const char g_szClassName[] = "myWindowClass";

上边的变量储存了我们窗口类的名字,马上会用来向系统注册窗口类。


WNDCLASSEX wc;

 wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
这是我们在WinMain()中注冊我们的窗口类的代码.我们填写一个WNDCLASSEX结构体的成员并调用RegisterClassEx().

结构体的成员对窗口类的影响如下:
cbSize
  结构体的大小.
style
  类的式样(CS_*),不要跟窗口式样(WS_*)混淆了.这个一般设置为0.
lpfnWndProc
  指向这个窗口类的窗口过程的指针.
cbClsExtra
  配置给这个类的额外內存.一般为0.
cbWndExtra
  配置给这个类的每个窗口的额外內存.一般为0.
hInstance
  应用程序实例的句柄.(从WinMain()第一个参数传递来.)
hIcon
  当用戶按下Alt+Tab组合时候显示的大图标(一般为32*32).
hCursor
  在我们的窗口上显示的光标.
hbrBackground
  设置我们窗口背景顏色的背景刷子.
lpszMenuName
  这个类的窗口所用的菜单资源的名字.
lpszClassName
  类的名字.
hIconSm
  在任务栏和窗口的左上角显示的小图标(一般为16*16).

然后我们调用RegisterClassEx()并检查是否成功,如果失败我们弹出一条提示消息并从WinMain()函数退出程序.

第二步:创建窗口

HWND hwnd;

hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);
第一个参数WS_EX_CLIENTEDGE是扩展的窗口式样。

接下来我置了类的名字g_szClassName),告诉系统我们要创建什么样的窗口.之后我们指定了我们窗口的名字或是标题用来显示在我们窗口的外观或是标题栏上

我们设置的WS_OVERLAPPEDWINDOW是一个窗口式样参数

接下来的四个参数CW_USEDEFAULTCW_USEDEFAULT320240是我们窗口的左上角的XY坐标和其宽度和高度.设为CW_USEDEFAULT来让系统自己选择在屏幕的哪个地方来放置窗口

再接下来的四个NULLNULLg_hInstNULL分別是父窗口的句柄菜单句柄应用程序实例句柄和窗口创建数据的指针.当你看到一个窗口中有一个按钮时候按钮就是子窗口包含它的窗口就是父窗口.

一定记住检查返回值

在我们创建了窗口并作检查以确定我们有一个正确的句柄后我们使用WinMain()最后的参数来显示窗口再更新它以确认它在屏幕上正确地重画了自己

ShowWindow(hwnd, nCmdShow);
   UpdateWindow(hwnd);

nCmdShow是可选的参数,你可以简单地传递SW_SHOWNORMAL即可.

第三步:消息循环

这是整个程序的心脏程序中几乎所有的控制都从这个点传递

 while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
GetMessage()从你应用的消息队列中取一个消息.调用GetMessage()时你请求将下一个可用的消息从队列中删除并返回给你来处理.如果队列为空,GetMessage()阻塞.

TranslateMessage()为键盘事件做一些额外的处理。

第四步:窗口过程

窗口过程就是程序的大脑这里所有送到窗口的息被处理

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}
窗口过程在每个息到来时被调用一次HWND参数是息相应的窗口的句柄

WM_CLOSE是在我们按下关闭按钮或按下Alt+F4组合时产生的


0 0