基本的Windows应用程序 窗体创建

时间:2021-11-29 21:47:18

标签:

基本的Windows应用程序

转载:

下面是一个完全可以运行的Windows程序,代码很简单,读者通过代码中的注释了解它们的含义。我们将在下一节详细讲解些代码。做为一个练习,我们建议读者在你的开发工具中创建一个工程,手工输入些代码,然后编译运行这个程序。注意,如果你使用的是Visual C++,那么在选择工程类型时必须是“Win32 application project”,而不能是“Win32 console application project”。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

 

// 包含Windows头文件;这个文件中包含所有Win32 API声明的

// 结构体、类型和函数,是使用Win32 API必须的基本条件。

#include <windows.h>

// 主窗口句柄;用于标示创建的窗体。

HWND ghMainWnd = 0;

// 封装了初始化一个Windows应用程序的代码。如果初始化成功则返回true,

// 否则则返回false。

bool InitWindowsApp(HINSTANCE instanceHandle,int show);

// 封装了消息循环的代码

int    Run();

// 消息处理函数用于处理窗口收到的消息。

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

 

// 在Windows中,WinMain相当于普通C++编程中的main函数

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR pCmdLine, int nShowCmd)

{

    // 首先调用InitWindowsApp函数创建并初始化主应用程序窗口,

    // 该函数的参数是hInstance和nShowCmd。

    if(!InitWindowsApp(hInstance, nShowCmd))

        return 0;

    // 之后进入消息循环,直到接收到WM_QUIT消息后才退出循环。

    return Run();

}

 

bool InitWindowsApp(HINSTANCE instanceHandle,int show)

{

    // 首先填写一个WNDCLASS结构体,描述窗口的基本属性。

    WNDCLASS wc;

    wc.style          = CS_HREDRAW | CS_VREDRAW;

    wc.lpfnWndProc    = WndProc;

    wc.cbClsExtra      = 0;

    wc.cbWndExtra      = 0;

    wc.hInstance      = instanceHandle;

    wc.hIcon          = LoadIcon(0, IDI_APPLICATION);

    wc.hCursor        = LoadCursor(0, IDC_ARROW);

    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName    = 0;

    wc.lpszClassName = L"BasicWndClass";

    // 然后注册这个WNDCLASS示例,这样就

    //  可以基于它创建一个窗口。

    if(!RegisterClass(&wc))

    {

        MessageBox(0, L"RegisterClass FAILED",0, 0);

        return false;

    }

    // 注册了WNDCLASS示例后,我们就可以使用CreateWindow方法创建一个窗口。

    // 这个方法返回一个指向新创建的窗口的句柄(HWND)。如果创建失败,这个

    // 句柄为零。我们使用这个HWND变量引用由Windows维护的主程序窗口。

    // 我们必须保存这个窗口句柄,因为许多API函数都要求传入窗口句柄,明确所要操纵的窗口对象。

    ghMainWnd = CreateWindow(

        L"BasicWndClass",      // Registered WNDCLASS instance to use.

        L"Win32Basic",          // window title

        WS_OVERLAPPEDWINDOW,    // style flags

        CW_USEDEFAULT,          // x-coordinate

        CW_USEDEFAULT,          // y-coordinate

        CW_USEDEFAULT,          // width

        CW_USEDEFAULT,          // height

        0,                      // parent window

        0,                      // menu handle

        instanceHandle,        // app instance

        0);                    // extra creationparameters

    if(ghMainWnd == 0)

    {

        MessageBox(0, L"CreateWindow FAILED", 0, 0);

        return false;

    }

    // 最后一步是使用下面的两个函数显示并更新新创建的窗口。

    // 将刚刚创建的窗口句柄传递给这两个函数,使Windows知道要显示和更新哪个窗口。

    ShowWindow(ghMainWnd, show);

    UpdateWindow(ghMainWnd);

    return true;

}

 

int Run()

{

    MSG msg = {0};

    // 直到接收到WM_QUIT消息才会退出循环。当收到一个WM_QUIT消息时,

    // GetMessage函数会返回0,并退出循环。当出现错误时,

    // GetMessage函数会返回−1。注意,若没有收到消息,

    // GetMessage方法会让线程进入休眠状态。

    BOOL bRet = 1;

    while( (bRet = GetMessage(&msg, 0, 0, 0)) != 0)

    {

        if(bRet == -1)

        {

            MessageBox(0, L"GetMessage FAILED",L"Error", MB_OK);

            break;

        }

        else

        {

            TranslateMessage(&msg);

            DispatchMessage(&msg);

        }

    }

    return (int)msg.wParam;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

    // 处理指定的消息。注意,若自己处理消息,就必须返回0。

    switch( msg)

    {

        // 点击鼠标左键,显示一个消息框。

        case WM_LBUTTONDOWN:

            MessageBox(0, L"Hello, World", L"Hello", MB_OK);

            return 0;

        // 当按下Escape时,会销毁主程序窗口

        case WM_KEYDOWN:

            if( wParam == VK_ESCAPE)

                DestroyWindow(ghMainWnd);

            return 0;

        // 接收到WM_DESTROY消息后,发送退出信息,终止消息循环。

        case WM_DESTROY:

            PostQuitMessage(0);

            return 0;

    }

    // 将前面未处理的其他信息发送到默认的信息处理程序。

    // 注意,这个程序返回的是DefWindowProc的返回值。

    return DefWindowProc(hWnd, msg, wParam, lParam);

}